2006-04-03 21:00:13 +00:00
/*
* FreeSWITCH Modular Media Switching Software Library / Soft - Switch Application
2014-02-05 21:02:28 +00:00
* Copyright ( C ) 2005 - 2014 , Anthony Minessale II < anthm @ freeswitch . org >
2006-04-03 21:00:13 +00:00
*
* 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
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2006-04-03 21:00:13 +00:00
* Portions created by the Initial Developer are Copyright ( C )
* the Initial Developer . All Rights Reserved .
*
* Contributor ( s ) :
*
2009-02-04 21:20:54 +00:00
* Anthony Minessale II < anthm @ freeswitch . org >
2007-04-07 03:07:43 +00:00
* Marcel Barbulescu < marcelbarbulescu @ gmail . com >
2013-08-08 00:19:05 +00:00
* Seven Du < dujinfang @ gmail . com >
2006-04-03 21:00:13 +00:00
*
* switch_rtp . c - - RTP
*
*/
2009-01-16 20:29:56 +00:00
//#define DEBUG_2833
2009-04-26 22:10:28 +00:00
//#define RTP_DEBUG_WRITE_DELTA
2011-01-21 21:03:19 +00:00
//#define DEBUG_MISSED_SEQ
2014-06-13 10:06:14 +00:00
//#define DEBUG_EXTRA
2014-07-21 09:40:59 +00:00
//#define DEBUG_RTCP
2015-10-24 00:27:25 +00:00
# define DEBUG_ESTIMATORS
2014-07-21 09:40:59 +00:00
2006-04-03 21:00:13 +00:00
# include <switch.h>
2013-04-03 13:54:42 +00:00
# ifndef _MSC_VER
2013-02-04 22:51:58 +00:00
# include <switch_private.h>
2013-04-03 13:54:42 +00:00
# endif
2007-06-20 09:02:30 +00:00
# include <switch_stun.h>
2011-12-16 00:13:09 +00:00
# include <apr_network_io.h>
2006-04-03 21:00:13 +00:00
# undef PACKAGE_NAME
# undef PACKAGE_STRING
# undef PACKAGE_TARNAME
# undef PACKAGE_VERSION
# undef PACKAGE_BUGREPORT
2006-10-02 20:49:26 +00:00
# undef VERSION
# undef PACKAGE
2006-12-15 15:33:43 +00:00
# undef inline
2006-04-03 21:00:13 +00:00
# include <datatypes.h>
# include <srtp.h>
2013-01-17 23:59:53 +00:00
# include <srtp_priv.h>
2013-02-04 16:47:27 +00:00
# include <switch_ssl.h>
2015-09-11 16:37:01 +00:00
# include <switch_jitterbuffer.h>
2015-10-24 00:27:25 +00:00
# include <switch_estimators.h>
2013-02-02 02:07:56 +00:00
2014-06-03 00:09:10 +00:00
# define JITTER_LEAD_FRAMES 10
2008-01-18 18:14:53 +00:00
# define READ_INC(rtp_session) switch_mutex_lock(rtp_session->read_mutex); rtp_session->reading++
# define READ_DEC(rtp_session) switch_mutex_unlock(rtp_session->read_mutex); rtp_session->reading--
# define WRITE_INC(rtp_session) switch_mutex_lock(rtp_session->write_mutex); rtp_session->writing++
# define WRITE_DEC(rtp_session) switch_mutex_unlock(rtp_session->write_mutex); rtp_session->writing--
2008-01-16 06:01:53 +00:00
2013-10-15 21:24:32 +00:00
# define RTP_STUN_FREQ 1000000
2006-04-03 21:00:13 +00:00
# define rtp_header_len 12
2006-04-05 20:17:22 +00:00
# define RTP_START_PORT 16384
# define RTP_END_PORT 32768
2006-04-10 16:11:24 +00:00
# define MASTER_KEY_LEN 30
2006-05-05 13:35:33 +00:00
# define RTP_MAGIC_NUMBER 42
2014-06-28 03:43:08 +00:00
# define WARN_SRTP_ERRS 10
# define MAX_SRTP_ERRS 100
2014-07-21 09:40:59 +00:00
# define NTP_TIME_OFFSET 2208988800UL
2015-10-09 17:57:36 +00:00
# define ZRTP_MAGIC_COOKIE 0x5a525450
2015-06-12 07:38:52 +00:00
static const switch_payload_t INVALID_PT = 255 ;
2006-04-05 20:17:22 +00:00
2014-01-30 00:08:27 +00:00
# define DTMF_SANITY (rtp_session->one_second * 30)
2014-02-27 16:42:30 +00:00
# define rtp_session_name(_rtp_session) _rtp_session->session ? switch_core_session_get_name(_rtp_session->session) : "-"
2007-04-07 03:07:43 +00:00
static switch_port_t START_PORT = RTP_START_PORT ;
static switch_port_t END_PORT = RTP_END_PORT ;
2006-04-05 20:17:22 +00:00
static switch_mutex_t * port_lock = NULL ;
2015-10-04 21:53:43 +00:00
static switch_size_t do_flush ( switch_rtp_t * rtp_session , int force , switch_size_t bytes_in ) ;
2006-04-03 21:00:13 +00:00
typedef srtp_hdr_t rtp_hdr_t ;
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
2012-04-05 04:10:55 +00:00
# include "zrtp.h"
2009-05-20 23:04:05 +00:00
static zrtp_global_t * zrtp_global ;
2012-05-17 06:13:32 +00:00
# ifndef WIN32
2009-05-20 23:04:05 +00:00
static zrtp_zid_t zid = { " FreeSWITCH01 " } ;
2012-05-17 06:13:32 +00:00
# else
2012-05-17 13:38:11 +00:00
static zrtp_zid_t zid = { " FreeSWITCH0 " } ;
2012-05-17 06:13:32 +00:00
# endif
2009-05-20 23:04:05 +00:00
static int zrtp_on = 0 ;
2009-09-10 14:47:27 +00:00
# define ZRTP_MITM_TRIES 100
2009-05-20 23:04:05 +00:00
# endif
2006-05-04 20:19:23 +00:00
# ifdef _MSC_VER
2006-05-05 13:35:33 +00:00
# pragma pack(4)
2006-05-04 20:19:23 +00:00
# endif
# ifdef _MSC_VER
# pragma pack()
2011-05-02 16:33:57 +00:00
# define ENABLE_SRTP
2006-05-04 20:19:23 +00:00
# endif
2007-12-11 19:15:02 +00:00
static switch_hash_t * alloc_hash = NULL ;
2006-05-04 20:19:23 +00:00
2006-04-03 21:00:13 +00:00
typedef struct {
2007-03-29 22:31:56 +00:00
srtp_hdr_t header ;
char body [ SWITCH_RTP_MAX_BUF_LEN ] ;
2012-12-14 01:49:02 +00:00
switch_rtp_hdr_ext_t * ext ;
char * ebody ;
2006-04-03 21:00:13 +00:00
} rtp_msg_t ;
2012-12-14 01:49:02 +00:00
# define RTP_BODY(_s) (char *) (_s->recv_msg.ebody ? _s->recv_msg.ebody : _s->recv_msg.body)
2013-06-18 00:52:37 +00:00
typedef struct {
uint32_t ssrc ;
uint8_t seq ;
uint8_t r1 ;
uint8_t r2 ;
uint8_t r3 ;
} rtcp_fir_t ;
# ifdef _MSC_VER
# pragma pack(push, r1, 1)
# endif
2016-04-07 19:11:42 +00:00
typedef struct switch_rtcp_sdes_unit_s {
unsigned char type ;
unsigned char length ;
char value [ ] ;
} switch_rtcp_sdes_unit_t ;
2015-05-07 16:58:49 +00:00
typedef struct {
uint32_t ssrc ;
2015-05-13 00:55:28 +00:00
uint8_t parts [ 4 ] ;
2015-05-07 16:58:49 +00:00
} rtcp_tmmbx_t ;
# if SWITCH_BYTE_ORDER == __BIG_ENDIAN
2013-06-18 00:52:37 +00:00
typedef struct {
unsigned version : 2 ;
unsigned p : 1 ;
unsigned fmt : 5 ;
unsigned pt : 8 ;
unsigned length : 16 ;
uint32_t send_ssrc ;
uint32_t recv_ssrc ;
} switch_rtcp_ext_hdr_t ;
# else /* BIG_ENDIAN */
typedef struct {
unsigned fmt : 5 ;
unsigned p : 1 ;
unsigned version : 2 ;
unsigned pt : 8 ;
unsigned length : 16 ;
uint32_t send_ssrc ;
uint32_t recv_ssrc ;
} switch_rtcp_ext_hdr_t ;
# endif
# ifdef _MSC_VER
# pragma pack(pop, r1)
# endif
2015-10-24 00:27:25 +00:00
# define KALMAN_SYSTEM_MODELS 3 /*loss, jitter, rtt*/
# define EST_LOSS 0
# define EST_JITTER 1
# define EST_RTT 2
2013-06-18 00:52:37 +00:00
typedef struct {
switch_rtcp_ext_hdr_t header ;
char body [ SWITCH_RTCP_MAX_BUF_LEN ] ;
} rtcp_ext_msg_t ;
2010-04-20 00:07:23 +00:00
typedef struct {
switch_rtcp_hdr_t header ;
char body [ SWITCH_RTCP_MAX_BUF_LEN ] ;
} rtcp_msg_t ;
2012-12-14 01:49:02 +00:00
2011-12-16 15:16:37 +00:00
typedef enum {
VAD_FIRE_TALK = ( 1 < < 0 ) ,
VAD_FIRE_NOT_TALK = ( 1 < < 1 )
} vad_talk_mask_t ;
2006-04-21 22:31:08 +00:00
struct switch_rtp_vad_data {
2006-04-29 06:05:03 +00:00
switch_core_session_t * session ;
switch_codec_t vad_codec ;
switch_codec_t * read_codec ;
2006-04-21 22:31:08 +00:00
uint32_t bg_level ;
uint32_t bg_count ;
uint32_t bg_len ;
uint32_t diff_level ;
uint8_t hangunder ;
uint8_t hangunder_hits ;
uint8_t hangover ;
uint8_t hangover_hits ;
uint8_t cng_freq ;
uint8_t cng_count ;
switch_vad_flag_t flags ;
uint32_t ts ;
uint8_t start ;
uint8_t start_count ;
uint8_t scan_freq ;
time_t next_scan ;
2016-04-01 00:25:56 +00:00
switch_time_t start_talking ;
switch_time_t stop_talking ;
switch_time_t total_talk_time ;
2011-12-16 15:16:37 +00:00
int fire_events ;
2006-04-21 22:31:08 +00:00
} ;
2006-05-04 17:51:53 +00:00
struct switch_rtp_rfc2833_data {
switch_queue_t * dtmf_queue ;
char out_digit ;
unsigned char out_digit_packet [ 4 ] ;
unsigned int out_digit_sofar ;
2008-01-11 21:59:17 +00:00
unsigned int out_digit_sub_sofar ;
2006-05-04 17:51:53 +00:00
unsigned int out_digit_dur ;
2007-03-22 20:55:46 +00:00
uint16_t in_digit_seq ;
2008-01-11 21:59:17 +00:00
uint32_t in_digit_ts ;
2011-02-18 22:54:51 +00:00
uint32_t last_in_digit_ts ;
2009-01-12 22:18:48 +00:00
uint32_t in_digit_sanity ;
2011-01-07 23:53:09 +00:00
uint32_t in_interleaved ;
2008-01-11 01:27:24 +00:00
uint32_t timestamp_dtmf ;
2008-01-11 21:59:17 +00:00
uint16_t last_duration ;
uint32_t flip ;
char first_digit ;
2006-05-04 17:51:53 +00:00
char last_digit ;
2007-12-22 00:32:20 +00:00
switch_queue_t * dtmf_inqueue ;
2006-05-04 17:51:53 +00:00
switch_mutex_t * dtmf_mutex ;
2011-01-07 22:04:24 +00:00
uint8_t in_digit_queued ;
2006-05-04 17:51:53 +00:00
} ;
2012-06-22 23:08:59 +00:00
typedef struct {
char * ice_user ;
char * user_ice ;
2014-12-12 20:55:14 +00:00
char * luser_ice ;
2012-06-22 23:08:59 +00:00
char * pass ;
2013-01-14 02:12:23 +00:00
char * rpass ;
2013-02-11 19:42:50 +00:00
switch_sockaddr_t * addr ;
2012-06-22 23:08:59 +00:00
uint32_t funny_stun ;
2013-06-18 00:52:37 +00:00
switch_time_t next_run ;
2013-01-13 07:29:05 +00:00
switch_core_media_ice_type_t type ;
2013-01-26 23:53:15 +00:00
ice_t * ice_params ;
ice_proto_t proto ;
2013-01-13 07:29:05 +00:00
uint8_t sending ;
uint8_t ready ;
2013-01-15 19:32:47 +00:00
uint8_t rready ;
2013-02-16 03:27:49 +00:00
int missed_count ;
2014-12-12 20:55:14 +00:00
char last_sent_id [ 13 ] ;
2015-01-12 18:55:42 +00:00
switch_time_t last_ok ;
2012-06-22 23:08:59 +00:00
} switch_rtp_ice_t ;
2013-02-01 20:29:40 +00:00
struct switch_rtp ;
typedef struct switch_dtls_s {
/* DTLS */
SSL_CTX * ssl_ctx ;
SSL * ssl ;
BIO * read_bio ;
BIO * write_bio ;
dtls_fingerprint_t * local_fp ;
dtls_fingerprint_t * remote_fp ;
dtls_state_t state ;
2013-06-18 00:52:37 +00:00
dtls_state_t last_state ;
uint8_t new_state ;
2013-02-01 20:29:40 +00:00
dtls_type_t type ;
switch_size_t bytes ;
void * data ;
switch_socket_t * sock_output ;
switch_sockaddr_t * remote_addr ;
char * rsa ;
char * pvt ;
2013-02-02 02:07:56 +00:00
char * ca ;
2014-02-19 02:05:29 +00:00
char * pem ;
2013-02-01 20:29:40 +00:00
struct switch_rtp * rtp_session ;
} switch_dtls_t ;
typedef int ( * dtls_state_handler_t ) ( switch_rtp_t * , switch_dtls_t * ) ;
static int dtls_state_handshake ( switch_rtp_t * rtp_session , switch_dtls_t * dtls ) ;
static int dtls_state_ready ( switch_rtp_t * rtp_session , switch_dtls_t * dtls ) ;
static int dtls_state_setup ( switch_rtp_t * rtp_session , switch_dtls_t * dtls ) ;
2014-02-19 02:05:29 +00:00
static int dtls_state_fail ( switch_rtp_t * rtp_session , switch_dtls_t * dtls ) ;
2013-02-01 20:29:40 +00:00
2014-12-10 20:44:59 +00:00
dtls_state_handler_t dtls_states [ DS_INVALID ] = { NULL , dtls_state_handshake , dtls_state_setup , dtls_state_ready , dtls_state_fail } ;
2013-02-01 20:29:40 +00:00
2013-07-11 22:38:24 +00:00
typedef struct ts_normalize_s {
uint32_t last_ssrc ;
uint32_t last_frame ;
uint32_t ts ;
uint32_t delta ;
2013-07-17 00:15:56 +00:00
uint32_t delta_ct ;
uint32_t delta_ttl ;
2013-07-11 22:38:24 +00:00
} ts_normalize_t ;
2013-02-01 20:29:40 +00:00
2006-04-03 21:00:13 +00:00
struct switch_rtp {
2008-07-03 18:50:15 +00:00
/*
* Two sockets are needed because we might be transcoding protocol families
* ( e . g . receive over IPv4 and send over IPv6 ) . In case the protocol
* families are equal , sock_input = = sock_output and only one socket is
* used .
*/
2010-04-20 00:07:23 +00:00
switch_socket_t * sock_input , * sock_output , * rtcp_sock_input , * rtcp_sock_output ;
switch_pollfd_t * read_pollfd , * rtcp_read_pollfd ;
2009-03-30 21:12:06 +00:00
switch_pollfd_t * jb_pollfd ;
2010-02-06 03:38:24 +00:00
2010-04-20 00:07:23 +00:00
switch_sockaddr_t * local_addr , * rtcp_local_addr ;
2006-04-03 21:00:13 +00:00
rtp_msg_t send_msg ;
2010-04-20 00:07:23 +00:00
rtcp_msg_t rtcp_send_msg ;
2015-06-05 23:11:14 +00:00
switch_rtcp_frame_t rtcp_frame ;
2014-12-09 20:18:36 +00:00
2013-06-18 00:52:37 +00:00
uint8_t fir_seq ;
2014-12-09 20:18:36 +00:00
uint16_t fir_count ;
uint16_t pli_count ;
2015-05-13 00:55:28 +00:00
uint32_t cur_tmmbr ;
2015-05-07 16:58:49 +00:00
uint32_t tmmbr ;
uint32_t tmmbn ;
2013-07-11 22:38:24 +00:00
ts_normalize_t ts_norm ;
2010-04-20 00:07:23 +00:00
switch_sockaddr_t * remote_addr , * rtcp_remote_addr ;
2006-04-03 21:00:13 +00:00
rtp_msg_t recv_msg ;
2010-04-20 00:07:23 +00:00
rtcp_msg_t rtcp_recv_msg ;
2013-01-17 01:04:57 +00:00
rtcp_msg_t * rtcp_recv_msg_p ;
2008-07-18 16:18:31 +00:00
2007-05-16 17:47:24 +00:00
uint32_t autoadj_window ;
2014-07-16 00:25:56 +00:00
uint32_t autoadj_threshold ;
2007-05-16 17:47:24 +00:00
uint32_t autoadj_tally ;
2007-03-29 22:31:56 +00:00
2013-02-03 05:57:27 +00:00
srtp_ctx_t * send_ctx [ 2 ] ;
srtp_ctx_t * recv_ctx [ 2 ] ;
srtp_policy_t send_policy [ 2 ] ;
srtp_policy_t recv_policy [ 2 ] ;
uint32_t srtp_errs [ 2 ] ;
uint32_t srctp_errs [ 2 ] ;
int srtp_idx_rtp ;
int srtp_idx_rtcp ;
2008-05-27 04:30:03 +00:00
2013-02-01 20:29:40 +00:00
switch_dtls_t * dtls ;
switch_dtls_t * rtcp_dtls ;
2015-05-05 16:58:27 +00:00
rtp_hdr_t last_rtp_hdr ;
2006-04-04 04:15:39 +00:00
uint16_t seq ;
2008-01-12 04:56:20 +00:00
uint32_t ssrc ;
2013-07-11 22:38:24 +00:00
uint32_t remote_ssrc ;
2015-05-05 16:58:27 +00:00
uint32_t last_jb_read_ssrc ;
2011-08-31 17:03:57 +00:00
int8_t sending_dtmf ;
2011-08-30 20:00:07 +00:00
uint8_t need_mark ;
2006-04-18 16:50:34 +00:00
switch_payload_t payload ;
2006-04-29 23:43:28 +00:00
switch_rtp_invalid_handler_t invalid_handler ;
2006-04-03 21:00:13 +00:00
void * private_data ;
uint32_t ts ;
2007-02-12 18:22:30 +00:00
uint32_t last_write_ts ;
2010-12-22 18:21:52 +00:00
uint32_t last_read_ts ;
2010-12-23 02:38:57 +00:00
uint32_t last_cng_ts ;
2007-03-17 01:52:05 +00:00
uint32_t last_write_samplecount ;
2011-11-14 18:37:45 +00:00
uint32_t delay_samples ;
2012-04-18 14:55:58 +00:00
uint32_t next_write_samplecount ;
2011-09-01 00:30:51 +00:00
uint32_t max_next_write_samplecount ;
uint32_t queue_delay ;
2008-12-09 00:32:51 +00:00
switch_time_t last_write_timestamp ;
2012-12-18 22:06:29 +00:00
uint32_t flags [ SWITCH_RTP_FLAG_INVALID ] ;
2006-04-29 01:00:52 +00:00
switch_memory_pool_t * pool ;
2015-01-21 01:20:20 +00:00
switch_sockaddr_t * from_addr , * rtp_from_addr , * rtcp_from_addr ;
2007-12-11 19:15:02 +00:00
char * rx_host ;
switch_port_t rx_port ;
2012-06-22 23:08:59 +00:00
switch_rtp_ice_t ice ;
switch_rtp_ice_t rtcp_ice ;
2007-03-29 22:31:56 +00:00
char * timer_name ;
2010-04-20 00:07:23 +00:00
char * local_host_str ;
2008-09-18 21:50:18 +00:00
char * remote_host_str ;
2010-06-24 21:01:55 +00:00
char * eff_remote_host_str ;
2015-08-24 18:13:43 +00:00
switch_time_t first_stun ;
2006-04-04 17:22:06 +00:00
switch_time_t last_stun ;
2015-08-26 18:38:51 +00:00
uint32_t wrong_addrs ;
2007-03-09 16:30:34 +00:00
uint32_t samples_per_interval ;
2009-09-10 00:46:24 +00:00
uint32_t samples_per_second ;
2007-03-09 16:30:34 +00:00
uint32_t conf_samples_per_interval ;
2014-11-15 01:01:56 +00:00
switch_time_t rtcp_last_sent ;
2007-03-09 16:30:34 +00:00
uint32_t rsamples_per_interval ;
2006-04-07 17:32:14 +00:00
uint32_t ms_per_packet ;
2014-01-30 00:08:27 +00:00
uint32_t one_second ;
uint32_t consecutive_flaws ;
uint32_t jitter_lead ;
double old_mean ;
switch_time_t next_stat_check_time ;
2010-04-20 00:07:23 +00:00
switch_port_t local_port ;
2008-09-22 18:28:21 +00:00
switch_port_t remote_port ;
2010-06-24 21:01:55 +00:00
switch_port_t eff_remote_port ;
2010-04-20 21:15:37 +00:00
switch_port_t remote_rtcp_port ;
2012-06-22 23:08:59 +00:00
2006-04-21 22:31:08 +00:00
struct switch_rtp_vad_data vad_data ;
2006-05-04 17:51:53 +00:00
struct switch_rtp_rfc2833_data dtmf_data ;
2006-05-27 00:24:32 +00:00
switch_payload_t te ;
2010-03-16 22:49:54 +00:00
switch_payload_t recv_te ;
2007-03-07 18:34:22 +00:00
switch_payload_t cng_pt ;
2006-08-28 23:05:26 +00:00
switch_mutex_t * flag_mutex ;
2008-01-18 18:14:53 +00:00
switch_mutex_t * read_mutex ;
switch_mutex_t * write_mutex ;
2015-01-22 03:08:09 +00:00
switch_mutex_t * ice_mutex ;
2006-09-12 22:23:45 +00:00
switch_timer_t timer ;
2006-09-14 00:15:03 +00:00
uint8_t ready ;
2007-03-17 01:52:05 +00:00
uint8_t cn ;
2015-09-11 16:37:01 +00:00
switch_jb_t * jb ;
switch_jb_t * vb ;
switch_jb_t * vbw ;
2007-10-31 02:12:30 +00:00
uint32_t max_missed_packets ;
uint32_t missed_count ;
2007-12-18 17:33:29 +00:00
rtp_msg_t write_msg ;
2008-01-16 06:01:53 +00:00
switch_rtp_crypto_key_t * crypto_keys [ SWITCH_RTP_CRYPTO_MAX ] ;
2008-01-18 18:14:53 +00:00
int reading ;
int writing ;
2008-07-18 16:18:31 +00:00
char * stun_ip ;
2008-07-18 20:25:39 +00:00
switch_port_t stun_port ;
2008-09-29 23:03:27 +00:00
int from_auto ;
2008-10-01 18:02:46 +00:00
uint32_t cng_count ;
2008-12-29 21:23:17 +00:00
switch_rtp_bug_flag_t rtp_bugs ;
2009-04-03 21:48:52 +00:00
switch_rtp_stats_t stats ;
2015-11-17 01:31:32 +00:00
uint32_t clean_stream ;
uint32_t bad_stream ;
uint32_t recovering_stream ;
2010-08-05 22:56:18 +00:00
uint32_t hot_hits ;
2009-09-10 18:26:50 +00:00
uint32_t sync_packets ;
2010-04-20 00:07:23 +00:00
int rtcp_interval ;
2015-05-13 16:50:04 +00:00
int rtcp_sent_packets ;
2010-04-20 00:07:23 +00:00
switch_bool_t rtcp_fresh_frame ;
2012-04-18 14:55:58 +00:00
switch_time_t send_time ;
switch_byte_t auto_adj_used ;
uint8_t pause_jb ;
uint16_t last_seq ;
switch_time_t last_read_time ;
switch_size_t last_flush_packet_count ;
uint32_t interdigit_delay ;
2013-01-15 05:17:28 +00:00
switch_core_session_t * session ;
2013-11-07 22:48:00 +00:00
payload_map_t * * pmaps ;
payload_map_t * pmap_tail ;
2015-10-24 00:27:25 +00:00
kalman_estimator_t * estimators [ KALMAN_SYSTEM_MODELS ] ;
cusum_kalman_detector_t * detectors [ KALMAN_SYSTEM_MODELS ] ;
2015-10-04 21:53:43 +00:00
int ice_adj ;
2015-10-05 23:59:58 +00:00
uint8_t has_rtp ;
uint8_t has_rtcp ;
uint8_t has_ice ;
2015-10-07 16:21:51 +00:00
uint8_t punts ;
uint8_t clean ;
2016-07-22 03:11:29 +00:00
uint32_t last_max_vb_frames ;
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
zrtp_session_t * zrtp_session ;
zrtp_profile_t * zrtp_profile ;
2010-02-03 19:19:10 +00:00
zrtp_stream_t * zrtp_stream ;
2009-05-23 01:50:56 +00:00
int zrtp_mitm_tries ;
2010-02-03 19:19:10 +00:00
int zinit ;
2009-05-20 23:04:05 +00:00
# endif
2010-04-20 00:07:23 +00:00
} ;
2009-04-26 22:10:05 +00:00
2014-02-24 22:06:01 +00:00
struct switch_rtcp_report_block {
uint32_t ssrc ; /* The SSRC identifier of the source to which the information in this reception report block pertains. */
unsigned int fraction : 8 ; /* The fraction of RTP data packets from source SSRC_n lost since the previous SR or RR packet was sent */
int lost : 24 ; /* The total number of RTP data packets from source SSRC_n that have been lost since the beginning of reception */
uint32_t highest_sequence_number_received ;
uint32_t jitter ; /* An estimate of the statistical variance of the RTP data packet interarrival time, measured in timestamp units and expressed as an unsigned integer. */
uint32_t lsr ; /* The middle 32 bits out of 64 in the NTP timestamp */
uint32_t dlsr ; /* The delay, expressed in units of 1/65536 seconds, between receiving the last SR packet from source SSRC_n and sending this reception report block */
} ;
struct switch_rtcp_sr_head {
2014-07-21 09:40:59 +00:00
uint32_t ssrc ;
uint32_t ntp_msw ;
uint32_t ntp_lsw ;
uint32_t ts ;
uint32_t pc ;
uint32_t oc ;
2014-07-21 09:40:59 +00:00
} ;
2014-07-21 09:40:59 +00:00
struct switch_rtcp_sender_info {
uint32_t ntp_msw ;
uint32_t ntp_lsw ;
uint32_t ts ;
uint32_t pc ;
uint32_t oc ;
2006-04-03 21:00:13 +00:00
} ;
2014-07-21 09:40:59 +00:00
struct switch_rtcp_sender_report {
uint32_t ssrc ;
struct switch_rtcp_sender_info sender_info ;
struct switch_rtcp_report_block report_block ;
2014-09-12 17:06:58 +00:00
} ;
2014-07-21 09:40:59 +00:00
struct switch_rtcp_receiver_report {
uint32_t ssrc ;
struct switch_rtcp_report_block report_block ;
2014-07-21 09:40:59 +00:00
} ;
2011-01-21 21:03:19 +00:00
typedef enum {
RESULT_CONTINUE ,
RESULT_GOTO_END ,
RESULT_GOTO_RECVFROM ,
RESULT_GOTO_TIMERCHECK
} handle_rfc2833_result_t ;
2013-01-15 05:17:28 +00:00
static void do_2833 ( switch_rtp_t * rtp_session ) ;
2011-03-10 02:06:27 +00:00
2013-01-14 18:15:31 +00:00
2016-07-11 03:25:14 +00:00
# define rtp_type(rtp_session) rtp_session->flags[SWITCH_RTP_FLAG_TEXT] ? "text" : (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] ? "video" : "audio")
2013-01-14 18:15:31 +00:00
2014-12-18 19:08:11 +00:00
static void switch_rtp_change_ice_dest ( switch_rtp_t * rtp_session , switch_rtp_ice_t * ice , const char * host , switch_port_t port )
{
int is_rtcp = ice = = & rtp_session - > rtcp_ice ;
const char * err = " " ;
ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . con_addr = switch_core_strdup ( rtp_session - > pool , host ) ;
ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . con_port = port ;
ice - > missed_count = 0 ;
2015-05-05 16:58:27 +00:00
2015-05-27 06:15:28 +00:00
if ( is_rtcp ) {
ice - > addr = rtp_session - > rtcp_remote_addr ;
} else {
switch_rtp_set_remote_address ( rtp_session , host , port , 0 , SWITCH_FALSE , & err ) ;
2015-05-05 16:58:27 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
2015-05-27 06:15:28 +00:00
ice - > addr = rtp_session - > remote_addr ;
2015-05-05 16:58:27 +00:00
}
}
2014-12-18 19:08:11 +00:00
}
2013-01-14 18:15:31 +00:00
2011-01-21 21:03:19 +00:00
static handle_rfc2833_result_t handle_rfc2833 ( switch_rtp_t * rtp_session , switch_size_t bytes , int * do_cng )
{
2012-11-21 19:59:23 +00:00
2013-12-30 19:21:45 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] ) {
rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] + + ;
2014-01-30 00:08:27 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] > DTMF_SANITY ) {
2013-12-30 19:21:45 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] = 0 ;
2014-01-30 00:08:27 +00:00
} else {
rtp_session - > stats . inbound . last_processed_seq = 0 ;
2013-12-30 19:21:45 +00:00
}
}
2011-01-21 21:03:19 +00:00
# ifdef DEBUG_2833
if ( rtp_session - > dtmf_data . in_digit_sanity & & ! ( rtp_session - > dtmf_data . in_digit_sanity % 100 ) ) {
2012-12-14 01:49:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " sanity %d %ld \n " , rtp_session - > dtmf_data . in_digit_sanity , bytes ) ;
2011-01-21 21:03:19 +00:00
}
# endif
if ( rtp_session - > dtmf_data . in_digit_sanity & & ! - - rtp_session - > dtmf_data . in_digit_sanity ) {
2013-01-15 05:17:28 +00:00
2011-01-21 21:03:19 +00:00
rtp_session - > dtmf_data . last_digit = 0 ;
rtp_session - > dtmf_data . in_digit_ts = 0 ;
2016-04-14 17:38:18 +00:00
rtp_session - > dtmf_data . in_digit_queued = 0 ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Failed DTMF sanity check. \n " ) ;
2011-01-21 21:03:19 +00:00
}
/* RFC2833 ... like all RFC RE: VoIP, guaranteed to drive you to insanity!
We know the real rules here , but if we enforce them , it ' s an interop nightmare so ,
we put up with as much as we can so we don ' t have to deal with being punished for
doing it right . Nice guys finish last !
*/
2013-12-30 19:21:45 +00:00
2012-12-18 22:06:29 +00:00
if ( bytes > rtp_header_len & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] & &
2015-10-06 14:34:19 +00:00
rtp_session - > last_rtp_hdr . pt = = rtp_session - > recv_te ) {
2011-01-21 21:03:19 +00:00
switch_size_t len = bytes - rtp_header_len ;
2012-12-14 01:49:02 +00:00
unsigned char * packet = ( unsigned char * ) RTP_BODY ( rtp_session ) ;
2011-01-21 21:03:19 +00:00
int end ;
uint16_t duration ;
char key ;
uint16_t in_digit_seq ;
uint32_t ts ;
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . last_processed_seq = 0 ;
2011-01-21 21:03:19 +00:00
if ( ! ( packet [ 0 ] | | packet [ 1 ] | | packet [ 2 ] | | packet [ 3 ] ) & & len > = 8 ) {
packet + = 4 ;
len - = 4 ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " DTMF payload offset by 4 bytes. \n " ) ;
2011-01-21 21:03:19 +00:00
}
2013-02-14 20:07:20 +00:00
if ( ! ( packet [ 0 ] | | packet [ 1 ] | | packet [ 2 ] | | packet [ 3 ] ) & & rtp_session - > dtmf_data . in_digit_ts ) {
2012-04-10 21:17:16 +00:00
switch_core_session_t * session = switch_core_memory_pool_get_data ( rtp_session - > pool , " __session " ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_ERROR , " Failed DTMF payload check. \n " ) ;
2011-01-21 21:03:19 +00:00
rtp_session - > dtmf_data . last_digit = 0 ;
rtp_session - > dtmf_data . in_digit_ts = 0 ;
2011-02-18 22:54:51 +00:00
rtp_session - > dtmf_data . in_digit_sanity = 0 ;
2016-04-14 17:38:18 +00:00
rtp_session - > dtmf_data . in_digit_queued = 0 ;
2011-01-21 21:03:19 +00:00
}
end = packet [ 1 ] & 0x80 ? 1 : 0 ;
duration = ( packet [ 2 ] < < 8 ) + packet [ 3 ] ;
key = switch_rfc2833_to_char ( packet [ 0 ] ) ;
2015-10-06 14:34:19 +00:00
in_digit_seq = ntohs ( ( uint16_t ) rtp_session - > last_rtp_hdr . seq ) ;
ts = htonl ( rtp_session - > last_rtp_hdr . ts ) ;
2011-01-21 21:03:19 +00:00
2013-12-30 19:21:45 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_PASS_RFC2833 ] ) {
if ( end ) {
2014-01-30 00:08:27 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] = DTMF_SANITY - 3 ;
2013-12-30 19:21:45 +00:00
} else if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] ) {
rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] = 1 ;
}
return RESULT_CONTINUE ;
}
2011-01-21 21:03:19 +00:00
if ( in_digit_seq < rtp_session - > dtmf_data . in_digit_seq ) {
if ( rtp_session - > dtmf_data . in_digit_seq - in_digit_seq > 100 ) {
rtp_session - > dtmf_data . in_digit_seq = 0 ;
}
}
# ifdef DEBUG_2833
2012-12-14 01:49:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " packet[%d]: %02x %02x %02x %02x \n " , ( int ) len , ( unsigned char ) packet [ 0 ] , ( unsigned char ) packet [ 1 ] , ( unsigned char ) packet [ 2 ] , ( unsigned char ) packet [ 3 ] ) ;
2011-01-21 21:03:19 +00:00
# endif
if ( in_digit_seq > rtp_session - > dtmf_data . in_digit_seq ) {
rtp_session - > dtmf_data . in_digit_seq = in_digit_seq ;
# ifdef DEBUG_2833
2012-11-21 19:59:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " read: %c %u %u %u %u %d %d %s \n " ,
2012-12-14 01:49:02 +00:00
key , in_digit_seq , rtp_session - > dtmf_data . in_digit_seq ,
2015-10-06 14:34:19 +00:00
ts , duration , rtp_session - > last_rtp_hdr . m , end , end & & ! rtp_session - > dtmf_data . in_digit_ts ? " ignored " : " " ) ;
2011-01-21 21:03:19 +00:00
# endif
2016-04-14 17:38:18 +00:00
if ( rtp_session - > dtmf_data . in_digit_ts & & rtp_session - > dtmf_data . in_digit_ts ! = ts ) {
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " TS changed from last packet, resetting.... \n " ) ;
rtp_session - > dtmf_data . last_digit = 0 ;
rtp_session - > dtmf_data . in_digit_ts = 0 ;
rtp_session - > dtmf_data . in_digit_sanity = 0 ;
rtp_session - > dtmf_data . in_digit_queued = 0 ;
}
2012-12-12 15:33:48 +00:00
if ( ! rtp_session - > dtmf_data . in_digit_queued & & rtp_session - > dtmf_data . in_digit_ts ) {
if ( ( rtp_session - > rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION ) ) {
switch_dtmf_t dtmf = { key , switch_core_min_dtmf_duration ( 0 ) , 0 , SWITCH_DTMF_RTP } ;
2011-01-21 21:03:19 +00:00
# ifdef DEBUG_2833
2012-12-12 15:33:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Early Queuing digit %c:%d \n " , dtmf . digit , dtmf . duration / 8 ) ;
2011-01-21 21:03:19 +00:00
# endif
2012-12-12 15:33:48 +00:00
switch_rtp_queue_rfc2833_in ( rtp_session , & dtmf ) ;
rtp_session - > dtmf_data . in_digit_queued = 1 ;
}
if ( rtp_session - > jb & & ( rtp_session - > rtp_bugs & RTP_BUG_FLUSH_JB_ON_DTMF ) ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > jb ) ;
2012-12-12 15:33:48 +00:00
}
2011-01-21 21:03:19 +00:00
}
/* only set sanity if we do NOT ignore the packet */
if ( rtp_session - > dtmf_data . in_digit_ts ) {
rtp_session - > dtmf_data . in_digit_sanity = 2000 ;
}
if ( rtp_session - > dtmf_data . last_duration > duration & &
rtp_session - > dtmf_data . last_duration > 0xFC17 & & ts = = rtp_session - > dtmf_data . in_digit_ts ) {
rtp_session - > dtmf_data . flip + + ;
}
if ( end ) {
2011-02-18 22:54:51 +00:00
if ( ! rtp_session - > dtmf_data . in_digit_ts & & rtp_session - > dtmf_data . last_in_digit_ts ! = ts ) {
# ifdef DEBUG_2833
2012-11-21 19:59:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " start with end packet %d \n " , ts ) ;
2011-02-18 22:54:51 +00:00
# endif
rtp_session - > dtmf_data . last_in_digit_ts = ts ;
rtp_session - > dtmf_data . in_digit_ts = ts ;
rtp_session - > dtmf_data . first_digit = key ;
rtp_session - > dtmf_data . in_digit_sanity = 2000 ;
}
2011-01-21 21:03:19 +00:00
if ( rtp_session - > dtmf_data . in_digit_ts ) {
2011-08-25 14:27:39 +00:00
switch_dtmf_t dtmf = { key , duration , 0 , SWITCH_DTMF_RTP } ;
2011-01-21 21:03:19 +00:00
if ( ts > rtp_session - > dtmf_data . in_digit_ts ) {
dtmf . duration + = ( ts - rtp_session - > dtmf_data . in_digit_ts ) ;
}
if ( rtp_session - > dtmf_data . flip ) {
dtmf . duration + = rtp_session - > dtmf_data . flip * 0xFFFF ;
rtp_session - > dtmf_data . flip = 0 ;
# ifdef DEBUG_2833
2012-11-21 19:59:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " you're welcome! \n " ) ;
2011-01-21 21:03:19 +00:00
# endif
}
# ifdef DEBUG_2833
2012-11-21 19:59:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " done digit=%c ts=%u start_ts=%u dur=%u ddur=%u \n " ,
2011-01-21 21:03:19 +00:00
dtmf . digit , ts , rtp_session - > dtmf_data . in_digit_ts , duration , dtmf . duration ) ;
# endif
if ( ! ( rtp_session - > rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION ) & & ! rtp_session - > dtmf_data . in_digit_queued ) {
# ifdef DEBUG_2833
2012-11-21 19:59:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Queuing digit %c:%d \n " , dtmf . digit , dtmf . duration / 8 ) ;
2011-01-21 21:03:19 +00:00
# endif
switch_rtp_queue_rfc2833_in ( rtp_session , & dtmf ) ;
}
rtp_session - > dtmf_data . last_digit = rtp_session - > dtmf_data . first_digit ;
rtp_session - > dtmf_data . in_digit_ts = 0 ;
rtp_session - > dtmf_data . in_digit_sanity = 0 ;
rtp_session - > dtmf_data . in_digit_queued = 0 ;
2014-03-10 19:42:52 +00:00
* do_cng = 1 ;
2011-01-21 21:03:19 +00:00
} else {
if ( ! switch_rtp_ready ( rtp_session ) ) {
return RESULT_GOTO_END ;
}
switch_cond_next ( ) ;
return RESULT_GOTO_RECVFROM ;
}
} else if ( ! rtp_session - > dtmf_data . in_digit_ts ) {
2011-02-18 22:54:51 +00:00
# ifdef DEBUG_2833
2012-12-14 01:49:02 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " start %d [%c] \n " , ts , key ) ;
2011-02-18 22:54:51 +00:00
# endif
2011-01-21 21:03:19 +00:00
rtp_session - > dtmf_data . in_digit_ts = ts ;
2011-02-18 22:54:51 +00:00
rtp_session - > dtmf_data . last_in_digit_ts = ts ;
2011-01-21 21:03:19 +00:00
rtp_session - > dtmf_data . first_digit = key ;
rtp_session - > dtmf_data . in_digit_sanity = 2000 ;
}
rtp_session - > dtmf_data . last_duration = duration ;
} else {
# ifdef DEBUG_2833
2012-11-21 19:59:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " drop: %c %u %u %u %u %d %d \n " ,
2015-10-06 14:34:19 +00:00
key , in_digit_seq , rtp_session - > dtmf_data . in_digit_seq , ts , duration , rtp_session - > last_rtp_hdr . m , end ) ;
2011-01-21 21:03:19 +00:00
# endif
switch_cond_next ( ) ;
return RESULT_GOTO_RECVFROM ;
}
}
if ( bytes & & rtp_session - > dtmf_data . in_digit_ts ) {
if ( ! switch_rtp_ready ( rtp_session ) ) {
return RESULT_GOTO_END ;
}
2015-10-06 14:34:19 +00:00
if ( ! rtp_session - > dtmf_data . in_interleaved & & rtp_session - > last_rtp_hdr . pt ! = rtp_session - > recv_te ) {
2011-01-21 21:03:19 +00:00
/* Drat, they are sending audio still as well as DTMF ok fine..... *sigh* */
rtp_session - > dtmf_data . in_interleaved = 1 ;
}
if ( rtp_session - > dtmf_data . in_interleaved | | ( rtp_session - > rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION ) ) {
2015-10-06 14:34:19 +00:00
if ( rtp_session - > last_rtp_hdr . pt = = rtp_session - > recv_te ) {
2011-01-21 21:03:19 +00:00
return RESULT_GOTO_RECVFROM ;
}
} else {
2014-03-10 19:42:52 +00:00
* do_cng = 1 ;
2011-01-21 21:03:19 +00:00
return RESULT_GOTO_TIMERCHECK ;
}
}
return RESULT_CONTINUE ;
}
2014-11-24 23:39:10 +00:00
static int rtp_write_ready ( switch_rtp_t * rtp_session , uint32_t bytes , int line ) ;
2006-04-03 21:00:13 +00:00
static int global_init = 0 ;
2008-05-27 04:30:03 +00:00
static int rtp_common_write ( switch_rtp_t * rtp_session ,
rtp_msg_t * send_msg , void * data , uint32_t datalen , switch_payload_t payload , uint32_t timestamp , switch_frame_flag_t * flags ) ;
2008-01-11 04:23:09 +00:00
2006-04-03 21:00:13 +00:00
2012-06-22 23:08:59 +00:00
static switch_status_t ice_out ( switch_rtp_t * rtp_session , switch_rtp_ice_t * ice )
2006-04-04 17:22:06 +00:00
{
2007-12-11 03:57:15 +00:00
uint8_t buf [ 256 ] = { 0 } ;
switch_stun_packet_t * packet ;
unsigned int elapsed ;
switch_size_t bytes ;
2008-01-18 18:14:53 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2013-02-11 19:42:50 +00:00
//switch_sockaddr_t *remote_addr = rtp_session->remote_addr;
2012-06-22 23:08:59 +00:00
switch_socket_t * sock_output = rtp_session - > sock_output ;
2013-06-18 00:52:37 +00:00
switch_time_t now = switch_micro_time_now ( ) ;
2013-01-13 07:29:05 +00:00
2013-06-18 00:52:37 +00:00
if ( ice - > next_run & & ice - > next_run > now ) {
return SWITCH_STATUS_BREAK ;
}
2013-01-13 07:29:05 +00:00
2013-06-18 00:52:37 +00:00
ice - > next_run = now + RTP_STUN_FREQ ;
2013-07-01 17:16:47 +00:00
if ( ice = = & rtp_session - > rtcp_ice & & rtp_session - > rtcp_sock_output ) {
2012-06-22 23:08:59 +00:00
sock_output = rtp_session - > rtcp_sock_output ;
}
2013-02-02 06:15:09 +00:00
2013-07-01 17:16:47 +00:00
if ( ! sock_output ) {
return SWITCH_STATUS_FALSE ;
}
2007-12-11 19:23:57 +00:00
switch_assert ( rtp_session ! = NULL ) ;
2012-06-22 23:08:59 +00:00
switch_assert ( ice - > ice_user ! = NULL ) ;
2006-04-04 17:22:06 +00:00
2012-06-22 23:08:59 +00:00
READ_INC ( rtp_session ) ;
2008-05-16 19:11:44 +00:00
2007-12-11 03:57:15 +00:00
if ( rtp_session - > last_stun ) {
2009-01-25 21:23:07 +00:00
elapsed = ( unsigned int ) ( ( switch_micro_time_now ( ) - rtp_session - > last_stun ) / 1000 ) ;
2006-04-04 17:22:06 +00:00
2007-12-11 03:57:15 +00:00
if ( elapsed > 30000 ) {
2013-10-15 21:24:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " No %s stun for a long time! \n " , rtp_type ( rtp_session ) ) ;
2013-07-11 22:38:24 +00:00
rtp_session - > last_stun = switch_micro_time_now ( ) ;
//status = SWITCH_STATUS_GENERR;
//goto end;
2006-04-04 17:22:06 +00:00
}
}
2007-12-11 03:57:15 +00:00
packet = switch_stun_packet_build_header ( SWITCH_STUN_BINDING_REQUEST , NULL , buf ) ;
2013-04-03 20:41:22 +00:00
switch_stun_packet_attribute_add_username ( packet , ice - > ice_user , ( uint16_t ) strlen ( ice - > ice_user ) ) ;
2013-04-10 16:27:04 +00:00
2013-06-18 00:52:37 +00:00
memcpy ( ice - > last_sent_id , packet - > header . id , 12 ) ;
2013-04-10 16:27:04 +00:00
2013-01-13 07:29:05 +00:00
//if (ice->pass && ice->type == ICE_GOOGLE_JINGLE) {
// switch_stun_packet_attribute_add_password(packet, ice->pass, (uint16_t)strlen(ice->pass));
//}
if ( ( ice - > type & ICE_VANILLA ) ) {
char sw [ 128 ] = " " ;
2013-02-03 05:57:27 +00:00
switch_stun_packet_attribute_add_priority ( packet , ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . priority ) ;
2013-01-13 07:29:05 +00:00
2014-01-16 20:54:47 +00:00
switch_snprintf ( sw , sizeof ( sw ) , " FreeSWITCH (%s) " , switch_version_revision_human ( ) ) ;
2013-04-03 20:41:22 +00:00
switch_stun_packet_attribute_add_software ( packet , sw , ( uint16_t ) strlen ( sw ) ) ;
2013-01-13 07:29:05 +00:00
2013-04-02 18:37:04 +00:00
if ( ( ice - > type & ICE_CONTROLLED ) ) {
2013-01-13 07:29:05 +00:00
switch_stun_packet_attribute_add_controlled ( packet ) ;
} else {
switch_stun_packet_attribute_add_controlling ( packet ) ;
2013-01-16 04:56:02 +00:00
switch_stun_packet_attribute_add_use_candidate ( packet ) ;
2013-01-13 07:29:05 +00:00
}
2013-01-14 02:12:23 +00:00
switch_stun_packet_attribute_add_integrity ( packet , ice - > rpass ) ;
2013-01-13 07:29:05 +00:00
switch_stun_packet_attribute_add_fingerprint ( packet ) ;
2012-06-22 23:08:59 +00:00
}
2013-01-13 07:29:05 +00:00
2007-12-11 03:57:15 +00:00
bytes = switch_stun_packet_length ( packet ) ;
2012-06-22 23:08:59 +00:00
2013-06-18 00:52:37 +00:00
# ifdef DEBUG_EXTRA
2014-02-27 16:42:30 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_CRIT , " %s send %s stun \n " , rtp_session_name ( rtp_session ) , rtp_type ( rtp_session ) ) ;
2013-06-18 00:52:37 +00:00
# endif
2013-02-11 19:42:50 +00:00
switch_socket_sendto ( sock_output , ice - > addr , 0 , ( void * ) packet , & bytes ) ;
2012-06-22 23:08:59 +00:00
2013-01-13 07:29:05 +00:00
ice - > sending = 3 ;
2007-12-11 03:57:15 +00:00
2013-07-11 22:38:24 +00:00
// end:
2012-06-22 23:08:59 +00:00
READ_DEC ( rtp_session ) ;
2008-05-27 04:30:03 +00:00
2008-07-18 16:18:31 +00:00
return status ;
}
2014-12-12 20:55:14 +00:00
int icecmp ( const char * them , switch_rtp_ice_t * ice )
{
if ( strchr ( them , ' : ' ) ) {
return strcmp ( them , ice - > user_ice ) ;
}
return strcmp ( them , ice - > luser_ice ) ;
}
2008-07-18 16:18:31 +00:00
2012-06-22 23:08:59 +00:00
static void handle_ice ( switch_rtp_t * rtp_session , switch_rtp_ice_t * ice , void * data , switch_size_t len )
2006-04-04 17:22:06 +00:00
{
switch_stun_packet_t * packet ;
switch_stun_packet_attribute_t * attr ;
2008-05-10 21:10:44 +00:00
void * end_buf ;
2013-06-18 00:52:37 +00:00
char username [ 34 ] = { 0 } ;
2007-03-29 22:31:56 +00:00
unsigned char buf [ 512 ] = { 0 } ;
2007-12-17 23:43:15 +00:00
switch_size_t cpylen = len ;
2013-01-14 02:12:23 +00:00
int xlen = 0 ;
int ok = 1 ;
2013-01-18 03:47:45 +00:00
uint32_t * pri = NULL ;
2013-02-16 03:27:49 +00:00
int is_rtcp = ice = = & rtp_session - > rtcp_ice ;
2014-05-08 20:14:48 +00:00
uint32_t elapsed ;
2015-08-24 18:13:43 +00:00
switch_time_t ref_point ;
2015-05-23 03:08:27 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
// switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF OK %s CALL\n", rtp_type(rtp_session));
//}
2008-01-18 18:14:53 +00:00
2012-06-22 23:08:59 +00:00
if ( ! switch_rtp_ready ( rtp_session ) | | zstr ( ice - > user_ice ) | | zstr ( ice - > ice_user ) ) {
2008-02-25 16:35:19 +00:00
return ;
}
2015-01-22 03:08:09 +00:00
switch_mutex_lock ( rtp_session - > ice_mutex ) ;
2008-01-18 18:14:53 +00:00
READ_INC ( rtp_session ) ;
WRITE_INC ( rtp_session ) ;
2008-05-27 04:30:03 +00:00
2008-02-25 16:35:19 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
goto end ;
}
2013-01-14 02:12:23 +00:00
if ( cpylen > sizeof ( buf ) ) {
cpylen = sizeof ( buf ) ;
2007-12-17 23:43:15 +00:00
}
2006-04-04 17:22:06 +00:00
2012-06-22 23:08:59 +00:00
2007-12-17 23:43:15 +00:00
memcpy ( buf , data , cpylen ) ;
2014-01-22 21:28:53 +00:00
packet = switch_stun_packet_parse ( buf , ( uint32_t ) cpylen ) ;
2008-05-13 00:17:58 +00:00
if ( ! packet ) {
2014-03-31 21:22:29 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Invalid STUN/ICE packet received %ld bytes \n " , ( long ) cpylen ) ;
2013-01-14 02:12:23 +00:00
goto end ;
2008-05-13 00:17:58 +00:00
}
2013-01-13 07:29:05 +00:00
2015-08-24 18:13:43 +00:00
rtp_session - > last_stun = switch_micro_time_now ( ) ;
if ( ! rtp_session - > first_stun ) {
rtp_session - > first_stun = rtp_session - > last_stun ;
2014-05-08 20:14:48 +00:00
}
2015-08-24 18:13:43 +00:00
if ( ice - > last_ok ) {
ref_point = ice - > last_ok ;
} else {
ref_point = rtp_session - > first_stun ;
}
elapsed = ( unsigned int ) ( ( switch_micro_time_now ( ) - ref_point ) / 1000 ) ;
2014-05-08 20:14:48 +00:00
2008-05-13 00:17:58 +00:00
2015-08-24 18:13:43 +00:00
end_buf = buf + ( ( sizeof ( buf ) > packet - > header . length ) ? packet - > header . length : sizeof ( buf ) ) ;
2007-03-29 22:31:56 +00:00
2006-04-04 17:22:06 +00:00
switch_stun_packet_first_attribute ( packet , attr ) ;
2015-09-01 20:59:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG8 , " %s STUN PACKET TYPE: %s \n " ,
rtp_type ( rtp_session ) , switch_stun_value_to_name ( SWITCH_STUN_TYPE_PACKET_TYPE , packet - > header . type ) ) ;
2006-04-04 17:22:06 +00:00
do {
2015-09-01 20:59:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG8 , " |---: %s STUN ATTR %d %x %s \n " , rtp_type ( rtp_session ) , attr - > type , attr - > type ,
2014-12-12 20:55:14 +00:00
switch_stun_value_to_name ( SWITCH_STUN_TYPE_ATTRIBUTE , attr - > type ) ) ;
2007-03-29 22:31:56 +00:00
switch ( attr - > type ) {
2014-12-12 20:55:14 +00:00
case SWITCH_STUN_ATTR_USE_CAND :
{
ice - > rready = 1 ;
}
break ;
2013-06-27 18:00:20 +00:00
case SWITCH_STUN_ATTR_ERROR_CODE :
{
switch_stun_error_code_t * err = ( switch_stun_error_code_t * ) attr - > value ;
uint32_t code = ( err - > code * 100 ) + err - > number ;
2015-09-01 20:59:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " %s got %s stun binding response %u %s \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) ,
2015-09-01 20:59:17 +00:00
rtp_type ( rtp_session ) ,
2013-06-27 18:00:20 +00:00
code ,
err - > reason
) ;
if ( ( ice - > type & ICE_VANILLA ) & & code = = 487 ) {
if ( ( ice - > type & ICE_CONTROLLED ) ) {
2015-09-01 20:59:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " %s STUN Changing role to CONTROLLING \n " , rtp_type ( rtp_session ) ) ;
2013-06-27 18:00:20 +00:00
ice - > type & = ~ ICE_CONTROLLED ;
} else {
2015-09-01 20:59:17 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " %s STUN Changing role to CONTROLLED \n " , rtp_type ( rtp_session ) ) ;
2013-06-27 18:00:20 +00:00
ice - > type | = ICE_CONTROLLED ;
}
packet - > header . type = SWITCH_STUN_BINDING_RESPONSE ;
}
}
break ;
2006-04-04 17:22:06 +00:00
case SWITCH_STUN_ATTR_MAPPED_ADDRESS :
if ( attr - > type ) {
2015-08-27 18:42:52 +00:00
char ip [ 50 ] ;
2006-04-04 17:22:06 +00:00
uint16_t port ;
2015-08-27 18:42:52 +00:00
switch_stun_packet_attribute_get_mapped_address ( attr , ip , sizeof ( ip ) , & port ) ;
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG8 , " |------: %s:%d \n " , ip , port ) ;
2006-04-04 17:22:06 +00:00
}
break ;
2015-06-03 02:20:03 +00:00
case SWITCH_STUN_ATTR_XOR_MAPPED_ADDRESS :
if ( attr - > type ) {
2015-08-27 18:42:52 +00:00
char ip [ 50 ] ;
2015-06-03 02:20:03 +00:00
uint16_t port ;
2015-08-27 18:42:52 +00:00
switch_stun_packet_attribute_get_xor_mapped_address ( attr , & packet - > header , ip , sizeof ( ip ) , & port ) ;
2015-06-03 02:20:03 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG8 , " |------: %s:%d \n " , ip , port ) ;
}
break ;
2006-04-04 17:22:06 +00:00
case SWITCH_STUN_ATTR_USERNAME :
2007-03-29 22:31:56 +00:00
if ( attr - > type ) {
2013-06-18 00:52:37 +00:00
switch_stun_packet_attribute_get_username ( attr , username , sizeof ( username ) ) ;
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG8 , " |------: %s \n " , username ) ;
2006-04-04 17:22:06 +00:00
}
break ;
2013-01-14 02:12:23 +00:00
case SWITCH_STUN_ATTR_PRIORITY :
{
2014-12-12 20:55:14 +00:00
uint32_t priority = 0 ;
2013-01-18 03:47:45 +00:00
pri = ( uint32_t * ) attr - > value ;
2014-12-12 20:55:14 +00:00
priority = ntohl ( * pri ) ;
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG8 , " |------: %u \n " , priority ) ;
2014-12-12 20:55:14 +00:00
ok = priority = = ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . priority ;
2013-01-14 02:12:23 +00:00
}
break ;
}
if ( ! switch_stun_packet_next_attribute ( attr , end_buf ) ) {
break ;
2006-04-04 17:22:06 +00:00
}
2014-12-12 20:55:14 +00:00
2013-01-14 02:12:23 +00:00
xlen + = 4 + switch_stun_attribute_padded_length ( attr ) ;
} while ( xlen < = packet - > header . length ) ;
2013-06-26 14:17:15 +00:00
if ( ( ice - > type & ICE_GOOGLE_JINGLE ) & & ok ) {
2013-01-14 02:12:23 +00:00
ok = ! strcmp ( ice - > user_ice , username ) ;
}
2014-12-12 20:55:14 +00:00
if ( packet - > header . type ! = SWITCH_STUN_BINDING_REQUEST & & packet - > header . type ! = SWITCH_STUN_BINDING_RESPONSE ) {
goto end ;
}
2013-06-25 19:54:29 +00:00
2013-02-16 03:27:49 +00:00
if ( ( ice - > type & ICE_VANILLA ) ) {
2013-06-18 00:52:37 +00:00
char foo1 [ 13 ] = " " , foo2 [ 13 ] = " " ;
2014-12-12 20:55:14 +00:00
if ( ! ok ) ok = ! memcmp ( packet - > header . id , ice - > last_sent_id , 12 ) ;
2013-06-18 00:52:37 +00:00
if ( packet - > header . type = = SWITCH_STUN_BINDING_RESPONSE ) {
ok = 1 ;
if ( ! ice - > rready ) {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
rtp_session - > ice . rready = 1 ;
rtp_session - > rtcp_ice . rready = 1 ;
} else {
ice - > rready = 1 ;
}
2014-11-15 01:01:56 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2014-11-24 23:39:10 +00:00
switch_core_session_video_reinit ( rtp_session - > session ) ;
2014-11-15 01:01:56 +00:00
}
2013-06-18 00:52:37 +00:00
}
}
2014-12-12 20:55:14 +00:00
memcpy ( foo1 , packet - > header . id , 12 ) ;
memcpy ( foo2 , ice - > last_sent_id , 12 ) ;
2013-06-18 00:52:37 +00:00
2013-02-20 02:18:12 +00:00
if ( ! ok & & ice = = & rtp_session - > ice & & rtp_session - > rtcp_ice . ice_params & & pri & &
2013-02-03 05:57:27 +00:00
* pri = = rtp_session - > rtcp_ice . ice_params - > cands [ rtp_session - > rtcp_ice . ice_params - > chosen [ 1 ] ] [ 1 ] . priority ) {
2013-01-26 23:53:15 +00:00
ice = & rtp_session - > rtcp_ice ;
ok = 1 ;
}
2013-06-18 00:52:37 +00:00
if ( ! zstr ( username ) ) {
2014-12-12 20:55:14 +00:00
if ( ! icecmp ( username , ice ) ) {
2013-06-18 00:52:37 +00:00
ok = 1 ;
2014-12-12 20:55:14 +00:00
} else if ( ! zstr ( rtp_session - > rtcp_ice . user_ice ) & & ! icecmp ( username , & rtp_session - > rtcp_ice ) ) {
2013-06-18 00:52:37 +00:00
ice = & rtp_session - > rtcp_ice ;
ok = 1 ;
}
}
2013-02-16 03:27:49 +00:00
if ( ok ) {
ice - > missed_count = 0 ;
} else {
2013-01-26 23:53:15 +00:00
switch_rtp_ice_t * icep [ 2 ] = { & rtp_session - > ice , & rtp_session - > rtcp_ice } ;
2013-02-11 19:42:50 +00:00
switch_port_t port = 0 ;
char * host = NULL ;
2013-01-26 23:53:15 +00:00
if ( elapsed > 20000 & & pri ) {
int i , j ;
uint32_t old ;
2013-02-11 19:42:50 +00:00
//const char *tx_host;
2013-01-26 23:53:15 +00:00
const char * old_host , * err = NULL ;
2015-08-27 18:42:52 +00:00
//char bufa[50];
char bufb [ 50 ] ;
2013-01-26 23:53:15 +00:00
char adj_port [ 6 ] ;
switch_channel_t * channel = NULL ;
2013-10-16 22:57:23 +00:00
ice - > missed_count + + ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " missed %d \n " , ice - > missed_count ) ;
2013-01-26 23:53:15 +00:00
if ( rtp_session - > session ) {
channel = switch_core_session_get_channel ( rtp_session - > session ) ;
}
//ice->ice_params->cands[ice->ice_params->chosen][ice->proto].priority;
for ( j = 0 ; j < 2 ; j + + ) {
2015-01-17 00:22:27 +00:00
if ( ! icep [ j ] | | ! icep [ j ] - > ice_params ) {
continue ;
}
2015-06-03 20:54:15 +00:00
for ( i = 0 ; i < icep [ j ] - > ice_params - > cand_idx [ icep [ j ] - > proto ] ; i + + ) {
2015-01-12 18:55:42 +00:00
if ( icep [ j ] - > ice_params & & icep [ j ] - > ice_params - > cands [ i ] [ icep [ j ] - > proto ] . priority = = * pri ) {
2013-01-26 23:53:15 +00:00
if ( j = = IPR_RTP ) {
2013-02-03 05:57:27 +00:00
icep [ j ] - > ice_params - > chosen [ j ] = i ;
2013-01-26 23:53:15 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO , " Change candidate index to %d \n " , i ) ;
}
ice = icep [ j ] ;
ok = 1 ;
2015-05-27 06:15:28 +00:00
2013-01-26 23:53:15 +00:00
if ( j ! = IPR_RTP ) {
break ;
}
old = rtp_session - > remote_port ;
2013-02-11 19:42:50 +00:00
//tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->from_addr);
2013-01-26 23:53:15 +00:00
old_host = switch_get_addr ( bufb , sizeof ( bufb ) , rtp_session - > remote_addr ) ;
2013-02-11 19:42:50 +00:00
host = ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . con_addr ;
port = ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . con_port ;
if ( ! host | | ! port ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error setting remote host! \n " ) ;
return ;
}
2013-01-26 23:53:15 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO ,
2015-09-01 20:59:17 +00:00
" %s ICE Auto Changing port from %s:%u to %s:%u \n " , rtp_type ( rtp_session ) , old_host , old , host , port ) ;
2013-02-11 19:42:50 +00:00
2013-01-26 23:53:15 +00:00
if ( channel ) {
switch_channel_set_variable ( channel , " remote_media_ip_reported " , switch_channel_get_variable ( channel , " remote_media_ip " ) ) ;
2013-02-11 19:42:50 +00:00
switch_channel_set_variable ( channel , " remote_media_ip " , host ) ;
2013-05-28 21:25:39 +00:00
switch_channel_set_variable ( channel , " rtp_auto_adjust_ip " , host ) ;
2013-02-11 19:42:50 +00:00
switch_snprintf ( adj_port , sizeof ( adj_port ) , " %u " , port ) ;
2013-01-26 23:53:15 +00:00
switch_channel_set_variable ( channel , " remote_media_port_reported " , switch_channel_get_variable ( channel , " remote_media_port " ) ) ;
switch_channel_set_variable ( channel , " remote_media_port " , adj_port ) ;
2013-05-28 21:25:39 +00:00
switch_channel_set_variable ( channel , " rtp_auto_adjust_port " , adj_port ) ;
2013-02-11 19:42:50 +00:00
switch_channel_set_variable ( channel , " rtp_auto_candidate_adjust " , " true " ) ;
2013-01-26 23:53:15 +00:00
}
rtp_session - > auto_adj_used = 1 ;
2013-02-11 19:42:50 +00:00
switch_rtp_set_remote_address ( rtp_session , host , port , 0 , SWITCH_FALSE , & err ) ;
if ( switch_sockaddr_info_get ( & ice - > addr , host , SWITCH_UNSPEC , port , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS | |
! ice - > addr ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error setting remote host! \n " ) ;
return ;
}
2013-01-26 23:53:15 +00:00
2014-10-02 16:55:53 +00:00
if ( ( rtp_session - > rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST ) ) {
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
} else {
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
2013-01-26 23:53:15 +00:00
}
}
}
}
}
2013-04-08 16:00:22 +00:00
}
2013-01-26 23:53:15 +00:00
2014-01-15 16:20:01 +00:00
if ( ice - > missed_count > 5 & & ! ( ice - > type & ICE_GOOGLE_JINGLE ) ) {
2013-10-15 21:24:32 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " missed too many: %d, looking for new ICE dest. \n " ,
ice - > missed_count ) ;
2013-04-08 16:00:22 +00:00
ice - > rready = 0 ;
2013-06-21 05:41:25 +00:00
ok = 1 ;
2013-01-18 03:47:45 +00:00
}
2013-01-14 02:12:23 +00:00
2015-05-23 03:08:27 +00:00
2015-05-27 06:15:28 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO] || 1) {
2015-05-23 03:08:27 +00:00
// switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF OK %s %d\n", rtp_type(rtp_session), ok);
//}
2013-06-18 00:52:37 +00:00
if ( ok ) {
2014-02-04 06:56:30 +00:00
const char * host = NULL , * host2 = NULL ;
switch_port_t port = 0 , port2 = 0 ;
char buf [ 80 ] = " " ;
char buf2 [ 80 ] = " " ;
2013-06-18 00:52:37 +00:00
if ( packet - > header . type = = SWITCH_STUN_BINDING_REQUEST ) {
2013-01-18 03:47:45 +00:00
uint8_t stunbuf [ 512 ] ;
switch_stun_packet_t * rpacket ;
const char * remote_ip ;
switch_size_t bytes ;
2015-08-27 18:42:52 +00:00
char ipbuf [ 50 ] ;
2013-01-18 03:47:45 +00:00
switch_sockaddr_t * from_addr = rtp_session - > from_addr ;
switch_socket_t * sock_output = rtp_session - > sock_output ;
2015-08-24 18:13:43 +00:00
uint8_t do_adj = 0 ;
2015-01-12 18:55:42 +00:00
switch_time_t now = switch_micro_time_now ( ) ;
2015-08-27 18:42:52 +00:00
int cmp = 0 ;
2013-01-18 03:47:45 +00:00
2013-06-18 00:52:37 +00:00
if ( is_rtcp ) {
2013-01-18 03:47:45 +00:00
from_addr = rtp_session - > rtcp_from_addr ;
sock_output = rtp_session - > rtcp_sock_output ;
}
2007-03-29 22:31:56 +00:00
2013-04-11 23:11:06 +00:00
if ( ! ice - > ready ) {
ice - > ready = 1 ;
}
2013-01-13 07:29:05 +00:00
2013-01-18 03:47:45 +00:00
memset ( stunbuf , 0 , sizeof ( stunbuf ) ) ;
rpacket = switch_stun_packet_build_header ( SWITCH_STUN_BINDING_RESPONSE , packet - > header . id , stunbuf ) ;
2013-01-13 07:29:05 +00:00
2013-06-26 14:17:15 +00:00
if ( ( ice - > type & ICE_GOOGLE_JINGLE ) ) {
2013-04-03 20:41:22 +00:00
switch_stun_packet_attribute_add_username ( rpacket , username , ( uint16_t ) strlen ( username ) ) ;
2013-01-18 03:47:45 +00:00
}
2013-01-13 07:29:05 +00:00
2013-01-18 03:47:45 +00:00
remote_ip = switch_get_addr ( ipbuf , sizeof ( ipbuf ) , from_addr ) ;
2015-08-27 18:42:52 +00:00
switch_stun_packet_attribute_add_xor_binded_address ( rpacket , ( char * ) remote_ip , switch_sockaddr_get_port ( from_addr ) , from_addr - > family ) ;
2013-01-13 07:29:05 +00:00
2013-01-18 03:47:45 +00:00
if ( ( ice - > type & ICE_VANILLA ) ) {
switch_stun_packet_attribute_add_integrity ( rpacket , ice - > pass ) ;
switch_stun_packet_attribute_add_fingerprint ( rpacket ) ;
2014-12-18 19:08:11 +00:00
}
2013-01-13 07:29:05 +00:00
2015-08-24 18:13:43 +00:00
bytes = switch_stun_packet_length ( rpacket ) ;
2014-02-04 06:56:30 +00:00
2015-08-24 18:13:43 +00:00
host = switch_get_addr ( buf , sizeof ( buf ) , from_addr ) ;
port = switch_sockaddr_get_port ( from_addr ) ;
host2 = switch_get_addr ( buf2 , sizeof ( buf2 ) , ice - > addr ) ;
port2 = switch_sockaddr_get_port ( ice - > addr ) ;
2015-08-27 18:42:52 +00:00
cmp = switch_cmp_addr ( from_addr , ice - > addr ) ;
2015-08-24 18:13:43 +00:00
2015-08-31 22:16:07 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG4 ,
2015-08-27 18:42:52 +00:00
" STUN from %s:%d %s \n " , host , port , cmp ? " EXPECTED " : " IGNORED " ) ;
2015-08-26 18:38:51 +00:00
2015-08-27 18:42:52 +00:00
if ( cmp ) {
2015-01-26 15:31:15 +00:00
ice - > last_ok = now ;
2015-08-27 18:55:41 +00:00
rtp_session - > wrong_addrs = 0 ;
2015-08-24 18:13:43 +00:00
} else {
2015-10-04 21:53:43 +00:00
if ( ( ( rtp_session - > dtls & & rtp_session - > dtls - > state ! = DS_READY ) | | ! ice - > ready | | ! ice - > rready ) & &
rtp_session - > wrong_addrs > 2 & & rtp_session - > ice_adj = = 0 ) {
2015-09-22 18:52:50 +00:00
do_adj + + ;
2015-10-04 21:53:43 +00:00
rtp_session - > ice_adj = 1 ;
rtp_session - > wrong_addrs = 0 ;
} else if ( rtp_session - > wrong_addrs > 10 | | elapsed > = 10000 ) {
2015-08-24 18:13:43 +00:00
do_adj + + ;
}
2012-06-22 23:08:59 +00:00
2015-08-26 18:38:51 +00:00
if ( ! do_adj ) {
rtp_session - > wrong_addrs + + ;
}
}
2013-02-11 19:42:50 +00:00
2015-08-24 18:13:43 +00:00
if ( ( ice - > type & ICE_VANILLA ) & & ice - > ice_params & & do_adj ) {
2013-10-15 21:24:32 +00:00
int i = 0 ;
2013-02-11 19:42:50 +00:00
2013-04-08 16:00:22 +00:00
ice - > missed_count = 0 ;
ice - > rready = 1 ;
2016-05-04 17:34:31 +00:00
for ( i = 0 ; i < ice - > ice_params - > cand_idx [ ice - > proto ] ; i + + ) {
2013-10-15 21:24:32 +00:00
if ( ice - > ice_params - > cands [ i ] [ ice - > proto ] . con_port = = port ) {
2016-05-04 17:34:31 +00:00
if ( ! strcmp ( ice - > ice_params - > cands [ i ] [ ice - > proto ] . con_addr , host ) & &
ice - > ice_params - > cands [ i ] [ ice - > proto ] . cand_type & &
2013-10-15 21:24:32 +00:00
! strcmp ( ice - > ice_params - > cands [ i ] [ ice - > proto ] . cand_type , " relay " ) ) {
2014-12-18 19:08:11 +00:00
2015-08-24 18:13:43 +00:00
if ( elapsed < 1000 ) {
2014-05-08 20:14:48 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING ,
" Skiping RELAY stun/%s/dtls port change from %s:%u to %s:%u \n " , is_rtcp ? " rtcp " : " rtp " ,
host2 , port2 ,
host , port ) ;
goto end ;
}
2013-10-15 21:24:32 +00:00
2014-05-08 20:14:48 +00:00
break ;
2013-10-15 21:24:32 +00:00
}
}
}
2013-06-18 00:52:37 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_NOTICE ,
2015-05-27 06:15:28 +00:00
" Auto Changing %s stun/%s/dtls port from %s:%u to %s:%u \n " , rtp_type ( rtp_session ) , is_rtcp ? " rtcp " : " rtp " ,
2013-06-18 00:52:37 +00:00
host2 , port2 ,
host , port ) ;
2013-10-15 21:24:32 +00:00
2014-12-18 19:08:11 +00:00
switch_rtp_change_ice_dest ( rtp_session , ice , host , port ) ;
2015-08-24 18:13:43 +00:00
ice - > last_ok = now ;
2015-08-26 18:38:51 +00:00
rtp_session - > wrong_addrs = 0 ;
2013-02-11 19:42:50 +00:00
}
2015-09-22 18:52:50 +00:00
if ( cmp ) {
switch_socket_sendto ( sock_output , from_addr , 0 , ( void * ) rpacket , & bytes ) ;
}
2013-01-18 03:47:45 +00:00
}
2012-06-24 07:36:14 +00:00
} else if ( packet - > header . type = = SWITCH_STUN_BINDING_ERROR_RESPONSE ) {
2013-01-15 05:17:28 +00:00
if ( rtp_session - > session ) {
2012-06-22 23:08:59 +00:00
switch_core_session_message_t msg = { 0 } ;
msg . from = __FILE__ ;
msg . numeric_arg = packet - > header . type ;
msg . pointer_arg = packet ;
msg . message_id = SWITCH_MESSAGE_INDICATE_STUN_ERROR ;
2013-01-15 05:17:28 +00:00
switch_core_session_receive_message ( rtp_session - > session , & msg ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG ,
2016-07-11 03:25:14 +00:00
" STUN/ICE binding error received on %s channel \n " , rtp_type ( rtp_session ) ) ;
2012-06-22 23:08:59 +00:00
}
2006-04-04 17:22:06 +00:00
}
2008-01-18 18:14:53 +00:00
2013-01-18 03:47:45 +00:00
2010-04-20 00:07:23 +00:00
end :
2015-01-22 03:08:09 +00:00
switch_mutex_unlock ( rtp_session - > ice_mutex ) ;
2008-01-18 18:14:53 +00:00
READ_DEC ( rtp_session ) ;
WRITE_DEC ( rtp_session ) ;
2006-04-04 17:22:06 +00:00
}
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
2009-05-22 05:33:21 +00:00
SWITCH_STANDARD_SCHED_FUNC ( zrtp_cache_save_callback )
2009-05-20 23:04:05 +00:00
{
2009-05-22 05:33:21 +00:00
zrtp_status_t status = zrtp_status_ok ;
2009-05-20 23:04:05 +00:00
2009-05-22 05:33:21 +00:00
status = zrtp_def_cache_store ( zrtp_global ) ;
2012-04-11 14:10:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Saving ZRTP cache: %s \n " , zrtp_status_ok = = status ? " OK " : " FAIL " ) ;
2009-05-22 05:33:21 +00:00
task - > runtime = switch_epoch_time_now ( NULL ) + 900 ;
2009-05-20 23:04:05 +00:00
}
2010-02-06 03:38:24 +00:00
static int zrtp_send_rtp_callback ( const zrtp_stream_t * stream , char * rtp_packet , unsigned int rtp_packet_length )
2009-05-20 23:04:05 +00:00
{
switch_rtp_t * rtp_session = zrtp_stream_get_userdata ( stream ) ;
switch_size_t len = rtp_packet_length ;
zrtp_status_t status = zrtp_status_ok ;
switch_socket_sendto ( rtp_session - > sock_output , rtp_session - > remote_addr , 0 , rtp_packet , & len ) ;
return status ;
}
2012-05-24 00:44:32 +00:00
static void zrtp_event_callback ( zrtp_stream_t * stream , unsigned event )
2009-05-20 23:04:05 +00:00
{
switch_rtp_t * rtp_session = zrtp_stream_get_userdata ( stream ) ;
2010-02-03 19:19:10 +00:00
zrtp_session_info_t zrtp_session_info ;
2013-01-15 05:17:28 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
2009-05-29 02:08:24 +00:00
switch_event_t * fsevent = NULL ;
2010-02-03 19:19:10 +00:00
const char * type ;
2010-02-06 03:38:24 +00:00
2013-04-01 14:13:39 +00:00
type = rtp_type ( rtp_session ) ;
2010-02-06 03:38:24 +00:00
2009-05-20 23:04:05 +00:00
switch ( event ) {
case ZRTP_EVENT_IS_SECURE :
2009-05-28 22:54:51 +00:00
{
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_SEND ] = 1 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_RECV ] = 1 ;
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] = 1 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] = 1 ;
2010-02-03 19:19:10 +00:00
}
if ( zrtp_status_ok = = zrtp_session_get ( stream - > session , & zrtp_session_info ) ) {
2009-05-28 22:54:51 +00:00
if ( zrtp_session_info . sas_is_ready ) {
2010-02-06 03:38:24 +00:00
2010-02-03 19:19:10 +00:00
switch_channel_set_variable_name_printf ( channel , " true " , " zrtp_secure_media_confirmed_%s " , type ) ;
switch_channel_set_variable_name_printf ( channel , stream - > session - > sas1 . buffer , " zrtp_sas1_string_%s " , type ) ;
switch_channel_set_variable_name_printf ( channel , stream - > session - > sas2 . buffer , " zrtp_sas2_string " , type ) ;
2012-06-22 13:25:40 +00:00
zrtp_verified_set ( zrtp_global , & stream - > session - > zid , & stream - > session - > peer_zid , ( uint8_t ) 1 ) ;
2009-05-28 22:54:51 +00:00
}
2009-05-22 21:33:15 +00:00
}
2010-02-03 19:19:10 +00:00
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2013-01-15 05:17:28 +00:00
2010-02-06 03:38:24 +00:00
2013-01-15 05:17:28 +00:00
if ( rtp_session - > session ) {
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
2010-02-03 19:19:10 +00:00
switch_rtp_t * video_rtp_session = switch_channel_get_private ( channel , " __zrtp_video_rtp_session " ) ;
2010-02-06 03:38:24 +00:00
2010-02-03 19:19:10 +00:00
if ( ! video_rtp_session ) {
video_rtp_session = switch_channel_get_private_partner ( channel , " __zrtp_video_rtp_session " ) ;
}
if ( video_rtp_session ) {
if ( zrtp_status_ok ! = zrtp_stream_attach ( stream - > session , & video_rtp_session - > zrtp_stream ) ) {
abort ( ) ;
}
zrtp_stream_set_userdata ( video_rtp_session - > zrtp_stream , video_rtp_session ) ;
if ( switch_true ( switch_channel_get_variable ( channel , " zrtp_enrollment " ) ) ) {
zrtp_stream_registration_start ( video_rtp_session - > zrtp_stream , video_rtp_session - > ssrc ) ;
} else {
zrtp_stream_start ( video_rtp_session - > zrtp_stream , video_rtp_session - > ssrc ) ;
}
}
2010-02-06 03:38:24 +00:00
}
2010-02-03 19:19:10 +00:00
}
if ( switch_event_create ( & fsevent , SWITCH_EVENT_CALL_SECURE ) = = SWITCH_STATUS_SUCCESS ) {
switch_event_add_header ( fsevent , SWITCH_STACK_BOTTOM , " secure_media_type " , " %s " , type ) ;
2010-02-06 03:38:24 +00:00
switch_event_add_header ( fsevent , SWITCH_STACK_BOTTOM , " secure_type " , " zrtp:%s:%s " , stream - > session - > sas1 . buffer ,
stream - > session - > sas2 . buffer ) ;
2010-02-03 19:19:10 +00:00
switch_event_add_header_string ( fsevent , SWITCH_STACK_BOTTOM , " caller-unique-id " , switch_channel_get_uuid ( channel ) ) ;
switch_event_fire ( & fsevent ) ;
}
2009-05-29 02:08:24 +00:00
}
2009-05-20 23:04:05 +00:00
break ;
2009-05-30 05:24:52 +00:00
#if 0
2009-05-30 05:01:28 +00:00
case ZRTP_EVENT_NO_ZRTP_QUICK :
{
2010-02-03 19:19:10 +00:00
if ( stream ! = NULL ) {
zrtp_stream_stop ( stream ) ;
2009-05-30 05:01:28 +00:00
}
}
break ;
2009-05-30 05:24:52 +00:00
# endif
2009-05-28 22:54:51 +00:00
case ZRTP_EVENT_IS_CLIENT_ENROLLMENT :
{
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Enrolled complete! \n " ) ;
2010-02-03 19:19:10 +00:00
switch_channel_set_variable_name_printf ( channel , " true " , " zrtp_enroll_complete_%s " , type ) ;
2009-05-28 22:54:51 +00:00
}
2009-05-22 21:33:15 +00:00
break ;
2009-05-23 01:50:56 +00:00
2009-05-28 22:54:51 +00:00
case ZRTP_EVENT_USER_ALREADY_ENROLLED :
{
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " User already enrolled! \n " ) ;
2010-02-03 19:19:10 +00:00
switch_channel_set_variable_name_printf ( channel , " true " , " zrtp_already_enrolled_%s " , type ) ;
2009-05-23 01:50:56 +00:00
}
2009-05-22 21:33:15 +00:00
break ;
2009-05-23 01:50:56 +00:00
2009-05-28 22:54:51 +00:00
case ZRTP_EVENT_NEW_USER_ENROLLED :
{
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " New user enrolled! \n " ) ;
2010-02-03 19:19:10 +00:00
switch_channel_set_variable_name_printf ( channel , " true " , " zrtp_new_user_enrolled_%s " , type ) ;
2009-05-23 01:50:56 +00:00
}
2009-05-22 21:33:15 +00:00
break ;
2010-02-06 03:38:24 +00:00
2009-05-22 21:33:15 +00:00
case ZRTP_EVENT_USER_UNENROLLED :
2009-05-28 22:54:51 +00:00
{
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " User unenrolled! \n " ) ;
2010-02-03 19:19:10 +00:00
switch_channel_set_variable_name_printf ( channel , " true " , " zrtp_user_unenrolled_%s " , type ) ;
2009-05-23 01:50:56 +00:00
}
2009-05-21 22:37:15 +00:00
break ;
2009-05-28 22:54:51 +00:00
2009-05-20 23:04:05 +00:00
case ZRTP_EVENT_IS_PENDINGCLEAR :
2009-05-28 22:54:51 +00:00
{
2010-02-03 19:19:10 +00:00
switch_channel_set_variable_name_printf ( channel , " false " , " zrtp_secure_media_confirmed_%s " , type ) ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_SEND ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_RECV ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] = 0 ;
2009-05-28 22:54:51 +00:00
rtp_session - > zrtp_mitm_tries = 0 ;
}
2009-05-21 22:37:15 +00:00
break ;
2009-05-28 22:54:51 +00:00
2009-05-20 23:04:05 +00:00
case ZRTP_EVENT_NO_ZRTP :
2009-05-28 22:54:51 +00:00
{
2010-02-03 19:19:10 +00:00
switch_channel_set_variable_name_printf ( channel , " false " , " zrtp_secure_media_confirmed_%s " , type ) ;
2009-05-28 22:54:51 +00:00
}
2009-05-21 22:37:15 +00:00
break ;
2009-05-28 22:54:51 +00:00
2009-05-20 23:04:05 +00:00
default :
break ;
}
}
2009-12-17 18:33:45 +00:00
static void zrtp_logger ( int level , const char * data , int len , int offset )
2009-05-20 23:04:05 +00:00
{
2012-04-11 14:10:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " %s " , data ) ;
2009-05-20 23:04:05 +00:00
}
# endif
2006-04-04 17:22:06 +00:00
2007-03-30 00:15:25 +00:00
SWITCH_DECLARE ( void ) switch_rtp_init ( switch_memory_pool_t * pool )
2006-04-03 21:00:13 +00:00
{
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
2011-02-02 21:43:26 +00:00
const char * zid_string = switch_core_get_variable_pdup ( " switch_serial " , pool ) ;
const char * zrtp_enabled = switch_core_get_variable_pdup ( " zrtp_enabled " , pool ) ;
2009-05-20 23:04:05 +00:00
zrtp_config_t zrtp_config ;
char zrtp_cache_path [ 256 ] = " " ;
2009-12-03 14:05:03 +00:00
zrtp_on = zrtp_enabled ? switch_true ( zrtp_enabled ) : 0 ;
2009-05-20 23:04:05 +00:00
# endif
2006-04-03 21:00:13 +00:00
if ( global_init ) {
return ;
}
2014-03-08 19:37:09 +00:00
switch_core_hash_init ( & alloc_hash ) ;
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
if ( zrtp_on ) {
2013-01-31 18:40:24 +00:00
uint32_t cache_len ;
2009-05-20 23:04:05 +00:00
zrtp_config_defaults ( & zrtp_config ) ;
strcpy ( zrtp_config . client_id , " FreeSWITCH " ) ;
2009-05-22 05:33:21 +00:00
zrtp_config . is_mitm = 1 ;
2009-05-20 23:04:05 +00:00
zrtp_config . lic_mode = ZRTP_LICENSE_MODE_ACTIVE ;
switch_snprintf ( zrtp_cache_path , sizeof ( zrtp_cache_path ) , " %s%szrtp.dat " , SWITCH_GLOBAL_dirs . db_dir , SWITCH_PATH_SEPARATOR ) ;
2013-01-31 18:40:24 +00:00
cache_len = ( uint32_t ) strlen ( zrtp_cache_path ) ;
ZSTR_SET_EMPTY ( zrtp_config . def_cache_path ) ;
zrtp_config . def_cache_path . length = cache_len > zrtp_config . def_cache_path . max_length ? zrtp_config . def_cache_path . max_length : ( uint16_t ) cache_len ;
strncpy ( zrtp_config . def_cache_path . buffer , zrtp_cache_path , zrtp_config . def_cache_path . max_length ) ;
2012-05-17 16:24:56 +00:00
zrtp_config . cb . event_cb . on_zrtp_protocol_event = ( void ( * ) ( zrtp_stream_t * , zrtp_protocol_event_t ) ) zrtp_event_callback ;
2009-05-20 23:04:05 +00:00
zrtp_config . cb . misc_cb . on_send_packet = zrtp_send_rtp_callback ;
2012-05-17 16:24:56 +00:00
zrtp_config . cb . event_cb . on_zrtp_security_event = ( void ( * ) ( zrtp_stream_t * , zrtp_security_event_t ) ) zrtp_event_callback ;
2010-02-06 03:38:24 +00:00
zrtp_log_set_log_engine ( ( zrtp_log_engine * ) zrtp_logger ) ;
2009-05-20 23:04:05 +00:00
zrtp_log_set_level ( 4 ) ;
2009-09-02 18:44:33 +00:00
if ( zrtp_status_ok = = zrtp_init ( & zrtp_config , & zrtp_global ) ) {
memcpy ( zid , zid_string , 12 ) ;
2010-02-06 03:38:24 +00:00
switch_scheduler_add_task ( switch_epoch_time_now ( NULL ) + 900 , zrtp_cache_save_callback , " zrtp_cache_save " , " core " , 0 , NULL ,
SSHF_NONE | SSHF_NO_DEL ) ;
2009-09-02 18:44:33 +00:00
} else {
switch_core_set_variable ( " zrtp_enabled " , NULL ) ;
zrtp_on = 0 ;
2012-04-11 14:10:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_CRIT , " ZRTP init failed! \n " ) ;
2009-05-20 23:04:05 +00:00
}
}
# endif
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2007-03-29 22:31:56 +00:00
srtp_init ( ) ;
2011-05-02 16:33:57 +00:00
# endif
2007-03-29 22:31:56 +00:00
switch_mutex_init ( & port_lock , SWITCH_MUTEX_NESTED , pool ) ;
global_init = 1 ;
2006-04-03 21:00:13 +00:00
}
2013-01-08 17:47:15 +00:00
static uint8_t get_next_write_ts ( switch_rtp_t * rtp_session , uint32_t timestamp )
{
uint8_t m = 0 ;
if ( rtp_session - > rtp_bugs & RTP_BUG_SEND_LINEAR_TIMESTAMPS ) {
rtp_session - > ts + = rtp_session - > samples_per_interval ;
if ( rtp_session - > ts < = rtp_session - > last_write_ts & & rtp_session - > ts > 0 ) {
rtp_session - > ts = rtp_session - > last_write_ts + rtp_session - > samples_per_interval ;
}
} else if ( timestamp ) {
rtp_session - > ts = ( uint32_t ) timestamp ;
/* Send marker bit if timestamp is lower/same as before (resetted/new timer) */
if ( rtp_session - > ts < = rtp_session - > last_write_ts & & ! ( rtp_session - > rtp_bugs & RTP_BUG_NEVER_SEND_MARKER ) ) {
m + + ;
}
2013-01-08 18:59:02 +00:00
} else if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ) {
2013-01-08 17:47:15 +00:00
rtp_session - > ts = rtp_session - > timer . samplecount ;
if ( rtp_session - > ts < = rtp_session - > last_write_ts & & rtp_session - > ts > 0 ) {
rtp_session - > ts = rtp_session - > last_write_ts + rtp_session - > samples_per_interval ;
}
} else {
rtp_session - > ts + = rtp_session - > samples_per_interval ;
2013-04-19 20:25:11 +00:00
if ( rtp_session - > ts < = rtp_session - > last_write_ts & & rtp_session - > ts > 0 ) {
rtp_session - > ts = rtp_session - > last_write_ts + rtp_session - > samples_per_interval ;
}
2013-01-08 17:47:15 +00:00
}
return m ;
}
2014-01-30 00:08:27 +00:00
static void do_mos ( switch_rtp_t * rtp_session , int force ) {
2014-01-30 02:46:38 +00:00
if ( ( switch_size_t ) rtp_session - > stats . inbound . recved < rtp_session - > stats . inbound . flaws ) {
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . flaws = 0 ;
}
if ( rtp_session - > stats . inbound . recved > 0 & &
rtp_session - > stats . inbound . flaws & & ( force | | rtp_session - > stats . inbound . last_flaw ! = rtp_session - > stats . inbound . flaws ) ) {
int R ;
if ( rtp_session - > consecutive_flaws + + ) {
int diff , penalty ;
diff = ( rtp_session - > stats . inbound . flaws - rtp_session - > stats . inbound . last_flaw ) ;
if ( diff < 1 ) diff = 1 ;
penalty = diff * 2 ;
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " %s %s %d consecutive flaws, adding %d flaw penalty \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) , rtp_type ( rtp_session ) ,
2014-01-30 00:08:27 +00:00
rtp_session - > consecutive_flaws , penalty ) ;
2015-11-17 01:31:32 +00:00
rtp_session - > bad_stream + + ;
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . flaws + = penalty ;
2016-09-12 17:21:21 +00:00
if ( rtp_session - > stats . inbound . error_log ) {
rtp_session - > stats . inbound . error_log - > flaws + = penalty ;
rtp_session - > stats . inbound . error_log - > consecutive_flaws + + ;
}
2014-01-30 00:08:27 +00:00
}
2014-01-30 02:46:38 +00:00
R = ( int ) ( ( double ) ( ( double ) ( rtp_session - > stats . inbound . recved - rtp_session - > stats . inbound . flaws ) / ( double ) rtp_session - > stats . inbound . recved ) * 100.0 ) ;
2014-01-30 00:08:27 +00:00
if ( R < 0 | | R > 100 ) R = 100 ;
rtp_session - > stats . inbound . R = R ;
rtp_session - > stats . inbound . mos = 1 + ( 0.035 ) * R + ( .000007 ) * R * ( R - 60 ) * ( 100 - R ) ;
rtp_session - > stats . inbound . last_flaw = rtp_session - > stats . inbound . flaws ;
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " %s %s stat %0.2f %ld/%d flaws: %ld mos: %0.2f v: %0.2f %0.2f/%0.2f \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) ,
2014-01-30 00:08:27 +00:00
rtp_type ( rtp_session ) ,
rtp_session - > stats . inbound . R ,
2014-01-31 17:49:44 +00:00
( long int ) ( rtp_session - > stats . inbound . recved - rtp_session - > stats . inbound . flaws ) , rtp_session - > stats . inbound . recved ,
( long int ) rtp_session - > stats . inbound . flaws ,
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . mos ,
rtp_session - > stats . inbound . variance ,
rtp_session - > stats . inbound . min_variance ,
rtp_session - > stats . inbound . max_variance
) ;
} else {
rtp_session - > consecutive_flaws = 0 ;
}
}
void burstr_calculate ( int loss [ ] , int received , double * burstr , double * lossr )
{
int lost = 0 ;
int bursts = 0 ;
int i ;
for ( i = 0 ; i < LOST_BURST_ANALYZE ; i + + ) {
lost + = i * loss [ i ] ;
bursts + = loss [ i ] ;
}
if ( received > 0 & & bursts > 0 ) {
* burstr = ( double ) ( ( double ) lost / ( double ) bursts ) / ( double ) ( 1.0 / ( 1.0 - ( double ) lost / ( double ) received ) ) ;
if ( * burstr < 0 ) {
* burstr = - * burstr ;
}
} else {
* burstr = 0 ;
}
if ( received > 0 ) {
* lossr = ( double ) ( ( double ) lost / ( double ) received ) ;
} else {
* lossr = 0 ;
}
}
static void reset_jitter_seq ( switch_rtp_t * rtp_session )
{
rtp_session - > stats . inbound . last_proc_time = 0 ;
rtp_session - > stats . inbound . last_processed_seq = 0 ;
rtp_session - > jitter_lead = 0 ;
2014-06-03 00:09:10 +00:00
rtp_session - > consecutive_flaws = 0 ;
rtp_session - > stats . inbound . last_flaw = 0 ;
2014-01-30 00:08:27 +00:00
}
static void check_jitter ( switch_rtp_t * rtp_session )
{
switch_time_t current_time ;
int64_t diff_time = 0 , cur_diff = 0 ;
int seq ;
current_time = switch_micro_time_now ( ) / 1000 ;
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_PAUSE ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] | | rtp_session - > dtmf_data . in_digit_ts ) {
reset_jitter_seq ( rtp_session ) ;
return ;
}
2014-06-03 00:09:10 +00:00
if ( + + rtp_session - > jitter_lead < JITTER_LEAD_FRAMES | | ! rtp_session - > stats . inbound . last_proc_time ) {
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . last_proc_time = current_time ;
return ;
}
diff_time = ( current_time - rtp_session - > stats . inbound . last_proc_time ) ;
2015-05-05 16:58:27 +00:00
seq = ( int ) ( uint16_t ) ntohs ( ( uint16_t ) rtp_session - > last_rtp_hdr . seq ) ;
2014-02-28 21:50:12 +00:00
2014-01-30 00:08:27 +00:00
/* Burst and Packet Loss */
rtp_session - > stats . inbound . recved + + ;
if ( rtp_session - > stats . inbound . last_processed_seq > 0 & & seq > ( int ) ( rtp_session - > stats . inbound . last_processed_seq + 1 ) ) {
int lost = ( seq - rtp_session - > stats . inbound . last_processed_seq - 1 ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " %s Got: %s seq %d but expected: %d lost: %d \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) ,
2014-01-30 00:08:27 +00:00
rtp_type ( rtp_session ) ,
seq ,
( rtp_session - > stats . inbound . last_processed_seq + 1 ) , lost ) ;
rtp_session - > stats . inbound . last_loss + + ;
if ( rtp_session - > stats . inbound . last_loss > 0 & & rtp_session - > stats . inbound . last_loss < LOST_BURST_CAPTURE ) {
rtp_session - > stats . inbound . loss [ rtp_session - > stats . inbound . last_loss ] + = lost ;
}
2015-11-17 01:31:32 +00:00
rtp_session - > bad_stream + + ;
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . flaws + = lost ;
2016-09-12 17:21:21 +00:00
if ( rtp_session - > stats . inbound . error_log ) {
rtp_session - > stats . inbound . error_log - > flaws + = lost ;
}
2014-01-30 00:08:27 +00:00
} else {
rtp_session - > stats . inbound . last_loss = 0 ;
}
2015-11-17 01:31:32 +00:00
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . last_processed_seq = seq ;
/* Burst and Packet Loss */
if ( current_time > rtp_session - > next_stat_check_time ) {
rtp_session - > next_stat_check_time = current_time + 5000 ;
burstr_calculate ( rtp_session - > stats . inbound . loss , rtp_session - > stats . inbound . recved ,
& ( rtp_session - > stats . inbound . burstrate ) , & ( rtp_session - > stats . inbound . lossrate ) ) ;
do_mos ( rtp_session , SWITCH_TRUE ) ;
} else {
do_mos ( rtp_session , SWITCH_FALSE ) ;
}
2015-11-17 01:31:32 +00:00
if ( rtp_session - > stats . inbound . last_loss | | rtp_session - > bad_stream ) {
if ( rtp_session - > session & & ( ! rtp_session - > stats . inbound . error_log | | rtp_session - > stats . inbound . error_log - > stop ) ) {
struct error_period * error = switch_core_session_alloc ( rtp_session - > session , sizeof ( * error ) ) ;
error - > start = switch_micro_time_now ( ) ;
error - > next = rtp_session - > stats . inbound . error_log ;
rtp_session - > stats . inbound . error_log = error ;
}
if ( ! rtp_session - > stats . inbound . last_loss ) {
if ( + + rtp_session - > recovering_stream > ( rtp_session - > one_second * 3 ) ) {
if ( rtp_session - > session & & rtp_session - > stats . inbound . error_log ) {
rtp_session - > stats . inbound . error_log - > stop = switch_micro_time_now ( ) ;
}
rtp_session - > bad_stream = 0 ;
}
} else {
rtp_session - > recovering_stream = 0 ;
rtp_session - > bad_stream + + ;
}
} else {
rtp_session - > recovering_stream = 0 ;
rtp_session - > clean_stream + + ;
}
2014-01-30 00:08:27 +00:00
if ( diff_time < 0 ) {
diff_time = - diff_time ;
}
rtp_session - > stats . inbound . jitter_n + + ;
rtp_session - > stats . inbound . jitter_add + = diff_time ;
2016-09-12 17:04:21 +00:00
if ( rtp_session - > stats . inbound . mean_interval ) {
cur_diff = ( int64_t ) ( diff_time - rtp_session - > stats . inbound . mean_interval ) ;
} else {
cur_diff = 0 ;
}
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . jitter_addsq + = ( cur_diff * cur_diff ) ;
rtp_session - > stats . inbound . last_proc_time = current_time ;
if ( rtp_session - > stats . inbound . jitter_n > 0 ) {
double ipdv ;
rtp_session - > stats . inbound . mean_interval = ( double ) rtp_session - > stats . inbound . jitter_add / ( double ) rtp_session - > stats . inbound . jitter_n ;
if ( ! rtp_session - > old_mean ) {
rtp_session - > old_mean = rtp_session - > stats . inbound . mean_interval ;
}
rtp_session - > stats . inbound . variance = ( double ) rtp_session - > stats . inbound . jitter_addsq / ( double ) rtp_session - > stats . inbound . jitter_n ;
//printf("CHECK %d +%ld +%ld %f %f\n", rtp_session->timer.samplecount, diff_time, (diff_time * diff_time), rtp_session->stats.inbound.mean_interval, rtp_session->stats.inbound.variance);
ipdv = rtp_session - > old_mean - rtp_session - > stats . inbound . mean_interval ;
if ( ipdv > IPDV_THRESHOLD ) { /* It shows Increasing Delays */
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG3 , " Calculated Instantaneous Packet Delay Variation: %s packet %lf \n " ,
2014-01-30 00:08:27 +00:00
rtp_type ( rtp_session ) , ipdv ) ;
}
if ( rtp_session - > stats . inbound . variance < rtp_session - > stats . inbound . min_variance | | rtp_session - > stats . inbound . min_variance = = 0 ) {
rtp_session - > stats . inbound . min_variance = rtp_session - > stats . inbound . variance ;
}
if ( rtp_session - > stats . inbound . variance > rtp_session - > stats . inbound . max_variance ) {
rtp_session - > stats . inbound . max_variance = rtp_session - > stats . inbound . variance ;
}
rtp_session - > old_mean = rtp_session - > stats . inbound . mean_interval ;
}
}
2013-07-11 22:38:24 +00:00
2014-07-21 09:40:59 +00:00
static void rtcp_generate_sender_info ( switch_rtp_t * rtp_session , struct switch_rtcp_sender_info * sr ) {
switch_core_session_t * session = switch_core_memory_pool_get_data ( rtp_session - > pool , " __session " ) ;
switch_time_t now ;
uint32_t sec , ntp_sec , ntp_usec ;
switch_time_exp_t now_hr ;
now = switch_time_now ( ) ;
2014-09-17 23:11:20 +00:00
sec = ( uint32_t ) ( now / 1000000 ) ; /* convert to seconds */
2014-07-21 09:40:59 +00:00
ntp_sec = sec + NTP_TIME_OFFSET ; /* convert to NTP seconds */
sr - > ntp_msw = htonl ( ntp_sec ) ; /* store result in "most significant word" */
2014-09-17 23:11:20 +00:00
ntp_usec = ( uint32_t ) ( now - ( sec * 1000000 ) ) ; /* remove seconds to keep only the microseconds */
sr - > ntp_lsw = htonl ( ( u_long ) ( ntp_usec * ( double ) ( ( ( uint64_t ) 1 ) < < 32 ) * 1.0e-6 ) ) ; /* convert microseconds to fraction of 32bits and store result in "least significatn word" */
2014-07-21 09:40:59 +00:00
sr - > ts = htonl ( rtp_session - > last_write_ts ) ;
sr - > pc = htonl ( rtp_session - > stats . outbound . packet_count ) ;
sr - > oc = htonl ( ( rtp_session - > stats . outbound . raw_bytes - rtp_session - > stats . outbound . packet_count * sizeof ( srtp_hdr_t ) ) ) ;
switch_time_exp_gmt ( & now_hr , now ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG10 , " Sending an RTCP packet[%04d-%02d-%02d %02d:%02d:%02d.%d] lsr[%u] msw[%u] lsw[%u] stats_ssrc[%u] \n " ,
2016-03-17 13:55:00 +00:00
1900 + now_hr . tm_year , now_hr . tm_mday , now_hr . tm_mon , now_hr . tm_hour , now_hr . tm_min , now_hr . tm_sec , now_hr . tm_usec ,
( ntohl ( sr - > ntp_lsw ) & 0xffff0000 ) > > 16 | ( ntohl ( sr - > ntp_msw ) & 0x0000ffff ) < < 16 ,
ntohl ( sr - > ntp_msw ) , ntohl ( sr - > ntp_lsw ) , rtp_session - > stats . rtcp . ssrc
) ;
2014-07-21 09:40:59 +00:00
}
2015-05-05 16:58:27 +00:00
//#define DEBUG_RTCP
2014-07-21 09:40:59 +00:00
static void rtcp_generate_report_block ( switch_rtp_t * rtp_session , struct switch_rtcp_report_block * rtcp_report_block ) {
# ifdef DEBUG_RTCP
switch_core_session_t * session = switch_core_memory_pool_get_data ( rtp_session - > pool , " __session " ) ;
# endif
switch_rtcp_numbers_t * stats = & rtp_session - > stats . rtcp ;
switch_time_t now ;
uint32_t expected_pkt , dlsr ;
int32_t pkt_lost ;
uint32_t ntp_sec , ntp_usec , lsr_now , sec ;
now = switch_time_now ( ) ;
2014-09-17 23:11:20 +00:00
sec = ( uint32_t ) ( now / 1000000 ) ; /* convert to seconds */
2014-07-21 09:40:59 +00:00
ntp_sec = sec + NTP_TIME_OFFSET ; /* convert to NTP seconds */
2014-09-17 23:11:20 +00:00
ntp_usec = ( uint32_t ) ( now - ( sec * 1000000 ) ) ; /* remove seconds to keep only the microseconds */
2014-07-21 09:40:59 +00:00
/* Packet loss */
if ( stats - > rtcp_rtp_count = = 0 ) {
expected_pkt = stats - > high_ext_seq_recv - stats - > base_seq + 1 ;
} else {
expected_pkt = stats - > high_ext_seq_recv - stats - > last_rpt_ext_seq ;
}
pkt_lost = expected_pkt - stats - > period_pkt_count ;
stats - > cum_lost = stats - > cum_lost + pkt_lost ;
if ( expected_pkt > 0 & & pkt_lost > 0 ) {
rtcp_report_block - > fraction = ( uint8_t ) ( pkt_lost * 256 / expected_pkt ) ;
} else {
rtcp_report_block - > fraction = 0 ;
}
# if SWITCH_BYTE_ORDER != __BIG_ENDIAN
/* Reversing byte order for 24bits */
rtcp_report_block - > lost = ( ( ( stats - > cum_lost & 0x0000FF ) < < 16 ) | ( ( stats - > cum_lost & 0x00FF00 ) ) | ( ( stats - > cum_lost & 0xFF0000 ) > > 16 ) ) ;
# endif
# ifdef DEBUG_RTCP
2015-05-05 16:58:27 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] )
2016-03-17 13:55:00 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_CRIT , " rtcp_generate_sr: stats_ssrc[%u] \n received[%d] \n expected[%d] \n cum[%d] \n lost[%d|%d/256]pkt \n last_seq[%d] \n cyc[%d] \n last_rpt_seq[%d] \n cyc[%d] \n ssrc[%d] \n " ,
rtp_session - > remote_ssrc , stats - > period_pkt_count , expected_pkt ,
stats - > cum_lost , pkt_lost , rtcp_report_block - > fraction , stats - > high_ext_seq_recv & 0x0000ffff ,
stats - > cycle , stats - > last_rpt_ext_seq & 0x0000ffff , stats - > last_rpt_cycle , rtp_session - > stats . rtcp . peer_ssrc
) ;
2014-07-21 09:40:59 +00:00
# endif
rtcp_report_block - > highest_sequence_number_received = htonl ( stats - > high_ext_seq_recv ) ;
/* Jitter */
rtcp_report_block - > jitter = htonl ( ( uint32_t ) stats - > inter_jitter ) ;
/* Delay since Last Sender Report (DLSR) : 32bits, 1/65536 seconds */
lsr_now = ( uint32_t ) ( ntp_usec * 0.065536 ) | ( ntp_sec & 0x0000ffff ) < < 16 ; /* 0.065536 is used for convertion from useconds to fraction of 65536 (x65536/1000000) */
if ( stats - > last_recv_lsr_local ) {
dlsr = lsr_now - stats - > last_recv_lsr_local ;
} else {
dlsr = 0 ;
}
rtcp_report_block - > lsr = stats - > last_recv_lsr_peer ;
rtcp_report_block - > dlsr = htonl ( dlsr ) ;
rtcp_report_block - > ssrc = htonl ( rtp_session - > stats . rtcp . peer_ssrc ) ;
stats - > rtcp_rtp_count + + ;
}
static void rtcp_stats_init ( switch_rtp_t * rtp_session )
{
switch_rtcp_numbers_t * stats = & rtp_session - > stats . rtcp ;
2015-05-05 16:58:27 +00:00
srtp_hdr_t * hdr = & rtp_session - > last_rtp_hdr ;
2014-07-21 09:40:59 +00:00
switch_core_session_t * session = switch_core_memory_pool_get_data ( rtp_session - > pool , " __session " ) ;
stats - > ssrc = ntohl ( hdr - > ssrc ) ;
stats - > last_rpt_ts = rtp_session - > timer . samplecount ;
2014-09-12 20:41:49 +00:00
stats - > init = 1 ;
2014-07-21 09:40:59 +00:00
stats - > last_rpt_ext_seq = 0 ;
stats - > last_rpt_cycle = 0 ;
stats - > last_pkt_tsdiff = 0 ;
stats - > inter_jitter = 0 ;
stats - > cycle = 0 ;
stats - > high_ext_seq_recv = ntohs ( ( uint16_t ) hdr - > seq ) ;
stats - > base_seq = ntohs ( ( uint16_t ) hdr - > seq ) ;
stats - > bad_seq = ( 1 < < 16 ) + 1 ; /* Make sure we wont missmatch 2 consecutive packets, so seq == bad_seq is false */
stats - > cum_lost = 0 ;
stats - > period_pkt_count = 0 ;
2015-05-13 16:50:04 +00:00
stats - > sent_pkt_count = 0 ;
2014-07-21 09:40:59 +00:00
stats - > pkt_count = 0 ;
stats - > rtcp_rtp_count = 0 ;
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2015-05-05 16:58:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " rtcp_stats_init: %s rtcp disabled \n " , rtp_type ( rtp_session ) ) ;
2014-07-21 09:40:59 +00:00
} else if ( ! rtp_session - > rtcp_sock_output ) {
2015-05-05 16:58:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_WARNING , " rtcp_stats_init: %s no rtcp socket \n " , rtp_type ( rtp_session ) ) ;
2014-07-21 09:40:59 +00:00
} else if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_PASSTHRU ] ) {
2015-05-05 16:58:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " rtcp_stats_init: %s rtcp passthru \n " , rtp_type ( rtp_session ) ) ;
2014-07-21 09:40:59 +00:00
} else {
2015-05-05 16:58:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " rtcp_stats_init: %s ssrc[%u] base_seq[%u] \n " , rtp_type ( rtp_session ) , stats - > ssrc , stats - > base_seq ) ;
2014-07-21 09:40:59 +00:00
}
2015-10-24 00:27:25 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] & & ( switch_core_media_codec_get_cap ( rtp_session - > session ,
SWITCH_MEDIA_TYPE_AUDIO , SWITCH_CODEC_FLAG_HAS_ADJ_BITRATE ) ) ) {
kalman_estimator_t * estimators [ KALMAN_SYSTEM_MODELS ] ;
cusum_kalman_detector_t * detectors [ KALMAN_SYSTEM_MODELS ] ;
rtp_session - > flags [ SWITCH_RTP_FLAG_ADJ_BITRATE_CAP ] = 1 ;
rtp_session - > flags [ SWITCH_RTP_FLAG_ESTIMATORS ] = 1 ;
rtp_session - > estimators [ EST_LOSS ] = switch_core_alloc ( rtp_session - > pool , sizeof ( * estimators [ 0 ] ) ) ;
switch_kalman_init ( rtp_session - > estimators [ EST_LOSS ] , 0.1 , 0.1 ) ;
rtp_session - > estimators [ EST_RTT ] = switch_core_alloc ( rtp_session - > pool , sizeof ( * estimators [ 0 ] ) ) ;
switch_kalman_init ( rtp_session - > estimators [ EST_RTT ] , 0.03 , 1 ) ;
rtp_session - > detectors [ EST_RTT ] = switch_core_alloc ( rtp_session - > pool , sizeof ( * detectors [ 0 ] ) ) ;
switch_kalman_cusum_init ( rtp_session - > detectors [ EST_RTT ] , 0.005 , 0.5 ) ;
rtp_session - > detectors [ EST_LOSS ] = switch_core_alloc ( rtp_session - > pool , sizeof ( * detectors [ 0 ] ) ) ;
switch_kalman_cusum_init ( rtp_session - > detectors [ EST_LOSS ] , 0.005 , 0.5 ) ;
}
2014-07-21 09:40:59 +00:00
}
static int rtcp_stats ( switch_rtp_t * rtp_session )
{
switch_core_session_t * session = switch_core_memory_pool_get_data ( rtp_session - > pool , " __session " ) ;
2015-05-05 16:58:27 +00:00
srtp_hdr_t * hdr = & rtp_session - > last_rtp_hdr ;
2014-07-21 09:40:59 +00:00
switch_rtcp_numbers_t * stats = & rtp_session - > stats . rtcp ;
2015-05-05 16:58:27 +00:00
uint32_t packet_spacing_diff = 0 , pkt_tsdiff , pkt_extended_seq ;
2014-07-21 09:40:59 +00:00
uint16_t pkt_seq , seq_diff , max_seq ;
const int MAX_DROPOUT = 3000 ;
const int MAX_MISORDER = 100 ;
const int RTP_SEQ_MOD = ( 1 < < 16 ) ;
if ( ! rtp_session - > rtcp_sock_output | | ! rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_PASSTHRU ] | | ! rtp_session - > rtcp_interval )
return 0 ; /* do not process RTCP in current state */
2015-05-05 16:58:27 +00:00
pkt_seq = ( uint16_t ) ntohs ( ( uint16_t ) rtp_session - > last_rtp_hdr . seq ) ;
2014-07-21 09:40:59 +00:00
/* Detect sequence number cycle change */
max_seq = stats - > high_ext_seq_recv & 0x0000ffff ;
seq_diff = pkt_seq - max_seq ;
if ( seq_diff < MAX_DROPOUT ) { /* in order, with permissible gap */
if ( pkt_seq < max_seq ) {
stats - > cycle + + ;
2015-07-15 16:50:36 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG , " rtcp_stats:[cycle change] pkt_seq[%d] cycle[%d] max_seq[%d] stats_ssrc[%u] local_ts[%u] \n " ,
2016-03-17 13:55:00 +00:00
pkt_seq , stats - > cycle , max_seq , stats - > ssrc , rtp_session - > timer . samplecount ) ;
2014-07-21 09:40:59 +00:00
}
pkt_extended_seq = stats - > cycle < < 16 | pkt_seq ; /* getting the extended packet extended sequence ID */
if ( pkt_extended_seq > stats - > high_ext_seq_recv ) {
stats - > high_ext_seq_recv = pkt_extended_seq ;
}
}
else if ( seq_diff < = ( RTP_SEQ_MOD - MAX_MISORDER ) ) { /* the sequence number made a very large jump */
if ( pkt_seq = = stats - > bad_seq ) {
rtcp_stats_init ( rtp_session ) ;
} else {
stats - > bad_seq = ( pkt_seq + 1 ) & ( RTP_SEQ_MOD - 1 ) ;
}
return 0 ; /* no stats, packet is out of sync and will be accounted as lost */
} else {
/* duplicate or reordered packet */
}
/* Verify that we are on the same stream source (we do not support multiple sources) */
2014-09-12 20:41:49 +00:00
if ( ntohl ( hdr - > ssrc ) ! = stats - > ssrc | | ! stats - > init ) {
2014-07-21 09:40:59 +00:00
rtcp_stats_init ( rtp_session ) ;
}
stats - > period_pkt_count + + ;
stats - > pkt_count + + ;
# ifdef DEBUG_RTCP
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG10 , " rtcp_stats: period_pkt_count[%d]last_seq[%d]cycle[%d]stats_ssrc[%u]local_ts[%u] \n " ,
2016-03-17 13:55:00 +00:00
stats - > period_pkt_count , pkt_seq , stats - > cycle , stats - > ssrc , rtp_session - > timer . samplecount ) ;
2014-07-21 09:40:59 +00:00
# endif
/* Interarrival jitter calculation */
2015-02-17 17:20:24 +00:00
pkt_tsdiff = abs ( ( int ) rtp_session - > timer . samplecount - ( int ) ntohl ( hdr - > ts ) ) ; /* relative transit times for this packet */
2014-07-21 09:40:59 +00:00
if ( stats - > pkt_count < 2 ) { /* Can not compute Jitter with only one packet */
stats - > last_pkt_tsdiff = pkt_tsdiff ;
} else {
2015-02-17 17:20:24 +00:00
packet_spacing_diff = abs ( ( int ) pkt_tsdiff - ( int ) stats - > last_pkt_tsdiff ) ; /* Jitter : difference of relative transit times for the two packets */
2014-07-21 09:40:59 +00:00
stats - > last_pkt_tsdiff = pkt_tsdiff ;
/* Interarrival jitter estimation, "J(i) = J(i-1) + ( |D(i-1,i)| - J(i-1) )/16" */
2015-02-17 17:20:24 +00:00
stats - > inter_jitter = ( stats - > inter_jitter + ( ( ( double ) packet_spacing_diff - stats - > inter_jitter ) / 16. ) ) ;
2014-07-21 09:40:59 +00:00
}
# ifdef DEBUG_RTCP
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( session ) , SWITCH_LOG_DEBUG10 , " rtcp_stats: pkt_ts[%d]local_ts[%d]diff[%d]pkt_spacing[%d]inter_jitter[%f]seq[%d]stats_ssrc[%d] " ,
2016-03-17 13:55:00 +00:00
ntohl ( hdr - > ts ) , rtp_session - > timer . samplecount , pkt_tsdiff , packet_spacing_diff , stats - > inter_jitter , ntohs ( hdr - > seq ) , stats - > ssrc ) ;
2014-07-21 09:40:59 +00:00
# endif
return 1 ;
}
2015-05-13 00:55:28 +00:00
static void calc_bw_exp ( uint32_t bps , uint8_t bits , rtcp_tmmbx_t * tmmbx )
{
uint32_t mantissa_max , i = 0 ;
uint8_t exp = 0 ;
uint32_t mantissa = 0 ;
2015-05-13 16:50:04 +00:00
uint16_t overhead = 60 ;
2015-05-13 00:55:28 +00:00
2015-05-27 22:14:49 +00:00
switch_assert ( bits < = 32 ) ;
2015-05-13 00:55:28 +00:00
mantissa_max = ( 1 < < bits ) - 1 ;
2015-05-27 22:14:49 +00:00
for ( i = 0 ; i < 32 ; + + i ) {
2015-05-13 00:55:28 +00:00
if ( bps < = ( mantissa_max < < i ) ) {
exp = i ;
break ;
}
}
mantissa = ( bps > > exp ) ;
tmmbx - > parts [ 0 ] = ( uint8_t ) ( ( exp < < 2 ) + ( ( mantissa > > 15 ) & 0x03 ) ) ;
tmmbx - > parts [ 1 ] = ( uint8_t ) ( mantissa > > 7 ) ;
tmmbx - > parts [ 2 ] = ( uint8_t ) ( ( mantissa > > 1 ) + ( ( overhead > > 8 ) & 0x01 ) ) ;
tmmbx - > parts [ 3 ] = ( uint8_t ) ( overhead ) ;
}
2015-05-13 16:50:04 +00:00
static int using_ice ( switch_rtp_t * rtp_session )
{
if ( rtp_session - > ice . ice_user | | rtp_session - > rtcp_ice . ice_user ) {
return 1 ;
}
return 0 ;
}
2015-05-13 00:55:28 +00:00
2015-09-19 04:36:11 +00:00
# define MAX_NACK 10
2013-06-18 00:52:37 +00:00
static int check_rtcp_and_ice ( switch_rtp_t * rtp_session )
2012-06-22 23:08:59 +00:00
{
int ret = 0 ;
2015-05-23 03:08:27 +00:00
int rtcp_ok = 0 , rtcp_fb = 0 ;
2013-06-18 00:52:37 +00:00
switch_time_t now = switch_micro_time_now ( ) ;
2015-09-11 16:37:01 +00:00
int rate = 0 , nack_ttl = 0 ;
2015-09-18 03:31:22 +00:00
uint32_t cur_nack [ MAX_NACK ] = { 0 } ;
2012-12-18 22:06:29 +00:00
2016-03-03 15:32:12 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & &
rtp_session - > flags [ SWITCH_RTP_FLAG_AUTO_CNG ] & &
rtp_session - > send_msg . header . ts & &
rtp_session - > cng_pt ! = INVALID_PT & &
2015-06-11 12:37:45 +00:00
( rtp_session - > timer . samplecount - rtp_session - > last_write_samplecount > = rtp_session - > samples_per_interval * 60 ) ) {
2013-01-08 17:47:15 +00:00
uint8_t data [ 10 ] = { 0 } ;
switch_frame_flag_t frame_flags = SFF_NONE ;
data [ 0 ] = 65 ;
rtp_session - > cn + + ;
2012-06-22 23:08:59 +00:00
2013-01-08 17:47:15 +00:00
get_next_write_ts ( rtp_session , 0 ) ;
rtp_session - > send_msg . header . ts = htonl ( rtp_session - > ts ) ;
switch_rtp_write_manual ( rtp_session , ( void * ) data , 2 , 0 , rtp_session - > cng_pt , ntohl ( rtp_session - > send_msg . header . ts ) , & frame_flags ) ;
2013-01-08 18:59:02 +00:00
if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ) {
2013-01-08 17:47:15 +00:00
rtp_session - > last_write_samplecount = rtp_session - > timer . samplecount ;
}
}
2012-06-22 23:08:59 +00:00
2015-05-13 16:50:04 +00:00
rate = rtp_session - > rtcp_interval ;
2013-01-14 02:12:23 +00:00
2015-09-11 16:37:01 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_NACK ] & & rtp_session - > vb ) {
int n ;
for ( n = 0 ; n < MAX_NACK ; n + + ) {
uint32_t nack = switch_jb_pop_nack ( rtp_session - > vb ) ;
if ( ! nack ) break ;
cur_nack [ nack_ttl + + ] = nack ;
}
}
2015-05-13 16:50:04 +00:00
if ( rtp_session - > rtcp_sent_packets < 4 ) {
rate = 4000 ;
} else {
2015-09-11 16:37:01 +00:00
if ( rtp_session - > pli_count | | rtp_session - > fir_count | | nack_ttl | | rtp_session - > tmmbr | | rtp_session - > tmmbn ) {
2015-05-23 03:08:27 +00:00
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "MARK BW/FIR ETC %d %d\n", rtp_session->pli_count, rtp_session->fir_count);
2015-05-13 16:50:04 +00:00
rtcp_ok = 1 ;
2015-05-23 03:08:27 +00:00
rtcp_fb = 1 ;
2015-05-13 16:50:04 +00:00
}
}
2015-05-23 03:08:27 +00:00
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "TIME CHECK %d > %d\n", (int)((now - rtp_session->rtcp_last_sent) / 1000), rate);
2015-05-13 16:50:04 +00:00
2015-05-13 18:25:41 +00:00
if ( ! rtcp_ok & & ( ! rtp_session - > rtcp_last_sent | | ( int ) ( ( now - rtp_session - > rtcp_last_sent ) / 1000 ) > rate ) ) {
2015-05-23 03:08:27 +00:00
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "TIME UP\n");
2015-05-13 16:50:04 +00:00
rtcp_ok = 1 ;
}
if ( rtcp_ok & & using_ice ( rtp_session ) ) {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
if ( ! rtp_session - > ice . rready ) {
rtcp_ok = 0 ;
}
} else {
if ( ! rtp_session - > rtcp_ice . rready ) {
rtcp_ok = 0 ;
}
}
2013-06-18 00:52:37 +00:00
}
2015-09-11 16:37:01 +00:00
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_ERROR, "WTF %d %d %d %d\n", rate, rtp_session->rtcp_sent_packets, rtcp_ok, nack_ttl);
2015-05-23 03:08:27 +00:00
2015-05-13 16:50:04 +00:00
if ( rtp_session - > rtcp_sock_output & & rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_PASSTHRU ] & & rtcp_ok ) {
2014-07-21 09:40:59 +00:00
switch_rtcp_numbers_t * stats = & rtp_session - > stats . rtcp ;
struct switch_rtcp_receiver_report * rr ;
struct switch_rtcp_sender_report * sr ;
struct switch_rtcp_report_block * rtcp_report_block ;
switch_size_t rtcp_bytes = sizeof ( struct switch_rtcp_hdr_s ) + sizeof ( uint32_t ) ; /* add size of the packet header and the ssrc */
2014-12-09 20:18:36 +00:00
switch_rtcp_hdr_t * sdes ;
uint8_t * p ;
switch_size_t sdes_bytes = sizeof ( struct switch_rtcp_hdr_s ) ;
uint32_t * ssrc ;
switch_rtcp_sdes_unit_t * unit ;
2013-01-20 18:04:10 +00:00
2015-05-23 03:08:27 +00:00
if ( ! rtcp_fb ) {
rtp_session - > rtcp_last_sent = now ;
rtp_session - > rtcp_sent_packets + + ;
}
2012-06-22 23:08:59 +00:00
rtp_session - > rtcp_send_msg . header . version = 2 ;
rtp_session - > rtcp_send_msg . header . p = 0 ;
rtp_session - > rtcp_send_msg . header . count = 1 ;
2015-05-23 03:08:27 +00:00
2015-05-13 16:50:04 +00:00
if ( ! rtp_session - > stats . rtcp . sent_pkt_count ) {
2015-07-21 04:09:07 +00:00
rtp_session - > rtcp_send_msg . header . type = _RTCP_PT_RR ; /* Receiver report */
2014-07-21 09:40:59 +00:00
rr = ( struct switch_rtcp_receiver_report * ) rtp_session - > rtcp_send_msg . body ;
rr - > ssrc = htonl ( rtp_session - > ssrc ) ;
rtcp_report_block = & rr - > report_block ;
rtcp_bytes + = sizeof ( struct switch_rtcp_report_block ) ;
2014-09-10 12:53:43 +00:00
} else {
2014-07-21 09:40:59 +00:00
struct switch_rtcp_sender_info * rtcp_sender_info ;
2015-07-21 04:09:07 +00:00
rtp_session - > rtcp_send_msg . header . type = _RTCP_PT_SR ; /* Sender report */
2014-07-21 09:40:59 +00:00
sr = ( struct switch_rtcp_sender_report * ) rtp_session - > rtcp_send_msg . body ;
sr - > ssrc = htonl ( rtp_session - > ssrc ) ;
rtcp_sender_info = & sr - > sender_info ;
rtcp_generate_sender_info ( rtp_session , rtcp_sender_info ) ;
rtcp_report_block = & sr - > report_block ;
rtcp_bytes + = sizeof ( struct switch_rtcp_sender_info ) + sizeof ( struct switch_rtcp_report_block ) ;
2014-07-21 09:40:59 +00:00
}
2014-07-21 09:40:59 +00:00
rtcp_generate_report_block ( rtp_session , rtcp_report_block ) ;
2014-07-21 09:40:59 +00:00
2014-07-21 09:40:59 +00:00
rtp_session - > rtcp_send_msg . header . length = htons ( ( uint16_t ) ( rtcp_bytes / 4 ) - 1 ) ;
2014-12-09 20:18:36 +00:00
2016-08-17 23:18:53 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2014-12-09 20:18:36 +00:00
if ( rtp_session - > pli_count ) {
switch_rtcp_ext_hdr_t * ext_hdr ;
p = ( uint8_t * ) ( & rtp_session - > rtcp_send_msg ) + rtcp_bytes ;
ext_hdr = ( switch_rtcp_ext_hdr_t * ) p ;
ext_hdr - > version = 2 ;
ext_hdr - > p = 0 ;
2015-07-21 04:09:07 +00:00
ext_hdr - > fmt = _RTCP_PSFB_PLI ;
ext_hdr - > pt = _RTCP_PT_PSFB ;
2014-12-09 20:18:36 +00:00
ext_hdr - > send_ssrc = htonl ( rtp_session - > ssrc ) ;
ext_hdr - > recv_ssrc = htonl ( rtp_session - > remote_ssrc ) ;
2016-08-12 19:28:45 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Sending RTCP PLI %u %u \n " ,
rtp_session - > ssrc , rtp_session - > remote_ssrc ) ;
2014-12-09 20:18:36 +00:00
ext_hdr - > length = htons ( ( uint8_t ) ( sizeof ( switch_rtcp_ext_hdr_t ) / 4 ) - 1 ) ;
rtcp_bytes + = sizeof ( switch_rtcp_ext_hdr_t ) ;
2015-05-13 16:50:04 +00:00
rtp_session - > pli_count = 0 ;
2014-12-09 20:18:36 +00:00
}
2015-01-09 19:36:57 +00:00
2015-09-11 16:37:01 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_NACK ] & & nack_ttl > 0 ) {
int n = 0 ;
2015-01-09 19:36:57 +00:00
2015-09-11 16:37:01 +00:00
for ( n = 0 ; n < nack_ttl ; n + + ) {
switch_rtcp_ext_hdr_t * ext_hdr ;
uint32_t * nack ;
p = ( uint8_t * ) ( & rtp_session - > rtcp_send_msg ) + rtcp_bytes ;
ext_hdr = ( switch_rtcp_ext_hdr_t * ) p ;
ext_hdr - > version = 2 ;
ext_hdr - > p = 0 ;
ext_hdr - > fmt = _RTCP_RTPFB_NACK ;
ext_hdr - > pt = _RTCP_PT_RTPFB ;
ext_hdr - > send_ssrc = htonl ( rtp_session - > ssrc ) ;
ext_hdr - > recv_ssrc = htonl ( rtp_session - > remote_ssrc ) ;
ext_hdr - > length = htons ( 3 ) ;
p + = sizeof ( switch_rtcp_ext_hdr_t ) ;
nack = ( uint32_t * ) p ;
* nack = cur_nack [ n ] ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Sending RTCP NACK %u \n " ,
ntohs ( * nack & 0xFFFF ) ) ;
2015-01-09 19:36:57 +00:00
2015-09-11 16:37:01 +00:00
rtcp_bytes + = sizeof ( switch_rtcp_ext_hdr_t ) + sizeof ( cur_nack [ n ] ) ;
2015-09-18 02:11:04 +00:00
cur_nack [ n ] = 0 ;
2015-09-11 16:37:01 +00:00
}
2015-01-09 19:36:57 +00:00
2015-09-11 16:37:01 +00:00
nack_ttl = 0 ;
2015-01-09 19:36:57 +00:00
}
2014-12-09 20:18:36 +00:00
if ( rtp_session - > fir_count ) {
switch_rtcp_ext_hdr_t * ext_hdr ;
rtcp_fir_t * fir ;
p = ( uint8_t * ) ( & rtp_session - > rtcp_send_msg ) + rtcp_bytes ;
ext_hdr = ( switch_rtcp_ext_hdr_t * ) p ;
p + = sizeof ( switch_rtcp_ext_hdr_t ) ;
fir = ( rtcp_fir_t * ) p ;
ext_hdr - > version = 2 ;
ext_hdr - > p = 0 ;
2015-07-21 04:09:07 +00:00
ext_hdr - > fmt = _RTCP_PSFB_FIR ;
ext_hdr - > pt = _RTCP_PT_PSFB ;
2014-12-09 20:18:36 +00:00
ext_hdr - > send_ssrc = htonl ( rtp_session - > ssrc ) ;
2015-01-24 07:55:57 +00:00
ext_hdr - > recv_ssrc = 0 ;
2014-12-09 20:18:36 +00:00
fir - > ssrc = htonl ( rtp_session - > remote_ssrc ) ;
2015-01-24 07:55:57 +00:00
fir - > seq = rtp_session - > fir_seq ;
2014-12-09 20:18:36 +00:00
fir - > r1 = fir - > r2 = fir - > r3 = 0 ;
2015-04-08 19:16:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Sending RTCP FIR SEQ %d \n " , rtp_session - > fir_seq ) ;
2015-01-24 07:55:57 +00:00
rtp_session - > fir_seq + + ;
2014-12-09 20:18:36 +00:00
ext_hdr - > length = htons ( ( uint8_t ) ( ( sizeof ( switch_rtcp_ext_hdr_t ) + sizeof ( rtcp_fir_t ) ) / 4 ) - 1 ) ;
rtcp_bytes + = sizeof ( switch_rtcp_ext_hdr_t ) + sizeof ( rtcp_fir_t ) ;
2015-05-13 16:50:04 +00:00
rtp_session - > fir_count = 0 ;
2014-12-09 20:18:36 +00:00
}
2015-05-07 16:58:49 +00:00
2015-05-13 00:55:28 +00:00
//if (!rtp_session->tmmbr && rtp_session->cur_tmmbr) {
// rtp_session->tmmbr = rtp_session->cur_tmmbr;
//}
2015-05-07 16:58:49 +00:00
while ( rtp_session - > tmmbr | | rtp_session - > tmmbn ) {
switch_rtcp_ext_hdr_t * ext_hdr ;
rtcp_tmmbx_t * tmmbx ;
2015-05-13 00:55:28 +00:00
uint32_t bps = 0 ;
2015-05-07 16:58:49 +00:00
p = ( uint8_t * ) ( & rtp_session - > rtcp_send_msg ) + rtcp_bytes ;
ext_hdr = ( switch_rtcp_ext_hdr_t * ) p ;
p + = sizeof ( switch_rtcp_ext_hdr_t ) ;
tmmbx = ( rtcp_tmmbx_t * ) p ;
ext_hdr - > version = 2 ;
ext_hdr - > p = 0 ;
2015-07-21 04:09:07 +00:00
ext_hdr - > pt = _RTCP_PT_RTPFB ;
2015-05-07 16:58:49 +00:00
ext_hdr - > send_ssrc = htonl ( rtp_session - > ssrc ) ;
ext_hdr - > recv_ssrc = 0 ;
if ( rtp_session - > tmmbr ) {
2015-05-13 00:55:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Sending RTCP TMMBR %u \n " , rtp_session - > tmmbr ) ;
2015-07-21 04:09:07 +00:00
ext_hdr - > fmt = _RTCP_RTPFB_TMMBR ;
2015-05-13 00:55:28 +00:00
bps = rtp_session - > tmmbr ;
2015-05-07 16:58:49 +00:00
rtp_session - > tmmbr = 0 ;
} else {
2015-05-13 00:55:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Sending RTCP TMMBN %u \n " , rtp_session - > tmmbr ) ;
2015-07-21 04:09:07 +00:00
ext_hdr - > fmt = _RTCP_RTPFB_TMMBN ;
2015-05-13 00:55:28 +00:00
bps = rtp_session - > tmmbn ;
2015-05-07 16:58:49 +00:00
rtp_session - > tmmbn = 0 ;
}
tmmbx - > ssrc = htonl ( rtp_session - > remote_ssrc ) ;
2015-05-13 00:55:28 +00:00
calc_bw_exp ( bps , 17 , tmmbx ) ;
2015-05-07 16:58:49 +00:00
2015-05-13 00:55:28 +00:00
ext_hdr - > length = htons ( ( uint8_t ) ( ( sizeof ( switch_rtcp_ext_hdr_t ) + sizeof ( rtcp_tmmbx_t ) ) / 4 ) - 1 ) ;
rtcp_bytes + = sizeof ( switch_rtcp_ext_hdr_t ) + sizeof ( rtcp_tmmbx_t ) ;
2015-05-07 16:58:49 +00:00
}
2014-12-09 20:18:36 +00:00
}
//SDES + CNAME
p = ( uint8_t * ) ( & rtp_session - > rtcp_send_msg ) + rtcp_bytes ;
sdes = ( switch_rtcp_hdr_t * ) p ;
sdes - > version = 2 ;
2015-07-21 04:09:07 +00:00
sdes - > type = _RTCP_PT_SDES ;
2014-12-09 20:18:36 +00:00
sdes - > count = 1 ;
sdes - > p = 0 ;
p = ( uint8_t * ) ( sdes ) + sdes_bytes ;
ssrc = ( uint32_t * ) p ;
* ssrc = htonl ( rtp_session - > ssrc ) ;
sdes_bytes + = sizeof ( uint32_t ) ;
p = ( uint8_t * ) ( sdes ) + sdes_bytes ;
unit = ( switch_rtcp_sdes_unit_t * ) p ;
2015-07-21 04:09:07 +00:00
unit - > type = _RTCP_SDES_CNAME ;
2014-12-09 20:18:36 +00:00
snprintf ( ( char * ) unit - > value , 80 , " %x " , rtp_session - > ssrc ) ;
unit - > length = strlen ( ( char * ) unit - > value ) ;
sdes_bytes + = sizeof ( switch_rtcp_sdes_unit_t ) + unit - > length ;
p + = sizeof ( switch_rtcp_sdes_unit_t ) + unit - > length ;
unit = ( switch_rtcp_sdes_unit_t * ) p ;
2015-07-21 04:09:07 +00:00
unit - > type = _RTCP_SDES_NOTE ;
2014-12-09 20:18:36 +00:00
snprintf ( ( char * ) unit - > value , 80 , " FreeSWITCH.org -- Come to ClueCon.com " ) ;
unit - > length = strlen ( ( char * ) unit - > value ) ;
sdes_bytes + = sizeof ( switch_rtcp_sdes_unit_t ) + unit - > length ;
sdes_bytes + + ; //END
sdes_bytes + = 4 - ( sdes_bytes % 4 ) ;
sdes - > length = htons ( ( uint16_t ) ( sdes_bytes / 4 ) - 1 ) ;
rtcp_bytes + = sdes_bytes ;
2015-05-23 03:08:27 +00:00
2014-07-21 09:40:59 +00:00
/* Prepare next report */
2015-05-23 03:08:27 +00:00
2014-07-21 09:40:59 +00:00
stats - > last_rpt_cycle = stats - > cycle ;
stats - > last_rpt_ext_seq = stats - > high_ext_seq_recv ;
stats - > last_rpt_ts = rtp_session - > timer . samplecount ;
stats - > period_pkt_count = 0 ;
2015-05-13 16:50:04 +00:00
stats - > sent_pkt_count = 0 ;
2014-07-21 09:40:59 +00:00
2015-05-23 03:08:27 +00:00
2012-06-22 23:08:59 +00:00
# ifdef ENABLE_SRTP
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] ) {
2012-06-22 23:08:59 +00:00
int sbytes = ( int ) rtcp_bytes ;
2013-02-03 05:57:27 +00:00
int stat = srtp_protect_rtcp ( rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtcp ] , & rtp_session - > rtcp_send_msg . header , & sbytes ) ;
2013-01-13 07:29:05 +00:00
2012-06-22 23:08:59 +00:00
if ( stat ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error: SRTP RTCP protection failed with code %d \n " , stat ) ;
2013-01-20 18:04:10 +00:00
goto end ;
} else {
rtcp_bytes = sbytes ;
2012-06-22 23:08:59 +00:00
}
2013-01-13 07:29:05 +00:00
2012-06-22 23:08:59 +00:00
}
# endif
# ifdef ENABLE_ZRTP
/* ZRTP Send */
2012-12-18 22:06:29 +00:00
if ( zrtp_on & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] ) {
2012-06-23 19:03:06 +00:00
unsigned int sbytes = ( int ) rtcp_bytes ;
2012-06-22 23:08:59 +00:00
zrtp_status_t stat = zrtp_status_fail ;
stat = zrtp_process_rtcp ( rtp_session - > zrtp_stream , ( void * ) & rtp_session - > rtcp_send_msg , & sbytes ) ;
switch ( stat ) {
case zrtp_status_ok :
break ;
case zrtp_status_drop :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error: zRTP protection drop with code %d \n " , stat ) ;
2012-06-23 19:03:06 +00:00
ret = ( int ) rtcp_bytes ;
2012-06-22 23:08:59 +00:00
goto end ;
break ;
case zrtp_status_fail :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error: zRTP protection fail with code %d \n " , stat ) ;
break ;
default :
break ;
}
2012-06-23 19:03:06 +00:00
rtcp_bytes = sbytes ;
2012-06-22 23:08:59 +00:00
}
# endif
2015-11-18 16:31:30 +00:00
//#define DEBUG_EXTRA
2013-06-18 00:52:37 +00:00
# ifdef DEBUG_EXTRA
2014-06-13 10:06:14 +00:00
{
const char * old_host ;
2015-08-27 18:42:52 +00:00
char bufb [ 50 ] ;
2014-06-13 10:06:14 +00:00
old_host = switch_get_addr ( bufb , sizeof ( bufb ) , rtp_session - > rtcp_remote_addr ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_CRIT , " %s SEND %s RTCP %s:%d %ld \n " ,
rtp_session_name ( rtp_session ) ,
2015-05-27 06:15:28 +00:00
rtp_type ( rtp_session ) ,
2014-06-13 10:06:14 +00:00
old_host ,
switch_sockaddr_get_port ( rtp_session - > rtcp_remote_addr ) ,
rtcp_bytes ) ;
}
2013-06-18 00:52:37 +00:00
# endif
2013-01-17 01:04:57 +00:00
if ( switch_socket_sendto ( rtp_session - > rtcp_sock_output , rtp_session - > rtcp_remote_addr , 0 , ( void * ) & rtp_session - > rtcp_send_msg , & rtcp_bytes ) ! = SWITCH_STATUS_SUCCESS ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " RTCP packet not written \n " ) ;
2012-06-22 23:08:59 +00:00
} else {
rtp_session - > stats . inbound . period_packet_count = 0 ;
}
}
if ( rtp_session - > ice . ice_user ) {
2013-06-21 17:42:37 +00:00
if ( ice_out ( rtp_session , & rtp_session - > ice ) = = SWITCH_STATUS_GENERR ) {
2012-06-22 23:08:59 +00:00
ret = - 1 ;
goto end ;
}
}
2013-06-18 00:52:37 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
if ( rtp_session - > rtcp_ice . ice_user ) {
2013-06-21 17:42:37 +00:00
if ( ice_out ( rtp_session , & rtp_session - > rtcp_ice ) = = SWITCH_STATUS_GENERR ) {
2013-06-18 00:52:37 +00:00
ret = - 1 ;
goto end ;
}
2012-06-22 23:08:59 +00:00
}
}
end :
return ret ;
}
SWITCH_DECLARE ( void ) switch_rtp_ping ( switch_rtp_t * rtp_session )
{
2013-06-18 00:52:37 +00:00
check_rtcp_and_ice ( rtp_session ) ;
2012-06-22 23:08:59 +00:00
}
2008-01-16 06:01:53 +00:00
SWITCH_DECLARE ( void ) switch_rtp_get_random ( void * buf , uint32_t len )
{
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2008-01-16 06:01:53 +00:00
crypto_get_random ( buf , len ) ;
2011-05-02 16:33:57 +00:00
# else
switch_stun_random_string ( buf , len , NULL ) ;
# endif
2008-01-16 06:01:53 +00:00
}
2007-12-11 19:15:02 +00:00
SWITCH_DECLARE ( void ) switch_rtp_shutdown ( void )
{
2009-03-03 20:16:05 +00:00
switch_core_port_allocator_t * alloc = NULL ;
switch_hash_index_t * hi ;
2010-02-06 03:38:24 +00:00
const void * var ;
void * val ;
2009-03-03 20:16:05 +00:00
2010-09-14 16:48:43 +00:00
if ( ! global_init ) {
return ;
}
2009-03-03 20:16:05 +00:00
switch_mutex_lock ( port_lock ) ;
2014-04-01 22:21:29 +00:00
for ( hi = switch_core_hash_first ( alloc_hash ) ; hi ; hi = switch_core_hash_next ( & hi ) ) {
2014-03-08 19:37:09 +00:00
switch_core_hash_this ( hi , & var , NULL , & val ) ;
2009-03-03 20:16:05 +00:00
if ( ( alloc = ( switch_core_port_allocator_t * ) val ) ) {
2010-02-06 03:38:24 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Destroy port allocator for %s \n " , ( char * ) var ) ;
2009-03-03 20:16:05 +00:00
switch_core_port_allocator_destroy ( & alloc ) ;
}
}
2007-12-11 19:15:02 +00:00
switch_core_hash_destroy ( & alloc_hash ) ;
2009-03-03 20:16:05 +00:00
switch_mutex_unlock ( port_lock ) ;
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
2009-05-20 23:53:44 +00:00
if ( zrtp_on ) {
2009-05-22 05:33:21 +00:00
zrtp_status_t status = zrtp_status_ok ;
status = zrtp_def_cache_store ( zrtp_global ) ;
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG , " Saving ZRTP cache: %s \n " , zrtp_status_ok = = status ? " OK " : " FAIL " ) ;
2009-05-20 23:53:44 +00:00
zrtp_down ( zrtp_global ) ;
}
2009-05-20 23:04:05 +00:00
# endif
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2009-03-03 20:16:05 +00:00
crypto_kernel_shutdown ( ) ;
2011-05-02 16:33:57 +00:00
# endif
2009-03-03 20:16:05 +00:00
2007-12-11 19:15:02 +00:00
}
2007-04-07 03:07:43 +00:00
SWITCH_DECLARE ( switch_port_t ) switch_rtp_set_start_port ( switch_port_t port )
{
if ( port ) {
if ( port_lock ) {
switch_mutex_lock ( port_lock ) ;
}
START_PORT = port ;
if ( port_lock ) {
switch_mutex_unlock ( port_lock ) ;
}
2008-05-27 04:30:03 +00:00
}
return START_PORT ;
2007-04-07 03:07:43 +00:00
}
SWITCH_DECLARE ( switch_port_t ) switch_rtp_set_end_port ( switch_port_t port )
{
if ( port ) {
if ( port_lock ) {
switch_mutex_lock ( port_lock ) ;
}
END_PORT = port ;
if ( port_lock ) {
switch_mutex_unlock ( port_lock ) ;
}
2008-05-27 04:30:03 +00:00
}
return END_PORT ;
2007-04-07 03:07:43 +00:00
}
2007-12-20 15:41:45 +00:00
SWITCH_DECLARE ( void ) switch_rtp_release_port ( const char * ip , switch_port_t port )
2006-04-05 20:17:22 +00:00
{
2007-12-11 19:15:02 +00:00
switch_core_port_allocator_t * alloc = NULL ;
2012-07-23 16:36:19 +00:00
if ( ! ip | | ! port ) {
2007-12-11 19:15:02 +00:00
return ;
}
2008-05-27 04:30:03 +00:00
switch_mutex_lock ( port_lock ) ;
if ( ( alloc = switch_core_hash_find ( alloc_hash , ip ) ) ) {
2007-12-13 15:10:55 +00:00
switch_core_port_allocator_free_port ( alloc , port ) ;
2007-12-11 19:15:02 +00:00
}
switch_mutex_unlock ( port_lock ) ;
}
2006-04-05 20:17:22 +00:00
2007-12-11 19:15:02 +00:00
SWITCH_DECLARE ( switch_port_t ) switch_rtp_request_port ( const char * ip )
{
switch_port_t port = 0 ;
switch_core_port_allocator_t * alloc = NULL ;
2008-05-27 04:30:03 +00:00
2006-04-05 20:17:22 +00:00
switch_mutex_lock ( port_lock ) ;
2007-12-11 19:15:02 +00:00
alloc = switch_core_hash_find ( alloc_hash , ip ) ;
if ( ! alloc ) {
2014-01-23 19:23:58 +00:00
if ( switch_core_port_allocator_new ( ip , START_PORT , END_PORT , SPF_EVEN , & alloc ) ! = SWITCH_STATUS_SUCCESS ) {
2007-12-13 17:25:33 +00:00
abort ( ) ;
2007-12-11 19:15:02 +00:00
}
switch_core_hash_insert ( alloc_hash , ip , alloc ) ;
2006-04-05 20:17:22 +00:00
}
2008-05-27 04:30:03 +00:00
2007-12-11 19:15:02 +00:00
if ( switch_core_port_allocator_request_port ( alloc , & port ) ! = SWITCH_STATUS_SUCCESS ) {
port = 0 ;
}
2006-04-05 20:17:22 +00:00
switch_mutex_unlock ( port_lock ) ;
return port ;
}
2013-11-07 22:48:00 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_set_payload_map ( switch_rtp_t * rtp_session , payload_map_t * * pmap )
{
if ( rtp_session ) {
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
rtp_session - > pmaps = pmap ;
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_FALSE ;
}
2008-12-29 21:23:17 +00:00
SWITCH_DECLARE ( void ) switch_rtp_intentional_bugs ( switch_rtp_t * rtp_session , switch_rtp_bug_flag_t bugs )
{
rtp_session - > rtp_bugs = bugs ;
2010-11-11 00:08:55 +00:00
if ( ( rtp_session - > rtp_bugs & RTP_BUG_START_SEQ_AT_ZERO ) ) {
rtp_session - > seq = 0 ;
}
2008-12-29 21:23:17 +00:00
}
2010-04-20 00:07:23 +00:00
static switch_status_t enable_remote_rtcp_socket ( switch_rtp_t * rtp_session , const char * * err ) {
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2010-04-20 00:07:23 +00:00
2010-06-24 21:01:55 +00:00
if ( switch_sockaddr_info_get ( & rtp_session - > rtcp_remote_addr , rtp_session - > eff_remote_host_str , SWITCH_UNSPEC ,
2010-04-20 21:15:37 +00:00
rtp_session - > remote_rtcp_port , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS | | ! rtp_session - > rtcp_remote_addr ) {
2010-04-20 00:07:23 +00:00
* err = " RTCP Remote Address Error! " ;
return SWITCH_STATUS_FALSE ;
2010-04-22 15:22:28 +00:00
} else {
const char * host ;
2015-08-27 18:42:52 +00:00
char bufa [ 50 ] ;
2013-01-15 05:17:28 +00:00
2010-04-22 15:22:28 +00:00
host = switch_get_addr ( bufa , sizeof ( bufa ) , rtp_session - > rtcp_remote_addr ) ;
2013-02-09 04:47:18 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG ,
2015-06-03 20:54:15 +00:00
" Setting RTCP remote addr to %s:%d %d \n " , host , rtp_session - > remote_rtcp_port , rtp_session - > rtcp_remote_addr - > family ) ;
2010-04-20 00:07:23 +00:00
}
2013-10-28 22:44:07 +00:00
if ( rtp_session - > rtcp_sock_input & & switch_sockaddr_get_family ( rtp_session - > rtcp_remote_addr ) = =
switch_sockaddr_get_family ( rtp_session - > rtcp_local_addr ) ) {
rtp_session - > rtcp_sock_output = rtp_session - > rtcp_sock_input ;
} else {
if ( rtp_session - > rtcp_sock_output & & rtp_session - > rtcp_sock_output ! = rtp_session - > rtcp_sock_input ) {
switch_socket_close ( rtp_session - > rtcp_sock_output ) ;
}
if ( ( status = switch_socket_create ( & rtp_session - > rtcp_sock_output ,
switch_sockaddr_get_family ( rtp_session - > rtcp_remote_addr ) ,
SOCK_DGRAM , 0 , rtp_session - > pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " RTCP Socket Error! " ;
2010-04-20 00:07:23 +00:00
}
}
2013-10-28 22:44:07 +00:00
2010-04-20 00:07:23 +00:00
} else {
* err = " RTCP NOT ACTIVE! " ;
}
return status ;
}
static switch_status_t enable_local_rtcp_socket ( switch_rtp_t * rtp_session , const char * * err ) {
const char * host = rtp_session - > local_host_str ;
switch_port_t port = rtp_session - > local_port ;
switch_socket_t * rtcp_new_sock = NULL , * rtcp_old_sock = NULL ;
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2015-08-27 18:42:52 +00:00
char bufa [ 50 ] ;
2010-04-20 00:07:23 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2010-04-20 00:07:23 +00:00
if ( switch_sockaddr_info_get ( & rtp_session - > rtcp_local_addr , host , SWITCH_UNSPEC , port + 1 , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " RTCP Local Address Error! " ;
goto done ;
}
if ( switch_socket_create ( & rtcp_new_sock , switch_sockaddr_get_family ( rtp_session - > rtcp_local_addr ) , SOCK_DGRAM , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " RTCP Socket Error! " ;
goto done ;
}
if ( switch_socket_opt_set ( rtcp_new_sock , SWITCH_SO_REUSEADDR , 1 ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " RTCP Socket Error! " ;
goto done ;
}
if ( switch_socket_bind ( rtcp_new_sock , rtp_session - > rtcp_local_addr ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " RTCP Bind Error! " ;
goto done ;
}
if ( switch_sockaddr_info_get ( & rtp_session - > rtcp_from_addr , switch_get_addr ( bufa , sizeof ( bufa ) , rtp_session - > from_addr ) ,
SWITCH_UNSPEC , switch_sockaddr_get_port ( rtp_session - > from_addr ) + 1 , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " RTCP From Address Error! " ;
goto done ;
}
rtcp_old_sock = rtp_session - > rtcp_sock_input ;
rtp_session - > rtcp_sock_input = rtcp_new_sock ;
rtcp_new_sock = NULL ;
switch_socket_create_pollset ( & rtp_session - > rtcp_read_pollfd , rtp_session - > rtcp_sock_input , SWITCH_POLLIN | SWITCH_POLLERR , rtp_session - > pool ) ;
done :
if ( * err ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error allocating rtcp [%s] \n " , * err ) ;
2010-04-20 00:07:23 +00:00
status = SWITCH_STATUS_FALSE ;
}
if ( rtcp_new_sock ) {
switch_socket_close ( rtcp_new_sock ) ;
}
if ( rtcp_old_sock ) {
switch_socket_close ( rtcp_old_sock ) ;
}
} else {
status = SWITCH_STATUS_FALSE ;
}
return status ;
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_set_local_address ( switch_rtp_t * rtp_session , const char * host , switch_port_t port , const char * * err )
2006-04-06 20:56:29 +00:00
{
2007-02-17 22:13:19 +00:00
switch_socket_t * new_sock = NULL , * old_sock = NULL ;
switch_status_t status = SWITCH_STATUS_FALSE ;
2013-11-21 23:52:11 +00:00
int j = 0 ;
2007-12-17 18:24:26 +00:00
# ifndef WIN32
2007-04-20 00:29:18 +00:00
char o [ 5 ] = " TEST " , i [ 5 ] = " " ;
2007-12-04 21:55:48 +00:00
switch_size_t len , ilen = 0 ;
int x ;
2007-12-17 18:24:26 +00:00
# endif
2007-12-04 21:55:48 +00:00
2008-02-25 16:35:19 +00:00
if ( rtp_session - > ready ! = 1 ) {
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
WRITE_INC ( rtp_session ) ;
READ_INC ( rtp_session ) ;
if ( ! switch_rtp_ready ( rtp_session ) ) {
goto done ;
}
}
2008-01-18 18:14:53 +00:00
2007-04-20 20:53:11 +00:00
* err = NULL ;
2007-03-29 22:31:56 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( host ) | | ! port ) {
2008-03-07 20:13:40 +00:00
* err = " Address Error " ;
goto done ;
}
2010-04-20 00:07:23 +00:00
rtp_session - > local_host_str = switch_core_strdup ( rtp_session - > pool , host ) ;
rtp_session - > local_port = port ;
2007-03-30 00:13:31 +00:00
if ( switch_sockaddr_info_get ( & rtp_session - > local_addr , host , SWITCH_UNSPEC , port , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-06 20:56:29 +00:00
* err = " Local Address Error! " ;
2007-02-17 22:13:19 +00:00
goto done ;
2006-04-04 02:28:11 +00:00
}
2010-04-20 00:07:23 +00:00
2008-07-03 18:50:15 +00:00
if ( rtp_session - > sock_input ) {
2006-08-30 19:46:43 +00:00
switch_rtp_kill_socket ( rtp_session ) ;
2006-04-03 21:00:13 +00:00
}
2007-03-29 22:31:56 +00:00
2008-07-03 18:50:15 +00:00
if ( switch_socket_create ( & new_sock , switch_sockaddr_get_family ( rtp_session - > local_addr ) , SOCK_DGRAM , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
2006-04-04 02:28:11 +00:00
* err = " Socket Error! " ;
2007-02-17 22:13:19 +00:00
goto done ;
2006-04-04 02:28:11 +00:00
}
2006-04-03 21:00:13 +00:00
2007-02-17 22:13:19 +00:00
if ( switch_socket_opt_set ( new_sock , SWITCH_SO_REUSEADDR , 1 ) ! = SWITCH_STATUS_SUCCESS ) {
2006-10-06 22:39:49 +00:00
* err = " Socket Error! " ;
2007-02-17 22:13:19 +00:00
goto done ;
2006-10-06 22:39:49 +00:00
}
2015-03-26 20:00:55 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2015-05-01 20:39:12 +00:00
switch_socket_opt_set ( new_sock , SWITCH_SO_RCVBUF , 1572864 ) ;
switch_socket_opt_set ( new_sock , SWITCH_SO_SNDBUF , 1572864 ) ;
2015-03-26 20:00:55 +00:00
}
2007-02-17 22:13:19 +00:00
if ( switch_socket_bind ( new_sock , rtp_session - > local_addr ) ! = SWITCH_STATUS_SUCCESS ) {
2011-08-02 04:55:58 +00:00
char * em = switch_core_sprintf ( rtp_session - > pool , " Bind Error! %s:%d " , host , port ) ;
* err = em ;
2007-02-17 22:13:19 +00:00
goto done ;
2006-04-04 02:28:11 +00:00
}
2010-04-20 00:07:23 +00:00
2013-11-21 23:52:11 +00:00
if ( ( j = atoi ( host ) ) & & j > 223 & & j < 240 ) { /* mcast */
if ( switch_mcast_interface ( new_sock , rtp_session - > local_addr ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " Multicast Socket interface Error " ;
goto done ;
}
if ( switch_mcast_join ( new_sock , rtp_session - > local_addr , NULL , NULL ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " Multicast Error " ;
goto done ;
}
if ( rtp_session - > session ) {
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
const char * var ;
if ( ( var = switch_channel_get_variable ( channel , " multicast_ttl " ) ) ) {
int ttl = atoi ( var ) ;
if ( ttl > 0 & & ttl < 256 ) {
if ( switch_mcast_hops ( new_sock , ( uint8_t ) ttl ) ! = SWITCH_STATUS_SUCCESS ) {
* err = " Mutlicast TTL set failed " ;
goto done ;
}
}
}
}
}
2007-12-17 18:24:26 +00:00
# ifndef WIN32
2007-04-20 00:29:18 +00:00
len = sizeof ( i ) ;
2007-12-04 21:55:48 +00:00
switch_socket_opt_set ( new_sock , SWITCH_SO_NONBLOCK , TRUE ) ;
2007-04-20 00:29:18 +00:00
switch_socket_sendto ( new_sock , rtp_session - > local_addr , 0 , ( void * ) o , & len ) ;
2007-12-04 21:55:48 +00:00
x = 0 ;
2008-05-27 04:30:03 +00:00
while ( ! ilen ) {
2007-12-04 23:06:12 +00:00
switch_status_t status ;
2007-12-04 21:55:48 +00:00
ilen = len ;
2007-12-04 23:06:12 +00:00
status = switch_socket_recvfrom ( rtp_session - > from_addr , new_sock , 0 , ( void * ) i , & ilen ) ;
2007-12-04 21:55:48 +00:00
if ( status ! = SWITCH_STATUS_SUCCESS & & status ! = SWITCH_STATUS_BREAK ) {
break ;
}
2008-03-07 20:13:40 +00:00
if ( + + x > 1000 ) {
2007-12-04 21:55:48 +00:00
break ;
}
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2007-12-04 21:55:48 +00:00
}
switch_socket_opt_set ( new_sock , SWITCH_SO_NONBLOCK , FALSE ) ;
2010-04-28 22:34:57 +00:00
# endif
2007-12-17 18:24:26 +00:00
2008-07-03 18:50:15 +00:00
old_sock = rtp_session - > sock_input ;
rtp_session - > sock_input = new_sock ;
2007-02-17 22:13:19 +00:00
new_sock = NULL ;
2013-06-18 00:52:37 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_NOBLOCK ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2008-07-03 18:50:15 +00:00
switch_socket_opt_set ( rtp_session - > sock_input , SWITCH_SO_NONBLOCK , TRUE ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_NOBLOCK ) ;
2006-04-07 17:32:14 +00:00
}
2007-02-17 22:13:19 +00:00
2010-02-17 22:36:07 +00:00
switch_socket_create_pollset ( & rtp_session - > read_pollfd , rtp_session - > sock_input , SWITCH_POLLIN | SWITCH_POLLERR , rtp_session - > pool ) ;
2009-03-31 19:10:43 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2010-04-20 00:07:23 +00:00
if ( ( status = enable_local_rtcp_socket ( rtp_session , err ) ) = = SWITCH_STATUS_SUCCESS ) {
* err = " Success " ;
}
} else {
status = SWITCH_STATUS_SUCCESS ;
* err = " Success " ;
}
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_IO ) ;
2007-02-17 22:13:19 +00:00
2010-04-20 00:07:23 +00:00
done :
2007-02-17 22:13:19 +00:00
if ( new_sock ) {
switch_socket_close ( new_sock ) ;
}
if ( old_sock ) {
switch_socket_close ( old_sock ) ;
}
2008-05-27 04:30:03 +00:00
2010-04-20 00:07:23 +00:00
2008-02-25 16:35:19 +00:00
if ( rtp_session - > ready ! = 1 ) {
WRITE_DEC ( rtp_session ) ;
READ_DEC ( rtp_session ) ;
}
2007-02-17 22:13:19 +00:00
return status ;
2006-04-06 20:56:29 +00:00
}
2007-10-31 02:12:30 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_max_missed_packets ( switch_rtp_t * rtp_session , uint32_t max )
{
2016-01-27 16:49:34 +00:00
if ( ! switch_rtp_ready ( rtp_session ) | | rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
return ;
}
2009-03-19 01:06:21 +00:00
if ( rtp_session - > missed_count > = max ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING ,
2010-02-06 03:38:24 +00:00
" new max missed packets(%d->%d) greater than current missed packets(%d). RTP will timeout. \n " ,
2009-03-19 01:06:21 +00:00
rtp_session - > missed_count , max , rtp_session - > missed_count ) ;
}
2009-03-18 20:36:30 +00:00
2007-10-31 02:12:30 +00:00
rtp_session - > max_missed_packets = max ;
}
2015-12-23 22:03:35 +00:00
SWITCH_DECLARE ( void ) switch_rtp_reset_jb ( switch_rtp_t * rtp_session )
{
if ( switch_rtp_ready ( rtp_session ) ) {
if ( rtp_session - > jb ) {
switch_jb_reset ( rtp_session - > jb ) ;
}
}
}
2015-11-18 16:31:30 +00:00
SWITCH_DECLARE ( void ) switch_rtp_reset_vb ( switch_rtp_t * rtp_session )
{
2016-09-27 01:06:30 +00:00
2015-11-18 16:31:30 +00:00
if ( rtp_session - > vb ) {
switch_jb_reset ( rtp_session - > vb ) ;
}
if ( rtp_session - > vbw ) {
switch_jb_reset ( rtp_session - > vbw ) ;
}
}
2014-06-14 02:05:00 +00:00
SWITCH_DECLARE ( void ) switch_rtp_reset ( switch_rtp_t * rtp_session )
{
if ( ! rtp_session ) {
return ;
}
rtp_session - > seq = ( uint16_t ) rand ( ) ;
rtp_session - > ts = 0 ;
memset ( & rtp_session - > ts_norm , 0 , sizeof ( rtp_session - > ts_norm ) ) ;
2015-08-24 18:13:43 +00:00
rtp_session - > last_stun = rtp_session - > first_stun = 0 ;
2015-08-26 18:38:51 +00:00
rtp_session - > wrong_addrs = 0 ;
2015-05-13 18:25:41 +00:00
rtp_session - > rtcp_sent_packets = 0 ;
rtp_session - > rtcp_last_sent = 0 ;
2015-10-04 21:53:43 +00:00
rtp_session - > ice_adj = 0 ;
2015-05-13 18:25:41 +00:00
//switch_rtp_del_dtls(rtp_session, DTLS_TYPE_RTP|DTLS_TYPE_RTCP);
2015-01-26 16:48:59 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_PAUSE ) ;
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_MUTE ) ;
2015-05-05 16:58:27 +00:00
rtcp_stats_init ( rtp_session ) ;
2015-01-26 16:48:59 +00:00
if ( rtp_session - > ice . ready ) {
2015-11-18 16:31:30 +00:00
switch_rtp_reset_vb ( rtp_session ) ;
2015-01-26 16:48:59 +00:00
rtp_session - > ice . ready = rtp_session - > ice . rready = 0 ;
}
2014-06-14 02:05:00 +00:00
}
2009-01-13 19:02:48 +00:00
SWITCH_DECLARE ( void ) switch_rtp_reset_media_timer ( switch_rtp_t * rtp_session )
{
rtp_session - > missed_count = 0 ;
}
2008-09-18 21:50:18 +00:00
SWITCH_DECLARE ( char * ) switch_rtp_get_remote_host ( switch_rtp_t * rtp_session )
{
2009-10-23 16:03:42 +00:00
return zstr ( rtp_session - > remote_host_str ) ? " 0.0.0.0 " : rtp_session - > remote_host_str ;
2008-09-18 21:50:18 +00:00
}
SWITCH_DECLARE ( switch_port_t ) switch_rtp_get_remote_port ( switch_rtp_t * rtp_session )
{
return rtp_session - > remote_port ;
}
2010-06-17 15:23:37 +00:00
static void ping_socket ( switch_rtp_t * rtp_session )
{
uint32_t o = UINT_MAX ;
switch_size_t len = sizeof ( o ) ;
switch_socket_sendto ( rtp_session - > sock_input , rtp_session - > local_addr , 0 , ( void * ) & o , & len ) ;
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] & & rtp_session - > rtcp_sock_input ) {
2010-06-17 15:23:37 +00:00
switch_socket_sendto ( rtp_session - > rtcp_sock_input , rtp_session - > rtcp_local_addr , 0 , ( void * ) & o , & len ) ;
}
}
2008-09-18 21:50:18 +00:00
2010-05-13 02:25:54 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_udptl_mode ( switch_rtp_t * rtp_session )
{
2010-06-17 15:23:37 +00:00
switch_socket_t * sock ;
2013-03-01 15:29:47 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2013-03-06 14:50:49 +00:00
if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_PROXY_MEDIA ) ) {
2013-03-01 15:29:47 +00:00
ping_socket ( rtp_session ) ;
}
2010-05-13 02:25:54 +00:00
READ_INC ( rtp_session ) ;
WRITE_INC ( rtp_session ) ;
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] | | rtp_session - > timer . timer_interface ) {
2010-05-13 02:25:54 +00:00
switch_core_timer_destroy ( & rtp_session - > timer ) ;
memset ( & rtp_session - > timer , 0 , sizeof ( rtp_session - > timer ) ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ;
2010-05-13 02:25:54 +00:00
}
2016-01-27 16:49:34 +00:00
rtp_session - > missed_count = 0 ;
rtp_session - > max_missed_packets = 0 ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] = 0 ;
2010-06-17 15:23:37 +00:00
if ( rtp_session - > rtcp_sock_input ) {
ping_socket ( rtp_session ) ;
switch_socket_shutdown ( rtp_session - > rtcp_sock_input , SWITCH_SHUTDOWN_READWRITE ) ;
}
if ( rtp_session - > rtcp_sock_output & & rtp_session - > rtcp_sock_output ! = rtp_session - > rtcp_sock_input ) {
switch_socket_shutdown ( rtp_session - > rtcp_sock_output , SWITCH_SHUTDOWN_READWRITE ) ;
}
2013-01-17 01:04:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
2010-06-17 15:23:37 +00:00
rtp_session - > rtcp_sock_input = NULL ;
2013-01-17 01:04:57 +00:00
rtp_session - > rtcp_sock_output = NULL ;
} else {
if ( ( sock = rtp_session - > rtcp_sock_input ) ) {
rtp_session - > rtcp_sock_input = NULL ;
switch_socket_close ( sock ) ;
if ( rtp_session - > rtcp_sock_output & & rtp_session - > rtcp_sock_output ! = sock ) {
if ( ( sock = rtp_session - > rtcp_sock_output ) ) {
rtp_session - > rtcp_sock_output = NULL ;
switch_socket_close ( sock ) ;
}
2010-06-17 15:23:37 +00:00
}
}
}
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_UDPTL ) ;
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_PROXY_MEDIA ) ;
2010-05-13 02:25:54 +00:00
switch_socket_opt_set ( rtp_session - > sock_input , SWITCH_SO_NONBLOCK , FALSE ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_NOBLOCK ) ;
2010-05-13 02:25:54 +00:00
WRITE_DEC ( rtp_session ) ;
READ_DEC ( rtp_session ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_STICKY_FLUSH ) ;
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_FLUSH ) ;
2010-05-13 02:25:54 +00:00
2010-05-27 01:12:54 +00:00
switch_rtp_break ( rtp_session ) ;
2010-05-13 02:25:54 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-04-22 15:22:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_set_remote_address ( switch_rtp_t * rtp_session , const char * host , switch_port_t port , switch_port_t remote_rtcp_port ,
2008-09-29 23:03:27 +00:00
switch_bool_t change_adv_addr , const char * * err )
2006-04-06 20:56:29 +00:00
{
2008-01-19 02:27:26 +00:00
switch_sockaddr_t * remote_addr ;
2008-07-03 18:50:15 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2006-04-06 20:56:29 +00:00
* err = " Success " ;
2008-05-27 04:30:03 +00:00
2008-01-19 02:27:26 +00:00
if ( switch_sockaddr_info_get ( & remote_addr , host , SWITCH_UNSPEC , port , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS | | ! remote_addr ) {
2006-04-06 20:56:29 +00:00
* err = " Remote Address Error! " ;
return SWITCH_STATUS_FALSE ;
}
2010-04-20 00:07:23 +00:00
2008-01-19 02:27:26 +00:00
switch_mutex_lock ( rtp_session - > write_mutex ) ;
2008-07-03 18:50:15 +00:00
2008-01-19 02:27:26 +00:00
rtp_session - > remote_addr = remote_addr ;
2008-09-29 23:03:27 +00:00
if ( change_adv_addr ) {
rtp_session - > remote_host_str = switch_core_strdup ( rtp_session - > pool , host ) ;
rtp_session - > remote_port = port ;
}
2008-07-03 18:50:15 +00:00
2010-06-24 21:01:55 +00:00
rtp_session - > eff_remote_host_str = switch_core_strdup ( rtp_session - > pool , host ) ;
rtp_session - > eff_remote_port = port ;
2010-02-06 03:38:24 +00:00
if ( rtp_session - > sock_input & & switch_sockaddr_get_family ( rtp_session - > remote_addr ) = = switch_sockaddr_get_family ( rtp_session - > local_addr ) ) {
rtp_session - > sock_output = rtp_session - > sock_input ;
} else {
if ( rtp_session - > sock_output & & rtp_session - > sock_output ! = rtp_session - > sock_input ) {
switch_socket_close ( rtp_session - > sock_output ) ;
2008-07-03 18:50:15 +00:00
}
if ( ( status = switch_socket_create ( & rtp_session - > sock_output ,
2010-02-06 03:38:24 +00:00
switch_sockaddr_get_family ( rtp_session - > remote_addr ) ,
SOCK_DGRAM , 0 , rtp_session - > pool ) ) ! = SWITCH_STATUS_SUCCESS ) {
2015-03-26 22:37:07 +00:00
2008-07-03 18:50:15 +00:00
* err = " Socket Error! " ;
}
}
2015-03-26 22:37:07 +00:00
if ( rtp_session - > dtls ) {
rtp_session - > dtls - > sock_output = rtp_session - > sock_output ;
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
switch_sockaddr_info_get ( & rtp_session - > dtls - > remote_addr , host , SWITCH_UNSPEC , port , 0 , rtp_session - > pool ) ;
}
}
2013-02-09 04:47:18 +00:00
2015-06-03 20:54:15 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
rtp_session - > rtcp_remote_addr = rtp_session - > remote_addr ;
rtp_session - > rtcp_sock_output = rtp_session - > sock_output ;
2010-04-22 15:22:28 +00:00
} else {
2015-06-03 20:54:15 +00:00
if ( remote_rtcp_port ) {
rtp_session - > remote_rtcp_port = remote_rtcp_port ;
} else {
rtp_session - > remote_rtcp_port = rtp_session - > eff_remote_port + 1 ;
}
status = enable_remote_rtcp_socket ( rtp_session , err ) ;
if ( rtp_session - > rtcp_dtls ) {
//switch_sockaddr_info_get(&rtp_session->rtcp_dtls->remote_addr, host, SWITCH_UNSPEC, port, 0, rtp_session->pool);
rtp_session - > rtcp_dtls - > remote_addr = rtp_session - > rtcp_remote_addr ;
rtp_session - > rtcp_dtls - > sock_output = rtp_session - > rtcp_sock_output ;
}
2015-03-26 22:37:07 +00:00
}
2010-04-20 00:07:23 +00:00
}
2008-01-19 02:27:26 +00:00
switch_mutex_unlock ( rtp_session - > write_mutex ) ;
2006-04-17 18:25:43 +00:00
2008-07-03 18:50:15 +00:00
return status ;
2006-04-06 20:56:29 +00:00
}
2013-02-01 20:29:40 +00:00
2014-12-11 02:59:09 +00:00
static const char * dtls_state_names_t [ ] = { " OFF " , " HANDSHAKE " , " SETUP " , " READY " , " FAIL " , " INVALID " } ;
2013-02-01 20:29:40 +00:00
static const char * dtls_state_names ( dtls_state_t s )
{
if ( s > DS_INVALID ) {
s = DS_INVALID ;
}
return dtls_state_names_t [ s ] ;
}
2013-06-18 00:52:37 +00:00
# define dtls_set_state(_dtls, _state) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_INFO, "Changing %s DTLS state from %s to %s\n", rtp_type(rtp_session), dtls_state_names(_dtls->state), dtls_state_names(_state)); _dtls->new_state = 1; _dtls->last_state = _dtls->state; _dtls->state = _state
2013-02-01 20:29:40 +00:00
2013-02-02 02:07:56 +00:00
# define cr_keylen 16
# define cr_saltlen 14
# define cr_kslen 30
2013-02-01 20:29:40 +00:00
static int dtls_state_setup ( switch_rtp_t * rtp_session , switch_dtls_t * dtls )
{
2013-02-02 02:07:56 +00:00
X509 * cert ;
int r = 0 ;
2013-02-02 06:15:09 +00:00
if ( ( dtls - > type & DTLS_TYPE_SERVER ) ) {
r = 1 ;
} else if ( ( cert = SSL_get_peer_certificate ( dtls - > ssl ) ) ) {
2013-02-02 02:07:56 +00:00
switch_core_cert_extract_fingerprint ( cert , dtls - > remote_fp ) ;
r = switch_core_cert_verify ( dtls - > remote_fp ) ;
X509_free ( cert ) ;
}
if ( ! r ) {
2013-02-02 06:15:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s Fingerprint Verification Failed! \n " , rtp_type ( rtp_session ) ) ;
2013-02-02 02:07:56 +00:00
dtls_set_state ( dtls , DS_FAIL ) ;
return - 1 ;
} else {
uint8_t raw_key_data [ cr_kslen * 2 ] = { 0 } ;
unsigned char * local_key , * remote_key , * local_salt , * remote_salt ;
unsigned char local_key_buf [ cr_kslen ] = { 0 } , remote_key_buf [ cr_kslen ] = { 0 } ;
2013-02-02 06:15:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO , " %s Fingerprint Verified. \n " , rtp_type ( rtp_session ) ) ;
2013-02-02 02:07:56 +00:00
2013-02-05 16:18:37 +00:00
# ifdef HAVE_OPENSSL_DTLS_SRTP
2013-02-02 02:07:56 +00:00
if ( ! SSL_export_keying_material ( dtls - > ssl , raw_key_data , sizeof ( raw_key_data ) , " EXTRACTOR-dtls_srtp " , 19 , NULL , 0 , 0 ) ) {
2013-02-02 06:15:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s Key material export failure \n " , rtp_type ( rtp_session ) ) ;
2013-02-02 02:07:56 +00:00
dtls_set_state ( dtls , DS_FAIL ) ;
return - 1 ;
}
2013-02-05 16:18:37 +00:00
# else
return - 1 ;
# endif
2013-02-02 02:07:56 +00:00
if ( ( dtls - > type & DTLS_TYPE_CLIENT ) ) {
local_key = raw_key_data ;
remote_key = local_key + cr_keylen ;
local_salt = remote_key + cr_keylen ;
remote_salt = local_salt + cr_saltlen ;
} else {
remote_key = raw_key_data ;
local_key = remote_key + cr_keylen ;
remote_salt = local_key + cr_keylen ;
local_salt = remote_salt + cr_saltlen ;
}
memcpy ( local_key_buf , local_key , cr_keylen ) ;
memcpy ( local_key_buf + cr_keylen , local_salt , cr_saltlen ) ;
memcpy ( remote_key_buf , remote_key , cr_keylen ) ;
memcpy ( remote_key_buf + cr_keylen , remote_salt , cr_saltlen ) ;
2013-02-03 05:57:27 +00:00
if ( dtls = = rtp_session - > rtcp_dtls & & rtp_session - > rtcp_dtls ! = rtp_session - > dtls ) {
switch_rtp_add_crypto_key ( rtp_session , SWITCH_RTP_CRYPTO_SEND_RTCP , 0 , AES_CM_128_HMAC_SHA1_80 , local_key_buf , cr_kslen ) ;
switch_rtp_add_crypto_key ( rtp_session , SWITCH_RTP_CRYPTO_RECV_RTCP , 0 , AES_CM_128_HMAC_SHA1_80 , remote_key_buf , cr_kslen ) ;
} else {
switch_rtp_add_crypto_key ( rtp_session , SWITCH_RTP_CRYPTO_SEND , 0 , AES_CM_128_HMAC_SHA1_80 , local_key_buf , cr_kslen ) ;
switch_rtp_add_crypto_key ( rtp_session , SWITCH_RTP_CRYPTO_RECV , 0 , AES_CM_128_HMAC_SHA1_80 , remote_key_buf , cr_kslen ) ;
}
2013-02-02 02:07:56 +00:00
}
2013-02-01 20:29:40 +00:00
dtls_set_state ( dtls , DS_READY ) ;
2013-02-02 02:07:56 +00:00
2013-02-01 20:29:40 +00:00
return 0 ;
}
static int dtls_state_ready ( switch_rtp_t * rtp_session , switch_dtls_t * dtls )
{
2013-06-18 00:52:37 +00:00
if ( dtls - > new_state ) {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
switch_core_session_t * other_session ;
if ( rtp_session - > session & & switch_core_session_get_partner ( rtp_session - > session , & other_session ) = = SWITCH_STATUS_SUCCESS ) {
2014-12-04 02:34:49 +00:00
switch_core_session_request_video_refresh ( other_session ) ;
2013-06-18 00:52:37 +00:00
switch_core_session_rwunlock ( other_session ) ;
}
}
dtls - > new_state = 0 ;
}
2013-02-01 20:29:40 +00:00
return 0 ;
}
2014-02-19 02:05:29 +00:00
static int dtls_state_fail ( switch_rtp_t * rtp_session , switch_dtls_t * dtls )
{
if ( rtp_session - > session ) {
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER ) ;
}
return - 1 ;
}
2013-02-01 20:29:40 +00:00
static int dtls_state_handshake ( switch_rtp_t * rtp_session , switch_dtls_t * dtls )
{
int ret ;
2013-02-09 04:47:18 +00:00
2013-02-01 20:29:40 +00:00
if ( ( ret = SSL_do_handshake ( dtls - > ssl ) ) ! = 1 ) {
switch ( ( ret = SSL_get_error ( dtls - > ssl , ret ) ) ) {
case SSL_ERROR_WANT_READ :
case SSL_ERROR_WANT_WRITE :
case SSL_ERROR_NONE :
break ;
default :
2013-02-02 06:15:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s Handshake failure %d \n " , rtp_type ( rtp_session ) , ret ) ;
2013-02-01 20:29:40 +00:00
dtls_set_state ( dtls , DS_FAIL ) ;
return - 1 ;
}
}
if ( SSL_is_init_finished ( dtls - > ssl ) ) {
dtls_set_state ( dtls , DS_SETUP ) ;
}
return 0 ;
}
2013-10-15 21:24:32 +00:00
static void free_dtls ( switch_dtls_t * * dtlsp )
{
switch_dtls_t * dtls ;
if ( ! dtlsp ) {
return ;
}
dtls = * dtlsp ;
* dtlsp = NULL ;
if ( dtls - > ssl ) {
SSL_free ( dtls - > ssl ) ;
}
if ( dtls - > ssl_ctx ) {
SSL_CTX_free ( dtls - > ssl_ctx ) ;
}
}
2013-02-01 20:29:40 +00:00
static int do_dtls ( switch_rtp_t * rtp_session , switch_dtls_t * dtls )
{
int r = 0 , ret = 0 , len ;
switch_size_t bytes ;
2014-02-19 02:05:29 +00:00
unsigned char buf [ 4096 ] = " " ;
int ready = rtp_session - > ice . ice_user ? ( rtp_session - > ice . rready & & rtp_session - > ice . ready ) : 1 ;
2013-02-01 20:29:40 +00:00
2014-02-19 02:05:29 +00:00
if ( ! dtls - > bytes & & ! ready ) {
return 0 ;
2013-02-01 20:29:40 +00:00
}
2014-02-19 02:05:29 +00:00
if ( ( ret = BIO_write ( dtls - > read_bio , dtls - > data , ( int ) dtls - > bytes ) ) ! = ( int ) dtls - > bytes & & dtls - > bytes > 0 ) {
ret = SSL_get_error ( dtls - > ssl , ret ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s DTLS packet read err %d \n " , rtp_type ( rtp_session ) , ret ) ;
2013-02-01 20:29:40 +00:00
}
2016-06-08 21:20:18 +00:00
2014-12-10 20:44:59 +00:00
if ( dtls_states [ dtls - > state ] ) {
r = dtls_states [ dtls - > state ] ( rtp_session , dtls ) ;
}
2013-02-01 20:29:40 +00:00
2014-02-19 02:05:29 +00:00
if ( ( len = BIO_read ( dtls - > write_bio , buf , sizeof ( buf ) ) ) > 0 ) {
2013-02-01 20:29:40 +00:00
bytes = len ;
2013-02-02 02:07:56 +00:00
2014-02-19 02:05:29 +00:00
if ( switch_socket_sendto ( dtls - > sock_output , dtls - > remote_addr , 0 , ( void * ) buf , & bytes ) ! = SWITCH_STATUS_SUCCESS ) {
2013-02-02 06:15:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s DTLS packet not written \n " , rtp_type ( rtp_session ) ) ;
2013-02-01 20:29:40 +00:00
}
}
2014-02-19 02:05:29 +00:00
2013-02-01 20:29:40 +00:00
return r ;
}
2013-02-02 02:07:56 +00:00
# if VERIFY
2013-02-01 20:29:40 +00:00
static int cb_verify_peer ( int preverify_ok , X509_STORE_CTX * ctx )
{
SSL * ssl = NULL ;
switch_dtls_t * dtls ;
X509 * cert ;
int r = 0 ;
ssl = X509_STORE_CTX_get_app_data ( ctx ) ;
dtls = ( switch_dtls_t * ) SSL_get_app_data ( ssl ) ;
if ( ! ( ssl & & dtls ) ) {
return 0 ;
}
if ( ( cert = SSL_get_peer_certificate ( dtls - > ssl ) ) ) {
switch_core_cert_extract_fingerprint ( cert , dtls - > remote_fp ) ;
r = switch_core_cert_verify ( dtls - > remote_fp ) ;
X509_free ( cert ) ;
} else {
2013-02-02 06:15:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( dtls - > rtp_session - > session ) , SWITCH_LOG_ERROR , " %s CERT ERR! \n " , rtp_type ( dtls - > rtp_session ) ) ;
2013-02-01 20:29:40 +00:00
}
return r ;
}
2013-02-02 02:07:56 +00:00
# endif
2013-02-01 20:29:40 +00:00
2013-02-04 20:12:48 +00:00
SWITCH_DECLARE ( int ) switch_rtp_has_dtls ( void ) {
# ifdef HAVE_OPENSSL_DTLS_SRTP
return 1 ;
# else
return 0 ;
# endif
}
2014-12-10 20:44:59 +00:00
SWITCH_DECLARE ( dtls_state_t ) switch_rtp_dtls_state ( switch_rtp_t * rtp_session , dtls_type_t type )
{
if ( ! rtp_session | | ( ! rtp_session - > dtls & & ! rtp_session - > rtcp_dtls ) ) {
return DS_OFF ;
}
if ( ( type = = DTLS_TYPE_RTP ) & & rtp_session - > dtls ) {
return rtp_session - > dtls - > state ;
}
if ( ( type = = DTLS_TYPE_RTCP ) & & rtp_session - > rtcp_dtls ) {
return rtp_session - > rtcp_dtls - > state ;
}
return DS_OFF ;
}
2013-10-15 21:24:32 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_del_dtls ( switch_rtp_t * rtp_session , dtls_type_t type )
{
2014-12-10 20:44:59 +00:00
if ( ! rtp_session | | ( ! rtp_session - > dtls & & ! rtp_session - > rtcp_dtls ) ) {
2013-10-15 21:24:32 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( ( type & DTLS_TYPE_RTP ) ) {
if ( rtp_session - > dtls & & rtp_session - > dtls = = rtp_session - > rtcp_dtls ) {
rtp_session - > rtcp_dtls = NULL ;
}
if ( rtp_session - > dtls ) {
free_dtls ( & rtp_session - > dtls ) ;
}
2013-11-01 20:21:35 +00:00
if ( rtp_session - > jb ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > jb ) ;
2013-11-01 20:21:35 +00:00
}
2015-01-24 08:47:17 +00:00
if ( rtp_session - > vb ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > vb ) ;
2015-01-24 08:47:17 +00:00
}
if ( rtp_session - > vbw ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > vbw ) ;
2015-01-24 08:47:17 +00:00
}
2013-10-15 21:24:32 +00:00
}
if ( ( type & DTLS_TYPE_RTCP ) & & rtp_session - > rtcp_dtls ) {
free_dtls ( & rtp_session - > rtcp_dtls ) ;
}
2013-11-01 20:21:35 +00:00
# ifdef ENABLE_SRTP
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] ) {
int x ;
for ( x = 0 ; x < 2 ; x + + ) {
if ( rtp_session - > send_ctx [ x ] ) {
srtp_dealloc ( rtp_session - > send_ctx [ x ] ) ;
rtp_session - > send_ctx [ x ] = NULL ;
}
}
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] = 0 ;
}
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] ) {
int x ;
for ( x = 0 ; x < 2 ; x + + ) {
if ( rtp_session - > recv_ctx [ x ] ) {
srtp_dealloc ( rtp_session - > recv_ctx [ x ] ) ;
rtp_session - > recv_ctx [ x ] = NULL ;
}
}
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] = 0 ;
}
# endif
2013-10-15 21:24:32 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2013-02-01 20:29:40 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_add_dtls ( switch_rtp_t * rtp_session , dtls_fingerprint_t * local_fp , dtls_fingerprint_t * remote_fp , dtls_type_t type )
{
switch_dtls_t * dtls ;
2013-02-02 02:07:56 +00:00
int ret ;
2013-02-16 03:27:49 +00:00
const char * kind = " " ;
2015-04-24 15:31:03 +00:00
BIO * bio ;
DH * dh ;
2015-11-24 19:44:49 +00:00
# ifndef OPENSSL_NO_EC
2015-07-24 20:21:49 +00:00
EC_KEY * ecdh ;
2015-11-24 19:44:49 +00:00
# endif
2013-02-01 20:29:40 +00:00
2013-02-04 20:12:48 +00:00
# ifndef HAVE_OPENSSL_DTLS_SRTP
return SWITCH_STATUS_FALSE ;
# endif
2013-02-01 20:29:40 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
if ( ! ( ( type & DTLS_TYPE_RTP ) | | ( type & DTLS_TYPE_RTCP ) ) | | ! ( ( type & DTLS_TYPE_CLIENT ) | | ( type & DTLS_TYPE_SERVER ) ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_CRIT , " INVALID TYPE! \n " ) ;
}
2013-10-15 21:24:32 +00:00
switch_rtp_del_dtls ( rtp_session , type ) ;
2013-02-16 03:27:49 +00:00
if ( ( type & DTLS_TYPE_RTP ) & & ( type & DTLS_TYPE_RTCP ) ) {
kind = " RTP/RTCP " ;
} else if ( ( type & DTLS_TYPE_RTP ) ) {
kind = " RTP " ;
} else {
kind = " RTCP " ;
}
2013-02-02 06:15:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO ,
2013-02-16 03:27:49 +00:00
" Activate %s %s DTLS %s \n " , kind , rtp_type ( rtp_session ) , ( type & DTLS_TYPE_SERVER ) ? " server " : " client " ) ;
2013-02-02 06:15:09 +00:00
2013-02-03 05:57:27 +00:00
if ( ( ( type & DTLS_TYPE_RTP ) & & rtp_session - > dtls ) | | ( ( type & DTLS_TYPE_RTCP ) & & rtp_session - > rtcp_dtls ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " DTLS ALREADY INIT \n " ) ;
return SWITCH_STATUS_FALSE ;
}
dtls = switch_core_alloc ( rtp_session - > pool , sizeof ( * dtls ) ) ;
2013-02-01 20:29:40 +00:00
2014-02-19 02:05:29 +00:00
dtls - > pem = switch_core_sprintf ( rtp_session - > pool , " %s%s%s.pem " , SWITCH_GLOBAL_dirs . certs_dir , SWITCH_PATH_SEPARATOR , DTLS_SRTP_FNAME ) ;
if ( switch_file_exists ( dtls - > pem , rtp_session - > pool ) = = SWITCH_STATUS_SUCCESS ) {
dtls - > pvt = dtls - > rsa = dtls - > pem ;
} else {
dtls - > pvt = switch_core_sprintf ( rtp_session - > pool , " %s%s%s.key " , SWITCH_GLOBAL_dirs . certs_dir , SWITCH_PATH_SEPARATOR , DTLS_SRTP_FNAME ) ;
dtls - > rsa = switch_core_sprintf ( rtp_session - > pool , " %s%s%s.crt " , SWITCH_GLOBAL_dirs . certs_dir , SWITCH_PATH_SEPARATOR , DTLS_SRTP_FNAME ) ;
}
2013-10-31 21:21:58 +00:00
dtls - > ca = switch_core_sprintf ( rtp_session - > pool , " %s%sca-bundle.crt " , SWITCH_GLOBAL_dirs . certs_dir , SWITCH_PATH_SEPARATOR ) ;
2013-02-01 20:29:40 +00:00
2015-09-19 01:54:42 +00:00
dtls - > ssl_ctx = SSL_CTX_new ( ( type & DTLS_TYPE_SERVER ) ? DTLSv1_server_method ( ) : DTLSv1_client_method ( ) ) ;
2013-02-03 05:57:27 +00:00
switch_assert ( dtls - > ssl_ctx ) ;
2013-02-01 20:29:40 +00:00
2015-04-24 15:31:03 +00:00
bio = BIO_new_file ( dtls - > pem , " r " ) ;
dh = PEM_read_bio_DHparams ( bio , NULL , NULL , NULL ) ;
BIO_free ( bio ) ;
2015-05-04 15:23:33 +00:00
if ( dh ) {
SSL_CTX_set_tmp_dh ( dtls - > ssl_ctx , dh ) ;
DH_free ( dh ) ;
}
2015-04-24 15:31:03 +00:00
2013-02-03 05:57:27 +00:00
SSL_CTX_set_mode ( dtls - > ssl_ctx , SSL_MODE_AUTO_RETRY ) ;
2013-02-02 06:15:09 +00:00
2013-02-03 05:57:27 +00:00
//SSL_CTX_set_verify(dtls->ssl_ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL);
SSL_CTX_set_verify ( dtls - > ssl_ctx , SSL_VERIFY_NONE , NULL ) ;
2013-02-02 06:15:09 +00:00
2016-06-08 21:20:18 +00:00
SSL_CTX_set_cipher_list ( dtls - > ssl_ctx , " ECDH:!RC4:!SSLv3:RSA_WITH_AES_128_CBC_SHA " ) ;
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ECDHE-RSA-AES256-GCM-SHA384");
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "ALL:!ADH:!LOW:!EXP:!MD5:@STRENGTH");
//SSL_CTX_set_cipher_list(dtls->ssl_ctx, "SUITEB128");
SSL_CTX_set_read_ahead ( dtls - > ssl_ctx , 1 ) ;
2013-02-04 20:12:48 +00:00
# ifdef HAVE_OPENSSL_DTLS_SRTP
2013-02-03 05:57:27 +00:00
//SSL_CTX_set_tlsext_use_srtp(dtls->ssl_ctx, "SRTP_AES128_CM_SHA1_80:SRTP_AES128_CM_SHA1_32");
SSL_CTX_set_tlsext_use_srtp ( dtls - > ssl_ctx , " SRTP_AES128_CM_SHA1_80 " ) ;
2013-02-04 20:12:48 +00:00
# endif
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
dtls - > type = type ;
dtls - > read_bio = BIO_new ( BIO_s_mem ( ) ) ;
switch_assert ( dtls - > read_bio ) ;
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
dtls - > write_bio = BIO_new ( BIO_s_mem ( ) ) ;
switch_assert ( dtls - > write_bio ) ;
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
BIO_set_mem_eof_return ( dtls - > read_bio , - 1 ) ;
BIO_set_mem_eof_return ( dtls - > write_bio , - 1 ) ;
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
if ( ( ret = SSL_CTX_use_certificate_file ( dtls - > ssl_ctx , dtls - > rsa , SSL_FILETYPE_PEM ) ) ! = 1 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s DTLS cert err [%d] \n " , rtp_type ( rtp_session ) , SSL_get_error ( dtls - > ssl , ret ) ) ;
return SWITCH_STATUS_FALSE ;
}
2013-02-02 02:07:56 +00:00
2013-02-03 05:57:27 +00:00
if ( ( ret = SSL_CTX_use_PrivateKey_file ( dtls - > ssl_ctx , dtls - > pvt , SSL_FILETYPE_PEM ) ) ! = 1 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s DTLS key err [%d] \n " , rtp_type ( rtp_session ) , SSL_get_error ( dtls - > ssl , ret ) ) ;
return SWITCH_STATUS_FALSE ;
}
2013-02-02 02:07:56 +00:00
2013-02-03 05:57:27 +00:00
if ( SSL_CTX_check_private_key ( dtls - > ssl_ctx ) = = 0 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s DTLS check key failed \n " , rtp_type ( rtp_session ) ) ;
return SWITCH_STATUS_FALSE ;
}
2013-02-02 02:07:56 +00:00
2013-10-31 21:21:58 +00:00
if ( ! zstr ( dtls - > ca ) & & switch_file_exists ( dtls - > ca , rtp_session - > pool ) = = SWITCH_STATUS_SUCCESS
& & ( ret = SSL_CTX_load_verify_locations ( dtls - > ssl_ctx , dtls - > ca , NULL ) ) ! = 1 ) {
2013-02-03 05:57:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " %s DTLS check chain cert failed [%d] \n " ,
rtp_type ( rtp_session ) ,
SSL_get_error ( dtls - > ssl , ret ) ) ;
return SWITCH_STATUS_FALSE ;
}
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
dtls - > ssl = SSL_new ( dtls - > ssl_ctx ) ;
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
SSL_set_bio ( dtls - > ssl , dtls - > read_bio , dtls - > write_bio ) ;
SSL_set_mode ( dtls - > ssl , SSL_MODE_AUTO_RETRY ) ;
SSL_set_read_ahead ( dtls - > ssl , 1 ) ;
//SSL_set_verify(dtls->ssl, (SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT), cb_verify_peer);
2015-07-24 20:21:49 +00:00
2015-11-24 19:44:49 +00:00
# ifndef OPENSSL_NO_EC
2015-07-24 20:21:49 +00:00
ecdh = EC_KEY_new_by_curve_name ( NID_X9_62_prime256v1 ) ;
if ( ! ecdh ) {
return SWITCH_STATUS_FALSE ;
}
SSL_set_options ( dtls - > ssl , SSL_OP_SINGLE_ECDH_USE ) ;
SSL_set_tmp_ecdh ( dtls - > ssl , ecdh ) ;
EC_KEY_free ( ecdh ) ;
2015-11-24 19:44:49 +00:00
# endif
2015-07-24 20:21:49 +00:00
2013-02-03 05:57:27 +00:00
SSL_set_verify ( dtls - > ssl , SSL_VERIFY_NONE , NULL ) ;
SSL_set_app_data ( dtls - > ssl , dtls ) ;
2013-02-01 20:29:40 +00:00
2016-06-08 21:20:18 +00:00
//BIO_ctrl(dtls->read_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
//BIO_ctrl(dtls->write_bio, BIO_CTRL_DGRAM_SET_MTU, 1400, NULL);
//SSL_set_mtu(dtls->ssl, 1400);
//BIO_ctrl(dtls->write_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
//BIO_ctrl(dtls->read_bio, BIO_C_SET_BUFF_SIZE, 1400, NULL);
2014-02-19 02:05:29 +00:00
2013-02-03 05:57:27 +00:00
dtls - > local_fp = local_fp ;
dtls - > remote_fp = remote_fp ;
dtls - > rtp_session = rtp_session ;
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
switch_core_cert_expand_fingerprint ( remote_fp , remote_fp - > str ) ;
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
if ( ( type & DTLS_TYPE_RTP ) ) {
rtp_session - > dtls = dtls ;
dtls - > sock_output = rtp_session - > sock_output ;
dtls - > remote_addr = rtp_session - > remote_addr ;
}
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
if ( ( type & DTLS_TYPE_RTCP ) ) {
rtp_session - > rtcp_dtls = dtls ;
if ( ! ( type & DTLS_TYPE_RTP ) ) {
dtls - > sock_output = rtp_session - > rtcp_sock_output ;
dtls - > remote_addr = rtp_session - > rtcp_remote_addr ;
2013-02-01 20:29:40 +00:00
}
2013-02-03 05:57:27 +00:00
}
2013-02-01 20:29:40 +00:00
2013-02-03 05:57:27 +00:00
if ( ( type & DTLS_TYPE_SERVER ) ) {
SSL_set_accept_state ( dtls - > ssl ) ;
} else {
SSL_set_connect_state ( dtls - > ssl ) ;
2013-02-01 20:29:40 +00:00
}
2014-12-10 20:44:59 +00:00
dtls_set_state ( dtls , DS_HANDSHAKE ) ;
2013-10-15 21:24:32 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO_BREAK ] = 1 ;
switch_rtp_break ( rtp_session ) ;
2013-02-03 05:57:27 +00:00
return SWITCH_STATUS_SUCCESS ;
2013-02-01 20:29:40 +00:00
}
2008-01-16 06:01:53 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_add_crypto_key ( switch_rtp_t * rtp_session ,
switch_rtp_crypto_direction_t direction ,
2008-05-27 04:30:03 +00:00
uint32_t index , switch_rtp_crypto_key_type_t type , unsigned char * key , switch_size_t keylen )
2008-01-16 06:01:53 +00:00
{
2011-05-02 16:33:57 +00:00
# ifndef ENABLE_SRTP
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_CRIT , " SRTP NOT SUPPORTED IN THIS BUILD! \n " ) ;
2011-05-02 16:33:57 +00:00
return SWITCH_STATUS_FALSE ;
# else
2008-01-16 06:01:53 +00:00
switch_rtp_crypto_key_t * crypto_key ;
srtp_policy_t * policy ;
err_status_t stat ;
2008-01-17 04:16:04 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
2013-01-15 05:17:28 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
2009-05-29 02:08:24 +00:00
switch_event_t * fsevent = NULL ;
2013-02-03 05:57:27 +00:00
int idx = 0 ;
2014-03-03 18:26:44 +00:00
const char * var ;
2015-10-02 13:56:51 +00:00
unsigned char b64_key [ 512 ] = " " ;
2008-01-16 06:01:53 +00:00
2008-01-17 06:07:17 +00:00
if ( direction > = SWITCH_RTP_CRYPTO_MAX | | keylen > SWITCH_RTP_MAX_CRYPTO_LEN ) {
return SWITCH_STATUS_FALSE ;
2008-05-27 04:30:03 +00:00
}
2008-01-17 06:07:17 +00:00
2015-10-02 13:56:51 +00:00
switch_b64_encode ( key , keylen , b64_key , sizeof ( b64_key ) ) ;
if ( switch_true ( switch_core_get_variable ( " rtp_retain_crypto_keys " ) ) ) {
switch ( direction ) {
case SWITCH_RTP_CRYPTO_SEND :
switch_channel_set_variable ( channel , " srtp_local_crypto_key " , ( const char * ) b64_key ) ;
break ;
case SWITCH_RTP_CRYPTO_RECV :
switch_channel_set_variable ( channel , " srtp_remote_crypto_key " , ( const char * ) b64_key ) ;
break ;
case SWITCH_RTP_CRYPTO_SEND_RTCP :
switch_channel_set_variable ( channel , " srtcp_local_crypto_key " , ( const char * ) b64_key ) ;
break ;
case SWITCH_RTP_CRYPTO_RECV_RTCP :
switch_channel_set_variable ( channel , " srtcp_remote_crypto_key " , ( const char * ) b64_key ) ;
break ;
default :
break ;
}
}
2008-01-16 06:01:53 +00:00
crypto_key = switch_core_alloc ( rtp_session - > pool , sizeof ( * crypto_key ) ) ;
2008-05-27 04:30:03 +00:00
2013-02-03 05:57:27 +00:00
if ( direction = = SWITCH_RTP_CRYPTO_RECV_RTCP ) {
direction = SWITCH_RTP_CRYPTO_RECV ;
rtp_session - > srtp_idx_rtcp = idx = 1 ;
} else if ( direction = = SWITCH_RTP_CRYPTO_SEND_RTCP ) {
direction = SWITCH_RTP_CRYPTO_SEND ;
rtp_session - > srtp_idx_rtcp = idx = 1 ;
}
2008-01-17 04:16:04 +00:00
if ( direction = = SWITCH_RTP_CRYPTO_RECV ) {
2013-02-03 05:57:27 +00:00
policy = & rtp_session - > recv_policy [ idx ] ;
2008-01-17 04:16:04 +00:00
} else {
2013-02-03 05:57:27 +00:00
policy = & rtp_session - > send_policy [ idx ] ;
2008-01-17 04:16:04 +00:00
}
2008-01-16 06:01:53 +00:00
crypto_key - > type = type ;
crypto_key - > index = index ;
memcpy ( crypto_key - > key , key , keylen ) ;
crypto_key - > next = rtp_session - > crypto_keys [ direction ] ;
rtp_session - > crypto_keys [ direction ] = crypto_key ;
memset ( policy , 0 , sizeof ( * policy ) ) ;
2010-02-06 03:38:24 +00:00
2014-03-03 18:26:44 +00:00
/* many devices can't handle gaps in SRTP streams */
2014-03-04 01:51:04 +00:00
if ( ! ( ( var = switch_channel_get_variable ( channel , " srtp_allow_idle_gaps " ) )
2014-03-03 18:33:25 +00:00
& & switch_true ( var ) )
& & ( ! ( var = switch_channel_get_variable ( channel , " send_silence_when_idle " ) )
| | ! ( atoi ( var ) ) ) ) {
2014-03-03 18:26:44 +00:00
switch_channel_set_variable ( channel , " send_silence_when_idle " , " -1 " ) ;
}
2012-07-18 17:19:47 +00:00
2008-05-27 04:30:03 +00:00
switch ( crypto_key - > type ) {
2008-01-16 06:01:53 +00:00
case AES_CM_128_HMAC_SHA1_80 :
crypto_policy_set_aes_cm_128_hmac_sha1_80 ( & policy - > rtp ) ;
2013-01-15 05:17:28 +00:00
crypto_policy_set_aes_cm_128_hmac_sha1_80 ( & policy - > rtcp ) ;
2009-06-09 23:17:50 +00:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
2013-04-02 18:10:00 +00:00
switch_channel_set_variable ( channel , " rtp_has_crypto " , " AES_CM_128_HMAC_SHA1_80 " ) ;
2009-06-09 23:17:50 +00:00
}
2008-01-16 06:01:53 +00:00
break ;
case AES_CM_128_HMAC_SHA1_32 :
crypto_policy_set_aes_cm_128_hmac_sha1_32 ( & policy - > rtp ) ;
2013-01-16 04:56:02 +00:00
crypto_policy_set_aes_cm_128_hmac_sha1_80 ( & policy - > rtcp ) ;
2013-01-15 05:17:28 +00:00
2009-06-09 23:17:50 +00:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
2013-04-02 18:10:00 +00:00
switch_channel_set_variable ( channel , " rtp_has_crypto " , " AES_CM_128_HMAC_SHA1_32 " ) ;
2009-06-09 23:17:50 +00:00
}
2008-01-16 06:01:53 +00:00
break ;
2013-02-02 02:07:56 +00:00
2014-02-25 05:44:35 +00:00
case AEAD_AES_256_GCM_8 :
2014-02-24 20:56:49 +00:00
crypto_policy_set_aes_gcm_256_8_auth ( & policy - > rtp ) ;
crypto_policy_set_aes_gcm_256_8_auth ( & policy - > rtcp ) ;
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
2014-02-25 05:44:35 +00:00
switch_channel_set_variable ( channel , " rtp_has_crypto " , " AEAD_AES_256_GCM_8 " ) ;
2014-02-24 20:56:49 +00:00
}
break ;
2014-02-25 05:44:35 +00:00
case AEAD_AES_128_GCM_8 :
2014-02-24 20:56:49 +00:00
crypto_policy_set_aes_gcm_128_8_auth ( & policy - > rtp ) ;
crypto_policy_set_aes_gcm_128_8_auth ( & policy - > rtcp ) ;
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
2014-02-25 05:44:35 +00:00
switch_channel_set_variable ( channel , " rtp_has_crypto " , " AEAD_AES_128_GCM_8 " ) ;
2014-02-24 20:56:49 +00:00
}
break ;
2013-02-02 02:07:56 +00:00
case AES_CM_256_HMAC_SHA1_80 :
crypto_policy_set_aes_cm_256_hmac_sha1_80 ( & policy - > rtp ) ;
crypto_policy_set_aes_cm_256_hmac_sha1_80 ( & policy - > rtcp ) ;
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
2013-04-02 18:10:00 +00:00
switch_channel_set_variable ( channel , " rtp_has_crypto " , " AES_CM_256_HMAC_SHA1_80 " ) ;
2013-02-02 02:07:56 +00:00
}
2014-03-06 02:33:05 +00:00
break ;
2008-07-07 17:56:16 +00:00
case AES_CM_128_NULL_AUTH :
crypto_policy_set_aes_cm_128_null_auth ( & policy - > rtp ) ;
2013-01-15 05:17:28 +00:00
crypto_policy_set_aes_cm_128_null_auth ( & policy - > rtcp ) ;
2009-06-09 23:17:50 +00:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
2013-04-02 18:10:00 +00:00
switch_channel_set_variable ( channel , " rtp_has_crypto " , " AES_CM_128_NULL_AUTH " ) ;
2009-06-09 23:17:50 +00:00
}
2008-07-07 17:56:16 +00:00
break ;
2008-01-16 06:01:53 +00:00
default :
break ;
}
policy - > key = ( uint8_t * ) crypto_key - > key ;
2013-01-16 04:56:02 +00:00
policy - > next = NULL ;
2013-01-18 04:39:32 +00:00
policy - > window_size = 1024 ;
policy - > allow_repeat_tx = 1 ;
2008-01-16 06:01:53 +00:00
2013-01-18 04:39:32 +00:00
//policy->rtp.sec_serv = sec_serv_conf_and_auth;
//policy->rtcp.sec_serv = sec_serv_conf_and_auth;
2013-01-15 05:17:28 +00:00
2008-05-27 04:30:03 +00:00
switch ( direction ) {
2008-01-16 06:01:53 +00:00
case SWITCH_RTP_CRYPTO_RECV :
policy - > ssrc . type = ssrc_any_inbound ;
2008-01-17 04:16:04 +00:00
2013-02-16 03:27:49 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] & & idx = = 0 & & rtp_session - > recv_ctx [ idx ] ) {
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV_RESET ] = 1 ;
2008-01-17 04:16:04 +00:00
} else {
2015-04-07 23:02:24 +00:00
if ( ( stat = srtp_create ( & rtp_session - > recv_ctx [ idx ] , policy ) ) | | ! rtp_session - > recv_ctx [ idx ] ) {
2008-01-17 04:16:04 +00:00
status = SWITCH_STATUS_FALSE ;
}
if ( status = = SWITCH_STATUS_SUCCESS ) {
2013-02-16 03:27:49 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO , " Activating %s Secure %s RECV \n " ,
2016-07-11 03:25:14 +00:00
rtp_type ( rtp_session ) , idx ? " RTCP " : " RTP " ) ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] = 1 ;
2008-01-17 04:16:04 +00:00
} else {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error allocating srtp [%d] \n " , stat ) ;
2008-01-17 04:16:04 +00:00
return status ;
}
2008-01-16 06:01:53 +00:00
}
break ;
case SWITCH_RTP_CRYPTO_SEND :
2013-01-18 04:39:32 +00:00
policy - > ssrc . type = ssrc_any_outbound ;
//policy->ssrc.type = ssrc_specific;
//policy->ssrc.value = rtp_session->ssrc;
2008-01-16 06:01:53 +00:00
2013-02-16 03:27:49 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] & & idx = = 0 & & rtp_session - > send_ctx [ idx ] ) {
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND_RESET ] = 1 ;
2008-01-17 04:16:04 +00:00
} else {
2015-04-07 23:02:24 +00:00
if ( ( stat = srtp_create ( & rtp_session - > send_ctx [ idx ] , policy ) ) | | ! rtp_session - > send_ctx [ idx ] ) {
2008-01-17 04:16:04 +00:00
status = SWITCH_STATUS_FALSE ;
}
if ( status = = SWITCH_STATUS_SUCCESS ) {
2013-02-16 03:27:49 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO , " Activating %s Secure %s SEND \n " ,
2016-07-11 03:25:14 +00:00
rtp_type ( rtp_session ) , idx ? " RTCP " : " RTP " ) ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] = 1 ;
2008-01-17 04:16:04 +00:00
} else {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error allocating SRTP [%d] \n " , stat ) ;
2008-01-17 04:16:04 +00:00
return status ;
}
2008-01-16 06:01:53 +00:00
}
2008-01-17 04:16:04 +00:00
2008-01-16 06:01:53 +00:00
break ;
default :
abort ( ) ;
break ;
}
2009-05-29 02:08:24 +00:00
if ( switch_event_create ( & fsevent , SWITCH_EVENT_CALL_SECURE ) = = SWITCH_STATUS_SUCCESS ) {
2013-02-27 20:16:00 +00:00
if ( rtp_session - > dtls ) {
switch_event_add_header ( fsevent , SWITCH_STACK_BOTTOM , " secure_type " , " srtp:dtls:AES_CM_128_HMAC_SHA1_80 " ) ;
2014-12-16 16:19:05 +00:00
switch_channel_set_variable ( channel , " rtp_has_crypto " , " srtp:dtls:AES_CM_128_HMAC_SHA1_80 " ) ;
2013-02-27 20:16:00 +00:00
} else {
2013-04-02 18:10:00 +00:00
switch_event_add_header ( fsevent , SWITCH_STACK_BOTTOM , " secure_type " , " srtp:sdes:%s " , switch_channel_get_variable ( channel , " rtp_has_crypto " ) ) ;
2013-02-27 20:16:00 +00:00
}
2009-05-29 02:08:24 +00:00
switch_event_add_header_string ( fsevent , SWITCH_STACK_BOTTOM , " caller-unique-id " , switch_channel_get_uuid ( channel ) ) ;
switch_event_fire ( & fsevent ) ;
}
2008-01-16 06:01:53 +00:00
return SWITCH_STATUS_SUCCESS ;
2011-05-02 16:33:57 +00:00
# endif
2008-01-16 06:01:53 +00:00
}
2009-09-10 00:46:24 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_set_interval ( switch_rtp_t * rtp_session , uint32_t ms_per_packet , uint32_t samples_per_interval )
2008-11-10 18:26:41 +00:00
{
rtp_session - > ms_per_packet = ms_per_packet ;
rtp_session - > samples_per_interval = rtp_session - > conf_samples_per_interval = samples_per_interval ;
2008-11-18 20:40:44 +00:00
rtp_session - > missed_count = 0 ;
2010-02-06 03:38:24 +00:00
rtp_session - > samples_per_second =
( uint32_t ) ( ( double ) ( 1000.0f / ( double ) ( rtp_session - > ms_per_packet / 1000 ) ) * ( double ) rtp_session - > samples_per_interval ) ;
2009-09-10 00:46:24 +00:00
2014-01-30 00:08:27 +00:00
rtp_session - > one_second = ( rtp_session - > samples_per_second / rtp_session - > samples_per_interval ) ;
2009-09-10 00:46:24 +00:00
return SWITCH_STATUS_SUCCESS ;
}
SWITCH_DECLARE ( switch_status_t ) switch_rtp_change_interval ( switch_rtp_t * rtp_session , uint32_t ms_per_packet , uint32_t samples_per_interval )
{
2009-12-03 22:51:50 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS ;
int change_timer = 0 ;
2010-02-06 03:38:24 +00:00
2016-09-23 20:50:47 +00:00
if ( rtp_session - > ms_per_packet ! = ms_per_packet | | rtp_session - > samples_per_interval ! = samples_per_interval ) {
2009-12-03 22:51:50 +00:00
change_timer = 1 ;
}
2008-11-18 20:40:44 +00:00
2009-09-10 00:46:24 +00:00
switch_rtp_set_interval ( rtp_session , ms_per_packet , samples_per_interval ) ;
2010-02-06 03:38:24 +00:00
2009-12-03 22:51:50 +00:00
if ( change_timer & & rtp_session - > timer_name ) {
READ_INC ( rtp_session ) ;
WRITE_INC ( rtp_session ) ;
2008-11-10 18:26:41 +00:00
if ( rtp_session - > timer . timer_interface ) {
switch_core_timer_destroy ( & rtp_session - > timer ) ;
}
2010-02-06 03:38:24 +00:00
if ( ( status = switch_core_timer_init ( & rtp_session - > timer ,
rtp_session - > timer_name , ms_per_packet / 1000 ,
2009-12-03 22:51:50 +00:00
samples_per_interval , rtp_session - > pool ) ) = = SWITCH_STATUS_SUCCESS ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG ,
2010-05-13 02:25:54 +00:00
" RE-Starting timer [%s] %d bytes per %dms \n " , rtp_session - > timer_name , samples_per_interval , ms_per_packet / 1000 ) ;
2008-11-18 23:26:25 +00:00
} else {
2013-01-15 05:17:28 +00:00
2008-11-18 23:26:25 +00:00
memset ( & rtp_session - > timer , 0 , sizeof ( rtp_session - > timer ) ) ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR ,
2008-11-18 23:44:41 +00:00
" Problem RE-Starting timer [%s] %d bytes per %dms \n " , rtp_session - > timer_name , samples_per_interval , ms_per_packet / 1000 ) ;
2008-11-18 23:26:25 +00:00
}
2009-12-03 22:51:50 +00:00
WRITE_DEC ( rtp_session ) ;
READ_DEC ( rtp_session ) ;
2008-11-10 18:26:41 +00:00
}
2010-02-06 03:38:24 +00:00
2009-12-03 22:51:50 +00:00
return status ;
2008-11-10 18:26:41 +00:00
}
2010-02-06 03:38:24 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_set_ssrc ( switch_rtp_t * rtp_session , uint32_t ssrc )
{
rtp_session - > ssrc = ssrc ;
rtp_session - > send_msg . header . ssrc = htonl ( rtp_session - > ssrc ) ;
return SWITCH_STATUS_SUCCESS ;
}
2013-07-11 22:38:24 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_set_remote_ssrc ( switch_rtp_t * rtp_session , uint32_t ssrc )
{
rtp_session - > remote_ssrc = ssrc ;
2016-08-17 23:18:53 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_DETECT_SSRC ] = 0 ;
2013-07-11 22:38:24 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_create ( switch_rtp_t * * new_rtp_session ,
2006-09-12 22:23:45 +00:00
switch_payload_t payload ,
2007-03-09 16:30:34 +00:00
uint32_t samples_per_interval ,
2006-09-12 22:23:45 +00:00
uint32_t ms_per_packet ,
2012-12-18 22:06:29 +00:00
switch_rtp_flag_t flags [ SWITCH_RTP_FLAG_INVALID ] , char * timer_name , const char * * err , switch_memory_pool_t * pool )
2006-04-06 20:56:29 +00:00
{
2006-04-29 01:00:52 +00:00
switch_rtp_t * rtp_session = NULL ;
2009-08-20 17:39:13 +00:00
switch_core_session_t * session = switch_core_memory_pool_get_data ( pool , " __session " ) ;
2010-04-20 21:15:37 +00:00
switch_channel_t * channel = NULL ;
if ( session ) channel = switch_core_session_get_channel ( session ) ;
2006-04-06 20:56:29 +00:00
* new_rtp_session = NULL ;
2007-03-29 22:31:56 +00:00
2007-03-09 16:30:34 +00:00
if ( samples_per_interval > SWITCH_RTP_MAX_BUF_LEN ) {
2006-04-07 17:32:14 +00:00
* err = " Packet Size Too Large! " ;
return SWITCH_STATUS_FALSE ;
}
2006-04-03 21:00:13 +00:00
if ( ! ( rtp_session = switch_core_alloc ( pool , sizeof ( * rtp_session ) ) ) ) {
* err = " Memory Error! " ;
2006-04-06 20:56:29 +00:00
return SWITCH_STATUS_MEMERR ;
2006-04-03 21:00:13 +00:00
}
2006-04-04 02:28:11 +00:00
rtp_session - > pool = pool ;
2015-06-12 07:38:52 +00:00
rtp_session - > te = INVALID_PT ;
rtp_session - > recv_te = INVALID_PT ;
rtp_session - > cng_pt = INVALID_PT ;
2013-01-15 05:17:28 +00:00
rtp_session - > session = session ;
2007-12-05 17:16:50 +00:00
switch_mutex_init ( & rtp_session - > flag_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2008-01-18 18:14:53 +00:00
switch_mutex_init ( & rtp_session - > read_mutex , SWITCH_MUTEX_NESTED , pool ) ;
switch_mutex_init ( & rtp_session - > write_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2015-01-22 03:08:09 +00:00
switch_mutex_init ( & rtp_session - > ice_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2007-12-05 17:16:50 +00:00
switch_mutex_init ( & rtp_session - > dtmf_data . dtmf_mutex , SWITCH_MUTEX_NESTED , pool ) ;
2007-12-22 00:32:20 +00:00
switch_queue_create ( & rtp_session - > dtmf_data . dtmf_queue , 100 , rtp_session - > pool ) ;
switch_queue_create ( & rtp_session - > dtmf_data . dtmf_inqueue , 100 , rtp_session - > pool ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_set_flags ( rtp_session , flags ) ;
2007-05-16 17:47:24 +00:00
2006-04-07 17:32:14 +00:00
/* for from address on recvfrom calls */
2010-12-11 17:41:19 +00:00
switch_sockaddr_create ( & rtp_session - > from_addr , pool ) ;
2015-01-21 01:20:20 +00:00
switch_sockaddr_create ( & rtp_session - > rtp_from_addr , pool ) ;
2010-12-11 17:41:19 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2010-12-11 17:41:19 +00:00
switch_sockaddr_create ( & rtp_session - > rtcp_from_addr , pool ) ;
2010-04-20 00:07:23 +00:00
}
2010-11-11 00:08:55 +00:00
rtp_session - > seq = ( uint16_t ) rand ( ) ;
2010-02-03 19:19:10 +00:00
rtp_session - > ssrc = ( uint32_t ) ( ( intptr_t ) rtp_session + ( uint32_t ) switch_epoch_time_now ( NULL ) ) ;
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . R = 100.0 ;
rtp_session - > stats . inbound . mos = 4.5 ;
2008-01-16 06:01:53 +00:00
rtp_session - > send_msg . header . ssrc = htonl ( rtp_session - > ssrc ) ;
2007-03-29 22:31:56 +00:00
rtp_session - > send_msg . header . ts = 0 ;
rtp_session - > send_msg . header . m = 0 ;
rtp_session - > send_msg . header . pt = ( switch_payload_t ) htonl ( payload ) ;
2006-04-03 21:00:13 +00:00
rtp_session - > send_msg . header . version = 2 ;
2007-03-29 22:31:56 +00:00
rtp_session - > send_msg . header . p = 0 ;
rtp_session - > send_msg . header . x = 0 ;
rtp_session - > send_msg . header . cc = 0 ;
2008-01-16 06:01:53 +00:00
rtp_session - > recv_msg . header . ssrc = 0 ;
2007-03-29 22:31:56 +00:00
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 = ( switch_payload_t ) htonl ( payload ) ;
2006-04-03 21:00:13 +00:00
rtp_session - > recv_msg . header . version = 2 ;
2007-03-29 22:31:56 +00:00
rtp_session - > recv_msg . header . p = 0 ;
rtp_session - > recv_msg . header . x = 0 ;
rtp_session - > recv_msg . header . cc = 0 ;
2006-04-03 21:00:13 +00:00
rtp_session - > payload = payload ;
2014-11-15 01:01:56 +00:00
rtp_session - > rtcp_last_sent = switch_micro_time_now ( ) ;
2010-04-20 21:15:37 +00:00
2009-09-10 00:46:24 +00:00
switch_rtp_set_interval ( rtp_session , ms_per_packet , samples_per_interval ) ;
rtp_session - > conf_samples_per_interval = samples_per_interval ;
2006-04-10 19:55:53 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & & zstr ( timer_name ) ) {
2006-09-16 20:46:52 +00:00
timer_name = " soft " ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( timer_name ) & & ! strcasecmp ( timer_name , " none " ) ) {
2008-11-10 18:26:41 +00:00
timer_name = NULL ;
}
2009-10-23 16:03:42 +00:00
if ( ! zstr ( timer_name ) ) {
2008-09-09 16:31:53 +00:00
rtp_session - > timer_name = switch_core_strdup ( pool , timer_name ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ;
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_NOBLOCK ) ;
2008-09-09 16:31:53 +00:00
2008-05-27 04:30:03 +00:00
if ( switch_core_timer_init ( & rtp_session - > timer , timer_name , ms_per_packet / 1000 , samples_per_interval , pool ) = = SWITCH_STATUS_SUCCESS ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG ,
2009-02-19 14:41:20 +00:00
" Starting timer [%s] %d bytes per %dms \n " , timer_name , samples_per_interval , ms_per_packet / 1000 ) ;
2006-09-17 18:03:32 +00:00
} else {
memset ( & rtp_session - > timer , 0 , sizeof ( rtp_session - > timer ) ) ;
2013-10-29 18:40:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR ,
" Error Starting timer [%s] %d bytes per %dms, async RTP disabled \n " , timer_name , samples_per_interval , ms_per_packet / 1000 ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ;
2006-09-17 18:03:32 +00:00
}
2008-09-09 16:31:53 +00:00
} else {
2014-11-14 02:52:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2014-12-04 21:45:33 +00:00
if ( switch_core_timer_init ( & rtp_session - > timer , " soft " , 1 , 90 , pool ) = = SWITCH_STATUS_SUCCESS ) {
2014-11-14 02:52:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Starting video timer. \n " ) ;
}
2014-12-17 00:48:07 +00:00
2015-09-11 16:37:01 +00:00
//switch_jb_create(&rtp_session->vb, 3, 10, rtp_session->pool);
//switch_jb_debug_level(rtp_session->vb, 10);
2014-12-17 00:48:07 +00:00
2014-11-14 02:52:57 +00:00
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Not using a timer \n " ) ;
}
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_USE_TIMER ) ;
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_NOBLOCK ) ;
2006-09-16 20:46:52 +00:00
}
2013-07-11 22:38:24 +00:00
2010-06-04 12:16:51 +00:00
if ( channel ) {
switch_channel_set_private ( channel , " __rtcp_audio_rtp_session " , rtp_session ) ;
}
2010-04-20 21:15:37 +00:00
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
2013-05-25 20:53:52 +00:00
if ( zrtp_on & & session & & channel & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] ) {
2010-02-03 19:19:10 +00:00
switch_rtp_t * master_rtp_session = NULL ;
2009-05-23 01:50:56 +00:00
int initiator = 0 ;
2009-05-27 05:07:19 +00:00
const char * zrtp_enabled = switch_channel_get_variable ( channel , " zrtp_secure_media " ) ;
2014-03-06 02:33:05 +00:00
int srtp_enabled = switch_channel_test_flag ( channel , CF_SECURE ) ;
2009-05-28 13:53:23 +00:00
2014-03-06 02:33:05 +00:00
if ( srtp_enabled & & switch_true ( zrtp_enabled ) ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING ,
2010-02-06 03:38:24 +00:00
" You can not have ZRTP and SRTP enabled simultaneously, ZRTP will be disabled for this call! \n " ) ;
2009-05-28 13:53:23 +00:00
switch_channel_set_variable ( channel , " zrtp_secure_media " , NULL ) ;
zrtp_enabled = NULL ;
}
2009-05-23 01:50:56 +00:00
2010-02-06 03:38:24 +00:00
2009-05-27 05:07:19 +00:00
if ( switch_true ( zrtp_enabled ) ) {
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2010-02-03 19:19:10 +00:00
switch_channel_set_private ( channel , " __zrtp_video_rtp_session " , rtp_session ) ;
master_rtp_session = switch_channel_get_private ( channel , " __zrtp_audio_rtp_session " ) ;
} else {
switch_channel_set_private ( channel , " __zrtp_audio_rtp_session " , rtp_session ) ;
master_rtp_session = rtp_session ;
}
2009-05-27 05:07:19 +00:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_OUTBOUND ) {
initiator = 1 ;
}
2010-02-03 19:19:10 +00:00
if ( rtp_session = = master_rtp_session ) {
rtp_session - > zrtp_profile = switch_core_alloc ( rtp_session - > pool , sizeof ( * rtp_session - > zrtp_profile ) ) ;
zrtp_profile_defaults ( rtp_session - > zrtp_profile , zrtp_global ) ;
2010-02-06 03:38:24 +00:00
2010-02-03 19:19:10 +00:00
rtp_session - > zrtp_profile - > allowclear = 0 ;
rtp_session - > zrtp_profile - > disclose_bit = 0 ;
2012-05-16 21:05:41 +00:00
rtp_session - > zrtp_profile - > cache_ttl = ( uint32_t ) - 1 ;
2010-02-06 03:38:24 +00:00
2010-02-03 19:19:10 +00:00
if ( zrtp_status_ok ! = zrtp_session_init ( zrtp_global , rtp_session - > zrtp_profile , zid , initiator , & rtp_session - > zrtp_session ) ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error! zRTP INIT Failed \n " ) ;
2010-02-03 19:19:10 +00:00
zrtp_session_down ( rtp_session - > zrtp_session ) ;
rtp_session - > zrtp_session = NULL ;
goto end ;
}
2010-02-06 03:38:24 +00:00
2010-02-03 19:19:10 +00:00
zrtp_session_set_userdata ( rtp_session - > zrtp_session , session ) ;
2010-02-06 03:38:24 +00:00
2010-02-03 19:19:10 +00:00
if ( zrtp_status_ok ! = zrtp_stream_attach ( master_rtp_session - > zrtp_session , & rtp_session - > zrtp_stream ) ) {
abort ( ) ;
}
2010-02-06 03:38:24 +00:00
2010-02-03 19:19:10 +00:00
zrtp_stream_set_userdata ( rtp_session - > zrtp_stream , rtp_session ) ;
if ( switch_true ( switch_channel_get_variable ( channel , " zrtp_enrollment " ) ) ) {
zrtp_stream_registration_start ( rtp_session - > zrtp_stream , rtp_session - > ssrc ) ;
} else {
zrtp_stream_start ( rtp_session - > zrtp_stream , rtp_session - > ssrc ) ;
}
2009-05-27 05:07:19 +00:00
}
2010-02-06 03:38:24 +00:00
2009-05-23 01:50:56 +00:00
}
2009-05-20 23:04:05 +00:00
}
2010-02-03 19:19:10 +00:00
2010-04-20 00:07:23 +00:00
end :
2010-02-03 19:19:10 +00:00
2010-02-06 03:38:24 +00:00
# endif
2006-04-06 20:56:29 +00:00
2014-01-30 00:08:27 +00:00
/* Jitter */
rtp_session - > stats . inbound . last_proc_time = switch_time_now ( ) / 1000 ;
rtp_session - > stats . inbound . jitter_n = 0 ;
rtp_session - > stats . inbound . jitter_add = 0 ;
rtp_session - > stats . inbound . jitter_addsq = 0 ;
rtp_session - > stats . inbound . min_variance = 0 ;
rtp_session - > stats . inbound . max_variance = 0 ;
/* Burst and Packet Loss */
rtp_session - > stats . inbound . lossrate = 0 ;
2016-03-17 13:55:00 +00:00
rtp_session - > stats . inbound . burstrate = 0 ;
memset ( rtp_session - > stats . inbound . loss , 0 , sizeof ( rtp_session - > stats . inbound . loss ) ) ;
rtp_session - > stats . inbound . last_loss = 0 ;
rtp_session - > stats . inbound . last_processed_seq = - 1 ;
2014-01-30 00:08:27 +00:00
2009-05-21 22:37:15 +00:00
rtp_session - > ready = 1 ;
* new_rtp_session = rtp_session ;
2006-04-06 20:56:29 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-05-12 14:48:14 +00:00
SWITCH_DECLARE ( switch_rtp_t * ) switch_rtp_new ( const char * rx_host ,
2007-03-29 22:31:56 +00:00
switch_port_t rx_port ,
2007-05-12 14:48:14 +00:00
const char * tx_host ,
2007-03-29 22:31:56 +00:00
switch_port_t tx_port ,
switch_payload_t payload ,
uint32_t samples_per_interval ,
uint32_t ms_per_packet ,
2012-12-18 22:06:29 +00:00
switch_rtp_flag_t flags [ SWITCH_RTP_FLAG_INVALID ] , char * timer_name , const char * * err , switch_memory_pool_t * pool )
2006-04-06 20:56:29 +00:00
{
2007-12-13 15:10:55 +00:00
switch_rtp_t * rtp_session = NULL ;
2008-03-07 20:13:40 +00:00
2009-10-23 16:03:42 +00:00
if ( zstr ( rx_host ) ) {
2008-03-07 20:13:40 +00:00
* err = " Missing local host " ;
goto end ;
}
if ( ! rx_port ) {
* err = " Missing local port " ;
goto end ;
}
2009-10-23 16:03:42 +00:00
if ( zstr ( tx_host ) ) {
2008-03-07 20:13:40 +00:00
* err = " Missing remote host " ;
goto end ;
}
if ( ! tx_port ) {
2008-05-24 01:27:19 +00:00
* err = " Missing remote port " ;
2007-12-13 15:10:55 +00:00
goto end ;
2006-04-06 20:56:29 +00:00
}
2008-05-27 04:30:03 +00:00
2008-03-07 20:13:40 +00:00
if ( switch_rtp_create ( & rtp_session , payload , samples_per_interval , ms_per_packet , flags , timer_name , err , pool ) ! = SWITCH_STATUS_SUCCESS ) {
2007-12-13 15:10:55 +00:00
goto end ;
2006-04-06 20:56:29 +00:00
}
2008-03-08 02:11:21 +00:00
2008-05-27 04:30:03 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
2008-03-08 02:11:21 +00:00
2006-04-06 20:56:29 +00:00
if ( switch_rtp_set_local_address ( rtp_session , rx_host , rx_port , err ) ! = SWITCH_STATUS_SUCCESS ) {
2008-05-27 04:30:03 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
2007-12-13 15:10:55 +00:00
rtp_session = NULL ;
2008-03-08 02:11:21 +00:00
goto end ;
2007-12-13 15:10:55 +00:00
}
2010-04-22 15:22:28 +00:00
if ( switch_rtp_set_remote_address ( rtp_session , tx_host , tx_port , 0 , SWITCH_TRUE , err ) ! = SWITCH_STATUS_SUCCESS ) {
2008-05-27 04:30:03 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
2008-03-07 20:13:40 +00:00
rtp_session = NULL ;
goto end ;
}
2008-05-27 04:30:03 +00:00
2010-04-20 00:07:23 +00:00
end :
2007-12-13 15:10:55 +00:00
if ( rtp_session ) {
2008-03-08 02:11:21 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
2008-01-18 18:14:53 +00:00
rtp_session - > ready = 2 ;
2007-12-13 15:10:55 +00:00
rtp_session - > rx_host = switch_core_strdup ( rtp_session - > pool , rx_host ) ;
rtp_session - > rx_port = rx_port ;
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_FLUSH ) ;
2016-08-17 23:18:53 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_DETECT_SSRC ) ;
2007-12-13 15:10:55 +00:00
} else {
2007-12-20 15:41:45 +00:00
switch_rtp_release_port ( rx_host , rx_port ) ;
2006-04-06 20:56:29 +00:00
}
2007-03-29 22:31:56 +00:00
2006-04-03 21:00:13 +00:00
return rtp_session ;
}
2006-05-27 00:24:32 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_telephony_event ( switch_rtp_t * rtp_session , switch_payload_t te )
{
2007-05-21 14:45:35 +00:00
if ( te > 95 ) {
2006-05-27 00:24:32 +00:00
rtp_session - > te = te ;
}
}
2006-04-06 20:56:29 +00:00
2010-03-16 22:49:54 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_telephony_recv_event ( switch_rtp_t * rtp_session , switch_payload_t te )
{
if ( te > 95 ) {
rtp_session - > recv_te = te ;
}
}
2011-02-15 22:09:48 +00:00
2007-03-07 18:34:22 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_cng_pt ( switch_rtp_t * rtp_session , switch_payload_t pt )
{
rtp_session - > cng_pt = pt ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_AUTO_CNG ] = 1 ;
2007-03-07 18:34:22 +00:00
}
2014-11-14 02:52:57 +00:00
SWITCH_DECLARE ( switch_timer_t * ) switch_rtp_get_media_timer ( switch_rtp_t * rtp_session )
{
2014-11-15 01:01:56 +00:00
if ( rtp_session & & rtp_session - > timer . timer_interface ) {
2014-11-14 02:52:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
switch_core_timer_sync ( & rtp_session - > timer ) ;
}
return & rtp_session - > timer ;
}
return NULL ;
}
2015-09-11 16:37:01 +00:00
SWITCH_DECLARE ( switch_jb_t * ) switch_rtp_get_jitter_buffer ( switch_rtp_t * rtp_session )
2012-10-18 19:29:00 +00:00
{
2016-07-11 03:25:14 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
2012-10-18 19:29:00 +00:00
return NULL ;
}
2016-07-11 03:25:14 +00:00
return rtp_session - > jb ? rtp_session - > jb : rtp_session - > vb ;
2012-10-18 19:29:00 +00:00
}
2011-01-05 22:25:07 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_pause_jitter_buffer ( switch_rtp_t * rtp_session , switch_bool_t pause )
{
2016-07-28 19:13:37 +00:00
if ( ! switch_rtp_ready ( rtp_session ) | | ! rtp_session - > jb ) {
2011-01-05 22:25:07 +00:00
return SWITCH_STATUS_FALSE ;
}
if ( ! ! pause = = ! ! rtp_session - > pause_jb ) {
return SWITCH_STATUS_FALSE ;
}
if ( rtp_session - > pause_jb & & ! pause ) {
2016-07-28 19:13:37 +00:00
switch_jb_reset ( rtp_session - > jb ) ;
2011-01-05 22:25:07 +00:00
}
rtp_session - > pause_jb = pause ? 1 : 0 ;
return SWITCH_STATUS_SUCCESS ;
}
2010-12-10 23:47:24 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_deactivate_jitter_buffer ( switch_rtp_t * rtp_session )
{
if ( ! switch_rtp_ready ( rtp_session ) | | ! rtp_session - > jb ) {
return SWITCH_STATUS_FALSE ;
}
2013-08-21 21:30:59 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_KILL_JB ] + + ;
2010-12-10 23:47:24 +00:00
2007-05-04 23:29:35 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2015-09-11 16:37:01 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_get_video_buffer_size ( switch_rtp_t * rtp_session , uint32_t * min_frame_len , uint32_t * max_frame_len , uint32_t * cur_frame_len , uint32_t * highest_frame_len )
2015-05-05 18:27:52 +00:00
{
2015-09-11 16:37:01 +00:00
2015-05-05 18:27:52 +00:00
if ( rtp_session - > vb ) {
2015-09-11 16:37:01 +00:00
return switch_jb_get_frames ( rtp_session - > vb , min_frame_len , max_frame_len , cur_frame_len , highest_frame_len ) ;
2015-05-05 18:27:52 +00:00
}
2015-09-11 16:37:01 +00:00
return SWITCH_STATUS_FALSE ;
2015-05-05 18:27:52 +00:00
}
2015-09-11 16:37:01 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_set_video_buffer_size ( switch_rtp_t * rtp_session , uint32_t frames , uint32_t max_frames )
2015-04-09 23:18:45 +00:00
{
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2015-09-11 16:37:01 +00:00
if ( ! max_frames ) {
2016-07-22 03:11:29 +00:00
max_frames = rtp_session - > last_max_vb_frames ;
}
if ( ! max_frames | | frames > = max_frames ) {
2016-06-08 21:20:18 +00:00
max_frames = frames * 10 ;
2015-09-11 16:37:01 +00:00
}
2016-07-22 03:11:29 +00:00
rtp_session - > last_max_vb_frames = max_frames ;
2015-09-11 16:37:01 +00:00
if ( ! rtp_session - > vb ) {
2016-07-11 03:25:14 +00:00
switch_jb_create ( & rtp_session - > vb , rtp_session - > flags [ SWITCH_RTP_FLAG_TEXT ] ? SJB_TEXT : SJB_VIDEO , frames , max_frames , rtp_session - > pool ) ;
2015-09-11 16:37:01 +00:00
switch_jb_set_session ( rtp_session - > vb , rtp_session - > session ) ;
2015-04-09 23:18:45 +00:00
} else {
2015-09-11 16:37:01 +00:00
switch_jb_set_frames ( rtp_session - > vb , frames , max_frames ) ;
2015-04-09 23:18:45 +00:00
}
2015-05-23 03:08:27 +00:00
//switch_rtp_flush(rtp_session);
2015-09-11 16:37:01 +00:00
switch_core_session_request_video_refresh ( rtp_session - > session ) ;
2015-05-12 20:52:25 +00:00
2015-10-20 23:13:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Setting video buffer %u Frames. \n " , frames ) ;
2015-04-09 23:18:45 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-12-15 05:46:26 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_debug_jitter_buffer ( switch_rtp_t * rtp_session , const char * name )
{
2015-09-11 16:37:01 +00:00
int x = 0 ;
2010-12-15 05:46:26 +00:00
2015-01-17 00:14:19 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
2011-02-04 16:58:26 +00:00
return SWITCH_STATUS_FALSE ;
}
2015-09-11 16:37:01 +00:00
if ( name ) x = atoi ( name ) ;
if ( x < 0 ) x = 0 ;
2011-02-04 16:58:26 +00:00
2015-01-17 00:14:19 +00:00
if ( rtp_session - > jb ) {
2015-09-11 16:37:01 +00:00
switch_jb_debug_level ( rtp_session - > jb , x ) ;
2015-01-17 00:14:19 +00:00
} else if ( rtp_session - > vb ) {
2015-09-11 16:37:01 +00:00
switch_jb_debug_level ( rtp_session - > vb , x ) ;
2015-01-17 00:14:19 +00:00
}
2010-12-15 05:46:26 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2010-12-10 23:47:24 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_activate_jitter_buffer ( switch_rtp_t * rtp_session ,
uint32_t queue_frames ,
uint32_t max_queue_frames ,
uint32_t samples_per_packet ,
2015-09-11 16:37:01 +00:00
uint32_t samples_per_second )
2010-12-10 23:47:24 +00:00
{
2015-09-11 16:37:01 +00:00
switch_status_t status = SWITCH_STATUS_FALSE ;
2010-12-10 23:47:24 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2011-03-18 03:29:16 +00:00
if ( queue_frames < 1 ) {
queue_frames = 3 ;
}
if ( max_queue_frames < queue_frames ) {
2016-06-08 21:20:18 +00:00
max_queue_frames = queue_frames * 3 ;
2011-03-18 03:29:16 +00:00
}
2015-10-07 16:21:51 +00:00
2014-10-16 22:57:40 +00:00
2010-12-10 23:47:24 +00:00
if ( rtp_session - > jb ) {
2015-09-11 16:37:01 +00:00
status = switch_jb_set_frames ( rtp_session - > jb , queue_frames , max_queue_frames ) ;
} else {
2015-10-07 16:21:51 +00:00
READ_INC ( rtp_session ) ;
2015-09-11 16:37:01 +00:00
status = switch_jb_create ( & rtp_session - > jb , SJB_AUDIO , queue_frames , max_queue_frames , rtp_session - > pool ) ;
switch_jb_set_session ( rtp_session - > jb , rtp_session - > session ) ;
2015-10-02 00:11:51 +00:00
if ( switch_true ( switch_channel_get_variable_dup ( switch_core_session_get_channel ( rtp_session - > session ) , " jb_use_timestamps " , SWITCH_FALSE , - 1 ) ) ) {
switch_jb_ts_mode ( rtp_session - > jb , samples_per_packet , samples_per_second ) ;
}
2015-09-15 19:59:05 +00:00
//switch_jb_debug_level(rtp_session->jb, 10);
2015-10-07 16:21:51 +00:00
READ_DEC ( rtp_session ) ;
2010-12-10 23:47:24 +00:00
}
2014-10-16 22:57:40 +00:00
2015-10-07 16:21:51 +00:00
2010-12-10 23:47:24 +00:00
2015-09-11 16:37:01 +00:00
return status ;
2010-12-10 23:47:24 +00:00
}
2013-01-17 01:04:57 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_activate_rtcp ( switch_rtp_t * rtp_session , int send_rate , switch_port_t remote_port , switch_bool_t mux )
2010-04-20 00:07:23 +00:00
{
const char * err = NULL ;
2010-09-29 19:14:41 +00:00
if ( ! rtp_session - > ms_per_packet ) {
return SWITCH_STATUS_FALSE ;
}
2010-04-20 00:07:23 +00:00
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] = 1 ;
2010-04-20 00:07:23 +00:00
2010-04-20 21:15:37 +00:00
if ( ! ( rtp_session - > remote_rtcp_port = remote_port ) ) {
rtp_session - > remote_rtcp_port = rtp_session - > remote_port + 1 ;
}
2013-01-17 01:04:57 +00:00
if ( mux ) {
rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] + + ;
}
2010-04-20 21:15:37 +00:00
if ( send_rate = = - 1 ) {
2013-01-15 05:17:28 +00:00
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_PASSTHRU ] = 1 ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " RTCP passthru enabled. Remote Port: %d \n " , rtp_session - > remote_rtcp_port ) ;
2010-04-20 21:15:37 +00:00
} else {
2013-01-17 01:04:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " RTCP send rate is: %d and packet rate is: %d Remote Port: %d \n " , send_rate , rtp_session - > ms_per_packet , rtp_session - > remote_rtcp_port ) ;
2013-01-18 05:14:32 +00:00
2013-06-18 00:52:37 +00:00
rtp_session - > rtcp_interval = send_rate ;
2010-04-20 21:15:37 +00:00
}
2010-04-20 00:07:23 +00:00
2013-01-17 01:04:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
if ( switch_sockaddr_info_get ( & rtp_session - > rtcp_remote_addr , rtp_session - > eff_remote_host_str , SWITCH_UNSPEC ,
rtp_session - > remote_rtcp_port , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS | | ! rtp_session - > rtcp_remote_addr ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " RTCP MUX Remote Address Error! " ) ;
return SWITCH_STATUS_FALSE ;
}
rtp_session - > rtcp_local_addr = rtp_session - > local_addr ;
2013-01-18 03:47:45 +00:00
rtp_session - > rtcp_from_addr = rtp_session - > from_addr ;
2013-01-17 01:04:57 +00:00
rtp_session - > rtcp_sock_input = rtp_session - > sock_input ;
2013-01-18 03:47:45 +00:00
rtp_session - > rtcp_sock_output = rtp_session - > sock_output ;
2013-01-17 01:04:57 +00:00
rtp_session - > rtcp_recv_msg_p = ( rtcp_msg_t * ) & rtp_session - > recv_msg ;
2015-06-03 20:54:15 +00:00
return SWITCH_STATUS_SUCCESS ;
2013-01-17 01:04:57 +00:00
2015-06-03 20:54:15 +00:00
//return enable_remote_rtcp_socket(rtp_session, &err);
2013-01-17 01:04:57 +00:00
} else {
rtp_session - > rtcp_recv_msg_p = ( rtcp_msg_t * ) & rtp_session - > rtcp_recv_msg ;
}
2010-04-20 00:07:23 +00:00
return enable_local_rtcp_socket ( rtp_session , & err ) | | enable_remote_rtcp_socket ( rtp_session , & err ) ;
}
2013-01-13 07:29:05 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_activate_ice ( switch_rtp_t * rtp_session , char * login , char * rlogin ,
2013-01-26 23:53:15 +00:00
const char * password , const char * rpassword , ice_proto_t proto ,
switch_core_media_ice_type_t type , ice_t * ice_params )
2006-04-04 17:22:06 +00:00
{
char ice_user [ 80 ] ;
char user_ice [ 80 ] ;
2014-12-12 20:55:14 +00:00
char luser_ice [ 80 ] ;
2013-01-26 23:53:15 +00:00
switch_rtp_ice_t * ice ;
2013-02-11 19:42:50 +00:00
char * host = NULL ;
switch_port_t port = 0 ;
2015-08-27 18:42:52 +00:00
char bufc [ 50 ] ;
2013-04-03 00:08:28 +00:00
2015-03-26 20:00:55 +00:00
2015-01-22 03:08:09 +00:00
switch_mutex_lock ( rtp_session - > ice_mutex ) ;
2013-01-26 23:53:15 +00:00
if ( proto = = IPR_RTP ) {
2015-01-26 16:48:59 +00:00
ice = & rtp_session - > ice ;
2015-01-24 08:47:17 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_PAUSE ] = 0 ;
rtp_session - > flags [ SWITCH_RTP_FLAG_MUTE ] = 0 ;
2013-01-26 23:53:15 +00:00
} else {
ice = & rtp_session - > rtcp_ice ;
}
2006-04-04 17:22:06 +00:00
2013-01-26 23:53:15 +00:00
ice - > proto = proto ;
2013-01-13 07:29:05 +00:00
if ( ( type & ICE_VANILLA ) ) {
switch_snprintf ( ice_user , sizeof ( ice_user ) , " %s:%s " , login , rlogin ) ;
switch_snprintf ( user_ice , sizeof ( user_ice ) , " %s:%s " , rlogin , login ) ;
2014-12-12 20:55:14 +00:00
switch_snprintf ( luser_ice , sizeof ( user_ice ) , " %s%s " , rlogin , login ) ;
2014-01-15 16:20:01 +00:00
ice - > ready = ice - > rready = 0 ;
2013-01-13 07:29:05 +00:00
} else {
switch_snprintf ( ice_user , sizeof ( ice_user ) , " %s%s " , login , rlogin ) ;
switch_snprintf ( user_ice , sizeof ( user_ice ) , " %s%s " , rlogin , login ) ;
2013-01-26 23:53:15 +00:00
ice - > ready = ice - > rready = 1 ;
2013-01-13 07:29:05 +00:00
}
2006-04-04 17:22:06 +00:00
2013-01-26 23:53:15 +00:00
ice - > ice_user = switch_core_strdup ( rtp_session - > pool , ice_user ) ;
ice - > user_ice = switch_core_strdup ( rtp_session - > pool , user_ice ) ;
2014-12-12 20:55:14 +00:00
ice - > luser_ice = switch_core_strdup ( rtp_session - > pool , luser_ice ) ;
2013-01-26 23:53:15 +00:00
ice - > type = type ;
ice - > ice_params = ice_params ;
ice - > pass = " " ;
ice - > rpass = " " ;
2013-06-18 00:52:37 +00:00
ice - > next_run = switch_micro_time_now ( ) ;
2012-06-22 23:08:59 +00:00
if ( password ) {
2013-01-26 23:53:15 +00:00
ice - > pass = switch_core_strdup ( rtp_session - > pool , password ) ;
2012-06-22 23:08:59 +00:00
}
2013-01-14 02:12:23 +00:00
if ( rpassword ) {
2013-01-26 23:53:15 +00:00
ice - > rpass = switch_core_strdup ( rtp_session - > pool , rpassword ) ;
2013-01-14 02:12:23 +00:00
}
2012-06-22 23:08:59 +00:00
2013-04-03 00:08:28 +00:00
if ( ( ice - > type & ICE_VANILLA ) & & ice - > ice_params ) {
host = ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . con_addr ;
port = ice - > ice_params - > cands [ ice - > ice_params - > chosen [ ice - > proto ] ] [ ice - > proto ] . con_port ;
2013-02-11 19:42:50 +00:00
2013-04-03 00:08:28 +00:00
if ( ! host | | ! port | | switch_sockaddr_info_get ( & ice - > addr , host , SWITCH_UNSPEC , port , 0 , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS | | ! ice - > addr ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error setting remote host! \n " ) ;
return SWITCH_STATUS_FALSE ;
}
} else {
if ( proto = = IPR_RTP ) {
ice - > addr = rtp_session - > remote_addr ;
} else {
ice - > addr = rtp_session - > rtcp_remote_addr ;
}
host = ( char * ) switch_get_addr ( bufc , sizeof ( bufc ) , ice - > addr ) ;
port = switch_sockaddr_get_port ( ice - > addr ) ;
2013-02-11 19:42:50 +00:00
}
2013-02-16 03:27:49 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_NOTICE , " Activating %s %s ICE: %s %s:%d \n " ,
proto = = IPR_RTP ? " RTP " : " RTCP " , rtp_type ( rtp_session ) , ice_user , host , port ) ;
2013-02-11 19:42:50 +00:00
2013-02-16 22:05:42 +00:00
rtp_session - > rtp_bugs | = RTP_BUG_ACCEPT_ANY_PACKETS ;
2013-10-15 21:24:32 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO_BREAK ] = 1 ;
switch_rtp_break ( rtp_session ) ;
}
2015-01-22 03:08:09 +00:00
switch_mutex_unlock ( rtp_session - > ice_mutex ) ;
2015-01-10 03:47:28 +00:00
2012-06-22 23:08:59 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2012-03-26 15:53:34 +00:00
SWITCH_DECLARE ( void ) switch_rtp_flush ( switch_rtp_t * rtp_session )
{
if ( ! switch_rtp_ready ( rtp_session ) ) {
return ;
}
2015-05-01 20:40:50 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_FLUSH ) ;
2012-03-26 15:53:34 +00:00
}
2015-05-13 00:55:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_req_bitrate ( switch_rtp_t * rtp_session , uint32_t bps )
2015-05-07 16:58:49 +00:00
{
2015-05-13 00:55:28 +00:00
if ( ! rtp_write_ready ( rtp_session , 0 , __LINE__ ) | | rtp_session - > tmmbr ) {
return SWITCH_STATUS_FALSE ;
2015-05-07 16:58:49 +00:00
}
2015-05-13 00:55:28 +00:00
rtp_session - > tmmbr = bps ;
2015-05-07 16:58:49 +00:00
2015-05-13 00:55:28 +00:00
return SWITCH_STATUS_SUCCESS ;
2015-05-07 16:58:49 +00:00
}
2015-05-13 00:55:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_ack_bitrate ( switch_rtp_t * rtp_session , uint32_t bps )
2015-05-07 16:58:49 +00:00
{
2015-05-13 00:55:28 +00:00
if ( ! rtp_write_ready ( rtp_session , 0 , __LINE__ ) | | rtp_session - > tmmbn ) {
2015-05-07 16:58:49 +00:00
return SWITCH_STATUS_FALSE ;
}
2015-05-13 00:55:28 +00:00
rtp_session - > tmmbn = bps ;
2015-05-07 16:58:49 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2013-06-18 00:52:37 +00:00
SWITCH_DECLARE ( void ) switch_rtp_video_refresh ( switch_rtp_t * rtp_session )
{
2014-12-11 03:08:16 +00:00
if ( ! rtp_write_ready ( rtp_session , 0 , __LINE__ ) ) {
return ;
}
2015-01-24 07:55:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & ( rtp_session - > ice . ice_user | | rtp_session - > flags [ SWITCH_RTP_FLAG_FIR ] ) ) {
2015-05-13 16:50:04 +00:00
rtp_session - > fir_count = 1 ;
2013-06-18 00:52:37 +00:00
}
}
2012-03-26 15:53:34 +00:00
2014-11-15 01:01:56 +00:00
SWITCH_DECLARE ( void ) switch_rtp_video_loss ( switch_rtp_t * rtp_session )
{
2014-12-11 03:08:16 +00:00
if ( ! rtp_write_ready ( rtp_session , 0 , __LINE__ ) ) {
return ;
}
2015-01-24 07:55:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & ( rtp_session - > ice . ice_user | | rtp_session - > flags [ SWITCH_RTP_FLAG_PLI ] ) ) {
2015-05-13 16:50:04 +00:00
rtp_session - > pli_count = 1 ;
2014-11-15 01:01:56 +00:00
}
}
2008-03-07 18:21:08 +00:00
SWITCH_DECLARE ( void ) switch_rtp_break ( switch_rtp_t * rtp_session )
{
2008-12-03 16:52:58 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return ;
}
2013-07-17 00:15:56 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2013-09-12 16:47:54 +00:00
int ret = 1 ;
2013-10-15 21:24:32 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO_BREAK ] ) {
rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO_BREAK ] = 0 ;
ret = 0 ;
} else if ( rtp_session - > session ) {
2013-09-12 16:47:54 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
if ( switch_channel_test_flag ( channel , CF_VIDEO_BREAK ) ) {
switch_channel_clear_flag ( channel , CF_VIDEO_BREAK ) ;
ret = 0 ;
}
}
if ( ret ) return ;
2013-10-15 21:24:32 +00:00
switch_rtp_video_refresh ( rtp_session ) ;
2013-07-17 00:15:56 +00:00
}
2008-05-27 04:30:03 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_BREAK ] = 1 ;
2010-02-06 03:38:24 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_NOBLOCK ] ) {
2008-12-03 16:52:58 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
return ;
}
2008-10-10 23:09:15 +00:00
2008-07-03 18:50:15 +00:00
if ( rtp_session - > sock_input ) {
2009-01-13 17:56:35 +00:00
ping_socket ( rtp_session ) ;
2008-03-07 18:21:08 +00:00
}
2013-06-18 00:52:37 +00:00
2008-03-07 18:21:08 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( void ) switch_rtp_kill_socket ( switch_rtp_t * rtp_session )
2006-04-03 21:00:13 +00:00
{
2007-12-11 19:23:57 +00:00
switch_assert ( rtp_session ! = NULL ) ;
2006-08-30 19:46:43 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_IO ] ) {
rtp_session - > flags [ SWITCH_RTP_FLAG_IO ] = 0 ;
2008-07-03 18:50:15 +00:00
if ( rtp_session - > sock_input ) {
2009-01-13 17:56:35 +00:00
ping_socket ( rtp_session ) ;
2008-07-03 18:50:15 +00:00
switch_socket_shutdown ( rtp_session - > sock_input , SWITCH_SHUTDOWN_READWRITE ) ;
}
if ( rtp_session - > sock_output & & rtp_session - > sock_output ! = rtp_session - > sock_input ) {
switch_socket_shutdown ( rtp_session - > sock_output , SWITCH_SHUTDOWN_READWRITE ) ;
2008-03-07 18:21:08 +00:00
}
2010-04-20 00:07:23 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2010-04-20 00:07:23 +00:00
if ( rtp_session - > rtcp_sock_input ) {
ping_socket ( rtp_session ) ;
switch_socket_shutdown ( rtp_session - > rtcp_sock_input , SWITCH_SHUTDOWN_READWRITE ) ;
}
if ( rtp_session - > rtcp_sock_output & & rtp_session - > rtcp_sock_output ! = rtp_session - > rtcp_sock_input ) {
switch_socket_shutdown ( rtp_session - > rtcp_sock_output , SWITCH_SHUTDOWN_READWRITE ) ;
}
}
2006-09-14 01:37:55 +00:00
}
2006-08-30 19:46:43 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
2006-04-03 21:00:13 +00:00
}
2006-08-28 23:05:26 +00:00
SWITCH_DECLARE ( uint8_t ) switch_rtp_ready ( switch_rtp_t * rtp_session )
{
2008-02-25 16:35:19 +00:00
uint8_t ret ;
2012-12-18 22:06:29 +00:00
if ( ! rtp_session | | ! rtp_session - > flag_mutex | | rtp_session - > flags [ SWITCH_RTP_FLAG_SHUTDOWN ] ) {
2008-02-25 16:35:19 +00:00
return 0 ;
}
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
2012-12-18 22:06:29 +00:00
ret = ( rtp_session - > flags [ SWITCH_RTP_FLAG_IO ] & & rtp_session - > sock_input & & rtp_session - > sock_output & & rtp_session - > remote_addr
2010-02-06 03:38:24 +00:00
& & rtp_session - > ready = = 2 ) ? 1 : 0 ;
2008-02-25 16:35:19 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
return ret ;
2006-08-28 23:05:26 +00:00
}
2006-04-03 21:00:13 +00:00
2016-04-01 00:25:56 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_sync_stats ( switch_rtp_t * rtp_session )
{
if ( ! rtp_session ) {
return SWITCH_STATUS_FALSE ;
}
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VAD ] ) {
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > vad_data . session ) ;
switch_channel_set_variable_printf ( channel , " vad_total_talk_time_ms " , " %u " , ( uint32_t ) rtp_session - > vad_data . total_talk_time / 1000 ) ;
switch_channel_set_variable_printf ( channel , " vad_total_talk_time_sec " , " %u " , ( uint32_t ) rtp_session - > vad_data . total_talk_time / 1000000 ) ;
}
do_mos ( rtp_session , SWITCH_TRUE ) ;
if ( rtp_session - > stats . inbound . error_log & & ! rtp_session - > stats . inbound . error_log - > stop ) {
rtp_session - > stats . inbound . error_log - > stop = switch_micro_time_now ( ) ;
}
return SWITCH_STATUS_SUCCESS ;
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( void ) switch_rtp_destroy ( switch_rtp_t * * rtp_session )
2006-04-03 21:00:13 +00:00
{
2007-12-22 00:32:20 +00:00
void * pop ;
2008-01-18 00:10:23 +00:00
switch_socket_t * sock ;
2014-02-26 14:05:22 +00:00
# ifdef ENABLE_SRTP
2013-02-03 05:57:27 +00:00
int x ;
2014-02-26 14:05:22 +00:00
# endif
2008-02-25 16:35:19 +00:00
2008-01-18 18:14:53 +00:00
if ( ! rtp_session | | ! * rtp_session | | ! ( * rtp_session ) - > ready ) {
2006-08-28 23:05:26 +00:00
return ;
}
2012-12-18 22:06:29 +00:00
( * rtp_session ) - > flags [ SWITCH_RTP_FLAG_SHUTDOWN ] = 1 ;
2008-03-11 03:45:16 +00:00
2008-02-25 16:35:19 +00:00
READ_INC ( ( * rtp_session ) ) ;
WRITE_INC ( ( * rtp_session ) ) ;
2008-01-18 18:14:53 +00:00
2008-02-25 16:35:19 +00:00
( * rtp_session ) - > ready = 0 ;
2008-01-18 18:14:53 +00:00
2008-02-25 16:35:19 +00:00
READ_DEC ( ( * rtp_session ) ) ;
WRITE_DEC ( ( * rtp_session ) ) ;
2008-05-27 04:30:03 +00:00
2016-04-01 00:25:56 +00:00
if ( ( * rtp_session ) - > flags [ SWITCH_RTP_FLAG_VAD ] ) {
switch_rtp_disable_vad ( * rtp_session ) ;
2015-11-17 01:31:32 +00:00
}
2008-04-02 20:53:13 +00:00
switch_mutex_lock ( ( * rtp_session ) - > flag_mutex ) ;
2008-01-18 18:14:53 +00:00
switch_rtp_kill_socket ( * rtp_session ) ;
2008-05-27 04:30:03 +00:00
while ( switch_queue_trypop ( ( * rtp_session ) - > dtmf_data . dtmf_inqueue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
2008-02-25 16:41:28 +00:00
switch_safe_free ( pop ) ;
2007-12-22 00:32:20 +00:00
}
2008-05-27 04:30:03 +00:00
while ( switch_queue_trypop ( ( * rtp_session ) - > dtmf_data . dtmf_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
2008-02-25 16:41:28 +00:00
switch_safe_free ( pop ) ;
2007-12-22 00:32:20 +00:00
}
2007-03-29 22:31:56 +00:00
2007-05-04 23:29:35 +00:00
if ( ( * rtp_session ) - > jb ) {
2015-09-11 16:37:01 +00:00
switch_jb_destroy ( & ( * rtp_session ) - > jb ) ;
2007-05-04 23:29:35 +00:00
}
2014-12-17 00:48:07 +00:00
if ( ( * rtp_session ) - > vb ) {
2015-09-11 16:37:01 +00:00
switch_jb_destroy ( & ( * rtp_session ) - > vb ) ;
2014-12-17 00:48:07 +00:00
}
2015-01-09 19:36:57 +00:00
if ( ( * rtp_session ) - > vbw ) {
2015-09-11 16:37:01 +00:00
switch_jb_destroy ( & ( * rtp_session ) - > vbw ) ;
2015-01-09 19:36:57 +00:00
}
2013-02-03 05:57:27 +00:00
if ( ( * rtp_session ) - > dtls & & ( * rtp_session ) - > dtls = = ( * rtp_session ) - > rtcp_dtls ) {
( * rtp_session ) - > rtcp_dtls = NULL ;
}
if ( ( * rtp_session ) - > dtls ) {
free_dtls ( & ( * rtp_session ) - > dtls ) ;
}
if ( ( * rtp_session ) - > rtcp_dtls ) {
free_dtls ( & ( * rtp_session ) - > rtcp_dtls ) ;
}
2008-07-03 18:50:15 +00:00
sock = ( * rtp_session ) - > sock_input ;
( * rtp_session ) - > sock_input = NULL ;
2008-01-18 00:10:23 +00:00
switch_socket_close ( sock ) ;
2010-02-06 03:38:24 +00:00
if ( ( * rtp_session ) - > sock_output ! = sock ) {
2008-07-03 18:50:15 +00:00
sock = ( * rtp_session ) - > sock_output ;
( * rtp_session ) - > sock_output = NULL ;
switch_socket_close ( sock ) ;
}
2006-09-19 20:04:35 +00:00
2010-06-17 15:23:37 +00:00
if ( ( sock = ( * rtp_session ) - > rtcp_sock_input ) ) {
( * rtp_session ) - > rtcp_sock_input = NULL ;
switch_socket_close ( sock ) ;
if ( ( * rtp_session ) - > rtcp_sock_output & & ( * rtp_session ) - > rtcp_sock_output ! = sock ) {
if ( ( sock = ( * rtp_session ) - > rtcp_sock_output ) ) {
( * rtp_session ) - > rtcp_sock_output = NULL ;
switch_socket_close ( sock ) ;
}
}
}
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2012-12-18 22:06:29 +00:00
if ( ( * rtp_session ) - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] ) {
2013-02-03 05:57:27 +00:00
for ( x = 0 ; x < 2 ; x + + ) {
if ( ( * rtp_session ) - > send_ctx [ x ] ) {
srtp_dealloc ( ( * rtp_session ) - > send_ctx [ x ] ) ;
( * rtp_session ) - > send_ctx [ x ] = NULL ;
}
}
2012-12-18 22:06:29 +00:00
( * rtp_session ) - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] = 0 ;
2008-01-17 04:16:04 +00:00
}
2012-12-18 22:06:29 +00:00
if ( ( * rtp_session ) - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] ) {
2013-02-03 05:57:27 +00:00
for ( x = 0 ; x < 2 ; x + + ) {
if ( ( * rtp_session ) - > recv_ctx [ x ] ) {
srtp_dealloc ( ( * rtp_session ) - > recv_ctx [ x ] ) ;
( * rtp_session ) - > recv_ctx [ x ] = NULL ;
}
}
2012-12-18 22:06:29 +00:00
( * rtp_session ) - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] = 0 ;
2006-04-10 19:55:53 +00:00
}
2011-05-02 16:33:57 +00:00
# endif
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
/* ZRTP */
2012-12-18 22:06:29 +00:00
if ( zrtp_on & & ! ( * rtp_session ) - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] ) {
2009-09-03 14:48:02 +00:00
2010-02-03 19:19:10 +00:00
if ( ( * rtp_session ) - > zrtp_stream ! = NULL ) {
zrtp_stream_stop ( ( * rtp_session ) - > zrtp_stream ) ;
2009-09-03 14:48:02 +00:00
}
2012-12-18 22:06:29 +00:00
if ( ( * rtp_session ) - > flags [ SWITCH_ZRTP_FLAG_SECURE_SEND ] ) {
( * rtp_session ) - > flags [ SWITCH_ZRTP_FLAG_SECURE_SEND ] = 0 ;
2009-05-20 23:04:05 +00:00
}
2006-04-10 19:55:53 +00:00
2012-12-18 22:06:29 +00:00
if ( ( * rtp_session ) - > flags [ SWITCH_ZRTP_FLAG_SECURE_RECV ] ) {
( * rtp_session ) - > flags [ SWITCH_ZRTP_FLAG_SECURE_RECV ] = 0 ;
2009-05-20 23:04:05 +00:00
}
if ( ( * rtp_session ) - > zrtp_session ) {
zrtp_session_down ( ( * rtp_session ) - > zrtp_session ) ;
( * rtp_session ) - > zrtp_session = NULL ;
}
}
# endif
2006-09-12 22:23:45 +00:00
if ( ( * rtp_session ) - > timer . timer_interface ) {
switch_core_timer_destroy ( & ( * rtp_session ) - > timer ) ;
}
2007-12-20 15:41:45 +00:00
switch_rtp_release_port ( ( * rtp_session ) - > rx_host , ( * rtp_session ) - > rx_port ) ;
2006-09-19 20:04:35 +00:00
switch_mutex_unlock ( ( * rtp_session ) - > flag_mutex ) ;
2008-01-18 18:14:53 +00:00
2006-04-03 21:00:13 +00:00
return ;
}
2012-04-18 14:55:58 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_interdigit_delay ( switch_rtp_t * rtp_session , uint32_t delay )
{
rtp_session - > interdigit_delay = delay ;
}
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( switch_socket_t * ) switch_rtp_get_rtp_socket ( switch_rtp_t * rtp_session )
2006-04-03 21:00:13 +00:00
{
2008-07-03 18:50:15 +00:00
return rtp_session - > sock_input ;
2006-04-03 21:00:13 +00:00
}
2007-03-09 16:30:34 +00:00
SWITCH_DECLARE ( uint32_t ) switch_rtp_get_default_samples_per_interval ( switch_rtp_t * rtp_session )
2006-04-07 17:32:14 +00:00
{
2007-03-09 16:30:34 +00:00
return rtp_session - > samples_per_interval ;
2006-04-07 17:32:14 +00:00
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_default_payload ( switch_rtp_t * rtp_session , switch_payload_t payload )
2006-04-06 21:08:30 +00:00
{
rtp_session - > payload = payload ;
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( uint32_t ) switch_rtp_get_default_payload ( switch_rtp_t * rtp_session )
2006-04-06 21:08:30 +00:00
{
return rtp_session - > payload ;
}
2014-06-28 00:32:41 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_invalid_handler ( switch_rtp_t * rtp_session , switch_rtp_invalid_handler_t on_invalid )
2006-04-03 21:00:13 +00:00
{
rtp_session - > invalid_handler = on_invalid ;
}
2012-12-18 22:06:29 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_flags ( switch_rtp_t * rtp_session , switch_rtp_flag_t flags [ SWITCH_RTP_FLAG_INVALID ] )
{
int i ;
for ( i = 0 ; i < SWITCH_RTP_FLAG_INVALID ; i + + ) {
if ( flags [ i ] ) {
rtp_session - > flags [ i ] = flags [ i ] ;
if ( i = = SWITCH_RTP_FLAG_AUTOADJ ) {
rtp_session - > autoadj_window = 20 ;
2014-07-16 00:25:56 +00:00
rtp_session - > autoadj_threshold = 10 ;
2012-12-18 22:06:29 +00:00
rtp_session - > autoadj_tally = 0 ;
2014-07-16 00:25:56 +00:00
if ( rtp_session - > session ) {
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
const char * x = switch_channel_get_variable ( channel , " rtp_auto_adjust_threshold " ) ;
if ( x & & * x ) {
int xn = atoi ( x ) ;
if ( xn > 0 & & xn < = 65535 ) {
rtp_session - > autoadj_window = xn * 2 ;
rtp_session - > autoadj_threshold = xn ;
}
}
}
2012-12-18 22:06:29 +00:00
rtp_flush_read_buffer ( rtp_session , SWITCH_RTP_FLUSH_ONCE ) ;
} else if ( i = = SWITCH_RTP_FLAG_NOBLOCK & & rtp_session - > sock_input ) {
switch_socket_opt_set ( rtp_session - > sock_input , SWITCH_SO_NONBLOCK , TRUE ) ;
}
}
}
}
SWITCH_DECLARE ( void ) switch_rtp_clear_flags ( switch_rtp_t * rtp_session , switch_rtp_flag_t flags [ SWITCH_RTP_FLAG_INVALID ] )
{
int i ;
for ( i = 0 ; i < SWITCH_RTP_FLAG_INVALID ; i + + ) {
if ( flags [ i ] ) {
rtp_session - > flags [ i ] = 0 ;
}
}
}
SWITCH_DECLARE ( void ) switch_rtp_set_flag ( switch_rtp_t * rtp_session , switch_rtp_flag_t flag )
2006-04-17 18:25:43 +00:00
{
2012-12-18 22:06:29 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
rtp_session - > flags [ flag ] = 1 ;
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
2014-01-30 00:08:27 +00:00
if ( flag = = SWITCH_RTP_FLAG_DTMF_ON ) {
rtp_session - > stats . inbound . last_processed_seq = 0 ;
} else if ( flag = = SWITCH_RTP_FLAG_FLUSH ) {
reset_jitter_seq ( rtp_session ) ;
} else if ( flag = = SWITCH_RTP_FLAG_AUTOADJ ) {
2007-05-16 17:47:24 +00:00
rtp_session - > autoadj_window = 20 ;
2014-07-16 00:25:56 +00:00
rtp_session - > autoadj_threshold = 10 ;
2007-05-16 17:47:24 +00:00
rtp_session - > autoadj_tally = 0 ;
2014-07-16 00:25:56 +00:00
if ( rtp_session - > session ) {
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
const char * x = switch_channel_get_variable ( channel , " rtp_auto_adjust_threshold " ) ;
if ( x & & * x ) {
int xn = atoi ( x ) ;
if ( xn > 0 & & xn < = 65535 ) {
rtp_session - > autoadj_window = xn * 2 ;
rtp_session - > autoadj_threshold = xn ;
}
}
}
2015-05-01 20:40:50 +00:00
2009-10-30 00:16:36 +00:00
rtp_flush_read_buffer ( rtp_session , SWITCH_RTP_FLUSH_ONCE ) ;
2015-05-01 20:40:50 +00:00
2013-08-21 21:30:59 +00:00
if ( rtp_session - > jb ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > jb ) ;
2013-08-21 21:30:59 +00:00
}
2012-12-18 22:06:29 +00:00
} else if ( flag = = SWITCH_RTP_FLAG_NOBLOCK & & rtp_session - > sock_input ) {
2011-03-09 21:17:09 +00:00
switch_socket_opt_set ( rtp_session - > sock_input , SWITCH_SO_NONBLOCK , TRUE ) ;
2007-05-16 17:47:24 +00:00
}
2011-03-09 21:17:09 +00:00
2006-04-17 18:25:43 +00:00
}
2008-05-13 20:36:23 +00:00
SWITCH_DECLARE ( uint32_t ) switch_rtp_test_flag ( switch_rtp_t * rtp_session , switch_rtp_flag_t flags )
2006-04-17 18:25:43 +00:00
{
2012-12-18 22:06:29 +00:00
return ( uint32_t ) rtp_session - > flags [ flags ] ;
2006-04-17 18:25:43 +00:00
}
2012-12-18 22:06:29 +00:00
SWITCH_DECLARE ( void ) switch_rtp_clear_flag ( switch_rtp_t * rtp_session , switch_rtp_flag_t flag )
2006-04-17 18:25:43 +00:00
{
2011-03-09 21:17:09 +00:00
2012-12-18 22:06:29 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
rtp_session - > flags [ flag ] = 0 ;
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
2014-01-30 00:08:27 +00:00
if ( flag = = SWITCH_RTP_FLAG_DTMF_ON ) {
rtp_session - > stats . inbound . last_processed_seq = 0 ;
2014-06-03 00:09:10 +00:00
} else if ( flag = = SWITCH_RTP_FLAG_PAUSE ) {
reset_jitter_seq ( rtp_session ) ;
2014-01-30 00:08:27 +00:00
} else if ( flag = = SWITCH_RTP_FLAG_NOBLOCK & & rtp_session - > sock_input ) {
2011-03-09 21:17:09 +00:00
switch_socket_opt_set ( rtp_session - > sock_input , SWITCH_SO_NONBLOCK , FALSE ) ;
}
2006-04-17 18:25:43 +00:00
}
2006-04-07 17:32:14 +00:00
2011-09-01 00:30:51 +00:00
static void set_dtmf_delay ( switch_rtp_t * rtp_session , uint32_t ms , uint32_t max_ms )
2011-08-29 16:04:38 +00:00
{
2011-09-01 00:30:51 +00:00
int upsamp , max_upsamp ;
2013-01-15 05:17:28 +00:00
2012-04-10 21:17:16 +00:00
2011-09-01 00:30:51 +00:00
if ( ! max_ms ) max_ms = ms ;
2011-08-29 16:04:38 +00:00
2011-09-01 00:30:51 +00:00
upsamp = ms * ( rtp_session - > samples_per_second / 1000 ) ;
max_upsamp = max_ms * ( rtp_session - > samples_per_second / 1000 ) ;
rtp_session - > queue_delay = upsamp ;
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) {
2011-09-01 00:30:51 +00:00
rtp_session - > max_next_write_samplecount = rtp_session - > timer . samplecount + max_upsamp ;
2012-04-18 14:55:58 +00:00
rtp_session - > next_write_samplecount = rtp_session - > timer . samplecount + upsamp ;
2012-05-08 17:52:47 +00:00
rtp_session - > last_write_ts + = upsamp ;
2011-08-29 16:04:38 +00:00
}
2011-09-01 00:30:51 +00:00
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Queue digit delay of %dms \n " , ms ) ;
2011-08-29 16:04:38 +00:00
}
2013-01-15 05:17:28 +00:00
static void do_2833 ( switch_rtp_t * rtp_session )
2006-05-04 17:51:53 +00:00
{
switch_frame_flag_t flags = 0 ;
2007-03-09 16:30:34 +00:00
uint32_t samples = rtp_session - > samples_per_interval ;
2006-05-04 17:51:53 +00:00
2011-09-01 00:30:51 +00:00
if ( ! rtp_session - > last_write_ts ) {
return ;
}
2006-05-04 17:51:53 +00:00
if ( rtp_session - > dtmf_data . out_digit_dur > 0 ) {
2008-01-08 22:30:52 +00:00
int x , loops = 1 ;
2011-03-10 02:06:27 +00:00
2006-05-04 17:51:53 +00:00
rtp_session - > dtmf_data . out_digit_sofar + = samples ;
2008-01-11 21:59:17 +00:00
rtp_session - > dtmf_data . out_digit_sub_sofar + = samples ;
2006-05-04 17:51:53 +00:00
2008-01-11 21:59:17 +00:00
if ( rtp_session - > dtmf_data . out_digit_sub_sofar > 0xFFFF ) {
rtp_session - > dtmf_data . out_digit_sub_sofar = samples ;
2008-01-08 21:43:09 +00:00
rtp_session - > dtmf_data . timestamp_dtmf + = 0xFFFF ;
}
2006-05-04 17:51:53 +00:00
if ( rtp_session - > dtmf_data . out_digit_sofar > = rtp_session - > dtmf_data . out_digit_dur ) {
rtp_session - > dtmf_data . out_digit_packet [ 1 ] | = 0x80 ;
loops = 3 ;
}
2008-05-27 04:30:03 +00:00
2008-01-11 21:59:17 +00:00
rtp_session - > dtmf_data . out_digit_packet [ 2 ] = ( unsigned char ) ( rtp_session - > dtmf_data . out_digit_sub_sofar > > 8 ) ;
rtp_session - > dtmf_data . out_digit_packet [ 3 ] = ( unsigned char ) rtp_session - > dtmf_data . out_digit_sub_sofar ;
2008-01-08 21:43:09 +00:00
2006-05-04 17:51:53 +00:00
for ( x = 0 ; x < loops ; x + + ) {
2009-04-03 21:48:52 +00:00
switch_size_t wrote = switch_rtp_write_manual ( rtp_session ,
2010-02-06 03:38:24 +00:00
rtp_session - > dtmf_data . out_digit_packet , 4 , 0 ,
2009-04-03 21:48:52 +00:00
rtp_session - > te , rtp_session - > dtmf_data . timestamp_dtmf , & flags ) ;
2009-04-15 15:08:21 +00:00
rtp_session - > stats . outbound . raw_bytes + = wrote ;
rtp_session - > stats . outbound . dtmf_packet_count + + ;
2009-04-03 21:48:52 +00:00
2011-09-01 00:30:51 +00:00
if ( loops = = 1 ) {
rtp_session - > last_write_ts + = samples ;
if ( rtp_session - > rtp_bugs & RTP_BUG_SONUS_SEND_INVALID_TIMESTAMP_2833 ) {
rtp_session - > dtmf_data . timestamp_dtmf = rtp_session - > last_write_ts ;
}
}
2009-04-03 21:48:52 +00:00
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Send %s packet for [%c] ts=%u dur=%d/%d/%d seq=%d lw=%u \n " ,
2008-05-27 04:30:03 +00:00
loops = = 1 ? " middle " : " end " , rtp_session - > dtmf_data . out_digit ,
2008-01-11 21:59:17 +00:00
rtp_session - > dtmf_data . timestamp_dtmf ,
2008-05-27 04:30:03 +00:00
rtp_session - > dtmf_data . out_digit_sofar ,
2011-09-01 00:30:51 +00:00
rtp_session - > dtmf_data . out_digit_sub_sofar , rtp_session - > dtmf_data . out_digit_dur , rtp_session - > seq , rtp_session - > last_write_ts ) ;
2006-05-04 17:51:53 +00:00
}
2007-03-08 22:18:33 +00:00
2007-07-06 16:19:40 +00:00
if ( loops ! = 1 ) {
2011-09-01 00:30:51 +00:00
rtp_session - > sending_dtmf = 0 ;
2011-08-30 20:00:07 +00:00
rtp_session - > need_mark = 1 ;
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) {
2008-01-11 21:59:17 +00:00
rtp_session - > last_write_samplecount = rtp_session - > timer . samplecount ;
}
2011-09-01 00:30:51 +00:00
2008-01-11 21:59:17 +00:00
rtp_session - > dtmf_data . out_digit_dur = 0 ;
2012-04-18 14:55:58 +00:00
if ( rtp_session - > interdigit_delay ) {
set_dtmf_delay ( rtp_session , rtp_session - > interdigit_delay , rtp_session - > interdigit_delay * 10 ) ;
}
2011-08-24 20:36:59 +00:00
return ;
2007-03-08 22:18:33 +00:00
}
2006-05-04 17:51:53 +00:00
}
2007-03-30 00:13:31 +00:00
if ( ! rtp_session - > dtmf_data . out_digit_dur & & rtp_session - > dtmf_data . dtmf_queue & & switch_queue_size ( rtp_session - > dtmf_data . dtmf_queue ) ) {
2006-05-04 17:51:53 +00:00
void * pop ;
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) {
2012-04-18 14:55:58 +00:00
if ( rtp_session - > timer . samplecount < rtp_session - > next_write_samplecount ) {
2011-09-01 00:30:51 +00:00
return ;
}
2011-11-14 18:37:45 +00:00
2011-09-01 00:30:51 +00:00
if ( rtp_session - > timer . samplecount > = rtp_session - > max_next_write_samplecount ) {
rtp_session - > queue_delay = 0 ;
}
2011-11-14 18:37:45 +00:00
} else if ( rtp_session - > queue_delay ) {
if ( rtp_session - > delay_samples > = rtp_session - > samples_per_interval ) {
rtp_session - > delay_samples - = rtp_session - > samples_per_interval ;
} else {
rtp_session - > delay_samples = 0 ;
}
if ( ! rtp_session - > delay_samples ) {
rtp_session - > queue_delay = 0 ;
2011-09-01 00:30:51 +00:00
}
}
if ( rtp_session - > queue_delay ) {
return ;
}
2011-08-31 17:03:57 +00:00
if ( ! rtp_session - > sending_dtmf ) {
2012-04-20 13:03:03 +00:00
rtp_session - > sending_dtmf = 1 ;
2008-01-14 21:51:31 +00:00
}
2008-05-27 04:30:03 +00:00
2009-12-12 00:04:07 +00:00
if ( switch_queue_trypop ( rtp_session - > dtmf_data . dtmf_queue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
2007-12-22 00:32:20 +00:00
switch_dtmf_t * rdigit = pop ;
2009-04-03 21:48:52 +00:00
switch_size_t wrote ;
2011-08-29 16:04:38 +00:00
if ( rdigit - > digit = = ' w ' ) {
2011-09-01 00:30:51 +00:00
set_dtmf_delay ( rtp_session , 500 , 0 ) ;
2011-08-29 16:04:38 +00:00
free ( rdigit ) ;
return ;
}
if ( rdigit - > digit = = ' W ' ) {
2011-09-01 00:30:51 +00:00
set_dtmf_delay ( rtp_session , 1000 , 0 ) ;
2011-08-29 16:04:38 +00:00
free ( rdigit ) ;
return ;
}
2008-01-09 17:20:05 +00:00
2011-08-31 17:03:57 +00:00
2006-05-04 17:51:53 +00:00
memset ( rtp_session - > dtmf_data . out_digit_packet , 0 , 4 ) ;
2008-01-08 21:43:09 +00:00
rtp_session - > dtmf_data . out_digit_sofar = samples ;
2008-01-11 21:59:17 +00:00
rtp_session - > dtmf_data . out_digit_sub_sofar = samples ;
2006-05-04 17:51:53 +00:00
rtp_session - > dtmf_data . out_digit_dur = rdigit - > duration ;
rtp_session - > dtmf_data . out_digit = rdigit - > digit ;
2007-03-29 22:31:56 +00:00
rtp_session - > dtmf_data . out_digit_packet [ 0 ] = ( unsigned char ) switch_char_to_rfc2833 ( rdigit - > digit ) ;
2013-10-17 16:33:55 +00:00
rtp_session - > dtmf_data . out_digit_packet [ 1 ] = 13 ;
2008-03-03 23:13:12 +00:00
rtp_session - > dtmf_data . out_digit_packet [ 2 ] = ( unsigned char ) ( rtp_session - > dtmf_data . out_digit_sub_sofar > > 8 ) ;
rtp_session - > dtmf_data . out_digit_packet [ 3 ] = ( unsigned char ) rtp_session - > dtmf_data . out_digit_sub_sofar ;
2006-05-04 17:51:53 +00:00
2010-02-06 03:38:24 +00:00
2011-09-01 00:30:51 +00:00
rtp_session - > dtmf_data . timestamp_dtmf = rtp_session - > last_write_ts + samples ;
rtp_session - > last_write_ts = rtp_session - > dtmf_data . timestamp_dtmf ;
2014-02-28 23:55:04 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] = 0 ;
2009-05-20 23:04:05 +00:00
wrote = switch_rtp_write_manual ( rtp_session ,
rtp_session - > dtmf_data . out_digit_packet ,
4 ,
rtp_session - > rtp_bugs & RTP_BUG_CISCO_SKIP_MARK_BIT_2833 ? 0 : 1 ,
rtp_session - > te , rtp_session - > dtmf_data . timestamp_dtmf , & flags ) ;
2010-02-06 03:38:24 +00:00
2011-09-01 00:30:51 +00:00
2009-04-15 15:08:21 +00:00
rtp_session - > stats . outbound . raw_bytes + = wrote ;
rtp_session - > stats . outbound . dtmf_packet_count + + ;
2011-09-01 00:30:51 +00:00
2014-04-19 01:44:40 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Send start packet for [%c] ts=%u dur=%d/%d/%d seq=%d lw=%u \n " ,
2008-05-27 04:30:03 +00:00
rtp_session - > dtmf_data . out_digit ,
2008-01-11 21:59:17 +00:00
rtp_session - > dtmf_data . timestamp_dtmf ,
2008-05-27 04:30:03 +00:00
rtp_session - > dtmf_data . out_digit_sofar ,
2011-09-01 00:30:51 +00:00
rtp_session - > dtmf_data . out_digit_sub_sofar , rtp_session - > dtmf_data . out_digit_dur , rtp_session - > seq , rtp_session - > last_write_ts ) ;
2008-01-11 21:59:17 +00:00
2006-05-04 17:51:53 +00:00
free ( rdigit ) ;
}
}
}
2009-04-16 22:13:55 +00:00
SWITCH_DECLARE ( void ) rtp_flush_read_buffer ( switch_rtp_t * rtp_session , switch_rtp_flush_t flush )
2008-12-02 21:33:01 +00:00
{
2011-09-06 16:30:28 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] | |
rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
2012-12-14 22:52:27 +00:00
return ;
}
2011-09-06 16:30:28 +00:00
if ( switch_rtp_ready ( rtp_session ) ) {
2014-02-28 23:55:04 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] = 1 ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_FLUSH ] = 1 ;
2014-01-30 00:08:27 +00:00
reset_jitter_seq ( rtp_session ) ;
2012-12-05 19:17:50 +00:00
2012-12-14 22:52:27 +00:00
switch ( flush ) {
case SWITCH_RTP_FLUSH_STICK :
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_STICKY_FLUSH ) ;
2012-12-14 22:52:27 +00:00
break ;
case SWITCH_RTP_FLUSH_UNSTICK :
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_STICKY_FLUSH ) ;
2012-12-14 22:52:27 +00:00
break ;
default :
2011-09-06 16:30:28 +00:00
break ;
2009-04-16 22:13:55 +00:00
}
2008-12-03 16:52:58 +00:00
}
2008-12-02 21:33:01 +00:00
}
2014-03-06 21:48:50 +00:00
static int jb_valid ( switch_rtp_t * rtp_session )
{
if ( rtp_session - > ice . ice_user ) {
if ( ! rtp_session - > ice . ready & & rtp_session - > ice . rready ) {
return 0 ;
}
}
if ( rtp_session - > dtls & & rtp_session - > dtls - > state ! = DS_READY ) {
return 0 ;
}
return 1 ;
}
2015-10-04 21:53:43 +00:00
static switch_size_t do_flush ( switch_rtp_t * rtp_session , int force , switch_size_t bytes_in )
2008-11-25 17:53:35 +00:00
{
int was_blocking = 0 ;
switch_size_t bytes ;
2012-11-29 05:12:35 +00:00
uint32_t flushed = 0 ;
2015-10-05 01:05:50 +00:00
switch_size_t bytes_out = 0 ;
2013-06-18 00:52:37 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
2015-10-04 21:53:43 +00:00
return 0 ;
2008-11-25 17:53:35 +00:00
}
2015-05-01 20:40:50 +00:00
2014-01-30 00:08:27 +00:00
reset_jitter_seq ( rtp_session ) ;
2013-06-18 00:52:37 +00:00
if ( ! force ) {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] | |
2013-12-30 19:21:45 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] | |
rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ]
2013-06-18 00:52:37 +00:00
) {
2016-09-22 23:52:48 +00:00
return bytes_in ;
2013-06-18 00:52:37 +00:00
}
}
2012-11-29 05:12:35 +00:00
2008-11-25 17:53:35 +00:00
READ_INC ( rtp_session ) ;
2014-03-06 21:48:50 +00:00
if ( switch_rtp_ready ( rtp_session ) ) {
if ( rtp_session - > jb & & ! rtp_session - > pause_jb & & jb_valid ( rtp_session ) ) {
2015-10-04 21:53:43 +00:00
//switch_jb_reset(rtp_session->jb);
2015-10-05 01:05:50 +00:00
bytes_out = bytes_in ;
goto end ;
2015-05-01 20:40:50 +00:00
}
if ( rtp_session - > vbw ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > vbw ) ;
2015-10-05 01:05:50 +00:00
}
if ( rtp_session - > vb ) {
//switch_jb_reset(rtp_session->vb);
bytes_out = bytes_in ;
2016-03-17 13:55:00 +00:00
goto end ;
2014-03-06 21:48:50 +00:00
}
2015-05-23 03:08:27 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DEBUG_RTP_READ ] ) {
2013-08-08 00:19:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) ,
2015-05-01 20:40:50 +00:00
SWITCH_LOG_CONSOLE , " %s FLUSH \n " ,
rtp_session - > session ? switch_channel_get_name ( switch_core_session_get_channel ( rtp_session - > session ) ) : " NoName "
) ;
2009-10-29 17:29:05 +00:00
}
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_NOBLOCK ] ) {
2008-11-26 15:22:26 +00:00
was_blocking = 1 ;
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_NOBLOCK ) ;
2008-11-26 15:22:26 +00:00
switch_socket_opt_set ( rtp_session - > sock_input , SWITCH_SO_NONBLOCK , TRUE ) ;
}
2010-02-06 03:38:24 +00:00
2008-11-26 15:22:26 +00:00
do {
if ( switch_rtp_ready ( rtp_session ) ) {
bytes = sizeof ( rtp_msg_t ) ;
2011-04-22 21:43:29 +00:00
switch_socket_recvfrom ( rtp_session - > from_addr , rtp_session - > sock_input , 0 , ( void * ) & rtp_session - > recv_msg , & bytes ) ;
2012-12-05 19:17:50 +00:00
2009-04-03 21:48:52 +00:00
if ( bytes ) {
2011-01-21 21:03:19 +00:00
int do_cng = 0 ;
/* Make sure to handle RFC2833 packets, even if we're flushing the packets */
2015-10-06 14:34:19 +00:00
if ( bytes > rtp_header_len & & rtp_session - > last_rtp_hdr . pt = = rtp_session - > recv_te ) {
2011-01-21 21:03:19 +00:00
handle_rfc2833 ( rtp_session , bytes , & do_cng ) ;
# ifdef DEBUG_2833
2012-11-21 19:59:23 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " *** RTP packet handled in flush loop %d *** \n " , do_cng ) ;
2011-01-21 21:03:19 +00:00
# endif
}
2010-12-10 23:47:24 +00:00
flushed + + ;
2009-04-15 15:08:21 +00:00
rtp_session - > stats . inbound . raw_bytes + = bytes ;
rtp_session - > stats . inbound . flush_packet_count + + ;
rtp_session - > stats . inbound . packet_count + + ;
2009-04-03 21:48:52 +00:00
}
2008-11-26 15:22:26 +00:00
} else {
break ;
}
2010-02-06 03:38:24 +00:00
} while ( bytes > 0 ) ;
2008-11-26 15:22:26 +00:00
if ( was_blocking & & switch_rtp_ready ( rtp_session ) ) {
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_NOBLOCK ) ;
2008-11-26 15:22:26 +00:00
switch_socket_opt_set ( rtp_session - > sock_input , SWITCH_SO_NONBLOCK , FALSE ) ;
}
2015-05-23 03:08:27 +00:00
2010-02-06 03:38:24 +00:00
2015-05-23 03:08:27 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & rtp_session - > session ) {
//int type = 1; // sum flags: 1 encoder; 2; decoder
//switch_core_media_codec_control(rtp_session->session, SWITCH_MEDIA_TYPE_VIDEO, SWITCH_IO_READ, SCC_VIDEO_RESET, SCCT_INT, (void *)&type, NULL, NULL);
switch_core_session_request_video_refresh ( rtp_session - > session ) ;
}
2015-05-06 19:23:10 +00:00
}
2015-10-05 01:05:50 +00:00
end :
2015-05-23 03:08:27 +00:00
2008-11-25 17:53:35 +00:00
READ_DEC ( rtp_session ) ;
2015-10-04 21:53:43 +00:00
2015-10-05 01:05:50 +00:00
return bytes_out ;
2008-11-25 17:53:35 +00:00
}
2013-11-07 22:48:00 +00:00
static int check_recv_payload ( switch_rtp_t * rtp_session )
{
2013-12-05 22:35:49 +00:00
int ok = 1 ;
2013-11-07 22:48:00 +00:00
if ( rtp_session - > pmaps & & * rtp_session - > pmaps ) {
payload_map_t * pmap ;
2013-12-05 22:35:49 +00:00
ok = 0 ;
2013-11-07 22:48:00 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
2014-02-19 02:05:29 +00:00
2013-11-07 22:48:00 +00:00
for ( pmap = * rtp_session - > pmaps ; pmap & & pmap - > allocated ; pmap = pmap - > next ) {
if ( ! pmap - > negotiated ) {
continue ;
}
2013-11-22 03:55:45 +00:00
2015-10-06 14:34:19 +00:00
if ( rtp_session - > last_rtp_hdr . pt = = pmap - > pt ) {
2013-11-07 22:48:00 +00:00
ok = 1 ;
}
}
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
}
return ok ;
}
2015-10-06 14:34:19 +00:00
static int get_recv_payload ( switch_rtp_t * rtp_session )
{
int r = - 1 ;
if ( rtp_session - > pmaps & & * rtp_session - > pmaps ) {
payload_map_t * pmap ;
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
for ( pmap = * rtp_session - > pmaps ; pmap & & pmap - > allocated ; pmap = pmap - > next ) {
if ( pmap - > negotiated ) {
r = pmap - > pt ;
break ;
}
}
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
}
return r ;
}
2008-10-01 18:02:46 +00:00
# define return_cng_frame() do_cng = 1; goto timer_check
2015-01-21 22:11:23 +00:00
static switch_status_t read_rtp_packet ( switch_rtp_t * rtp_session , switch_size_t * bytes , switch_frame_flag_t * flags ,
switch_status_t poll_status , switch_bool_t return_jb_packet )
2009-03-31 19:10:43 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2013-04-10 00:43:10 +00:00
uint32_t ts = 0 ;
2013-06-18 00:52:37 +00:00
unsigned char * b = NULL ;
2013-04-11 23:11:06 +00:00
int sync = 0 ;
2013-07-11 22:38:24 +00:00
switch_time_t now ;
2014-01-30 00:08:27 +00:00
switch_size_t xcheck_jitter = 0 ;
2015-10-04 21:53:43 +00:00
int tries = 0 ;
int block = 0 ;
2009-03-31 19:10:43 +00:00
switch_assert ( bytes ) ;
2011-02-25 17:59:45 +00:00
more :
2013-06-18 00:52:37 +00:00
2015-10-04 21:53:43 +00:00
tries + + ;
if ( tries > 20 ) {
2015-10-07 16:21:51 +00:00
if ( rtp_session - > jb & & ! rtp_session - > pause_jb & & jb_valid ( rtp_session ) ) {
switch_jb_reset ( rtp_session - > jb ) ;
}
rtp_session - > punts + + ;
rtp_session - > clean = 0 ;
* bytes = 0 ;
2015-10-04 21:53:43 +00:00
return SWITCH_STATUS_BREAK ;
}
if ( block ) {
int to = 20000 ;
int fdr = 0 ;
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
to = 100000 ;
} else {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & & rtp_session - > timer . interval ) {
to = rtp_session - > timer . interval * 1000 ;
}
}
2015-10-05 21:43:10 +00:00
poll_status = switch_poll ( rtp_session - > read_pollfd , 1 , & fdr , to ) ;
2015-10-04 21:53:43 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & & rtp_session - > timer . interval ) {
switch_core_timer_sync ( & rtp_session - > timer ) ;
}
2016-06-10 20:01:37 +00:00
if ( rtp_session - > session ) {
switch_ivr_parse_all_messages ( rtp_session - > session ) ;
}
2015-10-04 21:53:43 +00:00
block = 0 ;
}
2016-01-07 09:00:48 +00:00
* bytes = sizeof ( rtp_msg_t ) ;
2013-04-11 23:11:06 +00:00
sync = 0 ;
2012-12-14 01:49:02 +00:00
2015-10-05 23:59:58 +00:00
rtp_session - > has_rtp = 0 ;
rtp_session - > has_ice = 0 ;
rtp_session - > has_rtcp = 0 ;
if ( rtp_session - > dtls ) {
rtp_session - > dtls - > bytes = 0 ;
rtp_session - > dtls - > data = NULL ;
}
memset ( & rtp_session - > last_rtp_hdr , 0 , sizeof ( rtp_session - > last_rtp_hdr ) ) ;
2015-01-21 22:11:23 +00:00
if ( poll_status = = SWITCH_STATUS_SUCCESS ) {
status = switch_socket_recvfrom ( rtp_session - > from_addr , rtp_session - > sock_input , 0 , ( void * ) & rtp_session - > recv_msg , bytes ) ;
} else {
* bytes = 0 ;
}
2013-01-17 01:04:57 +00:00
2013-10-07 16:38:08 +00:00
if ( * bytes ) {
2015-10-05 23:59:58 +00:00
b = ( unsigned char * ) & rtp_session - > recv_msg ;
2016-02-24 04:01:38 +00:00
2015-10-09 17:57:36 +00:00
/* version 2 probably rtp, zrtp cookie present means zrtp */
rtp_session - > has_rtp = ( rtp_session - > recv_msg . header . version = = 2 | | ntohl ( * ( int * ) ( b + 4 ) ) = = ZRTP_MAGIC_COOKIE ) ;
2015-10-05 23:59:58 +00:00
if ( ( * b > = 20 ) & & ( * b < = 64 ) ) {
2015-10-20 16:24:47 +00:00
if ( rtp_session - > dtls ) {
rtp_session - > dtls - > bytes = * bytes ;
rtp_session - > dtls - > data = ( void * ) & rtp_session - > recv_msg ;
}
2015-10-05 23:59:58 +00:00
rtp_session - > has_ice = 0 ;
rtp_session - > has_rtp = 0 ;
rtp_session - > has_rtcp = 0 ;
2015-10-06 14:34:19 +00:00
} else if ( * b = = 0 | | * b = = 1 ) {
rtp_session - > has_ice = 1 ;
rtp_session - > has_rtp = 0 ;
rtp_session - > has_rtcp = 0 ;
} else {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
switch ( rtp_session - > recv_msg . header . pt ) {
case 64 : // 192 Full INTRA-frame request.
case 72 : // 200 Sender report.
case 73 : // 201 Receiver report.
case 74 : // 202 Source description.
case 75 : // 203 Goodbye.
case 76 : // 204 Application-defined.
case 77 : // 205 Transport layer FB message.
case 78 : // 206 Payload-specific FB message.
case 79 : // 207 Extended report.
rtp_session - > has_rtcp = 1 ;
rtp_session - > has_rtp = 0 ;
rtp_session - > has_ice = 0 ;
break ;
default :
if ( rtp_session - > rtcp_recv_msg_p - > header . version = = 2 & &
rtp_session - > rtcp_recv_msg_p - > header . type > 199 & & rtp_session - > rtcp_recv_msg_p - > header . type < 208 ) {
rtp_session - > has_rtcp = 1 ;
rtp_session - > has_rtp = 0 ;
rtp_session - > has_ice = 0 ;
}
break ;
}
2015-10-05 23:59:58 +00:00
}
}
if ( rtp_session - > has_rtp ) {
2015-10-07 16:21:51 +00:00
rtp_session - > missed_count = 0 ;
2015-01-21 01:20:20 +00:00
switch_cp_addr ( rtp_session - > rtp_from_addr , rtp_session - > from_addr ) ;
2015-05-13 16:50:04 +00:00
rtp_session - > last_rtp_hdr = rtp_session - > recv_msg . header ;
2016-08-17 23:18:53 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DETECT_SSRC ] ) {
//if (rtp_session->remote_ssrc != rtp_session->stats.rtcp.peer_ssrc && rtp_session->stats.rtcp.peer_ssrc) {
// rtp_session->remote_ssrc = rtp_session->stats.rtcp.peer_ssrc;
//}
if ( rtp_session - > remote_ssrc ! = rtp_session - > last_rtp_hdr . ssrc & & rtp_session - > last_rtp_hdr . ssrc ) {
rtp_session - > remote_ssrc = ntohl ( rtp_session - > last_rtp_hdr . ssrc ) ;
}
}
2015-01-21 01:20:20 +00:00
}
2013-10-07 16:38:08 +00:00
}
2015-04-28 19:44:26 +00:00
if ( ! rtp_session - > vb & & ( ! rtp_session - > jb | | rtp_session - > pause_jb | | ! jb_valid ( rtp_session ) ) ) {
2015-10-05 23:59:58 +00:00
if ( * bytes > rtp_header_len & & ( rtp_session - > has_rtp & & check_recv_payload ( rtp_session ) ) ) {
2014-02-28 21:50:12 +00:00
xcheck_jitter = * bytes ;
check_jitter ( rtp_session ) ;
}
2014-01-30 00:08:27 +00:00
}
2013-06-21 17:42:37 +00:00
if ( check_rtcp_and_ice ( rtp_session ) = = - 1 ) {
2015-05-23 03:08:27 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF CHECK FAIL\n");
//}
2013-06-21 17:42:37 +00:00
return SWITCH_STATUS_GENERR ;
}
2013-06-18 00:52:37 +00:00
2013-04-10 00:43:10 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
goto udptl ;
}
2013-06-18 00:52:37 +00:00
2013-02-11 19:42:50 +00:00
if ( * bytes ) {
2013-06-18 00:52:37 +00:00
* flags & = ~ SFF_PROXY_PACKET ;
2013-02-16 22:05:42 +00:00
2015-05-23 03:08:27 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
// switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_WARNING, "WTF BYTES %ld b=%d\n", *bytes, *b);
//}
2015-10-05 23:59:58 +00:00
if ( rtp_session - > has_ice ) {
2013-02-11 19:42:50 +00:00
if ( rtp_session - > ice . ice_user ) {
handle_ice ( rtp_session , & rtp_session - > ice , ( void * ) & rtp_session - > recv_msg , * bytes ) ;
}
* bytes = 0 ;
2013-04-11 23:11:06 +00:00
sync = 1 ;
2013-02-11 19:42:50 +00:00
}
}
2013-02-01 20:29:40 +00:00
if ( rtp_session - > dtls ) {
2013-02-16 03:27:49 +00:00
if ( rtp_session - > rtcp_dtls & & rtp_session - > rtcp_dtls ! = rtp_session - > dtls ) {
rtp_session - > rtcp_dtls - > bytes = 0 ;
rtp_session - > rtcp_dtls - > data = NULL ;
do_dtls ( rtp_session , rtp_session - > rtcp_dtls ) ;
}
2013-02-01 20:29:40 +00:00
do_dtls ( rtp_session , rtp_session - > dtls ) ;
2013-02-02 06:15:09 +00:00
2015-03-04 23:33:23 +00:00
if ( rtp_session - > dtls & & rtp_session - > dtls - > bytes ) {
2013-02-02 06:15:09 +00:00
* bytes = 0 ;
2013-04-11 23:11:06 +00:00
sync = 1 ;
2013-02-02 06:15:09 +00:00
}
2013-02-01 20:29:40 +00:00
}
2013-02-06 15:46:03 +00:00
2013-02-01 20:29:40 +00:00
if ( status = = SWITCH_STATUS_SUCCESS & & * bytes ) {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
2013-02-06 15:46:03 +00:00
* flags & = ~ SFF_RTCP ;
2015-10-05 23:59:58 +00:00
if ( rtp_session - > has_rtcp ) {
2013-02-01 20:29:40 +00:00
* flags | = SFF_RTCP ;
2014-12-03 00:40:47 +00:00
2015-12-29 15:50:38 +00:00
# ifdef ENABLE_SRTP
2014-12-03 00:40:47 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] ) {
int sbytes = ( int ) * bytes ;
err_status_t stat = 0 ;
if ( ( stat = srtp_unprotect_rtcp ( rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtcp ] , & rtp_session - > rtcp_recv_msg_p - > header , & sbytes ) ) ) {
//++rtp_session->srtp_errs[rtp_session->srtp_idx_rtp]++;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " RTCP UNPROTECT ERR \n " ) ;
} else {
//rtp_session->srtp_errs[rtp_session->srtp_idx_rtp] = 0;
}
* bytes = sbytes ;
}
2015-12-29 15:50:38 +00:00
# endif
2013-02-01 20:29:40 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2013-01-17 01:04:57 +00:00
}
}
2015-10-05 23:59:58 +00:00
if ( ( * bytes & & ( ! rtp_write_ready ( rtp_session , * bytes , __LINE__ ) | | ! rtp_session - > has_rtp | | rtp_session - > has_rtcp ) ) | | sync ) {
rtp_session - > hot_hits = 0 ;
block = 1 ;
2014-11-24 23:39:10 +00:00
* bytes = 0 ;
goto more ;
}
2013-04-11 23:11:06 +00:00
2013-06-18 00:52:37 +00:00
if ( * bytes & & rtp_session - > flags [ SWITCH_RTP_FLAG_DEBUG_RTP_READ ] ) {
2013-08-08 00:19:05 +00:00
const char * tx_host ;
const char * old_host ;
const char * my_host ;
2013-06-18 00:52:37 +00:00
2015-08-27 18:42:52 +00:00
char bufa [ 50 ] , bufb [ 50 ] , bufc [ 50 ] ;
2013-06-18 00:52:37 +00:00
2015-01-21 01:20:20 +00:00
tx_host = switch_get_addr ( bufa , sizeof ( bufa ) , rtp_session - > rtp_from_addr ) ;
2013-08-08 00:19:05 +00:00
old_host = switch_get_addr ( bufb , sizeof ( bufb ) , rtp_session - > remote_addr ) ;
my_host = switch_get_addr ( bufc , sizeof ( bufc ) , rtp_session - > local_addr ) ;
2013-06-18 00:52:37 +00:00
2013-08-08 00:19:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG_CLEAN ( rtp_session - > session ) , SWITCH_LOG_CONSOLE ,
2015-01-09 19:36:57 +00:00
" R %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u seq=%u m=%d \n " ,
2013-08-08 00:19:05 +00:00
rtp_session - > session ? switch_channel_get_name ( switch_core_session_get_channel ( rtp_session - > session ) ) : " No-Name " ,
( long ) * bytes ,
my_host , switch_sockaddr_get_port ( rtp_session - > local_addr ) ,
old_host , rtp_session - > remote_port ,
2015-01-21 01:20:20 +00:00
tx_host , switch_sockaddr_get_port ( rtp_session - > rtp_from_addr ) ,
2015-10-05 23:59:58 +00:00
rtp_session - > last_rtp_hdr . pt , ntohl ( rtp_session - > last_rtp_hdr . ts ) , ntohs ( rtp_session - > last_rtp_hdr . seq ) ,
rtp_session - > last_rtp_hdr . m ) ;
2013-06-18 00:52:37 +00:00
}
2015-01-09 19:36:57 +00:00
# ifdef RTP_READ_PLOSS
{
int r = ( rand ( ) % 10000 ) + 1 ;
if ( r < = 200 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ALERT ,
2015-10-05 23:59:58 +00:00
" Simulate dropped packet ......... ts: %u seq: %u \n " , ntohl ( rtp_session - > last_rtp_hdr . ts ) , ntohs ( rtp_session - > last_rtp_hdr . seq ) ) ;
2015-01-09 19:36:57 +00:00
* bytes = 0 ;
}
}
# endif
2013-04-11 23:11:06 +00:00
2013-04-10 00:43:10 +00:00
udptl :
2013-07-11 22:38:24 +00:00
ts = 0 ;
2012-12-14 01:49:02 +00:00
rtp_session - > recv_msg . ebody = NULL ;
2013-07-11 22:38:24 +00:00
now = switch_micro_time_now ( ) ;
2011-01-21 21:03:19 +00:00
2011-03-21 19:31:10 +00:00
if ( * bytes ) {
2015-10-06 14:34:19 +00:00
uint16_t seq = ntohs ( ( uint16_t ) rtp_session - > last_rtp_hdr . seq ) ;
ts = ntohl ( rtp_session - > last_rtp_hdr . ts ) ;
2012-12-14 01:49:02 +00:00
# ifdef DEBUG_MISSED_SEQ
2011-01-21 21:03:19 +00:00
if ( rtp_session - > last_seq & & rtp_session - > last_seq + 1 ! = seq ) {
2012-11-29 05:12:35 +00:00
//2012-11-28 18:33:11.799070 [ERR] switch_rtp.c:2883 Missed -65536 RTP frames from sequence [65536] to [-1] (missed). Time since last read [20021]
2011-01-21 21:03:19 +00:00
switch_size_t flushed_packets_diff = rtp_session - > stats . inbound . flush_packet_count - rtp_session - > last_flush_packet_count ;
switch_size_t num_missed = ( switch_size_t ) seq - ( rtp_session - > last_seq + 1 ) ;
if ( num_missed = = 1 ) { /* We missed one packet */
2012-11-29 05:12:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Missed one RTP frame with sequence [%d]%s. Time since last read [%ld] \n " ,
2011-01-21 21:03:19 +00:00
rtp_session - > last_seq + 1 , ( flushed_packets_diff = = 1 ) ? " (flushed by FS) " : " (missed) " ,
2013-07-11 22:38:24 +00:00
rtp_session - > last_read_time ? now - rtp_session - > last_read_time : 0 ) ;
2011-01-21 21:03:19 +00:00
} else { /* We missed multiple packets */
if ( flushed_packets_diff = = 0 ) {
2012-11-29 05:12:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
" Missed %ld RTP frames from sequence [%d] to [%d] (missed). Time since last read [%ld] \n " ,
2011-01-21 21:03:19 +00:00
num_missed , rtp_session - > last_seq + 1 , seq - 1 ,
2013-07-11 22:38:24 +00:00
rtp_session - > last_read_time ? now - rtp_session - > last_read_time : 0 ) ;
2011-01-21 21:03:19 +00:00
} else if ( flushed_packets_diff = = num_missed ) {
2012-11-29 05:12:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
" Missed %ld RTP frames from sequence [%d] to [%d] (flushed by FS). Time since last read [%ld] \n " ,
2011-01-21 21:03:19 +00:00
num_missed , rtp_session - > last_seq + 1 , seq - 1 ,
2013-07-11 22:38:24 +00:00
rtp_session - > last_read_time ? now - rtp_session - > last_read_time : 0 ) ;
2011-01-21 21:03:19 +00:00
} else if ( num_missed > flushed_packets_diff ) {
2012-11-29 05:12:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
" Missed %ld RTP frames from sequence [%d] to [%d] (%ld packets flushed by FS, %ld packets missed). "
" Time since last read [%ld] \n " ,
2011-01-21 21:03:19 +00:00
num_missed , rtp_session - > last_seq + 1 , seq - 1 ,
flushed_packets_diff , num_missed - flushed_packets_diff ,
2013-07-11 22:38:24 +00:00
rtp_session - > last_read_time ? now - rtp_session - > last_read_time : 0 ) ;
2011-01-21 21:03:19 +00:00
} else {
2012-11-29 05:12:35 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR ,
" Missed %ld RTP frames from sequence [%d] to [%d] (%ld packets flushed by FS). Time since last read [%ld] \n " ,
2011-01-21 21:03:19 +00:00
num_missed , rtp_session - > last_seq + 1 , seq - 1 ,
2013-07-11 22:38:24 +00:00
flushed_packets_diff , rtp_session - > last_read_time ? now - rtp_session - > last_read_time : 0 ) ;
2011-01-21 21:03:19 +00:00
}
}
2012-12-14 01:49:02 +00:00
2011-01-21 21:03:19 +00:00
}
2012-12-14 01:49:02 +00:00
# endif
2011-01-21 21:03:19 +00:00
rtp_session - > last_seq = seq ;
2013-07-11 22:38:24 +00:00
2011-01-21 21:03:19 +00:00
2013-07-11 22:38:24 +00:00
rtp_session - > last_flush_packet_count = rtp_session - > stats . inbound . flush_packet_count ;
2014-01-15 00:56:17 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & now - rtp_session - > last_read_time > 5000000 ) {
2013-07-11 22:38:24 +00:00
switch_rtp_video_refresh ( rtp_session ) ;
}
rtp_session - > last_read_time = now ;
}
2011-01-21 21:03:19 +00:00
2013-06-18 00:52:37 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & &
2015-10-06 14:34:19 +00:00
* bytes & & rtp_session - > last_rtp_hdr . pt ! = rtp_session - > recv_te & &
2013-11-01 20:21:35 +00:00
ts & & ! rtp_session - > jb & & ! rtp_session - > pause_jb & & jb_valid ( rtp_session ) & & ts = = rtp_session - > last_cng_ts ) {
2010-12-23 02:38:57 +00:00
/* we already sent this frame..... */
* bytes = 0 ;
return SWITCH_STATUS_SUCCESS ;
}
2009-03-31 19:10:43 +00:00
2009-04-03 21:48:52 +00:00
if ( * bytes ) {
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
2011-03-18 21:58:52 +00:00
# ifdef ENABLE_ZRTP
2011-03-22 17:07:06 +00:00
/* ZRTP Recv */
2014-01-30 00:08:27 +00:00
if ( zrtp_on ) {
2012-01-25 05:38:53 +00:00
unsigned int sbytes = ( int ) * bytes ;
zrtp_status_t stat = 0 ;
stat = zrtp_process_srtp ( rtp_session - > zrtp_stream , ( void * ) & rtp_session - > recv_msg , & sbytes ) ;
switch ( stat ) {
case zrtp_status_ok :
* bytes = sbytes ;
break ;
case zrtp_status_drop :
2012-05-24 03:58:26 +00:00
/* switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Error: zRTP protection drop with code %d\n", stat); */
2012-01-25 05:38:53 +00:00
* bytes = 0 ;
return SWITCH_STATUS_SUCCESS ;
case zrtp_status_fail :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error: zRTP protection fail with code %d \n " , stat ) ;
return SWITCH_STATUS_FALSE ;
default :
break ;
}
2011-03-18 21:58:52 +00:00
}
# endif
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2015-10-05 23:59:58 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] & & rtp_session - > has_rtp & &
2013-11-07 22:48:00 +00:00
( check_recv_payload ( rtp_session ) | |
2015-10-06 14:34:19 +00:00
rtp_session - > last_rtp_hdr . pt = = rtp_session - > recv_te | |
rtp_session - > last_rtp_hdr . pt = = rtp_session - > cng_pt ) ) {
2015-10-05 23:59:58 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && (!rtp_session->ice.ice_user || rtp_session->has_rtp)) {
2011-03-22 17:07:06 +00:00
int sbytes = ( int ) * bytes ;
err_status_t stat = 0 ;
2015-04-07 23:02:24 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV_RESET ] | | ! rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtp ] ) {
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_SECURE_RECV_RESET ) ;
2013-02-03 05:57:27 +00:00
srtp_dealloc ( rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtp ] ) ;
rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtp ] = NULL ;
2015-04-07 23:02:24 +00:00
if ( ( stat = srtp_create ( & rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtp ] ,
& rtp_session - > recv_policy [ rtp_session - > srtp_idx_rtp ] ) ) | | ! rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtp ] ) {
2013-01-15 05:17:28 +00:00
2015-04-07 23:02:24 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] = 0 ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error! RE-Activating Secure RTP RECV \n " ) ;
2015-04-07 23:02:24 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] = 0 ;
2011-03-22 17:07:06 +00:00
return SWITCH_STATUS_FALSE ;
} else {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO , " RE-Activating Secure RTP RECV \n " ) ;
2013-02-03 05:57:27 +00:00
rtp_session - > srtp_errs [ rtp_session - > srtp_idx_rtp ] = 0 ;
2011-03-22 17:07:06 +00:00
}
2011-03-18 21:58:52 +00:00
}
2011-03-22 17:07:06 +00:00
if ( ! ( * flags & SFF_PLC ) ) {
2013-02-03 05:57:27 +00:00
stat = srtp_unprotect ( rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtp ] , & rtp_session - > recv_msg . header , & sbytes ) ;
2015-02-28 22:02:52 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_NACK ] & & stat = = err_status_replay_fail ) {
/* false alarm nack */
2015-04-08 19:16:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " REPLAY ERR, FALSE NACK \n " ) ;
2015-02-28 22:02:52 +00:00
stat = 0 ;
sbytes = 0 ;
* bytes = 0 ;
goto more ;
}
2011-03-22 17:07:06 +00:00
}
2011-03-18 21:58:52 +00:00
2011-03-22 17:07:06 +00:00
if ( stat & & rtp_session - > recv_msg . header . pt ! = rtp_session - > recv_te & & rtp_session - > recv_msg . header . pt ! = rtp_session - > cng_pt ) {
2014-06-28 03:43:08 +00:00
int errs = + + rtp_session - > srtp_errs [ rtp_session - > srtp_idx_rtp ] ;
if ( stat ! = 10 ) {
char * msg ;
if ( stat = = err_status_replay_fail ) msg = " replay check failed " ;
else if ( stat = = err_status_auth_fail ) msg = " auth check failed " ;
else msg = " " ;
2014-06-29 20:40:49 +00:00
if ( errs > = MAX_SRTP_ERRS ) {
2014-06-28 03:43:08 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR ,
" SRTP %s unprotect failed with code %d (%s) %ld bytes %d errors \n " ,
rtp_type ( rtp_session ) , stat , msg , ( long ) * bytes , errs ) ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR ,
" Ending call due to SRTP error \n " ) ;
switch_channel_hangup ( channel , SWITCH_CAUSE_SRTP_READ_ERROR ) ;
2014-06-29 20:40:49 +00:00
} else if ( errs > = WARN_SRTP_ERRS & & ! ( errs % WARN_SRTP_ERRS ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING ,
" SRTP %s unprotect failed with code %d (%s) %ld bytes %d errors \n " ,
rtp_type ( rtp_session ) , stat , msg , ( long ) * bytes , errs ) ;
2014-06-28 03:43:08 +00:00
}
2011-03-22 17:07:06 +00:00
}
2014-06-28 01:18:50 +00:00
sbytes = 0 ;
2011-03-18 21:58:52 +00:00
} else {
2013-02-03 05:57:27 +00:00
rtp_session - > srtp_errs [ rtp_session - > srtp_idx_rtp ] = 0 ;
2011-03-18 21:58:52 +00:00
}
2011-03-22 17:07:06 +00:00
* bytes = sbytes ;
}
2011-05-02 16:33:57 +00:00
# endif
2011-03-18 21:58:52 +00:00
}
2015-05-13 16:50:04 +00:00
2015-10-05 23:59:58 +00:00
if ( rtp_session - > has_rtp ) {
2015-10-02 14:31:20 +00:00
if ( rtp_session - > recv_msg . header . cc > 0 ) { /* Contributing Source Identifiers (4 bytes = sizeof CSRC header)*/
rtp_session - > recv_msg . ebody = RTP_BODY ( rtp_session ) + ( rtp_session - > recv_msg . header . cc * 4 ) ;
}
2015-05-23 03:08:27 +00:00
/* recalculate body length in case rtp extension used */
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & &
2015-10-05 23:59:58 +00:00
rtp_session - > has_rtp & & rtp_session - > recv_msg . header . x ) { /* header extensions */
2015-05-23 03:08:27 +00:00
uint16_t length ;
2015-10-02 14:31:20 +00:00
rtp_session - > recv_msg . ext = ( switch_rtp_hdr_ext_t * ) RTP_BODY ( rtp_session ) ;
2015-05-23 03:08:27 +00:00
length = ntohs ( ( uint16_t ) rtp_session - > recv_msg . ext - > length ) ;
if ( length < SWITCH_RTP_MAX_BUF_LEN_WORDS ) {
2015-10-02 14:31:20 +00:00
rtp_session - > recv_msg . ebody = ( char * ) rtp_session - > recv_msg . ext + ( length * 4 ) + 4 ;
2015-05-23 03:08:27 +00:00
if ( * bytes > ( length * 4 + 4 ) ) {
* bytes - = ( length * 4 + 4 ) ;
} else {
* bytes = 0 ;
}
}
}
# ifdef DEBUG_CHROME
2015-10-05 23:59:58 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & rtp_session - > has_rtp ) {
2015-05-23 03:08:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_INFO ,
" VIDEO: seq: %d ts: %u len: %ld %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x mark: %d \n " ,
2015-10-06 14:34:19 +00:00
ntohs ( rtp_session - > last_rtp_hdr . seq ) , ntohl ( rtp_session - > last_rtp_hdr . ts ) , * bytes ,
2015-05-23 03:08:27 +00:00
* ( ( uint8_t * ) RTP_BODY ( rtp_session ) ) , * ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 1 ) ,
* ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 2 ) , * ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 3 ) ,
* ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 4 ) , * ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 5 ) ,
* ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 6 ) , * ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 7 ) ,
* ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 8 ) , * ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 9 ) ,
2015-10-06 14:34:19 +00:00
* ( ( uint8_t * ) RTP_BODY ( rtp_session ) + 10 ) , rtp_session - > last_rtp_hdr . m ) ;
2015-05-23 03:08:27 +00:00
}
# endif
2015-05-13 16:50:04 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
rtcp_stats ( rtp_session ) ;
}
}
2015-05-23 03:08:27 +00:00
rtp_session - > stats . inbound . raw_bytes + = * bytes ;
2015-10-06 14:34:19 +00:00
if ( rtp_session - > last_rtp_hdr . pt = = rtp_session - > recv_te ) {
2015-05-23 03:08:27 +00:00
rtp_session - > stats . inbound . dtmf_packet_count + + ;
2015-10-06 14:34:19 +00:00
} else if ( rtp_session - > last_rtp_hdr . pt = = rtp_session - > cng_pt | | rtp_session - > last_rtp_hdr . pt = = 13 ) {
2015-05-23 03:08:27 +00:00
rtp_session - > stats . inbound . cng_packet_count + + ;
} else {
rtp_session - > stats . inbound . media_packet_count + + ;
rtp_session - > stats . inbound . media_bytes + = * bytes ;
}
rtp_session - > stats . inbound . packet_count + + ;
2011-03-18 21:58:52 +00:00
}
2016-09-22 23:52:48 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & &
( ( rtp_session - > recv_te & & rtp_session - > last_rtp_hdr . pt = = rtp_session - > recv_te ) | |
( * bytes < rtp_header_len & & * bytes > 0 & & ! ( rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) ) ) ) {
2015-11-06 20:33:07 +00:00
return SWITCH_STATUS_BREAK ;
2011-03-22 17:07:06 +00:00
}
2013-07-11 22:38:24 +00:00
if ( ts ) {
rtp_session - > last_read_ts = ts ;
}
2011-03-22 17:07:06 +00:00
2013-11-07 22:48:00 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_BYTESWAP ] & & check_recv_payload ( rtp_session ) ) {
2012-12-14 01:49:02 +00:00
switch_swap_linear ( ( int16_t * ) RTP_BODY ( rtp_session ) , ( int ) * bytes - rtp_header_len ) ;
2011-03-21 20:03:44 +00:00
}
2011-03-18 21:58:52 +00:00
2013-08-21 21:30:59 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_KILL_JB ] ) {
rtp_session - > flags [ SWITCH_RTP_FLAG_KILL_JB ] = 0 ;
2015-09-19 04:36:11 +00:00
2013-08-21 21:30:59 +00:00
if ( rtp_session - > jb ) {
2015-09-11 16:37:01 +00:00
switch_jb_destroy ( & rtp_session - > jb ) ;
2013-08-21 21:30:59 +00:00
}
2015-09-19 04:36:11 +00:00
if ( rtp_session - > vb ) {
switch_jb_destroy ( & rtp_session - > vb ) ;
}
2013-08-21 21:30:59 +00:00
}
2016-07-11 03:25:14 +00:00
2015-10-05 23:59:58 +00:00
if ( rtp_session - > has_rtp & & * bytes ) {
2015-10-22 18:07:07 +00:00
uint32_t read_ssrc = ntohl ( rtp_session - > last_rtp_hdr . ssrc ) ;
2015-01-21 01:20:20 +00:00
2016-09-22 23:52:48 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
return SWITCH_STATUS_SUCCESS ;
}
2016-07-28 19:13:37 +00:00
if ( rtp_session - > vb & & jb_valid ( rtp_session ) ) {
2015-10-04 21:53:43 +00:00
status = switch_jb_put_packet ( rtp_session - > vb , ( switch_rtp_packet_t * ) & rtp_session - > recv_msg , * bytes ) ;
if ( status = = SWITCH_STATUS_TOO_LATE ) {
goto more ;
}
2014-12-17 00:48:07 +00:00
status = SWITCH_STATUS_FALSE ;
* bytes = 0 ;
2015-09-17 22:34:50 +00:00
if ( ! return_jb_packet ) {
return status ;
}
2009-03-31 19:10:43 +00:00
}
2010-02-06 03:38:24 +00:00
2015-09-23 19:46:47 +00:00
if ( rtp_session - > jb & & ! rtp_session - > pause_jb & & jb_valid ( rtp_session ) ) {
2015-09-17 22:34:50 +00:00
2015-10-22 18:07:07 +00:00
if ( rtp_session - > last_jb_read_ssrc & & rtp_session - > last_jb_read_ssrc ! = read_ssrc ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > jb ) ;
2014-12-17 00:48:07 +00:00
}
2015-09-17 22:34:50 +00:00
2015-05-05 16:58:27 +00:00
rtp_session - > last_jb_read_ssrc = read_ssrc ;
2011-03-09 21:17:09 +00:00
2014-12-17 00:48:07 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & & rtp_session - > timer . interval ) {
switch_core_timer_sync ( & rtp_session - > timer ) ;
reset_jitter_seq ( rtp_session ) ;
}
2015-10-04 21:53:43 +00:00
status = switch_jb_put_packet ( rtp_session - > jb , ( switch_rtp_packet_t * ) & rtp_session - > recv_msg , * bytes ) ;
if ( status = = SWITCH_STATUS_TOO_LATE ) {
goto more ;
}
2011-02-25 17:59:45 +00:00
2015-10-04 21:53:43 +00:00
2014-12-17 00:48:07 +00:00
status = SWITCH_STATUS_FALSE ;
* bytes = 0 ;
2014-03-06 21:48:50 +00:00
2014-12-17 00:48:07 +00:00
if ( ! return_jb_packet ) {
return status ;
}
2015-10-22 18:07:07 +00:00
} else {
if ( rtp_session - > last_rtp_hdr . m & & rtp_session - > last_rtp_hdr . pt ! = rtp_session - > recv_te & &
! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & ! ( rtp_session - > rtp_bugs & RTP_BUG_IGNORE_MARK_BIT ) ) {
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_FLUSH ) ;
} else if ( rtp_session - > last_jb_read_ssrc & & rtp_session - > last_jb_read_ssrc ! = read_ssrc ) {
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_FLUSH ) ;
}
2014-12-17 00:48:07 +00:00
}
2009-03-31 19:10:43 +00:00
}
2015-10-05 23:59:58 +00:00
if ( ! * bytes | | rtp_session - > has_rtp ) {
2016-07-11 03:25:14 +00:00
2015-05-05 16:58:27 +00:00
if ( rtp_session - > jb & & ! rtp_session - > pause_jb & & jb_valid ( rtp_session ) ) {
2015-09-11 16:37:01 +00:00
switch_status_t jstatus = switch_jb_get_packet ( rtp_session - > jb , ( switch_rtp_packet_t * ) & rtp_session - > recv_msg , bytes ) ;
2015-01-21 01:20:20 +00:00
2015-09-17 22:34:50 +00:00
status = jstatus ;
2015-05-05 16:58:27 +00:00
2015-09-17 22:34:50 +00:00
switch ( jstatus ) {
case SWITCH_STATUS_MORE_DATA :
2015-10-07 16:21:51 +00:00
if ( rtp_session - > punts < 4 ) {
block = 1 ;
goto more ;
}
* bytes = 0 ;
break ;
2015-09-17 22:34:50 +00:00
case SWITCH_STATUS_NOTFOUND :
{
2015-10-06 14:34:19 +00:00
int pt = get_recv_payload ( rtp_session ) ;
2015-09-17 22:34:50 +00:00
( * flags ) | = SFF_PLC ;
status = SWITCH_STATUS_SUCCESS ;
* bytes = switch_jb_get_last_read_len ( rtp_session - > jb ) ;
2015-10-02 00:11:51 +00:00
rtp_session - > last_rtp_hdr = rtp_session - > recv_msg . header ;
2015-10-06 14:34:19 +00:00
if ( pt > - 1 ) {
rtp_session - > last_rtp_hdr . pt = pt ;
}
2015-05-05 16:58:27 +00:00
}
2015-09-17 22:34:50 +00:00
break ;
case SWITCH_STATUS_SUCCESS :
default :
{
rtp_session - > stats . inbound . jb_packet_count + + ;
status = SWITCH_STATUS_SUCCESS ;
rtp_session - > last_rtp_hdr = rtp_session - > recv_msg . header ;
2015-10-07 16:21:51 +00:00
if ( + + rtp_session - > clean > 200 ) {
rtp_session - > punts = 0 ;
}
2015-09-17 22:34:50 +00:00
if ( ! xcheck_jitter ) {
check_jitter ( rtp_session ) ;
xcheck_jitter = * bytes ;
}
}
break ;
2015-05-05 16:58:27 +00:00
}
2009-03-31 19:10:43 +00:00
}
2015-09-17 22:34:50 +00:00
2016-07-28 19:13:37 +00:00
if ( rtp_session - > vb & & jb_valid ( rtp_session ) ) {
2015-09-11 16:37:01 +00:00
switch_status_t vstatus = switch_jb_get_packet ( rtp_session - > vb , ( switch_rtp_packet_t * ) & rtp_session - > recv_msg , bytes ) ;
2015-05-05 16:58:27 +00:00
status = vstatus ;
2014-12-17 07:03:31 +00:00
2015-05-05 16:58:27 +00:00
switch ( vstatus ) {
case SWITCH_STATUS_RESTART :
switch_core_session_request_video_refresh ( rtp_session - > session ) ;
status = SWITCH_STATUS_BREAK ;
break ;
case SWITCH_STATUS_MORE_DATA :
status = SWITCH_STATUS_BREAK ;
break ;
case SWITCH_STATUS_BREAK :
default :
break ;
}
2016-07-11 03:25:14 +00:00
if ( vstatus = = SWITCH_STATUS_NOTFOUND & & rtp_session - > flags [ SWITCH_RTP_FLAG_TEXT ] ) {
int pt = get_recv_payload ( rtp_session ) ;
( * flags ) | = SFF_PLC ;
status = SWITCH_STATUS_SUCCESS ;
* bytes = switch_jb_get_last_read_len ( rtp_session - > vb ) ;
rtp_session - > last_rtp_hdr = rtp_session - > recv_msg . header ;
if ( pt > - 1 ) {
rtp_session - > last_rtp_hdr . pt = pt ;
}
}
2015-05-05 16:58:27 +00:00
if ( vstatus = = SWITCH_STATUS_SUCCESS ) {
rtp_session - > last_rtp_hdr = rtp_session - > recv_msg . header ;
2016-07-11 03:25:14 +00:00
2015-05-05 16:58:27 +00:00
if ( ! xcheck_jitter ) {
check_jitter ( rtp_session ) ;
xcheck_jitter = * bytes ;
}
2014-12-17 00:48:07 +00:00
}
}
}
2009-03-31 19:10:43 +00:00
return status ;
}
2015-01-09 19:36:57 +00:00
static void handle_nack ( switch_rtp_t * rtp_session , uint32_t nack )
{
switch_size_t bytes = 0 ;
rtp_msg_t send_msg [ 1 ] = { { { 0 } } } ;
uint16_t seq = ( uint16_t ) ( nack & 0xFFFF ) ;
2015-02-05 02:23:17 +00:00
uint16_t blp = ( uint16_t ) ( nack > > 16 ) ;
2015-01-09 19:36:57 +00:00
int i ;
const char * tx_host = NULL ;
const char * old_host = NULL ;
const char * my_host = NULL ;
2015-08-27 18:42:52 +00:00
char bufa [ 50 ] , bufb [ 50 ] , bufc [ 50 ] ;
2015-01-09 19:36:57 +00:00
if ( ! ( rtp_session - > flags [ SWITCH_RTP_FLAG_NACK ] & & rtp_session - > vbw ) ) {
return ; /* not enabled */
}
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DEBUG_RTP_WRITE ] ) {
2015-01-21 01:20:20 +00:00
tx_host = switch_get_addr ( bufa , sizeof ( bufa ) , rtp_session - > rtcp_from_addr ) ;
2015-01-09 19:36:57 +00:00
old_host = switch_get_addr ( bufb , sizeof ( bufb ) , rtp_session - > remote_addr ) ;
my_host = switch_get_addr ( bufc , sizeof ( bufc ) , rtp_session - > local_addr ) ;
}
2015-04-08 19:16:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Got NACK [%u][0x%x] for seq %u \n " , nack , nack , ntohs ( seq ) ) ;
2015-01-09 19:36:57 +00:00
2015-09-11 16:37:01 +00:00
if ( switch_jb_get_packet_by_seq ( rtp_session - > vbw , seq , ( switch_rtp_packet_t * ) send_msg , & bytes ) = = SWITCH_STATUS_SUCCESS ) {
2015-01-09 19:36:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DEBUG_RTP_WRITE ] ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG_CLEAN ( rtp_session - > session ) , SWITCH_LOG_CONSOLE ,
" X %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u seq=%u m=%d \n " ,
rtp_session - > session ? switch_channel_get_name ( switch_core_session_get_channel ( rtp_session - > session ) ) : " NoName " ,
( long ) bytes ,
my_host , switch_sockaddr_get_port ( rtp_session - > local_addr ) ,
old_host , rtp_session - > remote_port ,
2015-01-21 01:20:20 +00:00
tx_host , switch_sockaddr_get_port ( rtp_session - > rtcp_from_addr ) ,
2015-01-09 19:36:57 +00:00
send_msg - > header . pt , ntohl ( send_msg - > header . ts ) , ntohs ( send_msg - > header . seq ) , send_msg - > header . m ) ;
}
2016-07-21 08:22:37 +00:00
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
2015-01-09 19:36:57 +00:00
switch_rtp_write_raw ( rtp_session , ( void * ) send_msg , & bytes , SWITCH_FALSE ) ;
} else {
2015-04-08 19:16:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Cannot send NACK for seq %u \n " , ntohs ( seq ) ) ;
2015-01-09 19:36:57 +00:00
}
2015-02-05 02:23:17 +00:00
blp = ntohs ( blp ) ;
2015-01-09 19:36:57 +00:00
for ( i = 0 ; i < 16 ; i + + ) {
2015-02-05 02:23:17 +00:00
if ( blp & ( 1 < < i ) ) {
2015-04-08 19:16:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Also Got NACK for seq %u \n " , ntohs ( seq ) + i + 1 ) ;
2015-08-19 18:14:24 +00:00
/* If they are missing more than one, may as well gen a key frame for good measure */
switch_core_media_gen_key_frame ( rtp_session - > session ) ;
2015-09-11 16:37:01 +00:00
if ( switch_jb_get_packet_by_seq ( rtp_session - > vbw , htons ( ntohs ( seq ) + i + 1 ) , ( switch_rtp_packet_t * ) & send_msg , & bytes ) = = SWITCH_STATUS_SUCCESS ) {
2015-01-09 19:36:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DEBUG_RTP_WRITE ] ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG_CLEAN ( rtp_session - > session ) , SWITCH_LOG_CONSOLE ,
" X %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u seq=%u m=%d \n " ,
rtp_session - > session ? switch_channel_get_name ( switch_core_session_get_channel ( rtp_session - > session ) ) : " NoName " ,
( long ) bytes ,
my_host , switch_sockaddr_get_port ( rtp_session - > local_addr ) ,
old_host , rtp_session - > remote_port ,
2015-01-21 01:20:20 +00:00
tx_host , switch_sockaddr_get_port ( rtp_session - > rtcp_from_addr ) ,
2015-01-09 19:36:57 +00:00
send_msg - > header . pt , ntohl ( send_msg - > header . ts ) , ntohs ( send_msg - > header . seq ) , send_msg - > header . m ) ;
}
2016-07-21 08:22:37 +00:00
//switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG1, "RE----SEND %u\n", ntohs(send_msg->header.seq));
2016-07-11 03:25:14 +00:00
2015-01-09 19:36:57 +00:00
switch_rtp_write_raw ( rtp_session , ( void * ) & send_msg , & bytes , SWITCH_FALSE ) ;
} else {
2015-04-08 19:16:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Cannot send NACK for seq %u \n " , ntohs ( seq ) + i ) ;
2015-01-09 19:36:57 +00:00
}
}
}
}
2014-12-03 00:40:47 +00:00
static switch_status_t process_rtcp_report ( switch_rtp_t * rtp_session , rtcp_msg_t * msg , switch_size_t bytes )
2013-01-17 01:04:57 +00:00
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2015-06-05 23:11:14 +00:00
int i ;
2014-11-15 01:01:56 +00:00
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 ,
2014-12-03 00:40:47 +00:00
" RTCP packet bytes % " SWITCH_SIZE_T_FMT " type %d pad %d \n " ,
bytes , msg - > header . type , msg - > header . p ) ;
2015-07-21 04:09:07 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & ( msg - > header . type = = _RTCP_PT_RTPFB | | msg - > header . type = = _RTCP_PT_PSFB ) ) {
2014-12-03 00:40:47 +00:00
rtcp_ext_msg_t * extp = ( rtcp_ext_msg_t * ) msg ;
2015-05-06 19:02:44 +00:00
2016-09-16 17:01:34 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " PICKED UP %s XRTCP type: %d fmt: %d \n " ,
rtp_type ( rtp_session ) , msg - > header . type , extp - > header . fmt ) ;
2015-05-13 16:50:04 +00:00
2015-07-21 04:09:07 +00:00
if ( msg - > header . type = = _RTCP_PT_PSFB & & ( extp - > header . fmt = = _RTCP_PSFB_FIR | | extp - > header . fmt = = _RTCP_PSFB_PLI ) ) {
2014-12-03 00:40:47 +00:00
switch_core_media_gen_key_frame ( rtp_session - > session ) ;
2015-05-05 18:27:52 +00:00
if ( rtp_session - > vbw ) {
2015-09-11 16:37:01 +00:00
switch_jb_reset ( rtp_session - > vbw ) ;
2015-05-05 18:27:52 +00:00
}
2014-12-03 00:40:47 +00:00
}
2015-01-09 19:36:57 +00:00
2015-07-21 04:09:07 +00:00
if ( msg - > header . type = = _RTCP_PT_RTPFB & & extp - > header . fmt = = _RTCP_RTPFB_NACK ) {
2015-01-09 19:36:57 +00:00
uint32_t * nack = ( uint32_t * ) extp - > body ;
int i ;
2015-04-09 20:52:18 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " Got NACK count %d \n " , ntohs ( extp - > header . length ) - 2 ) ;
2015-05-05 18:27:52 +00:00
2015-01-09 19:36:57 +00:00
for ( i = 0 ; i < ntohs ( extp - > header . length ) - 2 ; i + + ) {
handle_nack ( rtp_session , * nack ) ;
nack + + ;
}
2015-05-05 18:27:52 +00:00
switch_core_media_gen_key_frame ( rtp_session - > session ) ;
2015-01-09 19:36:57 +00:00
}
2014-12-03 00:40:47 +00:00
} else
2014-11-15 01:01:56 +00:00
2015-07-21 04:09:07 +00:00
if ( msg - > header . type = = _RTCP_PT_SR | | msg - > header . type = = _RTCP_PT_RR ) {
2014-07-21 09:40:59 +00:00
switch_time_t now ;
switch_time_exp_t now_hr ;
uint32_t sec , ntp_sec , ntp_usec , lsr_now ;
uint32_t lsr ;
uint32_t packet_ssrc ;
2015-10-24 00:27:25 +00:00
double rtt_now = 0 ;
int rtt_increase = 0 , packet_loss_increase = 0 ;
2015-05-05 16:58:27 +00:00
2014-07-21 09:40:59 +00:00
now = switch_time_now ( ) ; /* number of microseconds since 00:00:00 january 1, 1970 UTC */
2014-09-17 23:11:20 +00:00
sec = ( uint32_t ) ( now / 1000000 ) ; /* converted to second (NTP most significant bits) */
2014-07-21 09:40:59 +00:00
ntp_sec = sec + NTP_TIME_OFFSET ; /* 32bits most significant */
2014-09-17 23:11:20 +00:00
ntp_usec = ( uint32_t ) ( now - ( sec * 1000000 ) ) ; /* micro seconds */
2014-07-21 09:40:59 +00:00
lsr_now = ( uint32_t ) ( ntp_usec * 0.065536 ) | ( ntp_sec & 0x0000ffff ) < < 16 ; // 0.065536 is used for convertion from useconds
2015-07-21 04:09:07 +00:00
if ( msg - > header . type = = _RTCP_PT_SR ) { /* Sender report */
2014-12-03 00:40:47 +00:00
struct switch_rtcp_sender_report * sr = ( struct switch_rtcp_sender_report * ) msg - > body ;
2014-11-15 01:01:56 +00:00
2014-07-21 09:40:59 +00:00
rtp_session - > stats . rtcp . packet_count + = ntohl ( sr - > sender_info . pc ) ;
rtp_session - > stats . rtcp . octet_count + = ntohl ( sr - > sender_info . oc ) ;
packet_ssrc = sr - > ssrc ;
/* Extracting LSR from NTP timestamp and save it */
lsr = ( ntohl ( sr - > sender_info . ntp_lsw ) & 0xffff0000 ) > > 16 | ( ntohl ( sr - > sender_info . ntp_msw ) & 0x0000ffff ) < < 16 ; /* The middle 32 bits out of 64 in the NTP timestamp */
rtp_session - > stats . rtcp . last_recv_lsr_peer = htonl ( lsr ) ; /* Save it include it in the next SR */
rtp_session - > stats . rtcp . last_recv_lsr_local = lsr_now ; /* Save it to calculate DLSR when generating next SR */
2014-11-15 01:01:56 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG10 , " Received a SR with %d report blocks, " \
2014-12-03 00:40:47 +00:00
" length in words = %d, " \
" SSRC = 0x%X, " \
" NTP MSW = %u, " \
" NTP LSW = %u, " \
" RTP timestamp = %u, " \
" Sender Packet Count = %u, " \
" Sender Octet Count = %u \n " ,
msg - > header . count ,
ntohs ( ( uint16_t ) msg - > header . length ) ,
ntohl ( sr - > ssrc ) ,
ntohl ( sr - > sender_info . ntp_msw ) ,
ntohl ( sr - > sender_info . ntp_lsw ) ,
ntohl ( sr - > sender_info . ts ) ,
ntohl ( sr - > sender_info . pc ) ,
ntohl ( sr - > sender_info . oc ) ) ;
2015-06-05 23:11:14 +00:00
rtp_session - > rtcp_frame . ssrc = ntohl ( sr - > ssrc ) ;
rtp_session - > rtcp_frame . packet_type = ( uint16_t ) rtp_session - > rtcp_recv_msg_p - > header . type ;
rtp_session - > rtcp_frame . ntp_msw = ntohl ( sr - > sender_info . ntp_msw ) ;
rtp_session - > rtcp_frame . ntp_lsw = ntohl ( sr - > sender_info . ntp_lsw ) ;
rtp_session - > rtcp_frame . timestamp = ntohl ( sr - > sender_info . ts ) ;
rtp_session - > rtcp_frame . packet_count = ntohl ( sr - > sender_info . pc ) ;
rtp_session - > rtcp_frame . octect_count = ntohl ( sr - > sender_info . oc ) ;
for ( i = 0 ; i < ( int ) msg - > header . count & & i < MAX_REPORT_BLOCKS ; i + + ) {
struct switch_rtcp_report_block * report = ( struct switch_rtcp_report_block * ) ( msg - > body + ( sizeof ( struct switch_rtcp_sr_head ) + ( i * sizeof ( struct switch_rtcp_report_block ) ) ) ) ;
uint32_t old_avg = rtp_session - > rtcp_frame . reports [ i ] . loss_avg ;
2015-07-16 16:04:49 +00:00
uint8_t percent_fraction = ( uint8_t ) report - > fraction * 100 / 256 ;
2015-06-05 23:11:14 +00:00
if ( ! rtp_session - > rtcp_frame . reports [ i ] . loss_avg ) {
2015-07-16 16:04:49 +00:00
rtp_session - > rtcp_frame . reports [ i ] . loss_avg = ( uint8_t ) percent_fraction ;
2015-06-05 23:11:14 +00:00
} else {
rtp_session - > rtcp_frame . reports [ i ] . loss_avg = ( uint32_t ) ( ( ( float ) rtp_session - > rtcp_frame . reports [ i ] . loss_avg * .7 ) +
2015-07-16 16:04:49 +00:00
( ( float ) ( uint8_t ) percent_fraction * .3 ) ) ;
2015-06-05 23:11:14 +00:00
}
rtp_session - > rtcp_frame . reports [ i ] . ssrc = ntohl ( report - > ssrc ) ;
rtp_session - > rtcp_frame . reports [ i ] . fraction = ( uint8_t ) report - > fraction ;
rtp_session - > rtcp_frame . reports [ i ] . lost = ntohl ( report - > lost ) ;
rtp_session - > rtcp_frame . reports [ i ] . highest_sequence_number_received = ntohl ( report - > highest_sequence_number_received ) ;
rtp_session - > rtcp_frame . reports [ i ] . jitter = ntohl ( report - > jitter ) ;
rtp_session - > rtcp_frame . reports [ i ] . lsr = ntohl ( report - > lsr ) ;
rtp_session - > rtcp_frame . reports [ i ] . dlsr = ntohl ( report - > dlsr ) ;
2015-11-12 11:20:57 +00:00
if ( rtp_session - > rtcp_frame . reports [ i ] . lsr & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_PASSTHRU ] ) {
switch_time_exp_gmt ( & now_hr , now ) ;
/* Calculating RTT = A - DLSR - LSR */
rtt_now = ( double ) ( lsr_now - rtp_session - > rtcp_frame . reports [ i ] . dlsr - rtp_session - > rtcp_frame . reports [ i ] . lsr ) / 65536 ;
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 ,
" Receiving an RTCP packet \n [%04d-%02d-%02d %02d:%02d:%02d.%d] SSRC[0x%x] \n "
" RTT[%f] = A[%u] - DLSR[%u] - LSR[%u] \n " ,
1900 + now_hr . tm_year , now_hr . tm_mday , now_hr . tm_mon , now_hr . tm_hour , now_hr . tm_min , now_hr . tm_sec , now_hr . tm_usec ,
rtp_session - > rtcp_frame . reports [ i ] . ssrc , rtt_now ,
lsr_now , rtp_session - > rtcp_frame . reports [ i ] . dlsr , rtp_session - > rtcp_frame . reports [ i ] . lsr ) ;
if ( ! rtp_session - > rtcp_frame . reports [ i ] . rtt_avg ) {
rtp_session - > rtcp_frame . reports [ i ] . rtt_avg = rtt_now ;
} else {
rtp_session - > rtcp_frame . reports [ i ] . rtt_avg = ( double ) ( ( rtp_session - > rtcp_frame . reports [ i ] . rtt_avg * .7 ) + ( rtt_now * .3 ) ) ;
}
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " RTT average %f \n " ,
rtp_session - > rtcp_frame . reports [ i ] . rtt_avg ) ;
}
2015-10-24 00:27:25 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ADJ_BITRATE_CAP ] & & rtp_session - > flags [ SWITCH_RTP_FLAG_ESTIMATORS ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
/* SWITCH_RTP_FLAG_ADJ_BITRATE_CAP : Can the codec change its bitrate on the fly per API command ? */
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " Current packet loss: [%d %%] Current RTT: [%f ms] \n " , percent_fraction , rtt_now ) ;
# endif
switch_kalman_estimate ( rtp_session - > estimators [ EST_RTT ] , rtt_now , EST_RTT ) ;
if ( switch_kalman_cusum_detect_change ( rtp_session - > detectors [ EST_RTT ] , rtt_now , rtp_session - > estimators [ EST_RTT ] - > val_estimate_last ) ) {
/* sudden change in the mean value of RTT */
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " Sudden change in the mean value of RTT ! \n " ) ;
# endif
rtt_increase = 1 ;
}
switch_kalman_estimate ( rtp_session - > estimators [ EST_LOSS ] , percent_fraction , EST_LOSS ) ;
if ( switch_kalman_cusum_detect_change ( rtp_session - > detectors [ EST_LOSS ] , percent_fraction , rtp_session - > estimators [ EST_LOSS ] - > val_estimate_last ) ) {
/* sudden change in the mean value of packet loss */
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " Sudden change in the mean value of packet loss! \n " ) ;
# endif
packet_loss_increase = 1 ;
}
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " ESTIMATORS: Packet loss will be: [%f] RTT will be: [%f ms] \n " ,
rtp_session - > estimators [ EST_LOSS ] - > val_estimate_last , rtp_session - > estimators [ EST_RTT ] - > val_estimate_last ) ;
# endif
if ( rtp_session - > rtcp_frame . reports [ i ] . loss_avg ! = old_avg ) {
/*getting bad*/
if ( switch_kalman_is_slow_link ( rtp_session - > estimators [ EST_LOSS ] ,
rtp_session - > estimators [ EST_RTT ] ) ) {
/* going to minimum bitrate */
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " Slow link conditions: Loss average: [%d %%], Previous loss: [%d %%]. \
Going to minimum bitrate ! " ,rtp_session->rtcp_frame.reports[i].loss_avg, old_avg);
# endif
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_ADJUST_BITRATE , SCCT_STRING , " minimum " , SCCT_NONE , NULL , NULL , NULL ) ;
/* if after going to minimum bitrate we still have packet loss then we increase ptime. TODO */
} else if ( packet_loss_increase & & ( rtp_session - > estimators [ EST_LOSS ] - > val_estimate_last > = 5 ) ) {
/* sudden change in the mean value of packet loss percentage */
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_ADJUST_BITRATE ,
SCCT_STRING , " decrease " ,
SCCT_NONE , NULL , NULL , NULL ) ;
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " Sudden change in the mean value of packet loss percentage ! \n " ) ;
# endif
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_PACKET_LOSS , SCCT_INT ,
( void * ) & rtp_session - > rtcp_frame . reports [ i ] . loss_avg ,
SCCT_NONE , NULL , NULL , NULL ) ;
} else if ( ! rtt_increase & & rtp_session - > estimators [ EST_LOSS ] - > val_estimate_last > = rtp_session - > rtcp_frame . reports [ i ] . loss_avg ) {
/* lossy because of congestion (queues full somewhere -> some packets are dropped , but RTT is good ), packet loss with many small gaps */
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " packet loss, but RTT is not bad \n " ) ;
# endif
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_PACKET_LOSS , SCCT_INT ,
( void * ) & rtp_session - > rtcp_frame . reports [ i ] . loss_avg ,
SCCT_NONE , NULL , NULL , NULL ) ;
} else if ( ( rtp_session - > estimators [ EST_LOSS ] - > val_estimate_last < 1 ) & & packet_loss_increase ) {
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " small packet loss average \n " ) ;
# endif
/*small loss_avg*/
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_ADJUST_BITRATE ,
SCCT_STRING , " default " ,
SCCT_NONE , NULL , NULL , NULL ) ;
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_PACKET_LOSS , SCCT_INT ,
( void * ) & rtp_session - > rtcp_frame . reports [ i ] . loss_avg ,
SCCT_NONE , NULL , NULL , NULL ) ;
} else if ( ( rtp_session - > estimators [ EST_LOSS ] - > val_estimate_last < 5 ) & &
( rtp_session - > rtcp_frame . reports [ i ] . rtt_avg < rtp_session - > estimators [ EST_RTT ] - > val_estimate_last ) ) {
/* estimate that packet loss will decrease, we can increase the bitrate */
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_ADJUST_BITRATE ,
SCCT_STRING , " increase " ,
SCCT_NONE , NULL , NULL , NULL ) ;
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_PACKET_LOSS , SCCT_INT ,
( void * ) & rtp_session - > rtcp_frame . reports [ i ] . loss_avg ,
SCCT_NONE , NULL , NULL , NULL ) ;
} else {
/* *do nothing about bitrate, just pass the packet loss to the codec */
# ifdef DEBUG_ESTIMATORS
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " do nothing about bitrate, just pass the packet loss to the codec \n " ) ;
# endif
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_PACKET_LOSS , SCCT_INT ,
( void * ) & rtp_session - > rtcp_frame . reports [ i ] . loss_avg ,
SCCT_NONE , NULL , NULL , NULL ) ;
}
}
} else {
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & rtp_session - > rtcp_frame . reports [ i ] . loss_avg ! = old_avg ) {
switch_core_media_codec_control ( rtp_session - > session , SWITCH_MEDIA_TYPE_AUDIO ,
SWITCH_IO_WRITE , SCC_AUDIO_PACKET_LOSS , SCCT_INT ,
( void * ) & rtp_session - > rtcp_frame . reports [ i ] . loss_avg ,
SCCT_NONE , NULL , NULL , NULL ) ;
}
}
2015-06-05 23:11:14 +00:00
}
rtp_session - > rtcp_frame . report_count = ( uint16_t ) i ;
2014-07-21 09:40:59 +00:00
} else { /* Receiver report */
2014-12-03 00:40:47 +00:00
struct switch_rtcp_receiver_report * rr = ( struct switch_rtcp_receiver_report * ) msg - > body ;
2014-07-21 09:40:59 +00:00
packet_ssrc = rr - > ssrc ;
2015-06-05 23:11:14 +00:00
memset ( & rtp_session - > rtcp_frame , 0 , sizeof ( rtp_session - > rtcp_frame ) ) ;
2014-07-21 09:40:59 +00:00
}
2013-01-17 01:04:57 +00:00
rtp_session - > rtcp_fresh_frame = 1 ;
2014-07-21 09:40:59 +00:00
rtp_session - > stats . rtcp . peer_ssrc = ntohl ( packet_ssrc ) ;
2013-01-17 01:04:57 +00:00
}
2015-05-12 19:23:07 +00:00
2013-01-17 01:04:57 +00:00
2015-05-12 19:23:07 +00:00
if ( msg - > header . type > 194 & & msg - > header . type < 255 ) {
status = SWITCH_STATUS_SUCCESS ;
}
2014-12-03 00:40:47 +00:00
return status ;
}
static switch_status_t process_rtcp_packet ( switch_rtp_t * rtp_session , switch_size_t * bytes )
{
switch_size_t len ;
switch_size_t remain = * bytes ;
switch_status_t status = SWITCH_STATUS_FALSE ;
rtcp_msg_t * msg = rtp_session - > rtcp_recv_msg_p ;
if ( msg - > header . version ! = 2 ) {
if ( msg - > header . version = = 0 ) {
if ( rtp_session - > ice . ice_user ) {
handle_ice ( rtp_session , & rtp_session - > rtcp_ice , ( void * ) msg , * bytes ) ;
2013-01-17 01:04:57 +00:00
}
2014-12-03 00:40:47 +00:00
return SWITCH_STATUS_SUCCESS ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) ,
SWITCH_LOG_WARNING , " Received an unsupported RTCP packet version %d \n " , msg - > header . version ) ;
return SWITCH_STATUS_FALSE ;
2013-01-17 01:04:57 +00:00
}
}
2014-12-03 00:40:47 +00:00
do {
len = ( ( switch_size_t ) ntohs ( msg - > header . length ) * 4 ) + 4 ;
if ( msg - > header . version ! = 2 | | ! ( msg - > header . type > 199 & & msg - > header . type < 208 ) ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING ,
2015-06-01 19:28:33 +00:00
" INVALID RTCP PACKET TYPE %d VER %d LEN % " SWITCH_SIZE_T_FMT " \n " , msg - > header . type ,
2014-12-03 00:40:47 +00:00
msg - > header . version , len ) ;
status = SWITCH_STATUS_BREAK ;
break ;
}
2014-12-03 01:13:48 +00:00
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_CRIT,
//"WTF BYTES %ld REMAIN %ld PACKET TYPE %d LEN %ld\n", *bytes, remain, msg->header.type, len);
2014-12-03 00:40:47 +00:00
if ( len > remain ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING ,
" RTCP INVALID LENGTH % " SWITCH_SIZE_T_FMT " \n " , len ) ;
len = remain ;
}
2013-01-17 01:04:57 +00:00
2014-12-03 00:40:47 +00:00
status = process_rtcp_report ( rtp_session , msg , len ) ;
2013-01-17 01:04:57 +00:00
2014-12-03 00:40:47 +00:00
if ( remain > len ) {
unsigned char * p = ( unsigned char * ) msg ;
p + = len ;
msg = ( rtcp_msg_t * ) p ;
}
remain - = len ;
2013-02-16 03:27:49 +00:00
2014-12-03 00:40:47 +00:00
} while ( remain > = 4 ) ;
return status ;
}
2013-02-16 03:27:49 +00:00
2010-04-20 00:07:23 +00:00
static switch_status_t read_rtcp_packet ( switch_rtp_t * rtp_session , switch_size_t * bytes , switch_frame_flag_t * flags )
{
switch_status_t status = SWITCH_STATUS_FALSE ;
2013-02-16 03:27:49 +00:00
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2010-04-20 00:07:23 +00:00
return SWITCH_STATUS_FALSE ;
}
switch_assert ( bytes ) ;
* bytes = sizeof ( rtcp_msg_t ) ;
2013-01-17 01:04:57 +00:00
if ( ( status = switch_socket_recvfrom ( rtp_session - > rtcp_from_addr , rtp_session - > rtcp_sock_input , 0 , ( void * ) rtp_session - > rtcp_recv_msg_p , bytes ) )
2010-04-20 00:07:23 +00:00
! = SWITCH_STATUS_SUCCESS ) {
* bytes = 0 ;
}
2013-02-01 20:29:40 +00:00
if ( rtp_session - > rtcp_dtls ) {
2015-05-12 19:23:07 +00:00
char * b = ( char * ) rtp_session - > rtcp_recv_msg_p ;
2013-02-01 20:29:40 +00:00
2013-02-16 03:27:49 +00:00
if ( * b = = 0 | | * b = = 1 ) {
if ( rtp_session - > rtcp_ice . ice_user ) {
2015-05-12 19:23:07 +00:00
handle_ice ( rtp_session , & rtp_session - > rtcp_ice , ( void * ) rtp_session - > rtcp_recv_msg_p , * bytes ) ;
2013-02-16 03:27:49 +00:00
}
* bytes = 0 ;
}
2013-07-11 22:38:24 +00:00
2013-02-16 03:27:49 +00:00
if ( * bytes & & ( * b > = 20 ) & & ( * b < = 64 ) ) {
2013-02-01 20:29:40 +00:00
rtp_session - > rtcp_dtls - > bytes = * bytes ;
2015-05-12 19:23:07 +00:00
rtp_session - > rtcp_dtls - > data = ( void * ) rtp_session - > rtcp_recv_msg_p ;
2013-02-01 20:29:40 +00:00
} else {
rtp_session - > rtcp_dtls - > bytes = 0 ;
rtp_session - > rtcp_dtls - > data = NULL ;
}
2013-02-16 03:27:49 +00:00
2013-02-01 20:29:40 +00:00
do_dtls ( rtp_session , rtp_session - > rtcp_dtls ) ;
2013-02-16 03:27:49 +00:00
2013-02-02 06:15:09 +00:00
if ( rtp_session - > rtcp_dtls - > bytes ) {
* bytes = 0 ;
}
2013-02-01 20:29:40 +00:00
}
2013-01-15 05:17:28 +00:00
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2013-01-20 18:04:10 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_RECV ] & & rtp_session - > rtcp_recv_msg_p - > header . version = = 2 ) {
2013-01-17 01:04:57 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_SECURE_RECV] && (!rtp_session->ice.ice_user || rtp_session->rtcp_recv_msg_p->header.version == 2)) {
2010-04-20 00:07:23 +00:00
int sbytes = ( int ) * bytes ;
err_status_t stat = 0 ;
2013-01-15 05:17:28 +00:00
2013-02-03 05:57:27 +00:00
if ( ( stat = srtp_unprotect_rtcp ( rtp_session - > recv_ctx [ rtp_session - > srtp_idx_rtcp ] , & rtp_session - > rtcp_recv_msg_p - > header , & sbytes ) ) ) {
//++rtp_session->srtp_errs[rtp_session->srtp_idx_rtp]++;
2013-01-20 18:04:10 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " RTCP UNPROTECT ERR \n " ) ;
2010-04-20 00:07:23 +00:00
} else {
2013-02-03 05:57:27 +00:00
//rtp_session->srtp_errs[rtp_session->srtp_idx_rtp] = 0;
2010-04-20 00:07:23 +00:00
}
* bytes = sbytes ;
}
2011-05-02 16:33:57 +00:00
# endif
2010-04-20 00:07:23 +00:00
# ifdef ENABLE_ZRTP
2013-01-17 01:04:57 +00:00
if ( zrtp_on & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] & & rtp_session - > rtcp_recv_msg_p - > header . version = = 2 ) {
2012-01-25 05:38:53 +00:00
/* ZRTP Recv */
if ( bytes ) {
unsigned int sbytes = ( int ) * bytes ;
zrtp_status_t stat = 0 ;
2013-01-17 01:04:57 +00:00
stat = zrtp_process_srtcp ( rtp_session - > zrtp_stream , ( void * ) rtp_session - > rtcp_recv_msg_p , & sbytes ) ;
2012-01-25 05:38:53 +00:00
switch ( stat ) {
case zrtp_status_ok :
* bytes = sbytes ;
break ;
case zrtp_status_drop :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error: zRTP protection drop with code %d \n " , stat ) ;
* bytes = 0 ;
break ;
case zrtp_status_fail :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error: zRTP protection fail with code %d \n " , stat ) ;
* bytes = 0 ;
break ;
default :
break ;
}
2010-04-20 00:07:23 +00:00
}
}
# endif
if ( * bytes ) {
2013-01-17 01:04:57 +00:00
return process_rtcp_packet ( rtp_session , bytes ) ;
2010-04-20 00:07:23 +00:00
}
return status ;
}
2013-11-07 22:48:00 +00:00
static int rtp_common_read ( switch_rtp_t * rtp_session , switch_payload_t * payload_type ,
payload_map_t * * pmapP , switch_frame_flag_t * flags , switch_io_flag_t io_flags )
2006-04-03 21:00:13 +00:00
{
2013-01-15 05:17:28 +00:00
2009-11-24 21:40:28 +00:00
switch_channel_t * channel = NULL ;
2006-11-16 18:48:53 +00:00
switch_size_t bytes = 0 ;
2010-04-20 00:07:23 +00:00
switch_size_t rtcp_bytes = 0 ;
2009-03-30 21:12:06 +00:00
switch_status_t status = SWITCH_STATUS_SUCCESS , poll_status = SWITCH_STATUS_SUCCESS ;
2010-04-20 00:07:23 +00:00
switch_status_t rtcp_status = SWITCH_STATUS_SUCCESS , rtcp_poll_status = SWITCH_STATUS_SUCCESS ;
2008-11-12 10:42:55 +00:00
int check = 0 ;
2008-01-18 18:14:53 +00:00
int ret = - 1 ;
2008-09-29 23:03:27 +00:00
int sleep_mss = 1000 ;
2009-03-30 21:12:06 +00:00
int poll_sec = 5 ;
int poll_loop = 0 ;
int fdr = 0 ;
2010-04-20 00:07:23 +00:00
int rtcp_fdr = 0 ;
2009-03-31 19:10:43 +00:00
int hot_socket = 0 ;
2010-08-05 23:43:30 +00:00
int read_loops = 0 ;
2014-01-30 00:08:27 +00:00
int slept = 0 ;
2008-10-01 18:02:46 +00:00
2008-02-25 16:35:19 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return - 1 ;
}
2013-01-15 05:17:28 +00:00
if ( rtp_session - > session ) {
channel = switch_core_session_get_channel ( rtp_session - > session ) ;
}
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) {
2008-09-30 17:24:04 +00:00
sleep_mss = rtp_session - > timer . interval * 1000 ;
2006-09-16 20:46:52 +00:00
}
2008-01-18 18:14:53 +00:00
READ_INC ( rtp_session ) ;
2012-06-22 23:08:59 +00:00
2007-03-29 22:31:56 +00:00
while ( switch_rtp_ready ( rtp_session ) ) {
2008-02-13 00:32:09 +00:00
int do_cng = 0 ;
2011-02-18 23:26:58 +00:00
int read_pretriggered = 0 ;
2013-01-17 01:04:57 +00:00
int has_rtcp = 0 ;
2015-05-12 19:23:07 +00:00
int got_rtp_poll = 0 ;
2013-01-17 01:04:57 +00:00
2009-12-12 00:04:07 +00:00
bytes = 0 ;
2008-02-13 00:32:09 +00:00
2014-03-06 21:48:50 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & &
! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] & &
! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & &
! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & &
rtp_session - > read_pollfd ) {
if ( rtp_session - > jb & & ! rtp_session - > pause_jb & & jb_valid ( rtp_session ) ) {
while ( switch_poll ( rtp_session - > read_pollfd , 1 , & fdr , 0 ) = = SWITCH_STATUS_SUCCESS ) {
2015-01-21 22:11:23 +00:00
status = read_rtp_packet ( rtp_session , & bytes , flags , SWITCH_STATUS_SUCCESS , SWITCH_FALSE ) ;
2014-01-30 00:08:27 +00:00
2014-03-06 21:48:50 +00:00
if ( status = = SWITCH_STATUS_GENERR ) {
ret = - 1 ;
goto end ;
}
if ( ( * flags & SFF_RTCP ) ) {
* flags & = ~ SFF_RTCP ;
has_rtcp = 1 ;
read_pretriggered = 0 ;
goto rtcp ;
}
2015-09-17 22:34:50 +00:00
2015-11-06 20:33:07 +00:00
if ( status = = SWITCH_STATUS_BREAK ) {
read_pretriggered = 1 ;
break ;
}
2014-03-06 21:48:50 +00:00
}
} else if ( ( rtp_session - > flags [ SWITCH_RTP_FLAG_AUTOFLUSH ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_STICKY_FLUSH ] ) ) {
2010-08-05 22:56:18 +00:00
if ( switch_poll ( rtp_session - > read_pollfd , 1 , & fdr , 0 ) = = SWITCH_STATUS_SUCCESS ) {
2015-01-21 22:11:23 +00:00
status = read_rtp_packet ( rtp_session , & bytes , flags , SWITCH_STATUS_SUCCESS , SWITCH_FALSE ) ;
2013-05-17 20:39:21 +00:00
if ( status = = SWITCH_STATUS_GENERR ) {
ret = - 1 ;
goto end ;
}
2013-01-17 01:04:57 +00:00
if ( ( * flags & SFF_RTCP ) ) {
* flags & = ~ SFF_RTCP ;
has_rtcp = 1 ;
2013-04-11 23:11:06 +00:00
read_pretriggered = 0 ;
2013-01-17 01:04:57 +00:00
goto rtcp ;
}
2013-01-15 05:17:28 +00:00
/* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Initial (%i) %d\n", status, bytes); */
2011-02-21 16:51:26 +00:00
if ( status ! = SWITCH_STATUS_FALSE ) {
read_pretriggered = 1 ;
}
if ( bytes ) {
if ( switch_poll ( rtp_session - > read_pollfd , 1 , & fdr , 0 ) = = SWITCH_STATUS_SUCCESS ) {
2012-11-29 05:12:35 +00:00
rtp_session - > hot_hits + + ; //+= rtp_session->samples_per_interval;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG10 , " %s Hot Hit %d \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) ,
2012-11-29 19:42:56 +00:00
rtp_session - > hot_hits ) ;
2011-02-21 16:51:26 +00:00
} else {
rtp_session - > hot_hits = 0 ;
}
2011-02-18 23:26:58 +00:00
}
2010-12-21 21:35:13 +00:00
2012-11-30 20:05:45 +00:00
if ( rtp_session - > hot_hits > 1 & & ! rtp_session - > sync_packets ) { // >= (rtp_session->samples_per_second * 30)) {
2010-08-05 22:56:18 +00:00
hot_socket = 1 ;
}
} else {
rtp_session - > hot_hits = 0 ;
}
2009-03-30 21:12:06 +00:00
}
2010-08-05 22:56:18 +00:00
2016-07-11 03:25:14 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_TEXT ] ) {
///NOOP
} else if ( hot_socket & & ( rtp_session - > hot_hits % 10 ) ! = 0 ) {
2014-02-27 16:42:30 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG10 , " %s timer while HOT \n " , rtp_session_name ( rtp_session ) ) ;
2012-11-29 19:42:56 +00:00
switch_core_timer_next ( & rtp_session - > timer ) ;
} else if ( hot_socket ) {
2014-02-27 16:42:30 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG10 , " %s skip timer once \n " , rtp_session_name ( rtp_session ) ) ;
2009-09-10 00:46:24 +00:00
rtp_session - > sync_packets + + ;
2009-06-04 18:56:34 +00:00
switch_core_timer_sync ( & rtp_session - > timer ) ;
2014-01-30 00:08:27 +00:00
reset_jitter_seq ( rtp_session ) ;
2009-06-04 18:56:34 +00:00
} else {
2012-11-29 05:12:35 +00:00
2009-09-10 00:46:24 +00:00
if ( rtp_session - > sync_packets ) {
2012-11-29 19:42:56 +00:00
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG10 ,
2012-11-29 19:42:56 +00:00
" %s Auto-Flush catching up %d packets (%d)ms. \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) ,
2009-09-14 15:19:53 +00:00
rtp_session - > sync_packets , ( rtp_session - > ms_per_packet * rtp_session - > sync_packets ) / 1000 ) ;
2014-01-30 00:08:27 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_PAUSE ] ) {
2015-04-13 15:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG3 , " %s syncing %d %s packet(s) \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) ,
2014-01-30 00:08:27 +00:00
rtp_session - > sync_packets , rtp_type ( rtp_session ) ) ;
2015-11-17 01:31:32 +00:00
rtp_session - > bad_stream + + ;
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . flaws + = rtp_session - > sync_packets ;
2016-09-12 17:21:21 +00:00
if ( rtp_session - > stats . inbound . error_log ) {
rtp_session - > stats . inbound . error_log - > flaws + = rtp_session - > sync_packets ;
}
2014-01-30 00:08:27 +00:00
}
2012-11-30 19:54:43 +00:00
switch_core_timer_sync ( & rtp_session - > timer ) ;
2014-01-30 00:08:27 +00:00
reset_jitter_seq ( rtp_session ) ;
2012-11-30 20:05:45 +00:00
rtp_session - > hot_hits = 0 ;
2012-11-29 05:12:35 +00:00
} else {
2014-01-30 00:08:27 +00:00
if ( slept ) {
switch_cond_next ( ) ;
} else {
switch_core_timer_next ( & rtp_session - > timer ) ;
slept + + ;
}
2012-11-29 05:12:35 +00:00
2009-09-10 00:46:24 +00:00
}
2014-01-30 00:08:27 +00:00
2012-11-29 05:12:35 +00:00
rtp_session - > sync_packets = 0 ;
2009-03-30 21:12:06 +00:00
}
2008-11-10 18:26:41 +00:00
}
2012-06-22 23:08:59 +00:00
rtp_session - > stats . read_count + + ;
2013-06-18 00:52:37 +00:00
recvfrom :
2011-02-18 23:26:58 +00:00
if ( ! read_pretriggered ) {
bytes = 0 ;
}
2010-08-05 23:43:30 +00:00
read_loops + + ;
2012-06-22 23:08:59 +00:00
//poll_loop = 0;
2009-01-12 22:18:48 +00:00
2009-06-04 18:56:34 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
break ;
}
2011-03-09 21:17:09 +00:00
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & & rtp_session - > read_pollfd ) {
2009-09-02 19:55:08 +00:00
int pt = poll_sec * 1000000 ;
2013-01-15 05:17:28 +00:00
do_2833 ( rtp_session ) ;
2011-03-10 02:06:27 +00:00
2013-06-18 00:52:37 +00:00
if ( rtp_session - > dtmf_data . out_digit_dur > 0 | | rtp_session - > dtmf_data . in_digit_sanity | | rtp_session - > sending_dtmf | |
2011-03-10 02:06:27 +00:00
switch_queue_size ( rtp_session - > dtmf_data . dtmf_queue ) | | switch_queue_size ( rtp_session - > dtmf_data . dtmf_inqueue ) ) {
2009-09-02 19:55:08 +00:00
pt = 20000 ;
}
2010-05-27 01:12:54 +00:00
2013-08-13 21:00:31 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] ) {
2014-11-20 22:30:19 +00:00
pt = 200000 ;
2013-07-11 22:38:24 +00:00
}
2016-07-28 19:13:37 +00:00
if ( rtp_session - > vb ) {
2015-09-11 16:37:01 +00:00
if ( switch_jb_poll ( rtp_session - > vb ) ) {
2015-01-21 22:11:23 +00:00
pt = 0 ;
2015-01-16 16:29:30 +00:00
}
2014-12-17 00:48:07 +00:00
}
2016-02-24 04:01:38 +00:00
if ( ( io_flags & SWITCH_IO_FLAG_NOBLOCK ) ) {
pt = 0 ;
}
2016-07-28 19:13:37 +00:00
2015-01-21 22:11:23 +00:00
poll_status = switch_poll ( rtp_session - > read_pollfd , 1 , & fdr , pt ) ;
2014-12-17 00:48:07 +00:00
2015-05-23 03:08:27 +00:00
2014-11-20 22:30:19 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & rtp_session - > dtmf_data . out_digit_dur > 0 ) {
2011-02-18 22:54:51 +00:00
return_cng_frame ( ) ;
2009-09-02 19:55:08 +00:00
}
2013-09-12 16:47:54 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & rtp_session - > flags [ SWITCH_RTP_FLAG_BREAK ] ) {
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_BREAK ) ;
bytes = 0 ;
2014-01-30 00:08:27 +00:00
reset_jitter_seq ( rtp_session ) ;
2016-03-17 13:55:00 +00:00
return_cng_frame ( ) ;
2013-09-12 16:47:54 +00:00
}
2010-02-06 03:38:24 +00:00
}
2013-06-18 00:52:37 +00:00
2013-10-15 21:24:32 +00:00
2016-07-28 19:13:37 +00:00
if ( poll_status = = SWITCH_STATUS_SUCCESS | | ( rtp_session - > vb & & switch_jb_poll ( rtp_session - > vb ) ) ) {
2015-05-12 19:23:07 +00:00
got_rtp_poll = 1 ;
2011-02-21 16:51:26 +00:00
if ( read_pretriggered ) {
read_pretriggered = 0 ;
} else {
2016-07-11 03:25:14 +00:00
2015-01-21 22:11:23 +00:00
status = read_rtp_packet ( rtp_session , & bytes , flags , poll_status , SWITCH_TRUE ) ;
2013-06-18 00:52:37 +00:00
2013-05-17 20:39:21 +00:00
if ( status = = SWITCH_STATUS_GENERR ) {
ret = - 1 ;
goto end ;
}
2015-10-07 16:21:51 +00:00
2016-01-27 16:49:34 +00:00
if ( rtp_session - > max_missed_packets & & read_loops = = 1 & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & &
! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
2015-10-07 16:21:51 +00:00
if ( bytes & & status = = SWITCH_STATUS_SUCCESS ) {
2013-10-07 16:38:08 +00:00
rtp_session - > missed_count = 0 ;
} else if ( + + rtp_session - > missed_count > = rtp_session - > max_missed_packets ) {
ret = - 2 ;
goto end ;
}
}
2013-07-11 22:38:24 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
//switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_CRIT, "Read bytes (%i) %ld\n", status, bytes);
if ( bytes = = 0 ) {
if ( check_rtcp_and_ice ( rtp_session ) = = - 1 ) {
ret = - 1 ;
goto end ;
}
// This is dumb
2013-07-17 00:15:56 +00:00
//switch_rtp_video_refresh(rtp_session);
2013-07-11 22:38:24 +00:00
goto rtcp ;
}
}
2013-06-18 00:52:37 +00:00
if ( ( * flags & SFF_PROXY_PACKET ) ) {
ret = ( int ) bytes ;
goto end ;
}
2013-01-17 01:04:57 +00:00
if ( ( * flags & SFF_RTCP ) ) {
* flags & = ~ SFF_RTCP ;
has_rtcp = 1 ;
goto rtcp ;
}
2013-07-11 22:38:24 +00:00
2011-02-18 23:26:58 +00:00
}
2012-06-22 23:08:59 +00:00
poll_loop = 0 ;
2009-03-30 21:12:06 +00:00
} else {
2016-02-19 15:34:38 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
ret = - 1 ;
goto end ;
}
2009-03-30 21:12:06 +00:00
if ( ! SWITCH_STATUS_IS_BREAK ( poll_status ) & & poll_status ! = SWITCH_STATUS_TIMEOUT ) {
2011-01-11 21:09:03 +00:00
char tmp [ 128 ] = " " ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Poll failed with error: %d [%s] \n " ,
2016-02-19 15:34:38 +00:00
poll_status , switch_strerror_r ( poll_status , tmp , sizeof ( tmp ) ) ) ;
2009-03-30 21:12:06 +00:00
ret = - 1 ;
goto end ;
}
2013-06-18 00:52:37 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2011-01-11 21:09:03 +00:00
rtp_session - > missed_count + = ( poll_sec * 1000 ) / ( rtp_session - > ms_per_packet ? rtp_session - > ms_per_packet / 1000 : 20 ) ;
bytes = 0 ;
if ( rtp_session - > max_missed_packets ) {
if ( rtp_session - > missed_count > = rtp_session - > max_missed_packets ) {
ret = - 2 ;
goto end ;
}
2009-12-30 23:10:38 +00:00
}
}
2011-01-11 21:09:03 +00:00
2015-05-20 20:08:06 +00:00
if ( check_rtcp_and_ice ( rtp_session ) = = - 1 ) {
ret = - 1 ;
goto end ;
2013-10-28 18:39:23 +00:00
}
2016-02-24 04:01:38 +00:00
2013-07-11 22:38:24 +00:00
if ( ( ! ( io_flags & SWITCH_IO_FLAG_NOBLOCK ) ) & &
2015-05-12 19:23:07 +00:00
( rtp_session - > dtmf_data . out_digit_dur = = 0 ) & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2009-11-19 18:22:05 +00:00
return_cng_frame ( ) ;
}
2009-03-30 21:12:06 +00:00
}
2013-10-28 18:39:23 +00:00
2013-01-17 01:04:57 +00:00
rtcp :
2011-01-13 02:02:49 +00:00
2013-02-16 03:27:49 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2013-01-17 01:04:57 +00:00
rtcp_poll_status = SWITCH_STATUS_FALSE ;
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] & & has_rtcp ) {
if ( rtp_session - > rtcp_recv_msg_p - > header . version = = 2 ) { //rtcp muxed
2013-01-18 03:47:45 +00:00
rtp_session - > rtcp_from_addr = rtp_session - > from_addr ;
2013-01-17 01:04:57 +00:00
rtcp_status = rtcp_poll_status = SWITCH_STATUS_SUCCESS ;
rtcp_bytes = bytes ;
}
has_rtcp = 0 ;
2013-07-17 00:15:56 +00:00
2013-01-17 01:04:57 +00:00
} else if ( rtp_session - > rtcp_read_pollfd ) {
rtcp_poll_status = switch_poll ( rtp_session - > rtcp_read_pollfd , 1 , & rtcp_fdr , 0 ) ;
}
2010-04-20 00:07:23 +00:00
if ( rtcp_poll_status = = SWITCH_STATUS_SUCCESS ) {
2013-01-17 01:04:57 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
rtcp_status = read_rtcp_packet ( rtp_session , & rtcp_bytes , flags ) ;
}
2010-04-20 21:15:37 +00:00
2012-03-27 20:53:05 +00:00
if ( rtcp_status = = SWITCH_STATUS_SUCCESS ) {
switch_rtp_reset_media_timer ( rtp_session ) ;
2014-12-03 00:40:47 +00:00
2014-11-13 03:30:39 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_PASSTHRU ] ) {
2013-01-15 05:17:28 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
2012-06-22 23:08:59 +00:00
const char * uuid = switch_channel_get_partner_uuid ( channel ) ;
2013-06-18 00:52:37 +00:00
2012-06-22 23:08:59 +00:00
if ( uuid ) {
switch_core_session_t * other_session ;
switch_rtp_t * other_rtp_session = NULL ;
2010-04-20 21:15:37 +00:00
2012-06-22 23:08:59 +00:00
if ( ( other_session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * other_channel = switch_core_session_get_channel ( other_session ) ;
if ( ( other_rtp_session = switch_channel_get_private ( other_channel , " __rtcp_audio_rtp_session " ) ) & &
other_rtp_session - > rtcp_sock_output & &
2012-12-18 22:06:29 +00:00
switch_rtp_test_flag ( other_rtp_session , SWITCH_RTP_FLAG_ENABLE_RTCP ) ) {
2014-02-06 17:24:05 +00:00
other_rtp_session - > rtcp_send_msg = rtp_session - > rtcp_recv_msg ;
2014-11-13 03:30:39 +00:00
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2012-12-18 22:06:29 +00:00
if ( switch_rtp_test_flag ( other_rtp_session , SWITCH_RTP_FLAG_SECURE_SEND ) ) {
2012-06-22 23:08:59 +00:00
int sbytes = ( int ) rtcp_bytes ;
2013-02-03 05:57:27 +00:00
int stat = srtp_protect_rtcp ( other_rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtcp ] , & other_rtp_session - > rtcp_send_msg . header , & sbytes ) ;
2012-06-22 23:08:59 +00:00
if ( stat ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error: SRTP RTCP protection failed with code %d \n " , stat ) ;
2012-06-22 23:08:59 +00:00
}
rtcp_bytes = sbytes ;
2013-01-13 07:29:05 +00:00
2010-04-20 21:15:37 +00:00
}
2011-05-02 16:33:57 +00:00
# endif
2010-04-20 21:15:37 +00:00
# ifdef ENABLE_ZRTP
2012-06-22 23:08:59 +00:00
/* ZRTP Send */
2012-12-18 22:06:29 +00:00
if ( zrtp_on & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] ) {
2012-06-22 23:08:59 +00:00
unsigned int sbytes = ( unsigned int ) bytes ;
zrtp_status_t stat = zrtp_status_fail ;
2012-01-25 05:38:53 +00:00
2012-06-22 23:08:59 +00:00
stat = zrtp_process_rtcp ( other_rtp_session - > zrtp_stream , ( void * ) & other_rtp_session - > rtcp_send_msg , & sbytes ) ;
2012-01-25 05:38:53 +00:00
2012-06-22 23:08:59 +00:00
switch ( stat ) {
case zrtp_status_ok :
break ;
case zrtp_status_drop :
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error: zRTP protection drop with code %d \n " , stat ) ;
2012-06-22 23:08:59 +00:00
ret = ( int ) bytes ;
goto end ;
break ;
case zrtp_status_fail :
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error: zRTP protection fail with code %d \n " , stat ) ;
2012-06-22 23:08:59 +00:00
break ;
default :
break ;
}
2012-01-25 05:38:53 +00:00
2012-06-22 23:08:59 +00:00
bytes = sbytes ;
}
2010-04-20 21:15:37 +00:00
# endif
2012-06-22 23:08:59 +00:00
if ( switch_socket_sendto ( other_rtp_session - > rtcp_sock_output , other_rtp_session - > rtcp_remote_addr , 0 ,
( const char * ) & other_rtp_session - > rtcp_send_msg , & rtcp_bytes ) ! = SWITCH_STATUS_SUCCESS ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " RTCP packet not written \n " ) ;
2012-06-22 23:08:59 +00:00
}
2010-04-20 21:15:37 +00:00
2012-06-22 23:08:59 +00:00
}
switch_core_session_rwunlock ( other_session ) ;
2010-04-20 21:15:37 +00:00
}
}
2012-06-22 23:08:59 +00:00
}
2013-01-17 01:04:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_RTCP_MUX ] ) {
2014-12-03 00:40:47 +00:00
process_rtcp_packet ( rtp_session , & rtcp_bytes ) ;
2013-01-17 01:04:57 +00:00
ret = 1 ;
2013-04-11 23:11:06 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & & rtp_session - > timer . interval ) {
switch_core_timer_sync ( & rtp_session - > timer ) ;
2014-01-30 00:08:27 +00:00
reset_jitter_seq ( rtp_session ) ;
2013-04-11 23:11:06 +00:00
}
goto recvfrom ;
2013-01-17 01:04:57 +00:00
}
2010-04-20 21:15:37 +00:00
}
2010-04-20 00:07:23 +00:00
}
}
2015-05-12 19:23:07 +00:00
if ( ( ! ( io_flags & SWITCH_IO_FLAG_NOBLOCK ) ) & &
( rtp_session - > dtmf_data . out_digit_dur = = 0 ) & & ! got_rtp_poll ) {
return_cng_frame ( ) ;
}
2015-10-05 23:59:58 +00:00
if ( bytes & & rtp_session - > has_rtp & &
2012-12-18 22:06:29 +00:00
! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & &
2015-10-06 14:34:19 +00:00
rtp_session - > last_rtp_hdr . pt ! = 13 & &
rtp_session - > last_rtp_hdr . pt ! = rtp_session - > recv_te & &
rtp_session - > last_rtp_hdr . pt ! = rtp_session - > cng_pt ) {
2013-12-05 22:35:49 +00:00
int accept_packet = 1 ;
2013-11-07 22:48:00 +00:00
if ( rtp_session - > pmaps & & * rtp_session - > pmaps ) {
payload_map_t * pmap ;
2013-12-05 22:35:49 +00:00
accept_packet = 0 ;
2013-11-07 22:48:00 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
for ( pmap = * rtp_session - > pmaps ; pmap & & pmap - > allocated ; pmap = pmap - > next ) {
2013-11-25 18:08:17 +00:00
2013-11-07 22:48:00 +00:00
if ( ! pmap - > negotiated ) {
continue ;
}
2015-10-06 14:34:19 +00:00
if ( rtp_session - > last_rtp_hdr . pt = = pmap - > pt ) {
2013-11-07 22:48:00 +00:00
accept_packet = 1 ;
if ( pmapP ) {
* pmapP = pmap ;
}
2013-11-25 18:08:17 +00:00
break ;
2013-11-07 22:48:00 +00:00
}
}
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
}
if ( ! accept_packet & &
! ( rtp_session - > rtp_bugs & RTP_BUG_ACCEPT_ANY_PAYLOAD ) & & ! ( rtp_session - > rtp_bugs & RTP_BUG_ACCEPT_ANY_PACKETS ) ) {
/* drop frames of incorrect payload number and return CNG frame instead */
2013-11-25 18:08:17 +00:00
2013-11-07 22:48:00 +00:00
return_cng_frame ( ) ;
}
2011-01-21 21:08:26 +00:00
}
2010-08-05 23:43:30 +00:00
if ( ! bytes & & ( io_flags & SWITCH_IO_FLAG_NOBLOCK ) ) {
rtp_session - > missed_count = 0 ;
ret = 0 ;
goto end ;
}
2008-11-10 18:26:41 +00:00
check = ! bytes ;
2010-02-06 03:38:24 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_FLUSH ] ) {
2015-10-04 21:53:43 +00:00
bytes = do_flush ( rtp_session , SWITCH_FALSE , bytes ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_FLUSH ) ;
2012-03-26 15:53:34 +00:00
}
2016-09-23 00:52:05 +00:00
if ( ( ! bytes & & rtp_session - > flags [ SWITCH_RTP_FLAG_BREAK ] ) | | ( bytes & & bytes = = 4 & & * ( ( int * ) & rtp_session - > recv_msg ) = = UINT_MAX ) ) {
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_BREAK ) ;
2012-02-27 19:26:50 +00:00
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_NOBLOCK ] | | ! rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] | |
rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] | |
2012-03-26 15:53:34 +00:00
( bytes & & bytes < 5 ) | | ( ! bytes & & poll_loop ) ) {
2012-02-27 19:26:50 +00:00
bytes = 0 ;
2014-01-30 00:08:27 +00:00
reset_jitter_seq ( rtp_session ) ;
2012-02-27 19:26:50 +00:00
return_cng_frame ( ) ;
}
2008-10-09 22:44:48 +00:00
}
2008-10-21 18:04:20 +00:00
if ( bytes & & bytes < 5 ) {
2008-10-10 15:47:58 +00:00
continue ;
}
2009-03-30 21:12:06 +00:00
if ( ! bytes & & poll_loop ) {
goto recvfrom ;
}
2010-02-03 19:19:10 +00:00
2015-10-06 14:34:19 +00:00
if ( bytes & & rtp_session - > last_rtp_hdr . m & & rtp_session - > last_rtp_hdr . pt ! = rtp_session - > recv_te & &
2015-05-01 20:40:50 +00:00
! rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & &
2016-07-11 03:25:14 +00:00
! rtp_session - > flags [ SWITCH_RTP_FLAG_TEXT ] & &
2015-05-01 20:40:50 +00:00
! ( rtp_session - > rtp_bugs & RTP_BUG_IGNORE_MARK_BIT ) ) {
2009-04-16 22:13:55 +00:00
rtp_flush_read_buffer ( rtp_session , SWITCH_RTP_FLUSH_ONCE ) ;
2008-11-25 17:53:35 +00:00
}
2015-10-06 14:34:19 +00:00
if ( rtp_session - > last_rtp_hdr . pt = = rtp_session - > cng_pt | | rtp_session - > last_rtp_hdr . pt = = 13 ) {
2011-09-09 18:56:04 +00:00
* flags | = SFF_NOT_AUDIO ;
2012-08-20 17:11:17 +00:00
} else {
* flags & = ~ SFF_NOT_AUDIO ; /* If this flag was already set, make sure to remove it when we get real audio */
2011-09-09 18:56:04 +00:00
}
2015-08-27 18:46:08 +00:00
/* ignore packets not meant for us unless the auto-adjust window is open (ice mode has its own alternatives to this) */
if ( ! using_ice ( rtp_session ) & & bytes ) {
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_AUTOADJ ] ) {
2015-10-06 14:34:19 +00:00
if ( rtp_session - > last_rtp_hdr . pt = = rtp_session - > cng_pt | | rtp_session - > last_rtp_hdr . pt = = 13 ) {
2010-02-06 03:38:24 +00:00
goto recvfrom ;
}
2015-08-27 18:46:08 +00:00
} else if ( ! ( rtp_session - > rtp_bugs & RTP_BUG_ACCEPT_ANY_PACKETS ) & & ! switch_cmp_addr ( rtp_session - > rtp_from_addr , rtp_session - > remote_addr ) ) {
2010-02-06 03:38:24 +00:00
goto recvfrom ;
2009-10-31 22:13:15 +00:00
}
2009-10-27 21:46:05 +00:00
}
2015-01-21 01:20:20 +00:00
if ( bytes & & rtp_session - > flags [ SWITCH_RTP_FLAG_AUTOADJ ] & & switch_sockaddr_get_port ( rtp_session - > rtp_from_addr ) ) {
if ( ! switch_cmp_addr ( rtp_session - > rtp_from_addr , rtp_session - > remote_addr ) ) {
2014-07-16 00:25:56 +00:00
if ( + + rtp_session - > autoadj_tally > = rtp_session - > autoadj_threshold ) {
2009-10-30 14:26:17 +00:00
const char * err ;
uint32_t old = rtp_session - > remote_port ;
const char * tx_host ;
const char * old_host ;
2015-08-27 18:42:52 +00:00
char bufa [ 50 ] , bufb [ 50 ] ;
2012-06-27 20:16:46 +00:00
char adj_port [ 6 ] ;
2009-11-24 21:40:28 +00:00
2015-01-21 01:20:20 +00:00
tx_host = switch_get_addr ( bufa , sizeof ( bufa ) , rtp_session - > rtp_from_addr ) ;
2010-02-06 03:38:24 +00:00
old_host = switch_get_addr ( bufb , sizeof ( bufb ) , rtp_session - > remote_addr ) ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO ,
2015-01-21 01:20:20 +00:00
" Auto Changing %s port from %s:%u to %s:%u \n " , rtp_type ( rtp_session ) , old_host , old , tx_host ,
switch_sockaddr_get_port ( rtp_session - > rtp_from_addr ) ) ;
2009-11-24 21:40:28 +00:00
if ( channel ) {
2015-05-12 20:52:53 +00:00
char varname [ 80 ] = " " ;
switch_snprintf ( varname , sizeof ( varname ) , " remote_%s_ip_reported " , rtp_type ( rtp_session ) ) ;
switch_channel_set_variable ( channel , varname , switch_channel_get_variable ( channel , " remote_media_ip " ) ) ;
switch_snprintf ( varname , sizeof ( varname ) , " remote_%s_ip " , rtp_type ( rtp_session ) ) ;
switch_channel_set_variable ( channel , varname , tx_host ) ;
switch_snprintf ( varname , sizeof ( varname ) , " remote_%s_port_reported " , rtp_type ( rtp_session ) ) ;
2015-01-21 01:20:20 +00:00
switch_snprintf ( adj_port , sizeof ( adj_port ) , " %u " , switch_sockaddr_get_port ( rtp_session - > rtp_from_addr ) ) ;
2015-05-12 20:52:53 +00:00
switch_channel_set_variable ( channel , varname , switch_channel_get_variable ( channel , " remote_media_port " ) ) ;
switch_snprintf ( varname , sizeof ( varname ) , " remote_%s_port " , rtp_type ( rtp_session ) ) ;
switch_channel_set_variable ( channel , varname , adj_port ) ;
switch_snprintf ( varname , sizeof ( varname ) , " rtp_auto_adjust_%s " , rtp_type ( rtp_session ) ) ;
switch_channel_set_variable ( channel , varname , " true " ) ;
2009-11-24 21:40:28 +00:00
}
2010-09-29 19:14:41 +00:00
rtp_session - > auto_adj_used = 1 ;
2015-01-21 01:20:20 +00:00
switch_rtp_set_remote_address ( rtp_session , tx_host , switch_sockaddr_get_port ( rtp_session - > rtp_from_addr ) , 0 , SWITCH_FALSE , & err ) ;
2014-10-02 16:55:53 +00:00
if ( ( rtp_session - > rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST ) ) {
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
} else {
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
2014-02-04 06:56:30 +00:00
if ( rtp_session - > ice . ice_user ) {
rtp_session - > ice . addr = rtp_session - > remote_addr ;
}
2008-05-23 23:53:10 +00:00
}
2009-10-27 21:46:05 +00:00
} else {
2014-10-02 16:55:53 +00:00
if ( ( rtp_session - > rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST ) ) {
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
} else {
2015-05-12 20:52:53 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Correct %s ip/port confirmed. \n " , rtp_type ( rtp_session ) ) ;
2014-10-02 16:55:53 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
}
2010-09-29 19:14:41 +00:00
rtp_session - > auto_adj_used = 0 ;
2008-05-23 23:53:10 +00:00
}
}
2010-02-06 03:38:24 +00:00
2014-10-02 16:55:53 +00:00
if ( bytes & & ! ( rtp_session - > rtp_bugs & RTP_BUG_ALWAYS_AUTO_ADJUST ) & & rtp_session - > autoadj_window ) {
2008-05-23 23:53:10 +00:00
if ( - - rtp_session - > autoadj_window = = 0 ) {
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_AUTOADJ ) ;
2008-05-23 23:53:10 +00:00
}
}
2016-07-11 03:25:14 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_TEXT ] ) {
if ( ! bytes ) {
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) {
switch_core_timer_next ( & rtp_session - > timer ) ;
}
return_cng_frame ( ) ;
} else {
* payload_type = rtp_session - > last_rtp_hdr . pt ;
ret = ( int ) bytes ;
goto end ;
}
}
2012-12-18 22:06:29 +00:00
if ( bytes & & ( rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) ) {
2008-10-22 17:12:04 +00:00
/* Fast PASS! */
* flags | = SFF_PROXY_PACKET ;
2010-05-13 02:25:54 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
2012-12-14 22:52:27 +00:00
#if 0
2015-10-05 23:59:58 +00:00
if ( rtp_session - > has_rtp & & check_recv_payload ( rtp_session ) ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING ,
2012-12-14 22:52:27 +00:00
" Ignoring udptl packet of size of %ld bytes that looks strikingly like a RTP packet. \n " , ( long ) bytes ) ;
bytes = 0 ;
goto do_continue ;
}
# endif
2010-05-13 02:25:54 +00:00
* flags | = SFF_UDPTL_PACKET ;
}
2010-08-05 22:56:18 +00:00
2008-10-22 17:12:04 +00:00
ret = ( int ) bytes ;
goto end ;
}
2008-05-23 23:53:10 +00:00
if ( bytes ) {
2008-04-06 23:47:33 +00:00
rtp_session - > missed_count = 0 ;
2008-10-01 18:02:46 +00:00
2010-08-05 23:43:30 +00:00
if ( bytes < rtp_header_len ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " Ignoring invalid RTP packet size of %ld bytes. \n " , ( long ) bytes ) ;
2010-08-05 23:43:30 +00:00
bytes = 0 ;
goto do_continue ;
}
2015-10-06 14:34:19 +00:00
if ( rtp_session - > last_rtp_hdr . pt & & ( rtp_session - > last_rtp_hdr . pt = = rtp_session - > cng_pt | | rtp_session - > last_rtp_hdr . pt = = 13 ) ) {
2008-11-10 18:26:41 +00:00
return_cng_frame ( ) ;
2010-02-06 03:38:24 +00:00
}
2008-04-06 23:47:33 +00:00
}
2008-03-19 17:56:27 +00:00
if ( check | | bytes ) {
2013-01-15 05:17:28 +00:00
do_2833 ( rtp_session ) ;
2006-09-12 22:23:45 +00:00
}
2010-02-06 03:38:24 +00:00
2008-02-15 20:31:10 +00:00
if ( bytes & & rtp_session - > recv_msg . header . version ! = 2 ) {
2012-12-14 01:49:02 +00:00
uint8_t * data = ( uint8_t * ) RTP_BODY ( rtp_session ) ;
2010-02-03 19:19:10 +00:00
2015-10-06 14:34:19 +00:00
//if (rtp_session->recv_msg.header.version == 0) {
// if (rtp_session->ice.ice_user) {
// handle_ice(rtp_session, &rtp_session->ice, (void *) &rtp_session->recv_msg, bytes);
// goto recvfrom;
// }
//}
2010-02-06 03:38:24 +00:00
2008-02-15 20:31:10 +00:00
if ( rtp_session - > invalid_handler ) {
2015-01-21 01:20:20 +00:00
rtp_session - > invalid_handler ( rtp_session , rtp_session - > sock_input , ( void * ) & rtp_session - > recv_msg , bytes , rtp_session - > rtp_from_addr ) ;
2008-02-15 20:31:10 +00:00
}
2008-05-27 04:30:03 +00:00
2008-02-15 20:31:10 +00:00
memset ( data , 0 , 2 ) ;
data [ 0 ] = 65 ;
2015-10-06 14:34:19 +00:00
rtp_session - > last_rtp_hdr . pt = rtp_session - > cng_pt ! = INVALID_PT ? rtp_session - > cng_pt : SWITCH_RTP_CNG_PAYLOAD ;
2008-02-15 20:31:10 +00:00
* flags | = SFF_CNG ;
2015-10-06 14:34:19 +00:00
* payload_type = ( switch_payload_t ) rtp_session - > last_rtp_hdr . pt ;
2008-02-15 20:31:10 +00:00
ret = 2 + rtp_header_len ;
goto end ;
2012-06-22 23:08:59 +00:00
} else if ( bytes ) {
rtp_session - > stats . inbound . period_packet_count + + ;
2008-02-15 20:31:10 +00:00
}
2011-01-07 23:53:09 +00:00
2011-01-21 21:03:19 +00:00
/* Handle incoming RFC2833 packets */
switch ( handle_rfc2833 ( rtp_session , bytes , & do_cng ) ) {
case RESULT_GOTO_END :
goto end ;
case RESULT_GOTO_RECVFROM :
goto recvfrom ;
case RESULT_GOTO_TIMERCHECK :
goto timer_check ;
case RESULT_CONTINUE :
2015-11-25 20:45:32 +00:00
status = SWITCH_STATUS_SUCCESS ;
2011-01-21 21:03:19 +00:00
goto result_continue ;
2009-01-19 21:12:20 +00:00
}
2011-01-21 21:03:19 +00:00
result_continue :
2010-04-20 00:07:23 +00:00
timer_check :
2014-10-27 19:13:36 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_MUTE ] ) {
do_cng + + ;
}
2008-10-01 18:02:46 +00:00
2008-03-07 18:21:08 +00:00
if ( do_cng ) {
2012-12-14 01:49:02 +00:00
uint8_t * data = ( uint8_t * ) RTP_BODY ( rtp_session ) ;
2010-12-23 19:18:41 +00:00
2013-01-15 05:17:28 +00:00
do_2833 ( rtp_session ) ;
2012-09-28 21:17:20 +00:00
2010-12-23 19:18:41 +00:00
if ( rtp_session - > last_cng_ts = = rtp_session - > last_read_ts + rtp_session - > samples_per_interval ) {
rtp_session - > last_cng_ts = 0 ;
} else {
rtp_session - > last_cng_ts = rtp_session - > last_read_ts + rtp_session - > samples_per_interval ;
}
2008-10-01 18:02:46 +00:00
memset ( data , 0 , 2 ) ;
data [ 0 ] = 65 ;
2015-10-06 14:34:19 +00:00
rtp_session - > last_rtp_hdr . pt = rtp_session - > cng_pt ! = INVALID_PT ? rtp_session - > cng_pt : SWITCH_RTP_CNG_PAYLOAD ;
2007-03-29 22:31:56 +00:00
* flags | = SFF_CNG ;
2015-10-06 14:34:19 +00:00
* payload_type = ( switch_payload_t ) rtp_session - > last_rtp_hdr . pt ;
2008-01-18 18:14:53 +00:00
ret = 2 + rtp_header_len ;
2009-04-15 15:08:21 +00:00
rtp_session - > stats . inbound . skip_packet_count + + ;
2008-01-18 18:14:53 +00:00
goto end ;
2006-05-04 01:15:38 +00:00
}
2011-03-09 21:17:09 +00:00
2012-12-18 22:06:29 +00:00
if ( check | | ( bytes & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) ) {
if ( ! bytes & & rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) { /* We're late! We're Late! */
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_NOBLOCK ] & & status = = SWITCH_STATUS_BREAK ) {
2008-11-14 23:31:21 +00:00
switch_cond_next ( ) ;
2006-05-05 16:52:19 +00:00
continue ;
}
2014-01-30 00:08:27 +00:00
2010-08-05 23:43:30 +00:00
2014-06-03 00:09:10 +00:00
2014-01-30 00:08:27 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_PAUSE ] & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_DTMF_ON ] & & ! rtp_session - > dtmf_data . in_digit_ts
2014-06-03 00:09:10 +00:00
& & rtp_session - > cng_count > ( rtp_session - > one_second * 2 ) & & rtp_session - > jitter_lead > JITTER_LEAD_FRAMES ) {
2014-01-30 00:08:27 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG1 , " %s %s timeout \n " ,
2014-02-27 16:42:30 +00:00
rtp_session_name ( rtp_session ) , rtp_type ( rtp_session ) ) ;
2014-01-30 00:08:27 +00:00
2016-09-12 17:21:21 +00:00
if ( rtp_session - > stats . inbound . error_log ) {
rtp_session - > stats . inbound . error_log - > flaws + + ;
}
2014-01-30 00:08:27 +00:00
rtp_session - > stats . inbound . flaws + + ;
do_mos ( rtp_session , SWITCH_FALSE ) ;
}
rtp_session - > cng_count + + ;
2008-10-01 18:02:46 +00:00
return_cng_frame ( ) ;
2007-04-07 01:57:54 +00:00
}
}
2013-01-16 04:56:02 +00:00
2014-01-30 00:08:27 +00:00
rtp_session - > cng_count = 0 ;
2006-04-10 17:25:59 +00:00
if ( status = = SWITCH_STATUS_BREAK | | bytes = = 0 ) {
2012-12-18 22:06:29 +00:00
if ( ! ( io_flags & SWITCH_IO_FLAG_SINGLE_READ ) & & rtp_session - > flags [ SWITCH_RTP_FLAG_DATAWAIT ] ) {
2007-06-23 03:26:12 +00:00
goto do_continue ;
2006-09-20 20:25:26 +00:00
}
2010-08-05 23:43:30 +00:00
return_cng_frame ( ) ;
2006-04-10 17:25:59 +00:00
}
2008-05-27 04:30:03 +00:00
2015-10-06 14:34:19 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_GOOGLEHACK ] & & rtp_session - > last_rtp_hdr . pt = = 102 ) {
rtp_session - > last_rtp_hdr . pt = 97 ;
2006-04-03 21:00:13 +00:00
}
2006-04-07 17:32:14 +00:00
2006-05-05 16:03:15 +00:00
break ;
2007-06-23 03:26:12 +00:00
2010-04-20 00:07:23 +00:00
do_continue :
2010-02-06 03:38:24 +00:00
2012-12-18 22:06:29 +00:00
if ( ! bytes & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) {
2008-11-10 18:26:41 +00:00
switch_yield ( sleep_mss ) ;
}
2008-10-01 18:02:46 +00:00
2006-05-04 17:51:53 +00:00
}
2008-02-25 16:35:19 +00:00
if ( switch_rtp_ready ( rtp_session ) ) {
2015-10-06 14:34:19 +00:00
* payload_type = ( switch_payload_t ) rtp_session - > last_rtp_hdr . pt ;
2006-05-04 17:51:53 +00:00
2008-02-25 16:35:19 +00:00
if ( * payload_type = = SWITCH_RTP_CNG_PAYLOAD ) {
* flags | = SFF_CNG ;
}
2007-03-29 22:31:56 +00:00
2008-02-25 16:35:19 +00:00
ret = ( int ) bytes ;
} else {
ret = - 1 ;
}
2008-01-18 18:14:53 +00:00
2010-04-20 00:07:23 +00:00
end :
2010-08-05 22:56:18 +00:00
2008-01-18 18:14:53 +00:00
READ_DEC ( rtp_session ) ;
return ret ;
2006-04-03 21:00:13 +00:00
}
2010-09-29 19:14:41 +00:00
SWITCH_DECLARE ( switch_byte_t ) switch_rtp_check_auto_adj ( switch_rtp_t * rtp_session )
{
return rtp_session - > auto_adj_used ;
}
2006-05-04 17:51:53 +00:00
SWITCH_DECLARE ( switch_size_t ) switch_rtp_has_dtmf ( switch_rtp_t * rtp_session )
{
2007-03-07 23:24:09 +00:00
switch_size_t has = 0 ;
2006-05-04 17:51:53 +00:00
2007-03-07 23:24:09 +00:00
if ( switch_rtp_ready ( rtp_session ) ) {
switch_mutex_lock ( rtp_session - > dtmf_data . dtmf_mutex ) ;
2007-12-22 00:32:20 +00:00
has = switch_queue_size ( rtp_session - > dtmf_data . dtmf_inqueue ) ;
2007-03-07 23:24:09 +00:00
switch_mutex_unlock ( rtp_session - > dtmf_data . dtmf_mutex ) ;
}
2006-05-04 17:51:53 +00:00
return has ;
}
2007-12-22 00:32:20 +00:00
SWITCH_DECLARE ( switch_size_t ) switch_rtp_dequeue_dtmf ( switch_rtp_t * rtp_session , switch_dtmf_t * dtmf )
{
switch_size_t bytes = 0 ;
switch_dtmf_t * _dtmf = NULL ;
void * pop ;
2008-05-27 04:30:03 +00:00
2007-03-07 23:24:09 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
2007-12-22 00:32:20 +00:00
return bytes ;
2007-03-07 23:24:09 +00:00
}
2006-05-04 17:51:53 +00:00
switch_mutex_lock ( rtp_session - > dtmf_data . dtmf_mutex ) ;
2007-12-22 00:32:20 +00:00
if ( switch_queue_trypop ( rtp_session - > dtmf_data . dtmf_inqueue , & pop ) = = SWITCH_STATUS_SUCCESS ) {
2013-01-15 05:17:28 +00:00
2007-12-22 00:32:20 +00:00
_dtmf = ( switch_dtmf_t * ) pop ;
* dtmf = * _dtmf ;
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " RTP RECV DTMF %c:%d \n " , dtmf - > digit , dtmf - > duration ) ;
2007-12-22 00:32:20 +00:00
bytes + + ;
2009-02-27 18:52:15 +00:00
free ( pop ) ;
2006-05-04 17:51:53 +00:00
}
switch_mutex_unlock ( rtp_session - > dtmf_data . dtmf_mutex ) ;
2007-12-22 00:32:20 +00:00
return bytes ;
2006-05-04 17:51:53 +00:00
}
2007-12-22 00:32:20 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_queue_rfc2833 ( switch_rtp_t * rtp_session , const switch_dtmf_t * dtmf )
2006-05-04 17:51:53 +00:00
{
2007-12-22 00:32:20 +00:00
switch_dtmf_t * rdigit ;
2006-05-04 17:51:53 +00:00
2007-03-07 23:24:09 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
2007-12-22 00:32:20 +00:00
return SWITCH_STATUS_FALSE ;
2007-03-07 23:24:09 +00:00
}
2006-05-04 17:51:53 +00:00
2007-12-22 00:32:20 +00:00
if ( ( rdigit = malloc ( sizeof ( * rdigit ) ) ) ! = 0 ) {
* rdigit = * dtmf ;
2009-09-16 21:24:22 +00:00
if ( rdigit - > duration < switch_core_min_dtmf_duration ( 0 ) ) {
rdigit - > duration = switch_core_min_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
}
2008-05-27 04:30:03 +00:00
2008-01-14 21:27:40 +00:00
if ( ( switch_queue_trypush ( rtp_session - > dtmf_data . dtmf_queue , rdigit ) ) ! = SWITCH_STATUS_SUCCESS ) {
free ( rdigit ) ;
return SWITCH_STATUS_FALSE ;
}
2007-12-22 00:32:20 +00:00
} else {
abort ( ) ;
2006-05-04 17:51:53 +00:00
}
2008-05-27 04:30:03 +00:00
2007-12-22 00:32:20 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-05-04 17:51:53 +00:00
}
2007-12-22 00:32:20 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_queue_rfc2833_in ( switch_rtp_t * rtp_session , const switch_dtmf_t * dtmf )
2006-05-04 17:51:53 +00:00
{
2007-12-22 00:32:20 +00:00
switch_dtmf_t * rdigit ;
2006-05-04 17:51:53 +00:00
2007-03-07 23:24:09 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2008-05-27 04:30:03 +00:00
2007-12-22 00:32:20 +00:00
if ( ( rdigit = malloc ( sizeof ( * rdigit ) ) ) ! = 0 ) {
* rdigit = * dtmf ;
2009-09-16 21:24:22 +00:00
if ( rdigit - > duration < switch_core_min_dtmf_duration ( 0 ) ) {
rdigit - > duration = switch_core_min_dtmf_duration ( 0 ) ;
2008-02-21 21:38:49 +00:00
}
2008-01-14 21:27:40 +00:00
if ( ( switch_queue_trypush ( rtp_session - > dtmf_data . dtmf_inqueue , rdigit ) ) ! = SWITCH_STATUS_SUCCESS ) {
free ( rdigit ) ;
return SWITCH_STATUS_FALSE ;
}
2007-12-22 00:32:20 +00:00
} else {
abort ( ) ;
2006-05-04 17:51:53 +00:00
}
2008-05-27 04:30:03 +00:00
2006-05-04 17:51:53 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2008-05-27 04:30:03 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_read ( switch_rtp_t * rtp_session , void * data , uint32_t * datalen ,
2008-05-08 19:19:47 +00:00
switch_payload_t * payload_type , switch_frame_flag_t * flags , switch_io_flag_t io_flags )
2006-04-03 21:00:13 +00:00
{
2007-03-07 23:24:09 +00:00
int bytes = 0 ;
2006-04-03 21:00:13 +00:00
2007-03-07 23:24:09 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2013-11-07 22:48:00 +00:00
bytes = rtp_common_read ( rtp_session , payload_type , NULL , flags , io_flags ) ;
2007-03-29 22:31:56 +00:00
2006-04-12 20:48:47 +00:00
if ( bytes < 0 ) {
2006-04-10 18:28:46 +00:00
* datalen = 0 ;
2007-10-31 13:08:45 +00:00
return bytes = = - 2 ? SWITCH_STATUS_TIMEOUT : SWITCH_STATUS_GENERR ;
2006-05-04 01:15:38 +00:00
} else if ( bytes = = 0 ) {
* datalen = 0 ;
return SWITCH_STATUS_BREAK ;
2006-04-18 00:24:52 +00:00
} else {
2010-08-05 23:43:30 +00:00
if ( bytes > rtp_header_len ) {
bytes - = rtp_header_len ;
}
2006-04-03 21:00:13 +00:00
}
2006-04-10 18:28:46 +00:00
* datalen = bytes ;
2012-12-14 01:49:02 +00:00
memcpy ( data , RTP_BODY ( rtp_session ) , bytes ) ;
2006-04-10 18:28:46 +00:00
2007-03-29 22:31:56 +00:00
return SWITCH_STATUS_SUCCESS ;
2006-04-07 17:32:14 +00:00
}
2006-04-03 21:00:13 +00:00
2010-04-20 00:07:23 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtcp_zerocopy_read_frame ( switch_rtp_t * rtp_session , switch_rtcp_frame_t * frame )
{
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
2010-04-20 00:07:23 +00:00
return SWITCH_STATUS_FALSE ;
}
/* A fresh frame has been found! */
if ( rtp_session - > rtcp_fresh_frame ) {
/* turn the flag off! */
rtp_session - > rtcp_fresh_frame = 0 ;
2015-06-05 23:11:14 +00:00
* frame = rtp_session - > rtcp_frame ;
2011-12-16 00:13:09 +00:00
2010-04-20 00:07:23 +00:00
return SWITCH_STATUS_SUCCESS ;
}
return SWITCH_STATUS_TIMEOUT ;
}
2008-05-08 19:19:47 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_zerocopy_read_frame ( switch_rtp_t * rtp_session , switch_frame_t * frame , switch_io_flag_t io_flags )
2006-04-18 00:24:52 +00:00
{
2007-03-07 23:24:09 +00:00
int bytes = 0 ;
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2013-11-07 22:48:00 +00:00
bytes = rtp_common_read ( rtp_session , & frame - > payload , & frame - > pmap , & frame - > flags , io_flags ) ;
2008-02-13 00:32:09 +00:00
2012-12-14 01:49:02 +00:00
frame - > data = RTP_BODY ( rtp_session ) ;
2014-12-03 00:40:47 +00:00
2015-07-31 02:27:35 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & & ( bytes < rtp_header_len | | switch_test_flag ( frame , SFF_CNG ) ) ) {
2014-12-03 00:40:47 +00:00
frame - > packet = NULL ;
frame - > timestamp = 0 ;
frame - > seq = 0 ;
frame - > ssrc = 0 ;
frame - > m = 0 ;
} else {
frame - > packet = & rtp_session - > recv_msg ;
frame - > packetlen = bytes ;
frame - > source = __FILE__ ;
switch_set_flag ( frame , SFF_RAW_RTP ) ;
if ( frame - > payload = = rtp_session - > recv_te ) {
switch_set_flag ( frame , SFF_RFC2833 ) ;
}
2015-10-02 00:11:51 +00:00
frame - > timestamp = ntohl ( rtp_session - > last_rtp_hdr . ts ) ;
frame - > seq = ( uint16_t ) ntohs ( ( uint16_t ) rtp_session - > last_rtp_hdr . seq ) ;
2015-05-05 16:58:27 +00:00
frame - > ssrc = ntohl ( rtp_session - > last_rtp_hdr . ssrc ) ;
2015-10-02 00:11:51 +00:00
frame - > m = rtp_session - > last_rtp_hdr . m ? SWITCH_TRUE : SWITCH_FALSE ;
2014-12-03 00:40:47 +00:00
}
2014-01-30 00:08:27 +00:00
2009-05-23 01:50:56 +00:00
# ifdef ENABLE_ZRTP
2012-12-18 22:06:29 +00:00
if ( zrtp_on & & rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] ) {
2009-05-27 01:40:11 +00:00
zrtp_session_info_t zrtp_session_info ;
2010-02-06 03:38:24 +00:00
if ( rtp_session - > zrtp_session & & ( zrtp_status_ok = = zrtp_session_get ( rtp_session - > zrtp_session , & zrtp_session_info ) ) ) {
if ( zrtp_session_info . sas_is_ready ) {
2013-01-15 05:17:28 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
2010-01-07 23:29:06 +00:00
2012-05-29 18:10:15 +00:00
const char * uuid = switch_channel_get_partner_uuid ( channel ) ;
2010-02-06 03:38:24 +00:00
if ( uuid ) {
2010-01-07 23:29:06 +00:00
switch_core_session_t * other_session ;
if ( ( other_session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * other_channel = switch_core_session_get_channel ( other_session ) ;
2010-02-03 19:19:10 +00:00
switch_rtp_t * other_rtp_session = switch_channel_get_private ( other_channel , " __zrtp_audio_rtp_session " ) ;
2010-01-07 23:29:06 +00:00
if ( other_rtp_session ) {
2011-01-11 21:31:33 +00:00
if ( switch_channel_direction ( channel ) = = SWITCH_CALL_DIRECTION_INBOUND ) {
switch_mutex_lock ( other_rtp_session - > read_mutex ) ;
if ( zrtp_status_ok = = zrtp_session_get ( other_rtp_session - > zrtp_session , & zrtp_session_info ) ) {
if ( rtp_session - > zrtp_mitm_tries > ZRTP_MITM_TRIES ) {
2013-04-01 14:13:39 +00:00
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ) ;
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ) ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] = 0 ;
2011-01-11 21:31:33 +00:00
} else if ( zrtp_status_ok = = zrtp_resolve_mitm_call ( other_rtp_session - > zrtp_stream , rtp_session - > zrtp_stream ) ) {
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] = 0 ;
2013-04-01 14:13:39 +00:00
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ) ;
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ) ;
2011-01-11 21:31:33 +00:00
rtp_session - > zrtp_mitm_tries + + ;
}
2010-01-07 23:29:06 +00:00
}
2011-01-11 21:31:33 +00:00
switch_mutex_unlock ( other_rtp_session - > read_mutex ) ;
2010-01-07 23:29:06 +00:00
}
}
2010-02-06 03:38:24 +00:00
2010-01-07 23:29:06 +00:00
switch_core_session_rwunlock ( other_session ) ;
}
2009-05-27 01:40:11 +00:00
}
}
2010-02-03 19:19:10 +00:00
} else {
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] = 0 ;
2009-05-23 01:50:56 +00:00
}
}
# endif
2006-04-18 00:24:52 +00:00
if ( bytes < 0 ) {
frame - > datalen = 0 ;
2007-10-31 13:08:45 +00:00
return bytes = = - 2 ? SWITCH_STATUS_TIMEOUT : SWITCH_STATUS_GENERR ;
2016-03-03 15:32:12 +00:00
} else if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
if ( bytes < rtp_header_len ) {
frame - > datalen = 0 ;
return SWITCH_STATUS_BREAK ;
} else {
bytes - = rtp_header_len ;
}
2006-04-18 00:24:52 +00:00
}
2008-05-27 04:30:03 +00:00
2006-04-18 00:24:52 +00:00
frame - > datalen = bytes ;
return SWITCH_STATUS_SUCCESS ;
}
2006-05-04 17:51:53 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_zerocopy_read ( switch_rtp_t * rtp_session ,
2008-05-27 04:30:03 +00:00
void * * data , uint32_t * datalen , switch_payload_t * payload_type , switch_frame_flag_t * flags ,
switch_io_flag_t io_flags )
2006-04-07 17:32:14 +00:00
{
2007-03-07 23:24:09 +00:00
int bytes = 0 ;
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2013-11-07 22:48:00 +00:00
bytes = rtp_common_read ( rtp_session , payload_type , NULL , flags , io_flags ) ;
2012-12-14 01:49:02 +00:00
* data = RTP_BODY ( rtp_session ) ;
2006-04-10 18:09:02 +00:00
2006-04-12 20:48:47 +00:00
if ( bytes < 0 ) {
2006-04-10 18:28:46 +00:00
* datalen = 0 ;
return SWITCH_STATUS_GENERR ;
2006-04-18 00:24:52 +00:00
} else {
2010-08-05 23:43:30 +00:00
if ( bytes > rtp_header_len ) {
bytes - = rtp_header_len ;
}
2006-04-03 21:00:13 +00:00
}
2006-04-10 18:09:02 +00:00
2006-04-10 18:28:46 +00:00
* datalen = bytes ;
return SWITCH_STATUS_SUCCESS ;
2006-04-07 17:32:14 +00:00
}
2006-04-04 17:22:06 +00:00
2014-01-24 22:48:25 +00:00
static int rtp_write_ready ( switch_rtp_t * rtp_session , uint32_t bytes , int line )
{
2014-12-11 03:08:16 +00:00
if ( ! rtp_session ) return 0 ;
2015-05-23 03:08:27 +00:00
if ( rtp_session - > ice . ice_user & & ! ( rtp_session - > ice . rready | | rtp_session - > ice . ready ) ) {
2015-05-20 18:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG3 , " Skip sending %s packet %ld bytes (ice not ready @ line %d!) \n " ,
2014-01-24 22:48:25 +00:00
rtp_type ( rtp_session ) , ( long ) bytes , line ) ;
return 0 ;
}
if ( rtp_session - > dtls & & rtp_session - > dtls - > state ! = DS_READY ) {
2015-05-20 18:14:55 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_DEBUG3 , " Skip sending %s packet %ld bytes (dtls not ready @ line %d!) \n " ,
2014-01-24 22:48:25 +00:00
rtp_type ( rtp_session ) , ( long ) bytes , line ) ;
return 0 ;
}
return 1 ;
}
2008-05-27 04:30:03 +00:00
static int rtp_common_write ( switch_rtp_t * rtp_session ,
rtp_msg_t * send_msg , void * data , uint32_t datalen , switch_payload_t payload , uint32_t timestamp , switch_frame_flag_t * flags )
2006-04-07 17:32:14 +00:00
{
2012-06-22 23:08:59 +00:00
switch_size_t bytes ;
2006-04-21 22:31:08 +00:00
uint8_t send = 1 ;
2008-01-11 04:23:09 +00:00
uint32_t this_ts = 0 ;
2008-01-18 18:14:53 +00:00
int ret ;
2010-04-20 00:07:23 +00:00
switch_time_t now ;
2013-01-08 17:43:16 +00:00
uint8_t m = 0 ;
2006-04-10 16:56:11 +00:00
2007-03-07 23:24:09 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
2014-01-24 22:48:25 +00:00
return - 1 ;
}
if ( ! rtp_write_ready ( rtp_session , datalen , __LINE__ ) ) {
return 0 ;
2007-03-07 23:24:09 +00:00
}
2008-01-18 18:14:53 +00:00
WRITE_INC ( rtp_session ) ;
2008-01-11 04:23:09 +00:00
if ( send_msg ) {
2006-04-18 00:24:52 +00:00
bytes = datalen ;
2013-12-27 20:39:03 +00:00
2013-12-27 20:52:52 +00:00
m = ( uint8_t ) send_msg - > header . m ;
2015-06-11 12:37:45 +00:00
rtp_session - > ts = ntohl ( send_msg - > header . ts ) ;
2013-12-27 20:39:03 +00:00
2007-12-17 23:19:10 +00:00
if ( flags & & * flags & SFF_RFC2833 ) {
2015-06-12 07:38:52 +00:00
if ( rtp_session - > te = = INVALID_PT ) {
ret = 0 ;
goto end ;
}
2007-10-23 21:32:17 +00:00
send_msg - > header . pt = rtp_session - > te ;
}
2008-05-27 04:30:03 +00:00
data = send_msg - > body ;
2010-08-05 23:43:30 +00:00
if ( datalen > rtp_header_len ) {
datalen - = rtp_header_len ;
}
2006-04-18 00:24:52 +00:00
} else {
2007-10-23 21:32:17 +00:00
if ( * flags & SFF_RFC2833 ) {
2015-06-12 07:38:52 +00:00
if ( rtp_session - > te = = INVALID_PT ) {
ret = 0 ;
goto end ;
}
2007-10-23 21:32:17 +00:00
payload = rtp_session - > te ;
}
2007-06-11 22:12:10 +00:00
2008-01-11 04:23:09 +00:00
send_msg = & rtp_session - > send_msg ;
send_msg - > header . pt = payload ;
2013-01-08 17:47:15 +00:00
m = get_next_write_ts ( rtp_session , timestamp ) ;
2008-05-27 04:30:03 +00:00
2008-01-11 04:23:09 +00:00
rtp_session - > send_msg . header . ts = htonl ( rtp_session - > ts ) ;
2013-01-08 17:43:16 +00:00
memcpy ( send_msg - > body , data , datalen ) ;
bytes = datalen + rtp_header_len ;
}
2008-12-09 00:32:51 +00:00
2013-06-18 00:52:37 +00:00
if ( ! switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_VIDEO ) ) {
2013-01-08 17:43:16 +00:00
2013-06-18 00:52:37 +00:00
if ( ( rtp_session - > rtp_bugs & RTP_BUG_NEVER_SEND_MARKER ) ) {
m = 0 ;
} else {
2016-03-03 15:32:12 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & &
( ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] & & ( rtp_session - > ts - rtp_session - > last_write_ts > rtp_session - > samples_per_interval * 10 ) )
| | rtp_session - > ts = = rtp_session - > samples_per_interval ) ) {
2013-06-18 00:52:37 +00:00
m + + ;
}
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & &
( rtp_session - > timer . samplecount - rtp_session - > last_write_samplecount ) > rtp_session - > samples_per_interval * 10 ) {
m + + ;
}
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] & &
( ( unsigned ) ( ( switch_micro_time_now ( ) - rtp_session - > last_write_timestamp ) ) ) > ( rtp_session - > ms_per_packet * 10 ) ) {
m + + ;
}
if ( rtp_session - > cn & & payload ! = rtp_session - > cng_pt ) {
rtp_session - > cn = 0 ;
m + + ;
}
if ( rtp_session - > need_mark & & ! rtp_session - > sending_dtmf ) {
m + + ;
rtp_session - > need_mark = 0 ;
}
2008-12-09 00:32:51 +00:00
}
2012-12-18 22:06:29 +00:00
2013-06-18 00:52:37 +00:00
if ( m ) {
2014-02-28 23:55:04 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] = 1 ;
2013-06-18 00:52:37 +00:00
rtp_session - > ts = 0 ;
2008-12-09 00:32:51 +00:00
}
2013-06-18 00:52:37 +00:00
/* If the marker was set, and the timestamp seems to have started over - set a new SSRC, to indicate this is a new stream */
if ( m & & ! switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_SECURE_SEND ) & & ( rtp_session - > rtp_bugs & RTP_BUG_CHANGE_SSRC_ON_MARKER ) & &
2014-02-28 23:55:04 +00:00
( rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] | | ( rtp_session - > ts < = rtp_session - > last_write_ts & & rtp_session - > last_write_ts > 0 ) ) ) {
2013-06-18 00:52:37 +00:00
switch_rtp_set_ssrc ( rtp_session , ( uint32_t ) ( ( intptr_t ) rtp_session + ( uint32_t ) switch_epoch_time_now ( NULL ) ) ) ;
2007-03-17 01:52:05 +00:00
}
2010-11-10 22:55:56 +00:00
2013-06-18 00:52:37 +00:00
if ( ! switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_VIDEO ) & & ! switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_UDPTL ) ) {
send_msg - > header . m = ( m & & ! ( rtp_session - > rtp_bugs & RTP_BUG_NEVER_SEND_MARKER ) ) ? 1 : 0 ;
2011-08-30 20:00:07 +00:00
}
2006-04-03 21:00:13 +00:00
}
2006-04-18 00:24:52 +00:00
2016-07-28 19:13:37 +00:00
2015-09-15 17:14:09 +00:00
if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_GEN_TS_DELTA ) | | switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_VIDEO ) ) {
2013-07-11 22:38:24 +00:00
/* Normalize the timestamps to our own base by generating a made up starting point then adding the measured deltas to that base
so if the timestamps and ssrc of the source change , it will not break the other end ' s jitter bufffer / decoder etc * cough * CHROME * cough *
*/
if ( ! rtp_session - > ts_norm . ts ) {
2016-02-26 23:42:41 +00:00
if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_GEN_TS_DELTA ) ) {
rtp_session - > ts_norm . ts = ( uint32_t ) rand ( ) % 1000000 + 1 ;
} else {
switch_core_timer_sync ( & rtp_session - > timer ) ;
rtp_session - > ts_norm . ts = rtp_session - > timer . samplecount ;
}
2013-07-11 22:38:24 +00:00
}
if ( ! rtp_session - > ts_norm . last_ssrc | | send_msg - > header . ssrc ! = rtp_session - > ts_norm . last_ssrc ) {
2015-09-18 03:31:22 +00:00
if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_GEN_TS_DELTA ) ) {
if ( rtp_session - > ts_norm . last_ssrc ) {
rtp_session - > ts_norm . delta_ct = 1 ;
rtp_session - > ts_norm . delta_ttl = 0 ;
if ( rtp_session - > ts_norm . delta ) {
rtp_session - > ts_norm . ts + = rtp_session - > ts_norm . delta ;
}
2013-07-11 22:38:24 +00:00
}
}
2015-09-18 03:31:22 +00:00
2013-07-11 22:38:24 +00:00
rtp_session - > ts_norm . last_ssrc = send_msg - > header . ssrc ;
rtp_session - > ts_norm . last_frame = ntohl ( send_msg - > header . ts ) ;
}
2014-11-20 18:07:05 +00:00
2013-07-11 22:38:24 +00:00
if ( ntohl ( send_msg - > header . ts ) ! = rtp_session - > ts_norm . last_frame ) {
2015-09-18 03:31:22 +00:00
if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_GEN_TS_DELTA ) ) {
int32_t delta = ( int32_t ) ( ntohl ( send_msg - > header . ts ) - rtp_session - > ts_norm . last_frame ) ;
2015-09-15 17:14:09 +00:00
2015-09-18 15:06:41 +00:00
if ( switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_VIDEO ) & & delta > 0 & & delta < 90000 ) {
rtp_session - > ts_norm . delta = delta ;
}
2015-09-18 03:31:22 +00:00
rtp_session - > ts_norm . ts + = rtp_session - > ts_norm . delta ;
} else {
switch_core_timer_sync ( & rtp_session - > timer ) ;
rtp_session - > ts_norm . ts = rtp_session - > timer . samplecount ;
}
2013-07-11 22:38:24 +00:00
}
rtp_session - > ts_norm . last_frame = ntohl ( send_msg - > header . ts ) ;
send_msg - > header . ts = htonl ( rtp_session - > ts_norm . ts ) ;
}
2008-01-16 06:01:53 +00:00
send_msg - > header . ssrc = htonl ( rtp_session - > ssrc ) ;
2006-04-03 21:00:13 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_GOOGLEHACK ] & & rtp_session - > send_msg . header . pt = = 97 ) {
2015-10-06 14:34:19 +00:00
rtp_session - > last_rtp_hdr . pt = 102 ;
2006-04-19 20:38:02 +00:00
}
2006-12-13 22:58:32 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VAD ] & &
2015-10-06 14:34:19 +00:00
rtp_session - > last_rtp_hdr . pt = = rtp_session - > vad_data . read_codec - > implementation - > ianacode ) {
2010-11-19 00:24:32 +00:00
2008-05-27 04:30:03 +00:00
int16_t decoded [ SWITCH_RECOMMENDED_BUFFER_SIZE / sizeof ( int16_t ) ] = { 0 } ;
2007-04-07 01:57:54 +00:00
uint32_t rate = 0 ;
2007-12-17 23:19:10 +00:00
uint32_t codec_flags = 0 ;
2006-04-21 22:31:08 +00:00
uint32_t len = sizeof ( decoded ) ;
2009-01-25 21:23:07 +00:00
time_t now = switch_epoch_time_now ( NULL ) ;
2006-04-24 14:53:54 +00:00
send = 0 ;
2016-04-01 00:25:56 +00:00
2006-04-21 22:31:08 +00:00
if ( rtp_session - > vad_data . scan_freq & & rtp_session - > vad_data . next_scan < = now ) {
rtp_session - > vad_data . bg_count = rtp_session - > vad_data . bg_level = 0 ;
rtp_session - > vad_data . next_scan = now + rtp_session - > vad_data . scan_freq ;
}
if ( switch_core_codec_decode ( & rtp_session - > vad_data . vad_codec ,
rtp_session - > vad_data . read_codec ,
data ,
datalen ,
2007-10-19 15:31:02 +00:00
rtp_session - > vad_data . read_codec - > implementation - > actual_samples_per_second ,
2007-12-17 23:19:10 +00:00
decoded , & len , & rate , & codec_flags ) = = SWITCH_STATUS_SUCCESS ) {
2006-04-21 22:31:08 +00:00
2006-04-24 14:53:54 +00:00
uint32_t energy = 0 ;
2006-04-21 22:31:08 +00:00
uint32_t x , y = 0 , z = len / sizeof ( int16_t ) ;
uint32_t score = 0 ;
2007-11-24 21:48:25 +00:00
int divisor = 0 ;
2006-04-21 22:31:08 +00:00
if ( z ) {
2008-05-27 04:30:03 +00:00
2007-11-24 21:48:25 +00:00
if ( ! ( divisor = rtp_session - > vad_data . read_codec - > implementation - > actual_samples_per_second / 8000 ) ) {
divisor = 1 ;
}
2006-04-21 22:31:08 +00:00
for ( x = 0 ; x < z ; x + + ) {
2006-04-24 14:53:54 +00:00
energy + = abs ( decoded [ y ] ) ;
2006-04-21 22:31:08 +00:00
y + = rtp_session - > vad_data . read_codec - > implementation - > number_of_channels ;
}
2008-05-27 04:30:03 +00:00
2006-04-21 22:31:08 +00:00
if ( + + rtp_session - > vad_data . start_count < rtp_session - > vad_data . start ) {
send = 1 ;
} else {
2007-11-24 21:48:25 +00:00
score = ( energy / ( z / divisor ) ) ;
2006-04-21 22:31:08 +00:00
if ( score & & ( rtp_session - > vad_data . bg_count < rtp_session - > vad_data . bg_len ) ) {
rtp_session - > vad_data . bg_level + = score ;
if ( + + rtp_session - > vad_data . bg_count = = rtp_session - > vad_data . bg_len ) {
rtp_session - > vad_data . bg_level / = rtp_session - > vad_data . bg_len ;
}
send = 1 ;
} else {
2007-06-09 19:01:43 +00:00
if ( score > rtp_session - > vad_data . bg_level & & ! switch_test_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_TALKING ) ) {
2006-04-21 22:31:08 +00:00
uint32_t diff = score - rtp_session - > vad_data . bg_level ;
2016-04-01 00:25:56 +00:00
2006-04-21 22:31:08 +00:00
if ( rtp_session - > vad_data . hangover_hits ) {
rtp_session - > vad_data . hangover_hits - - ;
}
2007-03-30 00:13:31 +00:00
if ( diff > = rtp_session - > vad_data . diff_level | | + + rtp_session - > vad_data . hangunder_hits > = rtp_session - > vad_data . hangunder ) {
2007-06-09 19:01:43 +00:00
2006-04-21 22:31:08 +00:00
switch_set_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_TALKING ) ;
2016-04-01 00:25:56 +00:00
rtp_session - > vad_data . start_talking = switch_time_now ( ) ;
2010-11-10 22:55:56 +00:00
if ( ! ( rtp_session - > rtp_bugs & RTP_BUG_NEVER_SEND_MARKER ) ) {
send_msg - > header . m = 1 ;
}
2007-03-30 00:13:31 +00:00
rtp_session - > vad_data . hangover_hits = rtp_session - > vad_data . hangunder_hits = rtp_session - > vad_data . cng_count = 0 ;
2006-04-21 22:31:08 +00:00
if ( switch_test_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_EVENTS_TALK ) ) {
2011-12-16 15:16:37 +00:00
if ( ( rtp_session - > vad_data . fire_events & VAD_FIRE_TALK ) ) {
2011-12-15 19:44:25 +00:00
switch_event_t * event ;
if ( switch_event_create ( & event , SWITCH_EVENT_TALK ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( switch_core_session_get_channel ( rtp_session - > vad_data . session ) , event ) ;
switch_event_fire ( & event ) ;
}
2006-04-21 22:31:08 +00:00
}
}
2007-03-29 22:31:56 +00:00
}
2006-04-21 22:31:08 +00:00
} else {
if ( rtp_session - > vad_data . hangunder_hits ) {
rtp_session - > vad_data . hangunder_hits - - ;
}
if ( switch_test_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_TALKING ) ) {
if ( + + rtp_session - > vad_data . hangover_hits > = rtp_session - > vad_data . hangover ) {
2016-04-01 00:25:56 +00:00
rtp_session - > vad_data . stop_talking = switch_time_now ( ) ;
rtp_session - > vad_data . total_talk_time + = ( rtp_session - > vad_data . stop_talking - rtp_session - > vad_data . start_talking ) ;
2006-04-21 22:31:08 +00:00
switch_clear_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_TALKING ) ;
2016-04-01 00:25:56 +00:00
2007-03-30 00:13:31 +00:00
rtp_session - > vad_data . hangover_hits = rtp_session - > vad_data . hangunder_hits = rtp_session - > vad_data . cng_count = 0 ;
2006-04-21 22:31:08 +00:00
if ( switch_test_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_EVENTS_NOTALK ) ) {
2016-04-01 00:25:56 +00:00
2011-12-16 15:16:37 +00:00
if ( ( rtp_session - > vad_data . fire_events & VAD_FIRE_NOT_TALK ) ) {
2011-12-15 19:44:25 +00:00
switch_event_t * event ;
if ( switch_event_create ( & event , SWITCH_EVENT_NOTALK ) = = SWITCH_STATUS_SUCCESS ) {
switch_channel_event_set_data ( switch_core_session_get_channel ( rtp_session - > vad_data . session ) , event ) ;
switch_event_fire ( & event ) ;
}
2007-03-29 22:31:56 +00:00
}
2006-04-21 22:31:08 +00:00
}
}
}
}
}
}
2007-03-29 22:31:56 +00:00
2006-04-21 22:31:08 +00:00
if ( switch_test_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_TALKING ) ) {
send = 1 ;
2008-05-27 04:30:03 +00:00
}
2006-04-21 22:31:08 +00:00
}
} else {
2008-01-18 18:14:53 +00:00
ret = - 1 ;
goto end ;
2006-04-21 22:31:08 +00:00
}
}
2013-06-18 00:52:37 +00:00
if ( ! switch_rtp_test_flag ( rtp_session , SWITCH_RTP_FLAG_VIDEO ) ) {
this_ts = ntohl ( send_msg - > header . ts ) ;
2008-01-11 05:42:50 +00:00
2014-07-03 20:17:12 +00:00
if ( ( this_ts - rtp_session - > last_write_ts ) > 16000 ) {
2014-02-28 23:55:04 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] = 1 ;
2013-06-18 00:52:37 +00:00
}
2011-09-06 16:30:28 +00:00
2016-02-01 22:23:36 +00:00
if ( ! switch_rtp_ready ( rtp_session ) | | rtp_session - > sending_dtmf | |
( ! rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] & & this_ts > rtp_session - > one_second & & this_ts < rtp_session - > last_write_ts ) ) {
2013-06-18 00:52:37 +00:00
send = 0 ;
}
2008-01-11 04:23:09 +00:00
}
2007-04-07 01:57:54 +00:00
2013-10-28 18:39:23 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_PAUSE ] ) {
send = 0 ;
}
2013-07-11 22:38:24 +00:00
2008-01-11 04:23:09 +00:00
if ( send ) {
2008-01-11 16:01:07 +00:00
send_msg - > header . seq = htons ( + + rtp_session - > seq ) ;
2008-05-27 04:30:03 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_BYTESWAP ] & & send_msg - > header . pt = = rtp_session - > payload ) {
2011-03-21 19:31:10 +00:00
switch_swap_linear ( ( int16_t * ) send_msg - > body , ( int ) datalen ) ;
}
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] ) {
2008-01-16 06:01:53 +00:00
int sbytes = ( int ) bytes ;
err_status_t stat ;
2008-05-27 04:30:03 +00:00
2008-01-17 04:16:04 +00:00
2015-04-07 23:02:24 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND_RESET ] | | ! rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] ) {
2013-01-15 05:17:28 +00:00
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_SECURE_SEND_RESET ) ;
2013-02-03 05:57:27 +00:00
srtp_dealloc ( rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] ) ;
rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] = NULL ;
2015-04-07 23:02:24 +00:00
if ( ( stat = srtp_create ( & rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] ,
& rtp_session - > send_policy [ rtp_session - > srtp_idx_rtp ] ) ) | | ! rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] ) {
2015-01-22 03:08:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR ,
" Error! RE-Activating %s Secure RTP SEND \n " , rtp_type ( rtp_session ) ) ;
2015-04-07 23:02:24 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] = 0 ;
2008-01-18 18:14:53 +00:00
ret = - 1 ;
goto end ;
2008-01-17 04:16:04 +00:00
} else {
2015-01-22 03:08:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO ,
" RE-Activating %s Secure RTP SEND \n " , rtp_type ( rtp_session ) ) ;
2008-01-17 04:16:04 +00:00
}
}
2008-05-27 04:30:03 +00:00
2008-01-17 04:16:04 +00:00
2013-02-03 05:57:27 +00:00
stat = srtp_protect ( rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] , & send_msg - > header , & sbytes ) ;
2013-06-18 00:52:37 +00:00
2008-01-16 06:01:53 +00:00
if ( stat ) {
2015-01-22 03:08:09 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR ,
" Error: %s SRTP protection failed with code %d \n " , rtp_type ( rtp_session ) , stat ) ;
2008-01-16 06:01:53 +00:00
}
2013-02-02 02:07:56 +00:00
2008-01-16 06:01:53 +00:00
bytes = sbytes ;
}
2011-05-02 16:33:57 +00:00
# endif
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
/* ZRTP Send */
2012-12-18 22:06:29 +00:00
if ( zrtp_on & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] ) {
2009-05-20 23:04:05 +00:00
unsigned int sbytes = ( int ) bytes ;
zrtp_status_t stat = zrtp_status_fail ;
2013-01-15 05:17:28 +00:00
2010-02-06 03:38:24 +00:00
stat = zrtp_process_rtp ( rtp_session - > zrtp_stream , ( void * ) send_msg , & sbytes ) ;
2009-05-20 23:04:05 +00:00
switch ( stat ) {
case zrtp_status_ok :
break ;
case zrtp_status_drop :
2013-01-15 05:17:28 +00:00
/* switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rtp_session->session), SWITCH_LOG_DEBUG, "Error: zRTP protection drop with code %d\n", stat); */
2010-02-03 19:19:10 +00:00
ret = ( int ) bytes ;
goto end ;
2009-05-21 22:37:15 +00:00
break ;
2009-05-20 23:04:05 +00:00
case zrtp_status_fail :
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error: zRTP protection fail with code %d \n " , stat ) ;
2009-05-21 22:37:15 +00:00
break ;
2009-05-20 23:04:05 +00:00
default :
break ;
}
2010-02-06 03:38:24 +00:00
2009-05-20 23:04:05 +00:00
bytes = sbytes ;
}
# endif
2009-04-26 22:10:28 +00:00
2013-01-15 15:15:39 +00:00
now = switch_micro_time_now ( ) ;
2009-04-26 22:10:05 +00:00
# ifdef RTP_DEBUG_WRITE_DELTA
{
int delta = ( int ) ( now - rtp_session - > send_time ) / 1000 ;
2012-12-26 16:57:43 +00:00
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " WRITE %d delta %d \n " , ( int ) bytes , delta ) ;
2009-04-26 22:10:05 +00:00
}
# endif
2010-04-20 00:07:23 +00:00
rtp_session - > send_time = now ;
2009-04-26 22:10:05 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DEBUG_RTP_WRITE ] ) {
2013-08-08 00:19:05 +00:00
const char * tx_host ;
const char * old_host ;
const char * my_host ;
2009-10-29 17:52:52 +00:00
2015-08-27 18:42:52 +00:00
char bufa [ 50 ] , bufb [ 50 ] , bufc [ 50 ] ;
2010-02-06 03:38:24 +00:00
2015-01-21 01:20:20 +00:00
tx_host = switch_get_addr ( bufa , sizeof ( bufa ) , rtp_session - > rtp_from_addr ) ;
2013-08-08 00:19:05 +00:00
old_host = switch_get_addr ( bufb , sizeof ( bufb ) , rtp_session - > remote_addr ) ;
my_host = switch_get_addr ( bufc , sizeof ( bufc ) , rtp_session - > local_addr ) ;
2009-10-29 17:52:52 +00:00
2013-08-08 00:19:05 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG_CLEAN ( rtp_session - > session ) , SWITCH_LOG_CONSOLE ,
2015-01-09 19:36:57 +00:00
" W %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u seq=%u m=%d \n " ,
2013-08-08 00:19:05 +00:00
rtp_session - > session ? switch_channel_get_name ( switch_core_session_get_channel ( rtp_session - > session ) ) : " NoName " ,
( long ) bytes ,
my_host , switch_sockaddr_get_port ( rtp_session - > local_addr ) ,
old_host , rtp_session - > remote_port ,
2015-01-21 01:20:20 +00:00
tx_host , switch_sockaddr_get_port ( rtp_session - > rtp_from_addr ) ,
2015-01-09 19:36:57 +00:00
send_msg - > header . pt , ntohl ( send_msg - > header . ts ) , ntohs ( send_msg - > header . seq ) , send_msg - > header . m ) ;
2010-02-06 03:38:24 +00:00
2009-10-29 17:52:52 +00:00
}
2015-01-09 19:36:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_NACK ] ) {
if ( ! rtp_session - > vbw ) {
2015-09-19 04:36:11 +00:00
switch_jb_create ( & rtp_session - > vbw , SJB_VIDEO , 30 , 30 , rtp_session - > pool ) ;
2015-09-21 19:08:32 +00:00
if ( rtp_session - > vbw ) {
switch_jb_set_flag ( rtp_session - > vbw , SJB_QUEUE_ONLY ) ;
//switch_jb_debug_level(rtp_session->vbw, 10);
}
2015-01-09 19:36:57 +00:00
}
2015-09-21 19:08:32 +00:00
switch_jb_put_packet ( rtp_session - > vbw , ( switch_rtp_packet_t * ) send_msg , bytes ) ;
2015-01-09 19:36:57 +00:00
}
2009-10-29 17:52:52 +00:00
2015-01-09 19:36:57 +00:00
# ifdef RTP_WRITE_PLOSS
{
int r = ( rand ( ) % 10000 ) + 1 ;
if ( r < = 200 ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ALERT ,
" Simulate dropping packet ......... ts: %u seq: %u \n " , ntohl ( send_msg - > header . ts ) , ntohs ( send_msg - > header . seq ) ) ;
} else {
if ( switch_socket_sendto ( rtp_session - > sock_output , rtp_session - > remote_addr , 0 , ( void * ) send_msg , & bytes ) ! = SWITCH_STATUS_SUCCESS ) {
rtp_session - > seq - - ;
ret = - 1 ;
goto end ;
}
}
}
# else
2015-03-26 20:00:55 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
//
// rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]++;
//
// //switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "SEND %u\n", ntohs(send_msg->header.seq));
//}
2008-07-03 18:50:15 +00:00
if ( switch_socket_sendto ( rtp_session - > sock_output , rtp_session - > remote_addr , 0 , ( void * ) send_msg , & bytes ) ! = SWITCH_STATUS_SUCCESS ) {
2008-01-11 04:23:09 +00:00
rtp_session - > seq - - ;
2008-01-18 18:14:53 +00:00
ret = - 1 ;
goto end ;
2008-01-11 01:27:24 +00:00
}
2015-01-09 19:36:57 +00:00
# endif
2011-08-31 17:03:57 +00:00
rtp_session - > last_write_ts = this_ts ;
2014-02-28 23:55:04 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] = 0 ;
2008-05-27 04:30:03 +00:00
2011-09-01 00:30:51 +00:00
if ( rtp_session - > queue_delay ) {
2011-11-14 18:37:45 +00:00
rtp_session - > delay_samples = rtp_session - > queue_delay ;
2011-09-01 00:30:51 +00:00
rtp_session - > queue_delay = 0 ;
}
2009-04-15 15:08:21 +00:00
rtp_session - > stats . outbound . raw_bytes + = bytes ;
rtp_session - > stats . outbound . packet_count + + ;
2015-05-13 16:50:04 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_ENABLE_RTCP ] ) {
rtp_session - > stats . rtcp . sent_pkt_count + + ;
}
2009-04-03 21:48:52 +00:00
2015-06-12 07:38:52 +00:00
if ( send_msg - > header . pt = = rtp_session - > cng_pt ) {
2009-04-15 15:08:21 +00:00
rtp_session - > stats . outbound . cng_packet_count + + ;
2009-04-03 21:48:52 +00:00
} else {
2009-04-15 15:08:21 +00:00
rtp_session - > stats . outbound . media_packet_count + + ;
rtp_session - > stats . outbound . media_bytes + = bytes ;
2009-04-03 21:48:52 +00:00
}
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_USE_TIMER ] ) {
2007-03-17 01:52:05 +00:00
rtp_session - > last_write_samplecount = rtp_session - > timer . samplecount ;
}
2014-11-15 01:01:56 +00:00
rtp_session - > last_write_timestamp = switch_micro_time_now ( ) ;
2006-04-21 22:31:08 +00:00
}
2008-01-18 18:14:53 +00:00
ret = ( int ) bytes ;
2010-04-20 00:07:23 +00:00
end :
2008-01-18 18:14:53 +00:00
WRITE_DEC ( rtp_session ) ;
return ret ;
2006-04-03 21:00:13 +00:00
}
2006-04-29 23:43:28 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_disable_vad ( switch_rtp_t * rtp_session )
2006-04-21 22:31:08 +00:00
{
2007-03-07 23:24:09 +00:00
2013-05-15 13:08:41 +00:00
if ( ! rtp_session ) {
2007-03-07 23:24:09 +00:00
return SWITCH_STATUS_FALSE ;
}
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_VAD ] ) {
2006-04-21 22:31:08 +00:00
return SWITCH_STATUS_GENERR ;
}
switch_core_codec_destroy ( & rtp_session - > vad_data . vad_codec ) ;
2012-12-18 22:06:29 +00:00
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_VAD ) ;
2006-04-21 22:31:08 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2007-03-30 00:15:25 +00:00
SWITCH_DECLARE ( switch_status_t ) switch_rtp_enable_vad ( switch_rtp_t * rtp_session , switch_core_session_t * session , switch_codec_t * codec ,
switch_vad_flag_t flags )
2006-04-21 22:31:08 +00:00
{
2007-03-07 23:24:09 +00:00
if ( ! switch_rtp_ready ( rtp_session ) ) {
return SWITCH_STATUS_FALSE ;
}
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VAD ] ) {
2006-04-21 22:31:08 +00:00
return SWITCH_STATUS_GENERR ;
}
2011-12-28 21:27:39 +00:00
2006-04-21 22:31:08 +00:00
memset ( & rtp_session - > vad_data , 0 , sizeof ( rtp_session - > vad_data ) ) ;
2007-03-29 22:31:56 +00:00
2013-01-15 05:17:28 +00:00
if ( switch_true ( switch_channel_get_variable ( switch_core_session_get_channel ( rtp_session - > session ) , " fire_talk_events " ) ) ) {
2011-12-16 15:16:37 +00:00
rtp_session - > vad_data . fire_events | = VAD_FIRE_TALK ;
}
2013-01-15 05:17:28 +00:00
if ( switch_true ( switch_channel_get_variable ( switch_core_session_get_channel ( rtp_session - > session ) , " fire_not_talk_events " ) ) ) {
2011-12-16 15:16:37 +00:00
rtp_session - > vad_data . fire_events | = VAD_FIRE_NOT_TALK ;
}
2006-04-21 22:31:08 +00:00
if ( switch_core_codec_init ( & rtp_session - > vad_data . vad_codec ,
2006-06-23 20:14:29 +00:00
codec - > implementation - > iananame ,
2015-03-19 19:26:47 +00:00
codec - > implementation - > modname ,
2006-10-09 02:24:43 +00:00
NULL ,
2006-04-21 22:31:08 +00:00
codec - > implementation - > samples_per_second ,
2008-10-20 17:48:42 +00:00
codec - > implementation - > microseconds_per_packet / 1000 ,
2006-04-21 22:31:08 +00:00
codec - > implementation - > number_of_channels ,
2007-03-30 00:13:31 +00:00
SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE , NULL , rtp_session - > pool ) ! = SWITCH_STATUS_SUCCESS ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Can't load codec? \n " ) ;
2006-04-21 22:31:08 +00:00
return SWITCH_STATUS_FALSE ;
}
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_DEBUG , " Activate VAD codec %s %dms \n " , codec - > implementation - > iananame ,
2008-10-20 17:48:42 +00:00
codec - > implementation - > microseconds_per_packet / 1000 ) ;
2006-04-21 22:31:08 +00:00
rtp_session - > vad_data . diff_level = 400 ;
rtp_session - > vad_data . hangunder = 15 ;
rtp_session - > vad_data . hangover = 40 ;
2006-04-22 16:25:33 +00:00
rtp_session - > vad_data . bg_len = 5 ;
rtp_session - > vad_data . bg_count = 5 ;
rtp_session - > vad_data . bg_level = 300 ;
2006-04-21 22:31:08 +00:00
rtp_session - > vad_data . read_codec = codec ;
rtp_session - > vad_data . session = session ;
rtp_session - > vad_data . flags = flags ;
rtp_session - > vad_data . cng_freq = 50 ;
rtp_session - > vad_data . ts = 1 ;
2006-04-22 16:25:33 +00:00
rtp_session - > vad_data . start = 0 ;
2009-01-25 21:23:07 +00:00
rtp_session - > vad_data . next_scan = switch_epoch_time_now ( NULL ) ;
2006-04-21 22:31:08 +00:00
rtp_session - > vad_data . scan_freq = 0 ;
2016-04-01 00:25:56 +00:00
if ( switch_test_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_TALKING ) ) {
rtp_session - > vad_data . start_talking = switch_time_now ( ) ;
}
2012-12-18 22:06:29 +00:00
switch_rtp_set_flag ( rtp_session , SWITCH_RTP_FLAG_VAD ) ;
2006-04-22 16:12:03 +00:00
switch_set_flag ( & rtp_session - > vad_data , SWITCH_VAD_FLAG_CNG ) ;
2006-04-21 22:31:08 +00:00
return SWITCH_STATUS_SUCCESS ;
}
2008-01-11 04:23:09 +00:00
SWITCH_DECLARE ( int ) switch_rtp_write_frame ( switch_rtp_t * rtp_session , switch_frame_t * frame )
2006-04-18 16:20:47 +00:00
{
2007-03-07 23:24:09 +00:00
uint8_t fwd = 0 ;
2008-01-11 04:23:09 +00:00
void * data = NULL ;
uint32_t len , ts = 0 ;
2009-11-18 19:22:45 +00:00
switch_payload_t payload = 0 ;
2008-01-11 04:23:09 +00:00
rtp_msg_t * send_msg = NULL ;
2015-03-03 22:30:26 +00:00
srtp_hdr_t local_header ;
int r = 0 ;
2010-02-06 03:38:24 +00:00
2008-01-18 18:14:53 +00:00
if ( ! switch_rtp_ready ( rtp_session ) | | ! rtp_session - > remote_addr ) {
2007-03-07 23:24:09 +00:00
return - 1 ;
}
2014-01-24 22:48:25 +00:00
if ( ! rtp_write_ready ( rtp_session , frame - > datalen , __LINE__ ) ) {
return 0 ;
}
2010-02-06 03:38:24 +00:00
2013-06-18 00:52:37 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_VIDEO]) {
// rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_READ]++;
// rtp_session->flags[SWITCH_RTP_FLAG_DEBUG_RTP_WRITE]++;
//}
2012-07-03 18:17:38 +00:00
if ( switch_test_flag ( frame , SFF_PROXY_PACKET ) | | switch_test_flag ( frame , SFF_UDPTL_PACKET ) | |
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] | | rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] ) {
2012-07-16 23:47:45 +00:00
2013-06-18 00:52:37 +00:00
//if (rtp_session->flags[SWITCH_RTP_FLAG_PROXY_MEDIA] || rtp_session->flags[SWITCH_RTP_FLAG_UDPTL]) {
2008-02-21 17:48:41 +00:00
switch_size_t bytes ;
2015-08-27 18:42:52 +00:00
//char bufa[50];
2011-04-22 21:43:29 +00:00
2008-02-21 17:48:41 +00:00
/* Fast PASS! */
2010-05-13 02:25:54 +00:00
if ( ! switch_test_flag ( frame , SFF_PROXY_PACKET ) & & ! switch_test_flag ( frame , SFF_UDPTL_PACKET ) ) {
2008-02-21 17:48:41 +00:00
return 0 ;
}
bytes = frame - > packetlen ;
2011-04-22 21:43:29 +00:00
//tx_host = switch_get_addr(bufa, sizeof(bufa), rtp_session->remote_addr);
2010-02-06 03:38:24 +00:00
2009-11-18 19:22:45 +00:00
send_msg = frame - > packet ;
2012-12-18 22:06:29 +00:00
if ( ! rtp_session - > flags [ SWITCH_RTP_FLAG_UDPTL ] & & ! switch_test_flag ( frame , SFF_UDPTL_PACKET ) ) {
2012-10-05 16:49:29 +00:00
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] & & rtp_session - > payload > 0 ) {
2012-07-19 17:40:34 +00:00
send_msg - > header . pt = rtp_session - > payload ;
}
2012-07-16 23:47:45 +00:00
2012-07-19 17:40:34 +00:00
send_msg - > header . ssrc = htonl ( rtp_session - > ssrc ) ;
2013-09-04 19:15:44 +00:00
send_msg - > header . seq = htons ( + + rtp_session - > seq ) ;
2012-07-16 23:47:45 +00:00
}
2016-09-22 23:52:48 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_DEBUG_RTP_WRITE ] ) {
const char * tx_host ;
const char * old_host ;
const char * my_host ;
char bufa [ 50 ] , bufb [ 50 ] , bufc [ 50 ] ;
tx_host = switch_get_addr ( bufa , sizeof ( bufa ) , rtp_session - > rtp_from_addr ) ;
old_host = switch_get_addr ( bufb , sizeof ( bufb ) , rtp_session - > remote_addr ) ;
my_host = switch_get_addr ( bufc , sizeof ( bufc ) , rtp_session - > local_addr ) ;
printf (
" W %s b=%4ld %s:%u %s:%u %s:%u pt=%d ts=%u seq=%u m=%d \n " ,
rtp_session - > session ? switch_channel_get_name ( switch_core_session_get_channel ( rtp_session - > session ) ) : " NoName " ,
( long ) bytes ,
my_host , switch_sockaddr_get_port ( rtp_session - > local_addr ) ,
old_host , rtp_session - > remote_port ,
tx_host , switch_sockaddr_get_port ( rtp_session - > rtp_from_addr ) ,
send_msg - > header . pt , ntohl ( send_msg - > header . ts ) , ntohs ( send_msg - > header . seq ) , send_msg - > header . m ) ;
}
2009-11-23 16:32:25 +00:00
if ( switch_socket_sendto ( rtp_session - > sock_output , rtp_session - > remote_addr , 0 , frame - > packet , & bytes ) ! = SWITCH_STATUS_SUCCESS ) {
return - 1 ;
2008-02-21 17:48:41 +00:00
}
2010-02-06 03:38:24 +00:00
2009-04-03 21:48:52 +00:00
2009-04-15 15:08:21 +00:00
rtp_session - > stats . outbound . raw_bytes + = bytes ;
rtp_session - > stats . outbound . media_bytes + = bytes ;
rtp_session - > stats . outbound . media_packet_count + + ;
rtp_session - > stats . outbound . packet_count + + ;
2008-02-21 17:48:41 +00:00
return ( int ) bytes ;
}
2009-05-23 01:50:56 +00:00
# ifdef ENABLE_ZRTP
2012-12-18 22:06:29 +00:00
if ( zrtp_on & & rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] ) {
2009-05-27 01:40:11 +00:00
zrtp_session_info_t zrtp_session_info ;
2010-02-06 03:38:24 +00:00
if ( zrtp_status_ok = = zrtp_session_get ( rtp_session - > zrtp_session , & zrtp_session_info ) ) {
if ( zrtp_session_info . sas_is_ready ) {
2013-01-15 05:17:28 +00:00
switch_channel_t * channel = switch_core_session_get_channel ( rtp_session - > session ) ;
2010-01-07 23:29:06 +00:00
2012-05-29 18:10:15 +00:00
const char * uuid = switch_channel_get_partner_uuid ( channel ) ;
2010-02-06 03:38:24 +00:00
if ( uuid ) {
2010-01-07 23:29:06 +00:00
switch_core_session_t * other_session ;
if ( ( other_session = switch_core_session_locate ( uuid ) ) ) {
switch_channel_t * other_channel = switch_core_session_get_channel ( other_session ) ;
2010-02-03 19:19:10 +00:00
switch_rtp_t * other_rtp_session = switch_channel_get_private ( other_channel , " __zrtp_audio_rtp_session " ) ;
2010-01-07 23:29:06 +00:00
if ( other_rtp_session ) {
if ( zrtp_status_ok = = zrtp_session_get ( other_rtp_session - > zrtp_session , & zrtp_session_info ) ) {
if ( rtp_session - > zrtp_mitm_tries > ZRTP_MITM_TRIES ) {
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] = 0 ;
2013-04-01 14:13:39 +00:00
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ) ;
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ) ;
2010-02-03 19:19:10 +00:00
} else if ( zrtp_status_ok = = zrtp_resolve_mitm_call ( other_rtp_session - > zrtp_stream , rtp_session - > zrtp_stream ) ) {
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ] = 0 ;
rtp_session - > flags [ SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ] = 0 ;
2013-04-01 14:13:39 +00:00
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_RECV ) ;
switch_rtp_clear_flag ( other_rtp_session , SWITCH_ZRTP_FLAG_SECURE_MITM_SEND ) ;
2010-01-07 23:29:06 +00:00
rtp_session - > zrtp_mitm_tries + + ;
}
rtp_session - > zrtp_mitm_tries + + ;
}
}
switch_core_session_rwunlock ( other_session ) ;
}
2009-05-27 01:40:11 +00:00
}
}
2009-05-24 19:11:36 +00:00
}
2009-05-23 01:50:56 +00:00
}
# endif
2008-02-21 17:48:41 +00:00
2014-11-14 02:52:57 +00:00
fwd = ( rtp_session - > flags [ SWITCH_RTP_FLAG_RAW_WRITE ] & &
( switch_test_flag ( frame , SFF_RAW_RTP ) | | switch_test_flag ( frame , SFF_RAW_RTP_PARSE_FRAME ) ) ) ? 1 : 0 ;
2007-03-07 23:24:09 +00:00
2011-11-14 18:37:45 +00:00
if ( ! fwd & & ! rtp_session - > sending_dtmf & & ! rtp_session - > queue_delay & &
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RAW_WRITE ] & & ( rtp_session - > rtp_bugs & RTP_BUG_GEN_ONE_GEN_ALL ) ) {
2013-01-15 05:17:28 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_WARNING , " Generating RTP locally but timestamp passthru is configured, disabling.... \n " ) ;
2012-12-18 22:06:29 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RAW_WRITE ] = 0 ;
2014-02-28 23:55:04 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] = 1 ;
2011-10-07 15:40:30 +00:00
}
2007-12-11 19:23:57 +00:00
switch_assert ( frame ! = NULL ) ;
2007-03-07 21:21:42 +00:00
if ( switch_test_flag ( frame , SFF_CNG ) ) {
2015-06-12 07:38:52 +00:00
if ( rtp_session - > cng_pt ! = INVALID_PT ) {
2009-11-18 19:22:45 +00:00
payload = rtp_session - > cng_pt ;
} else {
2010-02-06 03:38:24 +00:00
return ( int ) frame - > packetlen ;
2009-11-18 19:22:45 +00:00
}
2007-03-07 21:21:42 +00:00
} else {
2007-03-10 00:43:53 +00:00
payload = rtp_session - > payload ;
2014-02-19 02:05:29 +00:00
#if 0
if ( rtp_session - > pmaps & & * rtp_session - > pmaps ) {
payload_map_t * pmap ;
for ( pmap = * rtp_session - > pmaps ; pmap ; pmap = pmap - > next ) {
if ( pmap - > current ) {
payload = pmap - > pt ;
}
}
}
# endif
2007-03-07 21:21:42 +00:00
}
2016-07-11 03:25:14 +00:00
if ( switch_test_flag ( frame , SFF_RTP_HEADER ) | | rtp_session - > flags [ SWITCH_RTP_FLAG_TEXT ] ) {
switch_size_t wrote ;
wrote = switch_rtp_write_manual ( rtp_session , frame - > data , frame - > datalen ,
frame - > m , frame - > payload , ( uint32_t ) ( frame - > timestamp ) , & frame - > flags ) ;
2013-06-18 00:52:37 +00:00
2009-04-15 15:08:21 +00:00
rtp_session - > stats . outbound . raw_bytes + = wrote ;
rtp_session - > stats . outbound . media_bytes + = wrote ;
rtp_session - > stats . outbound . media_packet_count + + ;
rtp_session - > stats . outbound . packet_count + + ;
2016-07-11 03:25:14 +00:00
return wrote ;
2007-04-19 21:40:50 +00:00
}
2013-11-09 18:02:11 +00:00
if ( frame - > pmap & & rtp_session - > pmaps & & * rtp_session - > pmaps ) {
2013-11-07 22:48:00 +00:00
payload_map_t * pmap ;
2013-11-09 18:02:11 +00:00
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
2013-11-07 22:48:00 +00:00
for ( pmap = * rtp_session - > pmaps ; pmap ; pmap = pmap - > next ) {
2013-11-22 03:55:45 +00:00
if ( pmap - > negotiated & & pmap - > hash = = frame - > pmap - > hash ) {
2013-11-07 22:48:00 +00:00
payload = pmap - > recv_pt ;
break ;
}
}
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
}
2007-04-05 19:29:48 +00:00
if ( fwd ) {
2008-01-11 04:23:09 +00:00
send_msg = frame - > packet ;
2015-03-03 22:30:26 +00:00
local_header = send_msg - > header ;
2006-04-18 16:20:47 +00:00
len = frame - > packetlen ;
2008-01-11 04:23:09 +00:00
ts = 0 ;
2013-11-07 22:48:00 +00:00
2010-08-25 00:12:24 +00:00
send_msg - > header . pt = payload ;
2014-11-14 02:52:57 +00:00
if ( switch_test_flag ( frame , SFF_RAW_RTP_PARSE_FRAME ) ) {
send_msg - > header . version = 2 ;
send_msg - > header . m = frame - > m ;
send_msg - > header . ts = htonl ( frame - > timestamp ) ;
2014-11-25 23:42:21 +00:00
if ( frame - > ssrc ) {
send_msg - > header . ssrc = htonl ( frame - > ssrc ) ;
} else {
send_msg - > header . ssrc = htonl ( rtp_session - > ssrc ) ;
}
2014-11-14 02:52:57 +00:00
}
2006-04-18 16:20:47 +00:00
} else {
data = frame - > data ;
len = frame - > datalen ;
2012-12-18 22:06:29 +00:00
ts = rtp_session - > flags [ SWITCH_RTP_FLAG_RAW_WRITE ] ? ( uint32_t ) frame - > timestamp : 0 ;
2006-04-18 16:20:47 +00:00
}
2010-03-11 17:37:08 +00:00
/*
2012-12-18 22:06:29 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_VIDEO ] ) {
2010-04-20 00:07:23 +00:00
send_msg - > header . pt = rtp_session - > payload ;
}
2010-03-11 17:37:08 +00:00
*/
2010-02-06 03:38:24 +00:00
2015-03-03 22:30:26 +00:00
r = rtp_common_write ( rtp_session , send_msg , data , len , payload , ts , & frame - > flags ) ;
if ( send_msg ) {
send_msg - > header = local_header ;
}
return r ;
2006-04-18 16:20:47 +00:00
}
2009-04-03 21:48:52 +00:00
SWITCH_DECLARE ( switch_rtp_stats_t * ) switch_rtp_get_stats ( switch_rtp_t * rtp_session , switch_memory_pool_t * pool )
{
switch_rtp_stats_t * s ;
2013-04-26 14:31:28 +00:00
if ( ! rtp_session ) {
return NULL ;
}
switch_mutex_lock ( rtp_session - > flag_mutex ) ;
2009-04-03 21:48:52 +00:00
if ( pool ) {
s = switch_core_alloc ( pool , sizeof ( * s ) ) ;
* s = rtp_session - > stats ;
} else {
s = & rtp_session - > stats ;
}
2011-05-06 20:25:00 +00:00
if ( rtp_session - > jb ) {
2015-09-11 16:37:01 +00:00
switch_jb_get_frames ( rtp_session - > jb , NULL , NULL , NULL , ( uint32_t * ) & s - > inbound . largest_jb_size ) ;
2011-05-06 20:25:00 +00:00
}
2014-01-30 00:08:27 +00:00
do_mos ( rtp_session , SWITCH_FALSE ) ;
2013-04-26 14:31:28 +00:00
switch_mutex_unlock ( rtp_session - > flag_mutex ) ;
2011-05-06 20:25:00 +00:00
2009-04-03 21:48:52 +00:00
return s ;
}
2007-02-13 17:13:57 +00:00
SWITCH_DECLARE ( int ) switch_rtp_write_manual ( switch_rtp_t * rtp_session ,
2008-05-27 04:30:03 +00:00
void * data , uint32_t datalen , uint8_t m , switch_payload_t payload , uint32_t ts , switch_frame_flag_t * flags )
2006-04-03 21:00:13 +00:00
{
2007-03-08 22:18:33 +00:00
switch_size_t bytes ;
2008-01-18 18:14:53 +00:00
int ret = - 1 ;
2006-04-03 21:00:13 +00:00
2008-01-18 18:14:53 +00:00
if ( ! switch_rtp_ready ( rtp_session ) | | ! rtp_session - > remote_addr | | datalen > SWITCH_RTP_MAX_BUF_LEN ) {
2007-03-07 23:24:09 +00:00
return - 1 ;
}
2014-01-24 22:48:25 +00:00
if ( ! rtp_write_ready ( rtp_session , datalen , __LINE__ ) ) {
return 0 ;
}
2015-06-12 07:38:52 +00:00
if ( payload = = INVALID_PT ) {
return 0 ;
}
2008-01-18 18:14:53 +00:00
WRITE_INC ( rtp_session ) ;
2007-12-17 23:43:15 +00:00
2007-12-18 17:33:29 +00:00
rtp_session - > write_msg = rtp_session - > send_msg ;
2008-01-11 16:01:07 +00:00
rtp_session - > write_msg . header . seq = htons ( + + rtp_session - > seq ) ;
2007-12-18 17:33:29 +00:00
rtp_session - > write_msg . header . ts = htonl ( ts ) ;
rtp_session - > write_msg . header . pt = payload ;
2012-05-08 17:52:47 +00:00
rtp_session - > write_msg . header . m = m ;
2007-12-18 17:33:29 +00:00
memcpy ( rtp_session - > write_msg . body , data , datalen ) ;
2006-04-03 21:00:13 +00:00
2007-03-08 22:18:33 +00:00
bytes = rtp_header_len + datalen ;
2015-01-09 19:36:57 +00:00
if ( switch_rtp_write_raw ( rtp_session , ( void * ) & rtp_session - > write_msg , & bytes , SWITCH_TRUE ) ! = SWITCH_STATUS_SUCCESS ) {
rtp_session - > seq - - ;
ret = - 1 ;
goto end ;
}
if ( ( ( * flags ) & SFF_RTP_HEADER ) ) {
rtp_session - > last_write_ts = ts ;
rtp_session - > flags [ SWITCH_RTP_FLAG_RESET ] = 0 ;
}
ret = ( int ) bytes ;
end :
WRITE_DEC ( rtp_session ) ;
return ret ;
}
SWITCH_DECLARE ( switch_status_t ) switch_rtp_write_raw ( switch_rtp_t * rtp_session , void * data , switch_size_t * bytes , switch_bool_t process_encryption )
{
switch_status_t status = SWITCH_STATUS_FALSE ;
switch_assert ( bytes ) ;
if ( ! switch_rtp_ready ( rtp_session ) | | ! rtp_session - > remote_addr | | * bytes > SWITCH_RTP_MAX_BUF_LEN ) {
return status ;
}
if ( ! rtp_write_ready ( rtp_session , * bytes , __LINE__ ) ) {
return SWITCH_STATUS_NOT_INITALIZED ;
}
WRITE_INC ( rtp_session ) ;
if ( process_encryption ) {
process_encryption = SWITCH_FALSE ;
2011-05-02 16:33:57 +00:00
# ifdef ENABLE_SRTP
2015-01-09 19:36:57 +00:00
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] ) {
2013-01-15 05:17:28 +00:00
2015-01-09 19:36:57 +00:00
int sbytes = ( int ) * bytes ;
err_status_t stat ;
if ( rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND_RESET ] ) {
switch_rtp_clear_flag ( rtp_session , SWITCH_RTP_FLAG_SECURE_SEND_RESET ) ;
srtp_dealloc ( rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] ) ;
rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] = NULL ;
2015-04-07 23:02:24 +00:00
if ( ( stat = srtp_create ( & rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] ,
& rtp_session - > send_policy [ rtp_session - > srtp_idx_rtp ] ) ) | | ! rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] ) {
2015-01-09 19:36:57 +00:00
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error! RE-Activating Secure RTP SEND \n " ) ;
2015-04-07 23:02:24 +00:00
rtp_session - > flags [ SWITCH_RTP_FLAG_SECURE_SEND ] = 0 ;
2015-01-09 19:36:57 +00:00
status = SWITCH_STATUS_FALSE ;
goto end ;
} else {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_INFO , " RE-Activating Secure RTP SEND \n " ) ;
}
2008-01-17 04:16:04 +00:00
}
2015-01-09 19:36:57 +00:00
stat = srtp_protect ( rtp_session - > send_ctx [ rtp_session - > srtp_idx_rtp ] , & rtp_session - > write_msg . header , & sbytes ) ;
if ( stat ) {
switch_log_printf ( SWITCH_CHANNEL_SESSION_LOG ( rtp_session - > session ) , SWITCH_LOG_ERROR , " Error: SRTP protection failed with code %d \n " , stat ) ;
}
* bytes = sbytes ;
2007-03-08 22:18:33 +00:00
}
2011-05-02 16:33:57 +00:00
# endif
2009-05-20 23:04:05 +00:00
# ifdef ENABLE_ZRTP
2015-01-09 19:36:57 +00:00
/* ZRTP Send */
if ( zrtp_on & & ! rtp_session - > flags [ SWITCH_RTP_FLAG_PROXY_MEDIA ] ) {
unsigned int sbytes = ( int ) * bytes ;
zrtp_status_t stat = zrtp_status_fail ;
2010-02-06 03:38:24 +00:00
2015-01-09 19:36:57 +00:00
stat = zrtp_process_rtp ( rtp_session - > zrtp_stream , ( void * ) & rtp_session - > write_msg , & sbytes ) ;
2010-02-06 03:38:24 +00:00
2015-01-09 19:36:57 +00:00
switch ( stat ) {
case zrtp_status_ok :
break ;
case zrtp_status_drop :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error: zRTP protection drop with code %d \n " , stat ) ;
2015-06-01 16:51:26 +00:00
status = SWITCH_STATUS_SUCCESS ;
2015-01-09 19:36:57 +00:00
goto end ;
break ;
case zrtp_status_fail :
switch_log_printf ( SWITCH_CHANNEL_LOG , SWITCH_LOG_ERROR , " Error: zRTP protection fail with code %d \n " , stat ) ;
break ;
default :
break ;
}
2010-02-06 03:38:24 +00:00
2015-01-09 19:36:57 +00:00
* bytes = sbytes ;
}
2009-05-20 23:04:05 +00:00
# endif
2011-08-31 17:03:57 +00:00
}
2008-01-10 03:10:58 +00:00
2015-01-09 19:36:57 +00:00
status = switch_socket_sendto ( rtp_session - > sock_output , rtp_session - > remote_addr , 0 , data , bytes ) ;
2008-05-27 04:30:03 +00:00
2010-04-20 00:07:23 +00:00
end :
2008-01-18 18:14:53 +00:00
WRITE_DEC ( rtp_session ) ;
2015-01-09 19:36:57 +00:00
return status ;
2006-04-03 21:00:13 +00:00
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( uint32_t ) switch_rtp_get_ssrc ( switch_rtp_t * rtp_session )
2006-04-03 21:00:13 +00:00
{
2012-07-11 20:15:43 +00:00
return rtp_session - > ssrc ;
2006-04-03 21:00:13 +00:00
}
2006-04-29 01:00:52 +00:00
SWITCH_DECLARE ( void ) switch_rtp_set_private ( switch_rtp_t * rtp_session , void * private_data )
2006-04-03 21:00:13 +00:00
{
rtp_session - > private_data = private_data ;
}
2007-03-29 22:31:56 +00:00
SWITCH_DECLARE ( void * ) switch_rtp_get_private ( switch_rtp_t * rtp_session )
2006-04-03 21:00:13 +00:00
{
return rtp_session - > private_data ;
}
2006-11-27 22:30:48 +00:00
/* For Emacs:
* Local Variables :
* mode : c
2008-02-03 22:14:57 +00:00
* indent - tabs - mode : t
2006-11-27 22:30:48 +00:00
* tab - width : 4
* c - basic - offset : 4
* End :
* For VIM :
2013-06-25 16:50:17 +00:00
* vim : set softtabstop = 4 shiftwidth = 4 tabstop = 4 noet :
2006-11-27 22:30:48 +00:00
*/
2012-11-29 05:12:35 +00:00