Asterisk - The Open Source Telephony Project GIT-master-4f52ed6
Data Structures | Macros | Enumerations | Functions | Variables
res_rtp_asterisk.c File Reference

Supports RTP and RTCP with Symmetric RTP support for NAT traversal. More...

#include "asterisk.h"
#include <arpa/nameser.h>
#include "asterisk/dns_core.h"
#include "asterisk/dns_internal.h"
#include "asterisk/dns_recurring.h"
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include <math.h>
#include "asterisk/conversions.h"
#include "asterisk/options.h"
#include "asterisk/logger_category.h"
#include "asterisk/stun.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.h"
#include "asterisk/format_cache.h"
#include "asterisk/channel.h"
#include "asterisk/acl.h"
#include "asterisk/config.h"
#include "asterisk/lock.h"
#include "asterisk/utils.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/unaligned.h"
#include "asterisk/module.h"
#include "asterisk/rtp_engine.h"
#include "asterisk/smoother.h"
#include "asterisk/uuid.h"
#include "asterisk/test.h"
#include "asterisk/data_buffer.h"
Include dependency graph for res_rtp_asterisk.c:

Go to the source code of this file.

Data Structures

struct  ast_rtcp
 Structure defining an RTCP session. More...
 
struct  ast_rtp
 RTP session description. More...
 
struct  ast_rtp_rtcp_nack_payload
 Structure for storing RTP packets for retransmission. More...
 
struct  frame_list
 
struct  optional_ts
 
struct  rtp_learning_info
 RTP learning mode tracking information. More...
 
struct  rtp_red
 
struct  rtp_ssrc_mapping
 Structure used for mapping an incoming SSRC to an RTP instance. More...
 
struct  rtp_transport_wide_cc_packet_statistics
 Packet statistics (used for transport-cc) More...
 
struct  rtp_transport_wide_cc_statistics
 Statistics information (used for transport-cc) More...
 

Macros

#define CALC_LEARNING_MIN_DURATION(count)   (((count) - 1) * 9 - 5)
 Calculate the min learning duration in ms. More...
 
#define DEFAULT_DTLS_MTU   1200
 
#define DEFAULT_DTMF_TIMEOUT   (150 * (8000 / 1000))
 
#define DEFAULT_ICESUPPORT   1
 
#define DEFAULT_LEARNING_MIN_DURATION   CALC_LEARNING_MIN_DURATION(DEFAULT_LEARNING_MIN_SEQUENTIAL)
 
#define DEFAULT_LEARNING_MIN_SEQUENTIAL   4
 
#define DEFAULT_RTP_END   31000
 
#define DEFAULT_RTP_RECV_BUFFER_SIZE   20
 
#define DEFAULT_RTP_SEND_BUFFER_SIZE   250
 
#define DEFAULT_RTP_START   5000
 
#define DEFAULT_SRTP_REPLAY_PROTECTION   1
 
#define DEFAULT_STRICT_RTP   STRICT_RTP_YES
 
#define DEFAULT_STUN_SOFTWARE_ATTRIBUTE   1
 
#define DEFAULT_TURN_PORT   3478
 
#define DTMF_SAMPLE_RATE_MS   8
 
#define FLAG_3389_WARNING   (1 << 0)
 
#define FLAG_DTMF_COMPENSATE   (1 << 4)
 
#define FLAG_NAT_ACTIVE   (3 << 1)
 
#define FLAG_NAT_INACTIVE   (0 << 1)
 
#define FLAG_NAT_INACTIVE_NOWARN   (1 << 1)
 
#define FLAG_NEED_MARKER_BIT   (1 << 3)
 
#define FLAG_REQ_LOCAL_BRIDGE_BIT   (1 << 5)
 
#define MAX_TIMESTAMP_SKEW   640
 
#define MAXIMUM_RTP_PORT   65535
 
#define MAXIMUM_RTP_RECV_BUFFER_SIZE   (DEFAULT_RTP_RECV_BUFFER_SIZE + 20)
 
#define MAXIMUM_RTP_SEND_BUFFER_SIZE   (DEFAULT_RTP_SEND_BUFFER_SIZE + 200)
 
#define MINIMUM_RTP_PORT   1024
 
#define MISSING_SEQNOS_ADDED_TRIGGER   2
 
#define OLD_PACKET_COUNT   1000
 
#define RESCALE(in, inmin, inmax, outmin, outmax)   ((((in - inmin)/(inmax-inmin))*(outmax-outmin))+outmin)
 
#define RTCP_DEFAULT_INTERVALMS   5000
 
#define RTCP_FB_NACK_BLOCK_WORD_LENGTH   2
 
#define RTCP_FB_REMB_BLOCK_WORD_LENGTH   4
 
#define RTCP_HEADER_SSRC_LENGTH   2
 
#define RTCP_LENGTH_MASK   0xFFFF
 
#define RTCP_LENGTH_SHIFT   0
 
#define RTCP_MAX_INTERVALMS   60000
 
#define RTCP_MIN_INTERVALMS   500
 
#define RTCP_PADDING_MASK   0x01
 
#define RTCP_PADDING_SHIFT   29
 
#define RTCP_PAYLOAD_TYPE_MASK   0xFF
 
#define RTCP_PAYLOAD_TYPE_SHIFT   16
 
#define RTCP_PT_APP   204
 
#define RTCP_PT_BYE   203
 
#define RTCP_PT_FUR   192
 
#define RTCP_PT_PSFB   AST_RTP_RTCP_PSFB
 
#define RTCP_PT_RR   AST_RTP_RTCP_RR
 
#define RTCP_PT_SDES   202
 
#define RTCP_PT_SR   AST_RTP_RTCP_SR
 
#define RTCP_REPORT_COUNT_MASK   0x1F
 
#define RTCP_REPORT_COUNT_SHIFT   24
 
#define RTCP_RR_BLOCK_WORD_LENGTH   6
 
#define RTCP_SR_BLOCK_WORD_LENGTH   5
 
#define RTCP_VALID_MASK   (RTCP_VERSION_MASK_SHIFTED | (((RTCP_PAYLOAD_TYPE_MASK & ~0x1)) << RTCP_PAYLOAD_TYPE_SHIFT))
 
#define RTCP_VALID_VALUE   (RTCP_VERSION_SHIFTED | (RTCP_PT_SR << RTCP_PAYLOAD_TYPE_SHIFT))
 
#define RTCP_VERSION   2U
 
#define RTCP_VERSION_MASK   0x03
 
#define RTCP_VERSION_MASK_SHIFTED   (RTCP_VERSION_MASK << RTCP_VERSION_SHIFT)
 
#define RTCP_VERSION_SHIFT   30
 
#define RTCP_VERSION_SHIFTED   (RTCP_VERSION << RTCP_VERSION_SHIFT)
 
#define RTP_DTLS_ESTABLISHED   -37
 
#define RTP_IGNORE_FIRST_PACKETS_COUNT   15
 
#define RTP_MTU   1200
 
#define RTP_SEQ_MOD   (1<<16)
 
#define SEQNO_CYCLE_OVER   65536
 
#define SRTP_MASTER_KEY_LEN   16
 
#define SRTP_MASTER_LEN   (SRTP_MASTER_KEY_LEN + SRTP_MASTER_SALT_LEN)
 
#define SRTP_MASTER_SALT_LEN   14
 
#define SSRC_MAPPING_ELEM_CMP(elem, value)   ((elem).instance == (value))
 SSRC mapping comparator for AST_VECTOR_REMOVE_CMP_UNORDERED() More...
 
#define STRICT_RTP_LEARN_TIMEOUT   5000
 Strict RTP learning timeout time in milliseconds. More...
 
#define TRANSPORT_SOCKET_RTCP   1
 
#define TRANSPORT_SOCKET_RTP   0
 
#define TRANSPORT_TURN_RTCP   3
 
#define TRANSPORT_TURN_RTP   2
 
#define TURN_STATE_WAIT_TIME   2000
 
#define ZFONE_PROFILE_ID   0x505a
 

Enumerations

enum  strict_rtp_mode { STRICT_RTP_NO = 0 , STRICT_RTP_YES , STRICT_RTP_SEQNO }
 
enum  strict_rtp_state { STRICT_RTP_OPEN = 0 , STRICT_RTP_LEARN , STRICT_RTP_CLOSED }
 

Functions

static void __reg_module (void)
 
static struct ast_rtp_instance__rtp_find_instance_by_ssrc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc, int source)
 
static int __rtp_recvfrom (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
 
static int __rtp_sendto (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp, int *via_ice, int use_srtp)
 
static void __unreg_module (void)
 
struct ast_moduleAST_MODULE_SELF_SYM (void)
 
static unsigned int ast_rtcp_calc_interval (struct ast_rtp *rtp)
 
static int ast_rtcp_calculate_sr_rr_statistics (struct ast_rtp_instance *instance, struct ast_rtp_rtcp_report *rtcp_report, struct ast_sockaddr remote_address, int ice, int sr)
 
static int ast_rtcp_generate_compound_prefix (struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *report, int *sr)
 
static int ast_rtcp_generate_nack (struct ast_rtp_instance *instance, unsigned char *rtcpheader)
 
static int ast_rtcp_generate_report (struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *rtcp_report, int *sr)
 
static int ast_rtcp_generate_sdes (struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *rtcp_report)
 
static struct ast_frameast_rtcp_interpret (struct ast_rtp_instance *instance, struct ast_srtp *srtp, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr)
 
static struct ast_frameast_rtcp_read (struct ast_rtp_instance *instance)
 
static int ast_rtcp_write (const void *data)
 Write a RTCP packet to the far end. More...
 
static int ast_rtp_bundle (struct ast_rtp_instance *child, struct ast_rtp_instance *parent)
 
static void ast_rtp_change_source (struct ast_rtp_instance *instance)
 
static int ast_rtp_destroy (struct ast_rtp_instance *instance)
 
static int ast_rtp_dtmf_begin (struct ast_rtp_instance *instance, char digit)
 
static int ast_rtp_dtmf_compatible (struct ast_channel *chan0, struct ast_rtp_instance *instance0, struct ast_channel *chan1, struct ast_rtp_instance *instance1)
 
static int ast_rtp_dtmf_continuation (struct ast_rtp_instance *instance)
 
static int ast_rtp_dtmf_end (struct ast_rtp_instance *instance, char digit)
 
static int ast_rtp_dtmf_end_with_duration (struct ast_rtp_instance *instance, char digit, unsigned int duration)
 
static enum ast_rtp_dtmf_mode ast_rtp_dtmf_mode_get (struct ast_rtp_instance *instance)
 
static int ast_rtp_dtmf_mode_set (struct ast_rtp_instance *instance, enum ast_rtp_dtmf_mode dtmf_mode)
 
static int ast_rtp_extension_enable (struct ast_rtp_instance *instance, enum ast_rtp_extension extension)
 
static int ast_rtp_fd (struct ast_rtp_instance *instance, int rtcp)
 
static const char * ast_rtp_get_cname (struct ast_rtp_instance *instance)
 
static unsigned int ast_rtp_get_ssrc (struct ast_rtp_instance *instance)
 
static int ast_rtp_get_stat (struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
 
static struct ast_frameast_rtp_interpret (struct ast_rtp_instance *instance, struct ast_srtp *srtp, const struct ast_sockaddr *remote_address, unsigned char *read_area, int length, int prev_seqno, unsigned int bundled)
 
static int ast_rtp_local_bridge (struct ast_rtp_instance *instance0, struct ast_rtp_instance *instance1)
 
static int ast_rtp_new (struct ast_rtp_instance *instance, struct ast_sched_context *sched, struct ast_sockaddr *addr, void *data)
 
static void ast_rtp_prop_set (struct ast_rtp_instance *instance, enum ast_rtp_property property, int value)
 
static int ast_rtp_qos_set (struct ast_rtp_instance *instance, int tos, int cos, const char *desc)
 
static struct ast_frameast_rtp_read (struct ast_rtp_instance *instance, int rtcp)
 
static void ast_rtp_remote_address_set (struct ast_rtp_instance *instance, struct ast_sockaddr *addr)
 
static int ast_rtp_rtcp_handle_nack (struct ast_rtp_instance *instance, unsigned int *nackdata, unsigned int position, unsigned int length)
 
static int ast_rtp_sendcng (struct ast_rtp_instance *instance, int level)
 generate comfort noice (CNG) More...
 
static void ast_rtp_set_remote_ssrc (struct ast_rtp_instance *instance, unsigned int ssrc)
 
static void ast_rtp_set_stream_num (struct ast_rtp_instance *instance, int stream_num)
 
static void ast_rtp_stop (struct ast_rtp_instance *instance)
 
static void ast_rtp_stun_request (struct ast_rtp_instance *instance, struct ast_sockaddr *suggestion, const char *username)
 
static void ast_rtp_update_source (struct ast_rtp_instance *instance)
 
static int ast_rtp_write (struct ast_rtp_instance *instance, struct ast_frame *frame)
 
static int bridge_p2p_rtp_write (struct ast_rtp_instance *instance, struct ast_rtp_instance *instance1, unsigned int *rtpheader, int len, int hdrlen)
 
static void calc_mean_and_standard_deviation (double new_sample, double *mean, double *std_dev, unsigned int *count)
 
static double calc_media_experience_score (struct ast_rtp_instance *instance, double normdevrtt, double normdev_rxjitter, double stdev_rxjitter, double normdev_rxlost)
 Calculate a "media experience score" based on given data. More...
 
static void calc_rxstamp_and_jitter (struct timeval *tv, struct ast_rtp *rtp, unsigned int rx_rtp_ts, int mark)
 
static unsigned int calc_txstamp (struct ast_rtp *rtp, struct timeval *delivery)
 
static void calculate_lost_packet_statistics (struct ast_rtp *rtp, unsigned int *lost_packets, int *fraction_lost)
 
static int compare_by_value (int elem, int value)
 Helper function to compare an elem in a vector by value. More...
 
static struct ast_framecreate_dtmf_frame (struct ast_rtp_instance *instance, enum ast_frame_type type, int compensate)
 
static int create_new_socket (const char *type, int af)
 
static int find_by_value (int elem, int value)
 Helper function to find an elem in a vector by value. More...
 
static char * handle_cli_rtcp_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_rtcp_set_stats (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_rtp_set_debug (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static char * handle_cli_rtp_settings (struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
 
static int load_module (void)
 
static void ntp2timeval (unsigned int msw, unsigned int lsw, struct timeval *tv)
 
static struct ast_frameprocess_cn_rfc3389 (struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark)
 
static struct ast_frameprocess_dtmf_cisco (struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark)
 
static void process_dtmf_rfc2833 (struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark, struct frame_list *frames)
 
static void put_unaligned_time24 (void *p, uint32_t time_msw, uint32_t time_lsw)
 
static struct ast_framered_t140_to_red (struct rtp_red *red)
 
static int red_write (const void *data)
 Write t140 redundancy frame. More...
 
static int reload_module (void)
 
static int rtcp_debug_test_addr (struct ast_sockaddr *addr)
 
static char * rtcp_do_debug_ip (struct ast_cli_args *a)
 
static int rtcp_mux (struct ast_rtp *rtp, const unsigned char *packet)
 
static const char * rtcp_payload_subtype2str (unsigned int pt, unsigned int subtype)
 
static const char * rtcp_payload_type2str (unsigned int pt)
 
static int rtcp_recvfrom (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
 
static int rtcp_sendto (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
 
static int rtp_allocate_transport (struct ast_rtp_instance *instance, struct ast_rtp *rtp)
 
static void rtp_deallocate_transport (struct ast_rtp_instance *instance, struct ast_rtp *rtp)
 
static int rtp_debug_test_addr (struct ast_sockaddr *addr)
 
static char * rtp_do_debug_ip (struct ast_cli_args *a)
 
static struct ast_rtp_instancertp_find_instance_by_media_source_ssrc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
 
static struct ast_rtp_instancertp_find_instance_by_packet_source_ssrc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
 
static void rtp_instance_parse_extmap_extensions (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned char *extension, int len)
 
static void rtp_instance_parse_transport_wide_cc (struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned char *data, int len)
 
static void rtp_instance_unlock (struct ast_rtp_instance *instance)
 
static int rtp_learning_rtp_seq_update (struct rtp_learning_info *info, uint16_t seq)
 
static void rtp_learning_seq_init (struct rtp_learning_info *info, uint16_t seq)
 
static void rtp_learning_start (struct ast_rtp *rtp)
 Start the strictrtp learning mode. More...
 
static int rtp_raw_write (struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
 
static int rtp_recvfrom (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
 
static int rtp_red_buffer (struct ast_rtp_instance *instance, struct ast_frame *frame)
 
static int rtp_red_init (struct ast_rtp_instance *instance, int buffer_time, int *payloads, int generations)
 
static int rtp_reload (int reload, int by_external_config)
 
static int rtp_sendto (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
 
static int rtp_transport_wide_cc_feedback_produce (const void *data)
 
static void rtp_transport_wide_cc_feedback_status_append (unsigned char *rtcpheader, int *packet_len, int *status_vector_chunk_bits, uint16_t *status_vector_chunk, int *run_length_chunk_count, int *run_length_chunk_status, int status)
 
static void rtp_transport_wide_cc_feedback_status_vector_append (unsigned char *rtcpheader, int *packet_len, int *status_vector_chunk_bits, uint16_t *status_vector_chunk, int status)
 
static int rtp_transport_wide_cc_packet_statistics_cmp (struct rtp_transport_wide_cc_packet_statistics a, struct rtp_transport_wide_cc_packet_statistics b)
 
static void rtp_write_rtcp_fir (struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_sockaddr *remote_address)
 
static void rtp_write_rtcp_psfb (struct ast_rtp_instance *instance, struct ast_rtp *rtp, struct ast_frame *frame, struct ast_sockaddr *remote_address)
 
static void timeval2ntp (struct timeval tv, unsigned int *msw, unsigned int *lsw)
 
static int unload_module (void)
 
static void update_jitter_stats (struct ast_rtp *rtp, unsigned int ia_jitter)
 
static void update_local_mes_stats (struct ast_rtp *rtp)
 
static void update_lost_stats (struct ast_rtp *rtp, unsigned int lost_packets)
 
static void update_reported_mes_stats (struct ast_rtp *rtp)
 
static int update_rtt_stats (struct ast_rtp *rtp, unsigned int lsr, unsigned int dlsr)
 

Variables

static struct ast_module_info __mod_info = { .name = AST_MODULE, .flags = AST_MODFLAG_LOAD_ORDER , .description = "Asterisk RTP Stack" , .key = "This paragraph is copyright (c) 2006 by Digium, Inc. \In order for your module to load, it must return this \key via a function called \"key\". Any code which \includes this paragraph must be licensed under the GNU \General Public License version 2 or later (at your \option). In addition to Digium's general reservations \of rights, Digium expressly reserves the right to \allow other parties to license this paragraph under \different terms. Any use of Digium, Inc. trademarks or \logos (including \"Asterisk\" or \"Digium\") without \express written permission of Digium, Inc. is prohibited.\n" , .buildopt_sum = AST_BUILDOPT_SUM, .support_level = AST_MODULE_SUPPORT_CORE, .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, #ifdef HAVE_PJPROJECT .requires = "res_pjproject", #endif }
 
static const struct ast_module_infoast_module_info = &__mod_info
 
static struct ast_rtp_engine asterisk_rtp_engine
 
static struct ast_cli_entry cli_rtp []
 
static int dtmftimeout = DEFAULT_DTMF_TIMEOUT
 
static int learning_min_duration = DEFAULT_LEARNING_MIN_DURATION
 
static int learning_min_sequential = DEFAULT_LEARNING_MIN_SEQUENTIAL
 
struct ast_srtp_resres_srtp
 
struct ast_srtp_policy_resres_srtp_policy
 
static struct ast_sockaddr rtcpdebugaddr
 
static int rtcpdebugport
 
static int rtcpinterval = RTCP_DEFAULT_INTERVALMS
 
static int rtcpstats
 
static struct ast_sockaddr rtpdebugaddr
 
static int rtpdebugport
 
static int rtpend = DEFAULT_RTP_END
 
static int rtpstart = DEFAULT_RTP_START
 
static int srtp_replay_protection = DEFAULT_SRTP_REPLAY_PROTECTION
 
static int strictrtp = DEFAULT_STRICT_RTP
 

Detailed Description

Supports RTP and RTCP with Symmetric RTP support for NAT traversal.

Author
Mark Spencer marks.nosp@m.ter@.nosp@m.digiu.nosp@m.m.co.nosp@m.m
Note
RTP is defined in RFC 3550.

Definition in file res_rtp_asterisk.c.

Macro Definition Documentation

◆ CALC_LEARNING_MIN_DURATION

#define CALC_LEARNING_MIN_DURATION (   count)    (((count) - 1) * 9 - 5)

Calculate the min learning duration in ms.

The min supported packet size represents 10 ms and we need to account for some jitter and fast clocks while learning. Some messed up devices have very bad jitter for a small packet sample size. Jitter can also be introduced by the network itself.

So we'll allow packets to come in every 9ms on average for fast clocking with the last one coming in 5ms early for jitter.

Definition at line 160 of file res_rtp_asterisk.c.

◆ DEFAULT_DTLS_MTU

#define DEFAULT_DTLS_MTU   1200

Definition at line 194 of file res_rtp_asterisk.c.

◆ DEFAULT_DTMF_TIMEOUT

#define DEFAULT_DTMF_TIMEOUT   (150 * (8000 / 1000))

samples

Definition at line 143 of file res_rtp_asterisk.c.

◆ DEFAULT_ICESUPPORT

#define DEFAULT_ICESUPPORT   1

Definition at line 192 of file res_rtp_asterisk.c.

◆ DEFAULT_LEARNING_MIN_DURATION

#define DEFAULT_LEARNING_MIN_DURATION   CALC_LEARNING_MIN_DURATION(DEFAULT_LEARNING_MIN_SEQUENTIAL)

Definition at line 161 of file res_rtp_asterisk.c.

◆ DEFAULT_LEARNING_MIN_SEQUENTIAL

#define DEFAULT_LEARNING_MIN_SEQUENTIAL   4

Definition at line 147 of file res_rtp_asterisk.c.

◆ DEFAULT_RTP_END

#define DEFAULT_RTP_END   31000

Default maximum port number to end allocating RTP ports at

Definition at line 106 of file res_rtp_asterisk.c.

◆ DEFAULT_RTP_RECV_BUFFER_SIZE

#define DEFAULT_RTP_RECV_BUFFER_SIZE   20

The initial size of the RTP receiver buffer

Definition at line 117 of file res_rtp_asterisk.c.

◆ DEFAULT_RTP_SEND_BUFFER_SIZE

#define DEFAULT_RTP_SEND_BUFFER_SIZE   250

The initial size of the RTP send buffer

Definition at line 115 of file res_rtp_asterisk.c.

◆ DEFAULT_RTP_START

#define DEFAULT_RTP_START   5000

Default port number to start allocating RTP ports from

Definition at line 105 of file res_rtp_asterisk.c.

◆ DEFAULT_SRTP_REPLAY_PROTECTION

#define DEFAULT_SRTP_REPLAY_PROTECTION   1

Definition at line 191 of file res_rtp_asterisk.c.

◆ DEFAULT_STRICT_RTP

#define DEFAULT_STRICT_RTP   STRICT_RTP_YES

Enabled by default

Definition at line 190 of file res_rtp_asterisk.c.

◆ DEFAULT_STUN_SOFTWARE_ATTRIBUTE

#define DEFAULT_STUN_SOFTWARE_ATTRIBUTE   1

Definition at line 193 of file res_rtp_asterisk.c.

◆ DEFAULT_TURN_PORT

#define DEFAULT_TURN_PORT   3478

Definition at line 111 of file res_rtp_asterisk.c.

◆ DTMF_SAMPLE_RATE_MS

#define DTMF_SAMPLE_RATE_MS   8

DTMF samples per millisecond

Definition at line 141 of file res_rtp_asterisk.c.

◆ FLAG_3389_WARNING

#define FLAG_3389_WARNING   (1 << 0)

Definition at line 303 of file res_rtp_asterisk.c.

◆ FLAG_DTMF_COMPENSATE

#define FLAG_DTMF_COMPENSATE   (1 << 4)

Definition at line 308 of file res_rtp_asterisk.c.

◆ FLAG_NAT_ACTIVE

#define FLAG_NAT_ACTIVE   (3 << 1)

Definition at line 304 of file res_rtp_asterisk.c.

◆ FLAG_NAT_INACTIVE

#define FLAG_NAT_INACTIVE   (0 << 1)

Definition at line 305 of file res_rtp_asterisk.c.

◆ FLAG_NAT_INACTIVE_NOWARN

#define FLAG_NAT_INACTIVE_NOWARN   (1 << 1)

Definition at line 306 of file res_rtp_asterisk.c.

◆ FLAG_NEED_MARKER_BIT

#define FLAG_NEED_MARKER_BIT   (1 << 3)

Definition at line 307 of file res_rtp_asterisk.c.

◆ FLAG_REQ_LOCAL_BRIDGE_BIT

#define FLAG_REQ_LOCAL_BRIDGE_BIT   (1 << 5)

Definition at line 309 of file res_rtp_asterisk.c.

◆ MAX_TIMESTAMP_SKEW

#define MAX_TIMESTAMP_SKEW   640

Definition at line 98 of file res_rtp_asterisk.c.

◆ MAXIMUM_RTP_PORT

#define MAXIMUM_RTP_PORT   65535

Maximum port number to accept

Definition at line 109 of file res_rtp_asterisk.c.

◆ MAXIMUM_RTP_RECV_BUFFER_SIZE

#define MAXIMUM_RTP_RECV_BUFFER_SIZE   (DEFAULT_RTP_RECV_BUFFER_SIZE + 20)

Maximum RTP receive buffer size

Definition at line 118 of file res_rtp_asterisk.c.

◆ MAXIMUM_RTP_SEND_BUFFER_SIZE

#define MAXIMUM_RTP_SEND_BUFFER_SIZE   (DEFAULT_RTP_SEND_BUFFER_SIZE + 200)

Maximum RTP send buffer size

Definition at line 116 of file res_rtp_asterisk.c.

◆ MINIMUM_RTP_PORT

#define MINIMUM_RTP_PORT   1024

Minimum port number to accept

Definition at line 108 of file res_rtp_asterisk.c.

◆ MISSING_SEQNOS_ADDED_TRIGGER

#define MISSING_SEQNOS_ADDED_TRIGGER   2

The number of immediate missing packets that will trigger an immediate NACK

Definition at line 120 of file res_rtp_asterisk.c.

◆ OLD_PACKET_COUNT

#define OLD_PACKET_COUNT   1000

The number of previous packets that are considered old

Definition at line 119 of file res_rtp_asterisk.c.

◆ RESCALE

#define RESCALE (   in,
  inmin,
  inmax,
  outmin,
  outmax 
)    ((((in - inmin)/(inmax-inmin))*(outmax-outmin))+outmin)

Definition at line 6119 of file res_rtp_asterisk.c.

◆ RTCP_DEFAULT_INTERVALMS

#define RTCP_DEFAULT_INTERVALMS   5000

Default milli-seconds between RTCP reports we send

Definition at line 101 of file res_rtp_asterisk.c.

◆ RTCP_FB_NACK_BLOCK_WORD_LENGTH

#define RTCP_FB_NACK_BLOCK_WORD_LENGTH   2

Definition at line 6502 of file res_rtp_asterisk.c.

◆ RTCP_FB_REMB_BLOCK_WORD_LENGTH

#define RTCP_FB_REMB_BLOCK_WORD_LENGTH   4

Definition at line 6501 of file res_rtp_asterisk.c.

◆ RTCP_HEADER_SSRC_LENGTH

#define RTCP_HEADER_SSRC_LENGTH   2

Definition at line 6500 of file res_rtp_asterisk.c.

◆ RTCP_LENGTH_MASK

#define RTCP_LENGTH_MASK   0xFFFF

Definition at line 6465 of file res_rtp_asterisk.c.

◆ RTCP_LENGTH_SHIFT

#define RTCP_LENGTH_SHIFT   0

Definition at line 6474 of file res_rtp_asterisk.c.

◆ RTCP_MAX_INTERVALMS

#define RTCP_MAX_INTERVALMS   60000

Max milli-seconds between RTCP reports we send

Definition at line 103 of file res_rtp_asterisk.c.

◆ RTCP_MIN_INTERVALMS

#define RTCP_MIN_INTERVALMS   500

Min milli-seconds between RTCP reports we send

Definition at line 102 of file res_rtp_asterisk.c.

◆ RTCP_PADDING_MASK

#define RTCP_PADDING_MASK   0x01

Definition at line 6468 of file res_rtp_asterisk.c.

◆ RTCP_PADDING_SHIFT

#define RTCP_PADDING_SHIFT   29

Definition at line 6477 of file res_rtp_asterisk.c.

◆ RTCP_PAYLOAD_TYPE_MASK

#define RTCP_PAYLOAD_TYPE_MASK   0xFF

Definition at line 6466 of file res_rtp_asterisk.c.

◆ RTCP_PAYLOAD_TYPE_SHIFT

#define RTCP_PAYLOAD_TYPE_SHIFT   16

Definition at line 6475 of file res_rtp_asterisk.c.

◆ RTCP_PT_APP

#define RTCP_PT_APP   204

Application defined (From RFC3550)

Definition at line 135 of file res_rtp_asterisk.c.

◆ RTCP_PT_BYE

#define RTCP_PT_BYE   203

Goodbye (To remove SSRC's from tables) (From RFC3550)

Definition at line 133 of file res_rtp_asterisk.c.

◆ RTCP_PT_FUR

#define RTCP_PT_FUR   192

Full INTRA-frame Request / Fast Update Request (From RFC2032)

Definition at line 125 of file res_rtp_asterisk.c.

◆ RTCP_PT_PSFB

#define RTCP_PT_PSFB   AST_RTP_RTCP_PSFB

Payload Specific Feed Back (From RFC4585 also RFC5104)

Definition at line 138 of file res_rtp_asterisk.c.

◆ RTCP_PT_RR

#define RTCP_PT_RR   AST_RTP_RTCP_RR

Receiver Report (From RFC3550)

Definition at line 129 of file res_rtp_asterisk.c.

◆ RTCP_PT_SDES

#define RTCP_PT_SDES   202

Source Description (From RFC3550)

Definition at line 131 of file res_rtp_asterisk.c.

◆ RTCP_PT_SR

#define RTCP_PT_SR   AST_RTP_RTCP_SR

Sender Report (From RFC3550)

Definition at line 127 of file res_rtp_asterisk.c.

◆ RTCP_REPORT_COUNT_MASK

#define RTCP_REPORT_COUNT_MASK   0x1F

Definition at line 6467 of file res_rtp_asterisk.c.

◆ RTCP_REPORT_COUNT_SHIFT

#define RTCP_REPORT_COUNT_SHIFT   24

Definition at line 6476 of file res_rtp_asterisk.c.

◆ RTCP_RR_BLOCK_WORD_LENGTH

#define RTCP_RR_BLOCK_WORD_LENGTH   6

Definition at line 6499 of file res_rtp_asterisk.c.

◆ RTCP_SR_BLOCK_WORD_LENGTH

#define RTCP_SR_BLOCK_WORD_LENGTH   5

Definition at line 6498 of file res_rtp_asterisk.c.

◆ RTCP_VALID_MASK

#define RTCP_VALID_MASK   (RTCP_VERSION_MASK_SHIFTED | (((RTCP_PAYLOAD_TYPE_MASK & ~0x1)) << RTCP_PAYLOAD_TYPE_SHIFT))

Definition at line 6495 of file res_rtp_asterisk.c.

◆ RTCP_VALID_VALUE

#define RTCP_VALID_VALUE   (RTCP_VERSION_SHIFTED | (RTCP_PT_SR << RTCP_PAYLOAD_TYPE_SHIFT))

Definition at line 6496 of file res_rtp_asterisk.c.

◆ RTCP_VERSION

#define RTCP_VERSION   2U

Definition at line 6480 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_MASK

#define RTCP_VERSION_MASK   0x03

Definition at line 6469 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_MASK_SHIFTED

#define RTCP_VERSION_MASK_SHIFTED   (RTCP_VERSION_MASK << RTCP_VERSION_SHIFT)

Definition at line 6482 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_SHIFT

#define RTCP_VERSION_SHIFT   30

Definition at line 6478 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_SHIFTED

#define RTCP_VERSION_SHIFTED   (RTCP_VERSION << RTCP_VERSION_SHIFT)

Definition at line 6481 of file res_rtp_asterisk.c.

◆ RTP_DTLS_ESTABLISHED

#define RTP_DTLS_ESTABLISHED   -37

Definition at line 167 of file res_rtp_asterisk.c.

◆ RTP_IGNORE_FIRST_PACKETS_COUNT

#define RTP_IGNORE_FIRST_PACKETS_COUNT   15

Because both ends usually don't start sending RTP at the same time, some of the calculations like rtt and jitter will probably be unstable for a while so we'll skip some received packets before starting analyzing. This just affects analyzing; we still process the RTP as normal.

Definition at line 204 of file res_rtp_asterisk.c.

◆ RTP_MTU

#define RTP_MTU   1200

Definition at line 140 of file res_rtp_asterisk.c.

◆ RTP_SEQ_MOD

#define RTP_SEQ_MOD   (1<<16)

A sequence number can't be more than 16 bits

Definition at line 100 of file res_rtp_asterisk.c.

◆ SEQNO_CYCLE_OVER

#define SEQNO_CYCLE_OVER   65536

The number after the maximum allowed sequence number

Definition at line 122 of file res_rtp_asterisk.c.

◆ SRTP_MASTER_KEY_LEN

#define SRTP_MASTER_KEY_LEN   16

Definition at line 163 of file res_rtp_asterisk.c.

◆ SRTP_MASTER_LEN

#define SRTP_MASTER_LEN   (SRTP_MASTER_KEY_LEN + SRTP_MASTER_SALT_LEN)

Definition at line 165 of file res_rtp_asterisk.c.

◆ SRTP_MASTER_SALT_LEN

#define SRTP_MASTER_SALT_LEN   14

Definition at line 164 of file res_rtp_asterisk.c.

◆ SSRC_MAPPING_ELEM_CMP

#define SSRC_MAPPING_ELEM_CMP (   elem,
  value 
)    ((elem).instance == (value))

SSRC mapping comparator for AST_VECTOR_REMOVE_CMP_UNORDERED()

Parameters
elemElement to compare against
valueValue to compare with the vector element.
Return values
0if element does not match.
Non-zeroif element matches.

Definition at line 4139 of file res_rtp_asterisk.c.

◆ STRICT_RTP_LEARN_TIMEOUT

#define STRICT_RTP_LEARN_TIMEOUT   5000

Strict RTP learning timeout time in milliseconds.

Note
Set to 5 seconds to allow reinvite chains for direct media to settle before media actually starts to arrive. There may be a reinvite collision involved on the other leg.

Definition at line 188 of file res_rtp_asterisk.c.

◆ TRANSPORT_SOCKET_RTCP

#define TRANSPORT_SOCKET_RTCP   1

Definition at line 312 of file res_rtp_asterisk.c.

◆ TRANSPORT_SOCKET_RTP

#define TRANSPORT_SOCKET_RTP   0

Definition at line 311 of file res_rtp_asterisk.c.

◆ TRANSPORT_TURN_RTCP

#define TRANSPORT_TURN_RTCP   3

Definition at line 314 of file res_rtp_asterisk.c.

◆ TRANSPORT_TURN_RTP

#define TRANSPORT_TURN_RTP   2

Definition at line 313 of file res_rtp_asterisk.c.

◆ TURN_STATE_WAIT_TIME

#define TURN_STATE_WAIT_TIME   2000

Definition at line 113 of file res_rtp_asterisk.c.

◆ ZFONE_PROFILE_ID

#define ZFONE_PROFILE_ID   0x505a

Definition at line 145 of file res_rtp_asterisk.c.

Enumeration Type Documentation

◆ strict_rtp_mode

Enumerator
STRICT_RTP_NO 
STRICT_RTP_YES 

Don't adhere to any strict RTP rules

STRICT_RTP_SEQNO 

Strict RTP that restricts packets based on time and sequence number

Definition at line 175 of file res_rtp_asterisk.c.

175 {
176 STRICT_RTP_NO = 0, /*! Don't adhere to any strict RTP rules */
177 STRICT_RTP_YES, /*! Strict RTP that restricts packets based on time and sequence number */
178 STRICT_RTP_SEQNO, /*! Strict RTP that restricts packets based on sequence number */
179};
@ STRICT_RTP_SEQNO
@ STRICT_RTP_YES
@ STRICT_RTP_NO

◆ strict_rtp_state

Enumerator
STRICT_RTP_OPEN 
STRICT_RTP_LEARN 

No RTP packets should be dropped, all sources accepted

STRICT_RTP_CLOSED 

Accept next packet as source

Definition at line 169 of file res_rtp_asterisk.c.

169 {
170 STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
171 STRICT_RTP_LEARN, /*! Accept next packet as source */
172 STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */
173};
@ STRICT_RTP_LEARN
@ STRICT_RTP_OPEN
@ STRICT_RTP_CLOSED

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 10293 of file res_rtp_asterisk.c.

◆ __rtp_find_instance_by_ssrc()

static struct ast_rtp_instance * __rtp_find_instance_by_ssrc ( struct ast_rtp_instance instance,
struct ast_rtp rtp,
unsigned int  ssrc,
int  source 
)
static
Precondition
instance is locked

Definition at line 6273 of file res_rtp_asterisk.c.

6275{
6276 int index;
6277
6278 if (!AST_VECTOR_SIZE(&rtp->ssrc_mapping)) {
6279 /* This instance is not bundled */
6280 return instance;
6281 }
6282
6283 /* Find the bundled child instance */
6284 for (index = 0; index < AST_VECTOR_SIZE(&rtp->ssrc_mapping); ++index) {
6285 struct rtp_ssrc_mapping *mapping = AST_VECTOR_GET_ADDR(&rtp->ssrc_mapping, index);
6286 unsigned int mapping_ssrc = source ? ast_rtp_get_ssrc(mapping->instance) : mapping->ssrc;
6287
6288 if (mapping->ssrc_valid && mapping_ssrc == ssrc) {
6289 return mapping->instance;
6290 }
6291 }
6292
6293 /* Does the SSRC match the bundled parent? */
6294 if (rtp->themssrc_valid && rtp->themssrc == ssrc) {
6295 return instance;
6296 }
6297 return NULL;
6298}
static unsigned int ast_rtp_get_ssrc(struct ast_rtp_instance *instance)
#define NULL
Definition: resample.c:96
unsigned int themssrc_valid
struct ast_rtp::@472 ssrc_mapping
unsigned int themssrc
Structure used for mapping an incoming SSRC to an RTP instance.
unsigned int ssrc
The received SSRC.
unsigned int ssrc_valid
struct ast_rtp_instance * instance
The RTP instance this SSRC belongs to.
#define AST_VECTOR_SIZE(vec)
Get the number of elements in a vector.
Definition: vector.h:609
#define AST_VECTOR_GET_ADDR(vec, idx)
Get an address of element in a vector.
Definition: vector.h:668

References ast_rtp_get_ssrc(), AST_VECTOR_GET_ADDR, AST_VECTOR_SIZE, rtp_ssrc_mapping::instance, NULL, rtp_ssrc_mapping::ssrc, ast_rtp::ssrc_mapping, rtp_ssrc_mapping::ssrc_valid, ast_rtp::themssrc, and ast_rtp::themssrc_valid.

Referenced by rtp_find_instance_by_media_source_ssrc(), and rtp_find_instance_by_packet_source_ssrc().

◆ __rtp_recvfrom()

static int __rtp_recvfrom ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa,
int  rtcp 
)
static
Precondition
instance is locked

Definition at line 3169 of file res_rtp_asterisk.c.

3170{
3171 int len;
3172 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
3173#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
3174 char *in = buf;
3175#endif
3176#ifdef HAVE_PJPROJECT
3177 struct ast_sockaddr *loop = rtcp ? &rtp->rtcp_loop : &rtp->rtp_loop;
3178#endif
3179#ifdef TEST_FRAMEWORK
3180 struct ast_rtp_engine_test *test = ast_rtp_instance_get_test(instance);
3181#endif
3182
3183 if ((len = ast_recvfrom(rtcp ? rtp->rtcp->s : rtp->s, buf, size, flags, sa)) < 0) {
3184 return len;
3185 }
3186
3187#ifdef TEST_FRAMEWORK
3188 if (test && test->packets_to_drop > 0) {
3189 test->packets_to_drop--;
3190 return 0;
3191 }
3192#endif
3193
3194#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
3195 /* If this is an SSL packet pass it to OpenSSL for processing. RFC section for first byte value:
3196 * https://tools.ietf.org/html/rfc5764#section-5.1.2 */
3197 if ((*in >= 20) && (*in <= 63)) {
3198 struct dtls_details *dtls = !rtcp ? &rtp->dtls : &rtp->rtcp->dtls;
3199 int res = 0;
3200
3201 /* If no SSL session actually exists terminate things */
3202 if (!dtls->ssl) {
3203 ast_log(LOG_ERROR, "Received SSL traffic on RTP instance '%p' without an SSL session\n",
3204 instance);
3205 return -1;
3206 }
3207
3208 ast_debug_dtls(3, "(%p) DTLS - __rtp_recvfrom rtp=%p - Got SSL packet '%d'\n", instance, rtp, *in);
3209
3210 /*
3211 * A race condition is prevented between dtls_perform_handshake()
3212 * and this function because both functions have to get the
3213 * instance lock before they can do anything. The
3214 * dtls_perform_handshake() function needs to start the timer
3215 * before we stop it below.
3216 */
3217
3218 /* Before we feed data into OpenSSL ensure that the timeout timer is either stopped or completed */
3219 ao2_unlock(instance);
3220 dtls_srtp_stop_timeout_timer(instance, rtp, rtcp);
3221 ao2_lock(instance);
3222
3223 /* If we don't yet know if we are active or passive and we receive a packet... we are obviously passive */
3224 if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
3225 dtls->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
3226 SSL_set_accept_state(dtls->ssl);
3227 }
3228
3229 BIO_write(dtls->read_bio, buf, len);
3230
3231 len = SSL_read(dtls->ssl, buf, len);
3232
3233 if ((len < 0) && (SSL_get_error(dtls->ssl, len) == SSL_ERROR_SSL)) {
3234 unsigned long error = ERR_get_error();
3235 ast_log(LOG_ERROR, "DTLS failure occurred on RTP instance '%p' due to reason '%s', terminating\n",
3236 instance, ERR_reason_error_string(error));
3237 return -1;
3238 }
3239
3240 if (SSL_is_init_finished(dtls->ssl)) {
3241 /* Any further connections will be existing since this is now established */
3242 dtls->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
3243 /* Use the keying material to set up key/salt information */
3244 if ((res = dtls_srtp_setup(rtp, instance, rtcp))) {
3245 return res;
3246 }
3247 /* Notify that dtls has been established */
3249
3250 ast_debug_dtls(3, "(%p) DTLS - __rtp_recvfrom rtp=%p - established'\n", instance, rtp);
3251 } else {
3252 /* Since we've sent additional traffic start the timeout timer for retransmission */
3253 dtls_srtp_start_timeout_timer(instance, rtp, rtcp);
3254 }
3255
3256 return res;
3257 }
3258#endif
3259
3260#ifdef HAVE_PJPROJECT
3261 if (!ast_sockaddr_isnull(loop) && !ast_sockaddr_cmp(loop, sa)) {
3262 /* ICE traffic will have been handled in the TURN callback, so skip it but update the address
3263 * so it reflects the actual source and not the loopback
3264 */
3265 if (rtcp) {
3266 ast_sockaddr_copy(sa, &rtp->rtcp->them);
3267 } else {
3269 }
3270 } else if (rtp->ice) {
3271 pj_str_t combined = pj_str(ast_sockaddr_stringify(sa));
3272 pj_sockaddr address;
3273 pj_status_t status;
3274 struct ice_wrap *ice;
3275
3276 pj_thread_register_check();
3277
3278 pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &combined, &address);
3279
3280 /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
3281 ice = rtp->ice;
3282 ao2_ref(ice, +1);
3283 ao2_unlock(instance);
3284 status = pj_ice_sess_on_rx_pkt(ice->real_ice,
3287 pj_sockaddr_get_len(&address));
3288 ao2_ref(ice, -1);
3289 ao2_lock(instance);
3290 if (status != PJ_SUCCESS) {
3291 char err_buf[100];
3292
3293 pj_strerror(status, err_buf, sizeof(err_buf));
3294 ast_log(LOG_WARNING, "PJ ICE Rx error status code: %d '%s'.\n",
3295 (int)status, err_buf);
3296 return -1;
3297 }
3298 if (!rtp->passthrough) {
3299 /* If a unidirectional ICE negotiation occurs then lock on to the source of the
3300 * ICE traffic and use it as the target. This will occur if the remote side only
3301 * wants to receive media but never send to us.
3302 */
3303 if (!rtp->ice_active_remote_candidates && !rtp->ice_proposed_remote_candidates) {
3304 if (rtcp) {
3305 ast_sockaddr_copy(&rtp->rtcp->them, sa);
3306 } else {
3308 }
3309 }
3310 return 0;
3311 }
3312 rtp->passthrough = 0;
3313 }
3314#endif
3315
3316 return len;
3317}
jack_status_t status
Definition: app_jack.c:146
#define ast_log
Definition: astobj2.c:42
#define ao2_unlock(a)
Definition: astobj2.h:729
#define ao2_lock(a)
Definition: astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition: astobj2.h:459
char buf[BUFSIZE]
Definition: eagi_proxy.c:66
char * address
Definition: f2c.h:59
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
#define LOG_ERROR
#define LOG_WARNING
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
static void ast_sockaddr_copy(struct ast_sockaddr *dst, const struct ast_sockaddr *src)
Copies the data from one ast_sockaddr to another.
Definition: netsock2.h:167
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. "null" in this sense essentially means uninitialized,...
Definition: netsock2.h:127
ssize_t ast_recvfrom(int sockfd, void *buf, size_t len, int flags, struct ast_sockaddr *src_addr)
Wrapper around recvfrom(2) that uses struct ast_sockaddr.
Definition: netsock2.c:606
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:388
#define RTP_DTLS_ESTABLISHED
#define TRANSPORT_SOCKET_RTP
#define TRANSPORT_SOCKET_RTCP
@ AST_RTP_DTLS_SETUP_PASSIVE
Definition: rtp_engine.h:561
@ AST_RTP_DTLS_SETUP_ACTPASS
Definition: rtp_engine.h:562
@ AST_RTP_ICE_COMPONENT_RTCP
Definition: rtp_engine.h:510
@ AST_RTP_ICE_COMPONENT_RTP
Definition: rtp_engine.h:509
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:584
#define ast_rtp_instance_get_remote_address(instance, address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1238
#define ast_rtp_instance_set_remote_address(instance, address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.h:1126
@ AST_RTP_DTLS_CONNECTION_EXISTING
Definition: rtp_engine.h:569
#define ast_debug_dtls(sublevel,...)
Log debug level DTLS information.
Definition: rtp_engine.h:2940
struct ast_sockaddr them
RTP session description.
struct ast_rtcp * rtcp
Socket address structure.
Definition: netsock2.h:97
int error(const char *format,...)
Definition: utils/frame.c:999
FILE * in
Definition: utils/frame.c:33

References ao2_lock, ao2_ref, ao2_unlock, ast_debug_dtls, ast_log, ast_recvfrom(), AST_RTP_DTLS_CONNECTION_EXISTING, AST_RTP_DTLS_SETUP_ACTPASS, AST_RTP_DTLS_SETUP_PASSIVE, AST_RTP_ICE_COMPONENT_RTCP, AST_RTP_ICE_COMPONENT_RTP, ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_rtp_instance_set_remote_address, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), buf, error(), in, len(), LOG_ERROR, LOG_WARNING, ast_rtp::rtcp, RTP_DTLS_ESTABLISHED, ast_rtp::s, ast_rtcp::s, status, ast_rtcp::them, TRANSPORT_SOCKET_RTCP, and TRANSPORT_SOCKET_RTP.

Referenced by rtcp_recvfrom(), and rtp_recvfrom().

◆ __rtp_sendto()

static int __rtp_sendto ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa,
int  rtcp,
int *  via_ice,
int  use_srtp 
)
static
Precondition
instance is locked

Definition at line 3332 of file res_rtp_asterisk.c.

3333{
3334 int len = size;
3335 void *temp = buf;
3336 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
3337 struct ast_rtp_instance *transport = rtp->bundled ? rtp->bundled : instance;
3338 struct ast_rtp *transport_rtp = ast_rtp_instance_get_data(transport);
3339 struct ast_srtp *srtp = ast_rtp_instance_get_srtp(transport, rtcp);
3340 int res;
3341
3342 *via_ice = 0;
3343
3344 if (use_srtp && res_srtp && srtp && res_srtp->protect(srtp, &temp, &len, rtcp) < 0) {
3345 return -1;
3346 }
3347
3348#ifdef HAVE_PJPROJECT
3349 if (transport_rtp->ice) {
3351 pj_status_t status;
3352 struct ice_wrap *ice;
3353
3354 /* If RTCP is sharing the same socket then use the same component */
3355 if (rtcp && rtp->rtcp->s == rtp->s) {
3356 component = AST_RTP_ICE_COMPONENT_RTP;
3357 }
3358
3359 pj_thread_register_check();
3360
3361 /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
3362 ice = transport_rtp->ice;
3363 ao2_ref(ice, +1);
3364 if (instance == transport) {
3365 ao2_unlock(instance);
3366 }
3367 status = pj_ice_sess_send_data(ice->real_ice, component, temp, len);
3368 ao2_ref(ice, -1);
3369 if (instance == transport) {
3370 ao2_lock(instance);
3371 }
3372 if (status == PJ_SUCCESS) {
3373 *via_ice = 1;
3374 return len;
3375 }
3376 }
3377#endif
3378
3379 res = ast_sendto(rtcp ? transport_rtp->rtcp->s : transport_rtp->s, temp, len, flags, sa);
3380 if (res > 0) {
3381 ast_rtp_instance_set_last_tx(instance, time(NULL));
3382 }
3383
3384 return res;
3385}
ssize_t ast_sendto(int sockfd, const void *buf, size_t len, int flags, const struct ast_sockaddr *dest_addr)
Wrapper around sendto(2) that uses ast_sockaddr.
Definition: netsock2.c:614
struct ast_srtp_res * res_srtp
Definition: rtp_engine.c:176
ast_rtp_ice_component_type
ICE component types.
Definition: rtp_engine.h:508
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance, int rtcp)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:2796
void ast_rtp_instance_set_last_tx(struct ast_rtp_instance *rtp, time_t time)
Set the last RTP transmission time.
Definition: rtp_engine.c:3801
struct ast_rtp_instance * bundled
int(* protect)(struct ast_srtp *srtp, void **buf, int *size, int rtcp)
Definition: res_srtp.h:50

References ao2_lock, ao2_ref, ao2_unlock, AST_RTP_ICE_COMPONENT_RTCP, AST_RTP_ICE_COMPONENT_RTP, ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_rtp_instance_set_last_tx(), ast_sendto(), buf, ast_rtp::bundled, len(), NULL, ast_srtp_res::protect, res_srtp, ast_rtp::rtcp, ast_rtp::s, ast_rtcp::s, and status.

Referenced by rtcp_sendto(), and rtp_sendto().

◆ __unreg_module()

static void __unreg_module ( void  )
static

Definition at line 10293 of file res_rtp_asterisk.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module * AST_MODULE_SELF_SYM ( void  )

Definition at line 10293 of file res_rtp_asterisk.c.

◆ ast_rtcp_calc_interval()

static unsigned int ast_rtcp_calc_interval ( struct ast_rtp rtp)
static
Todo:
XXX Do a more reasonable calculation on this one Look in RFC 3550 Section A.7 for an example

Definition at line 3408 of file res_rtp_asterisk.c.

3409{
3410 unsigned int interval;
3411 /*! \todo XXX Do a more reasonable calculation on this one
3412 * Look in RFC 3550 Section A.7 for an example*/
3413 interval = rtcpinterval;
3414 return interval;
3415}
static int rtcpinterval

References rtcpinterval.

Referenced by ast_rtp_interpret(), and rtp_raw_write().

◆ ast_rtcp_calculate_sr_rr_statistics()

static int ast_rtcp_calculate_sr_rr_statistics ( struct ast_rtp_instance instance,
struct ast_rtp_rtcp_report rtcp_report,
struct ast_sockaddr  remote_address,
int  ice,
int  sr 
)
static

Definition at line 4682 of file res_rtp_asterisk.c.

4684{
4685 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4686 struct ast_rtp_rtcp_report_block *report_block = NULL;
4687 RAII_VAR(struct ast_json *, message_blob, NULL, ast_json_unref);
4688
4689 if (!rtp || !rtp->rtcp) {
4690 return 0;
4691 }
4692
4693 if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
4694 return 0;
4695 }
4696
4697 if (!rtcp_report) {
4698 return -1;
4699 }
4700
4701 report_block = rtcp_report->report_block[0];
4702
4703 if (sr) {
4704 rtp->rtcp->txlsr = rtcp_report->sender_information.ntp_timestamp;
4705 rtp->rtcp->sr_count++;
4706 rtp->rtcp->lastsrtxcount = rtp->txcount;
4707 } else {
4708 rtp->rtcp->rr_count++;
4709 }
4710
4711 if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
4712 ast_verbose("* Sent RTCP %s to %s%s\n", sr ? "SR" : "RR",
4713 ast_sockaddr_stringify(&remote_address), ice ? " (via ICE)" : "");
4714 ast_verbose(" Our SSRC: %u\n", rtcp_report->ssrc);
4715 if (sr) {
4716 ast_verbose(" Sent(NTP): %u.%06u\n",
4717 (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_sec,
4718 (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_usec);
4719 ast_verbose(" Sent(RTP): %u\n", rtcp_report->sender_information.rtp_timestamp);
4720 ast_verbose(" Sent packets: %u\n", rtcp_report->sender_information.packet_count);
4721 ast_verbose(" Sent octets: %u\n", rtcp_report->sender_information.octet_count);
4722 }
4723 if (report_block) {
4724 int rate = ast_rtp_get_rate(rtp->f.subclass.format);
4725 ast_verbose(" Report block:\n");
4726 ast_verbose(" Their SSRC: %u\n", report_block->source_ssrc);
4727 ast_verbose(" Fraction lost: %d\n", report_block->lost_count.fraction);
4728 ast_verbose(" Cumulative loss: %u\n", report_block->lost_count.packets);
4729 ast_verbose(" Highest seq no: %u\n", report_block->highest_seq_no);
4730 ast_verbose(" IA jitter (samp): %u\n", report_block->ia_jitter);
4731 ast_verbose(" IA jitter (secs): %.6f\n", ast_samp2sec(report_block->ia_jitter, rate));
4732 ast_verbose(" Their last SR: %u\n", report_block->lsr);
4733 ast_verbose(" DLSR: %4.4f (sec)\n\n", (double)(report_block->dlsr / 65536.0));
4734 }
4735 }
4736
4737 message_blob = ast_json_pack("{s: s, s: s, s: f}",
4738 "to", ast_sockaddr_stringify(&remote_address),
4739 "from", rtp->rtcp->local_addr_str,
4740 "mes", rtp->rxmes);
4741
4743 rtcp_report, message_blob);
4744
4745 return 1;
4746}
void ast_verbose(const char *fmt,...)
Definition: extconf.c:2206
struct stasis_message_type * ast_rtp_rtcp_sent_type(void)
Message type for an RTCP message sent from this Asterisk instance.
void ast_json_unref(struct ast_json *value)
Decrease refcount on value. If refcount reaches zero, value is freed.
Definition: json.c:73
struct ast_json * ast_json_pack(char const *format,...)
Helper for creating complex JSON values.
Definition: json.c:612
static int rtcp_debug_test_addr(struct ast_sockaddr *addr)
void ast_rtp_publish_rtcp_message(struct ast_rtp_instance *rtp, struct stasis_message_type *message_type, struct ast_rtp_rtcp_report *report, struct ast_json *blob)
Publish an RTCP message to Stasis Message Bus API.
Definition: rtp_engine.c:3523
int ast_rtp_get_rate(const struct ast_format *format)
Retrieve the sample rate of a format according to RTP specifications.
Definition: rtp_engine.c:4081
struct ast_format * format
struct ast_frame_subclass subclass
Abstract JSON element (object, array, string, int, ...).
unsigned int sr_count
unsigned int lastsrtxcount
struct timeval txlsr
unsigned int rr_count
char * local_addr_str
A report block within a SR/RR report.
Definition: rtp_engine.h:341
unsigned int highest_seq_no
Definition: rtp_engine.h:347
struct ast_rtp_rtcp_report_block::@272 lost_count
unsigned short fraction
Definition: rtp_engine.h:344
unsigned int source_ssrc
Definition: rtp_engine.h:342
struct ast_rtp_rtcp_report::@273 sender_information
unsigned int rtp_timestamp
Definition: rtp_engine.h:362
struct ast_rtp_rtcp_report_block * report_block[0]
Definition: rtp_engine.h:369
struct timeval ntp_timestamp
Definition: rtp_engine.h:361
unsigned int octet_count
Definition: rtp_engine.h:364
unsigned int ssrc
Definition: rtp_engine.h:358
unsigned int packet_count
Definition: rtp_engine.h:363
double rxmes
struct ast_frame f
unsigned int txcount
double ast_samp2sec(unsigned int _nsamp, unsigned int _rate)
Returns the duration in seconds of _nsamp samples at rate _rate.
Definition: time.h:316
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition: utils.h:941

References ast_json_pack(), ast_json_unref(), ast_rtp_get_rate(), ast_rtp_instance_get_data(), ast_rtp_publish_rtcp_message(), ast_rtp_rtcp_sent_type(), ast_samp2sec(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verbose(), ast_rtp_rtcp_report_block::dlsr, ast_rtp::f, ast_frame_subclass::format, ast_rtp_rtcp_report_block::fraction, ast_rtp_rtcp_report_block::highest_seq_no, ast_rtp_rtcp_report_block::ia_jitter, ast_rtcp::lastsrtxcount, ast_rtcp::local_addr_str, ast_rtp_rtcp_report_block::lost_count, ast_rtp_rtcp_report_block::lsr, ast_rtp_rtcp_report::ntp_timestamp, NULL, ast_rtp_rtcp_report::octet_count, ast_rtp_rtcp_report::packet_count, ast_rtp_rtcp_report_block::packets, RAII_VAR, ast_rtp_rtcp_report::report_block, ast_rtcp::rr_count, ast_rtp::rtcp, rtcp_debug_test_addr(), ast_rtp_rtcp_report::rtp_timestamp, ast_rtp::rxmes, ast_rtp_rtcp_report::sender_information, ast_rtp_rtcp_report_block::source_ssrc, ast_rtcp::sr_count, ast_rtp_rtcp_report::ssrc, ast_frame::subclass, ast_rtcp::them, ast_rtp::txcount, and ast_rtcp::txlsr.

Referenced by ast_rtcp_write(), ast_rtp_read(), rtp_write_rtcp_fir(), and rtp_write_rtcp_psfb().

◆ ast_rtcp_generate_compound_prefix()

static int ast_rtcp_generate_compound_prefix ( struct ast_rtp_instance instance,
unsigned char *  rtcpheader,
struct ast_rtp_rtcp_report report,
int *  sr 
)
static

Definition at line 4806 of file res_rtp_asterisk.c.

4808{
4809 int packet_len = 0;
4810 int res;
4811
4812 /* Every RTCP packet needs to be sent out with a SR/RR and SDES prefixing it.
4813 * At the end of this function, rtcpheader should contain both of those packets,
4814 * and will return the length of the overall packet. This can be used to determine
4815 * where further packets can be inserted in the compound packet.
4816 */
4817 res = ast_rtcp_generate_report(instance, rtcpheader, report, sr);
4818
4819 if (res == 0 || res == 1) {
4820 ast_debug_rtcp(1, "(%p) RTCP failed to generate %s report!\n", instance, sr ? "SR" : "RR");
4821 return 0;
4822 }
4823
4824 packet_len += res;
4825
4826 res = ast_rtcp_generate_sdes(instance, rtcpheader + packet_len, report);
4827
4828 if (res == 0 || res == 1) {
4829 ast_debug_rtcp(1, "(%p) RTCP failed to generate SDES!\n", instance);
4830 return 0;
4831 }
4832
4833 return packet_len + res;
4834}
static int ast_rtcp_generate_report(struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *rtcp_report, int *sr)
static int ast_rtcp_generate_sdes(struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *rtcp_report)
#define ast_debug_rtcp(sublevel,...)
Log debug level RTCP information.
Definition: rtp_engine.h:2923

References ast_debug_rtcp, ast_rtcp_generate_report(), and ast_rtcp_generate_sdes().

Referenced by ast_rtcp_write(), ast_rtp_read(), rtp_write_rtcp_fir(), and rtp_write_rtcp_psfb().

◆ ast_rtcp_generate_nack()

static int ast_rtcp_generate_nack ( struct ast_rtp_instance instance,
unsigned char *  rtcpheader 
)
static

Definition at line 4836 of file res_rtp_asterisk.c.

4837{
4838 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4839 int packet_len;
4840 int blp_index = -1;
4841 int current_seqno;
4842 unsigned int fci = 0;
4843 size_t remaining_missing_seqno;
4844
4845 if (!rtp || !rtp->rtcp) {
4846 return 0;
4847 }
4848
4849 if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
4850 return 0;
4851 }
4852
4853 current_seqno = rtp->expectedrxseqno;
4854 remaining_missing_seqno = AST_VECTOR_SIZE(&rtp->missing_seqno);
4855 packet_len = 12; /* The header length is 12 (version line, packet source SSRC, media source SSRC) */
4856
4857 /* If there are no missing sequence numbers then don't bother sending a NACK needlessly */
4858 if (!remaining_missing_seqno) {
4859 return 0;
4860 }
4861
4862 /* This iterates through the possible forward sequence numbers seeing which ones we
4863 * have no packet for, adding it to the NACK until we are out of missing packets.
4864 */
4865 while (remaining_missing_seqno) {
4866 int *missing_seqno;
4867
4868 /* On the first entry to this loop blp_index will be -1, so this will become 0
4869 * and the sequence number will be placed into the packet as the PID.
4870 */
4871 blp_index++;
4872
4873 missing_seqno = AST_VECTOR_GET_CMP(&rtp->missing_seqno, current_seqno,
4875 if (missing_seqno) {
4876 /* We hit the max blp size, reset */
4877 if (blp_index >= 17) {
4878 put_unaligned_uint32(rtcpheader + packet_len, htonl(fci));
4879 fci = 0;
4880 blp_index = 0;
4881 packet_len += 4;
4882 }
4883
4884 if (blp_index == 0) {
4885 fci |= (current_seqno << 16);
4886 } else {
4887 fci |= (1 << (blp_index - 1));
4888 }
4889
4890 /* Since we've used a missing sequence number, we're down one */
4891 remaining_missing_seqno--;
4892 }
4893
4894 /* Handle cycling of the sequence number */
4895 current_seqno++;
4896 if (current_seqno == SEQNO_CYCLE_OVER) {
4897 current_seqno = 0;
4898 }
4899 }
4900
4901 put_unaligned_uint32(rtcpheader + packet_len, htonl(fci));
4902 packet_len += 4;
4903
4904 /* Length MUST be 2+n, where n is the number of NACKs. Same as length in words minus 1 */
4905 put_unaligned_uint32(rtcpheader, htonl((2 << 30) | (AST_RTP_RTCP_FMT_NACK << 24)
4906 | (AST_RTP_RTCP_RTPFB << 16) | ((packet_len / 4) - 1)));
4907 put_unaligned_uint32(rtcpheader + 4, htonl(rtp->ssrc));
4908 put_unaligned_uint32(rtcpheader + 8, htonl(rtp->themssrc));
4909
4910 return packet_len;
4911}
static int find_by_value(int elem, int value)
Helper function to find an elem in a vector by value.
#define SEQNO_CYCLE_OVER
#define AST_RTP_RTCP_RTPFB
Definition: rtp_engine.h:322
#define AST_RTP_RTCP_FMT_NACK
Definition: rtp_engine.h:328
int expectedrxseqno
unsigned int ssrc
struct ast_rtp::@471 missing_seqno
static void put_unaligned_uint32(void *p, unsigned int datum)
Definition: unaligned.h:58
#define AST_VECTOR_GET_CMP(vec, value, cmp)
Get an element from a vector that matches the given comparison.
Definition: vector.h:731

References ast_rtp_instance_get_data(), AST_RTP_RTCP_FMT_NACK, AST_RTP_RTCP_RTPFB, ast_sockaddr_isnull(), AST_VECTOR_GET_CMP, AST_VECTOR_SIZE, ast_rtp::expectedrxseqno, find_by_value(), ast_rtp::missing_seqno, put_unaligned_uint32(), ast_rtp::rtcp, SEQNO_CYCLE_OVER, ast_rtp::ssrc, ast_rtcp::them, and ast_rtp::themssrc.

Referenced by ast_rtp_read().

◆ ast_rtcp_generate_report()

static int ast_rtcp_generate_report ( struct ast_rtp_instance instance,
unsigned char *  rtcpheader,
struct ast_rtp_rtcp_report rtcp_report,
int *  sr 
)
static

Definition at line 4589 of file res_rtp_asterisk.c.

4591{
4592 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4593 int len = 0;
4594 struct timeval now;
4595 unsigned int now_lsw;
4596 unsigned int now_msw;
4597 unsigned int lost_packets;
4598 int fraction_lost;
4599 struct timeval dlsr = { 0, };
4600 struct ast_rtp_rtcp_report_block *report_block = NULL;
4601
4602 if (!rtp || !rtp->rtcp) {
4603 return 0;
4604 }
4605
4606 if (ast_sockaddr_isnull(&rtp->rtcp->them)) { /* This'll stop rtcp for this rtp session */
4607 /* RTCP was stopped. */
4608 return 0;
4609 }
4610
4611 if (!rtcp_report) {
4612 return 1;
4613 }
4614
4615 *sr = rtp->txcount > rtp->rtcp->lastsrtxcount ? 1 : 0;
4616
4617 /* Compute statistics */
4618 calculate_lost_packet_statistics(rtp, &lost_packets, &fraction_lost);
4619 /*
4620 * update_local_mes_stats must be called AFTER
4621 * calculate_lost_packet_statistics
4622 */
4624
4625 gettimeofday(&now, NULL);
4626 rtcp_report->reception_report_count = rtp->themssrc_valid ? 1 : 0;
4627 rtcp_report->ssrc = rtp->ssrc;
4628 rtcp_report->type = *sr ? RTCP_PT_SR : RTCP_PT_RR;
4629 if (*sr) {
4630 rtcp_report->sender_information.ntp_timestamp = now;
4631 rtcp_report->sender_information.rtp_timestamp = rtp->lastts;
4632 rtcp_report->sender_information.packet_count = rtp->txcount;
4633 rtcp_report->sender_information.octet_count = rtp->txoctetcount;
4634 }
4635
4636 if (rtp->themssrc_valid) {
4637 report_block = ast_calloc(1, sizeof(*report_block));
4638 if (!report_block) {
4639 return 1;
4640 }
4641
4642 rtcp_report->report_block[0] = report_block;
4643 report_block->source_ssrc = rtp->themssrc;
4644 report_block->lost_count.fraction = (fraction_lost & 0xff);
4645 report_block->lost_count.packets = (lost_packets & 0xffffff);
4646 report_block->highest_seq_no = (rtp->cycles | (rtp->lastrxseqno & 0xffff));
4647 report_block->ia_jitter = (unsigned int)rtp->rxjitter_samples;
4648 report_block->lsr = rtp->rtcp->themrxlsr;
4649 /* If we haven't received an SR report, DLSR should be 0 */
4650 if (!ast_tvzero(rtp->rtcp->rxlsr)) {
4651 timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
4652 report_block->dlsr = (((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000;
4653 }
4654 }
4655 timeval2ntp(rtcp_report->sender_information.ntp_timestamp, &now_msw, &now_lsw);
4656 put_unaligned_uint32(rtcpheader + 4, htonl(rtcp_report->ssrc)); /* Our SSRC */
4657 len += 8;
4658 if (*sr) {
4659 put_unaligned_uint32(rtcpheader + len, htonl(now_msw)); /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970 */
4660 put_unaligned_uint32(rtcpheader + len + 4, htonl(now_lsw)); /* now, LSW */
4661 put_unaligned_uint32(rtcpheader + len + 8, htonl(rtcp_report->sender_information.rtp_timestamp));
4662 put_unaligned_uint32(rtcpheader + len + 12, htonl(rtcp_report->sender_information.packet_count));
4663 put_unaligned_uint32(rtcpheader + len + 16, htonl(rtcp_report->sender_information.octet_count));
4664 len += 20;
4665 }
4666 if (report_block) {
4667 put_unaligned_uint32(rtcpheader + len, htonl(report_block->source_ssrc)); /* Their SSRC */
4668 put_unaligned_uint32(rtcpheader + len + 4, htonl((report_block->lost_count.fraction << 24) | report_block->lost_count.packets));
4669 put_unaligned_uint32(rtcpheader + len + 8, htonl(report_block->highest_seq_no));
4670 put_unaligned_uint32(rtcpheader + len + 12, htonl(report_block->ia_jitter));
4671 put_unaligned_uint32(rtcpheader + len + 16, htonl(report_block->lsr));
4672 put_unaligned_uint32(rtcpheader + len + 20, htonl(report_block->dlsr));
4673 len += 24;
4674 }
4675
4676 put_unaligned_uint32(rtcpheader, htonl((2 << 30) | (rtcp_report->reception_report_count << 24)
4677 | ((*sr ? RTCP_PT_SR : RTCP_PT_RR) << 16) | ((len/4)-1)));
4678
4679 return len;
4680}
if(!yyg->yy_init)
Definition: ast_expr2f.c:854
#define ast_calloc(num, len)
A wrapper for calloc()
Definition: astmm.h:202
void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff)
#define RTCP_PT_RR
static void calculate_lost_packet_statistics(struct ast_rtp *rtp, unsigned int *lost_packets, int *fraction_lost)
#define RTCP_PT_SR
static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
static void update_local_mes_stats(struct ast_rtp *rtp)
unsigned int themrxlsr
struct timeval rxlsr
unsigned int type
Definition: rtp_engine.h:359
unsigned short reception_report_count
Definition: rtp_engine.h:357
unsigned int lastts
unsigned int cycles
double rxjitter_samples
unsigned int txoctetcount
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:117

References ast_calloc, ast_rtp_instance_get_data(), ast_sockaddr_isnull(), ast_tvzero(), calculate_lost_packet_statistics(), ast_rtp::cycles, ast_rtp_rtcp_report_block::dlsr, ast_rtp_rtcp_report_block::fraction, ast_rtp_rtcp_report_block::highest_seq_no, ast_rtp_rtcp_report_block::ia_jitter, if(), ast_rtp::lastrxseqno, ast_rtcp::lastsrtxcount, ast_rtp::lastts, len(), ast_rtp_rtcp_report_block::lost_count, ast_rtp_rtcp_report_block::lsr, ast_rtp_rtcp_report::ntp_timestamp, NULL, ast_rtp_rtcp_report::octet_count, ast_rtp_rtcp_report::packet_count, ast_rtp_rtcp_report_block::packets, put_unaligned_uint32(), ast_rtp_rtcp_report::reception_report_count, ast_rtp_rtcp_report::report_block, ast_rtp::rtcp, RTCP_PT_RR, RTCP_PT_SR, ast_rtp_rtcp_report::rtp_timestamp, ast_rtp::rxjitter_samples, ast_rtcp::rxlsr, ast_rtp_rtcp_report::sender_information, ast_rtp_rtcp_report_block::source_ssrc, ast_rtp_rtcp_report::ssrc, ast_rtp::ssrc, ast_rtcp::them, ast_rtcp::themrxlsr, ast_rtp::themssrc, ast_rtp::themssrc_valid, timersub(), timeval2ntp(), ast_rtp::txcount, ast_rtp::txoctetcount, ast_rtp_rtcp_report::type, and update_local_mes_stats().

Referenced by ast_rtcp_generate_compound_prefix().

◆ ast_rtcp_generate_sdes()

static int ast_rtcp_generate_sdes ( struct ast_rtp_instance instance,
unsigned char *  rtcpheader,
struct ast_rtp_rtcp_report rtcp_report 
)
static

Definition at line 4748 of file res_rtp_asterisk.c.

4750{
4751 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4752 int len = 0;
4753 uint16_t sdes_packet_len_bytes;
4754 uint16_t sdes_packet_len_rounded;
4755
4756 if (!rtp || !rtp->rtcp) {
4757 return 0;
4758 }
4759
4760 if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
4761 return 0;
4762 }
4763
4764 if (!rtcp_report) {
4765 return -1;
4766 }
4767
4768 sdes_packet_len_bytes =
4769 4 + /* RTCP Header */
4770 4 + /* SSRC */
4771 1 + /* Type (CNAME) */
4772 1 + /* Text Length */
4773 AST_UUID_STR_LEN /* Text and NULL terminator */
4774 ;
4775
4776 /* Round to 32 bit boundary */
4777 sdes_packet_len_rounded = (sdes_packet_len_bytes + 3) & ~0x3;
4778
4779 put_unaligned_uint32(rtcpheader, htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | ((sdes_packet_len_rounded / 4) - 1)));
4780 put_unaligned_uint32(rtcpheader + 4, htonl(rtcp_report->ssrc));
4781 rtcpheader[8] = 0x01; /* CNAME */
4782 rtcpheader[9] = AST_UUID_STR_LEN - 1; /* Number of bytes of text */
4783 memcpy(rtcpheader + 10, rtp->cname, AST_UUID_STR_LEN);
4784 len += 10 + AST_UUID_STR_LEN;
4785
4786 /* Padding - Note that we don't set the padded bit on the packet. From
4787 * RFC 3550 Section 6.5:
4788 *
4789 * No length octet follows the null item type octet, but additional null
4790 * octets MUST be included if needd to pad until the next 32-bit
4791 * boundary. Note that this padding is separate from that indicated by
4792 * the P bit in the RTCP header.
4793 *
4794 * These bytes will already be zeroed out during array initialization.
4795 */
4796 len += (sdes_packet_len_rounded - sdes_packet_len_bytes);
4797
4798 return len;
4799}
#define RTCP_PT_SDES
char cname[AST_UUID_STR_LEN]
#define AST_UUID_STR_LEN
Definition: uuid.h:27

References ast_rtp_instance_get_data(), ast_sockaddr_isnull(), AST_UUID_STR_LEN, ast_rtp::cname, len(), put_unaligned_uint32(), ast_rtp::rtcp, RTCP_PT_SDES, ast_rtp_rtcp_report::ssrc, and ast_rtcp::them.

Referenced by ast_rtcp_generate_compound_prefix().

◆ ast_rtcp_interpret()

static struct ast_frame * ast_rtcp_interpret ( struct ast_rtp_instance instance,
struct ast_srtp srtp,
const unsigned char *  rtcpdata,
size_t  size,
struct ast_sockaddr addr 
)
static

True if we have seen an acceptable SSRC to learn the remote RTCP address

True if the ssrc value we have is valid and not garbage because it doesn't exist.

Always use packet source SSRC to find the rtp instance unless explicitly told not to.

Definition at line 6504 of file res_rtp_asterisk.c.

6506{
6507 struct ast_rtp_instance *transport = instance;
6508 struct ast_rtp *transport_rtp = ast_rtp_instance_get_data(instance);
6509 int len = size;
6510 unsigned int *rtcpheader = (unsigned int *)(rtcpdata);
6511 unsigned int packetwords;
6512 unsigned int position;
6513 unsigned int first_word;
6514 /*! True if we have seen an acceptable SSRC to learn the remote RTCP address */
6515 unsigned int ssrc_seen;
6516 struct ast_rtp_rtcp_report_block *report_block;
6517 struct ast_frame *f = &ast_null_frame;
6518#ifdef TEST_FRAMEWORK
6519 struct ast_rtp_engine_test *test_engine;
6520#endif
6521
6522 /* If this is encrypted then decrypt the payload */
6523 if ((*rtcpheader & 0xC0) && res_srtp && srtp && res_srtp->unprotect(
6524 srtp, rtcpheader, &len, 1 | (srtp_replay_protection << 1)) < 0) {
6525 return &ast_null_frame;
6526 }
6527
6528 packetwords = len / 4;
6529
6530 ast_debug_rtcp(2, "(%s) RTCP got report of %d bytes from %s\n",
6533
6534 /*
6535 * Validate the RTCP packet according to an adapted and slightly
6536 * modified RFC3550 validation algorithm.
6537 */
6538 if (packetwords < RTCP_HEADER_SSRC_LENGTH) {
6539 ast_debug_rtcp(2, "(%s) RTCP %p -- from %s: Frame size (%u words) is too short\n",
6541 transport_rtp, ast_sockaddr_stringify(addr), packetwords);
6542 return &ast_null_frame;
6543 }
6544 position = 0;
6545 first_word = ntohl(rtcpheader[position]);
6546 if ((first_word & RTCP_VALID_MASK) != RTCP_VALID_VALUE) {
6547 ast_debug_rtcp(2, "(%s) RTCP %p -- from %s: Failed first packet validity check\n",
6549 transport_rtp, ast_sockaddr_stringify(addr));
6550 return &ast_null_frame;
6551 }
6552 do {
6553 position += ((first_word >> RTCP_LENGTH_SHIFT) & RTCP_LENGTH_MASK) + 1;
6554 if (packetwords <= position) {
6555 break;
6556 }
6557 first_word = ntohl(rtcpheader[position]);
6558 } while ((first_word & RTCP_VERSION_MASK_SHIFTED) == RTCP_VERSION_SHIFTED);
6559 if (position != packetwords) {
6560 ast_debug_rtcp(2, "(%s) RTCP %p -- from %s: Failed packet version or length check\n",
6562 transport_rtp, ast_sockaddr_stringify(addr));
6563 return &ast_null_frame;
6564 }
6565
6566 /*
6567 * Note: RFC3605 points out that true NAT (vs NAPT) can cause RTCP
6568 * to have a different IP address and port than RTP. Otherwise, when
6569 * strictrtp is enabled we could reject RTCP packets not coming from
6570 * the learned RTP IP address if it is available.
6571 */
6572
6573 /*
6574 * strictrtp safety needs SSRC to match before we use the
6575 * sender's address for symmetrical RTP to send our RTCP
6576 * reports.
6577 *
6578 * If strictrtp is not enabled then claim to have already seen
6579 * a matching SSRC so we'll accept this packet's address for
6580 * symmetrical RTP.
6581 */
6582 ssrc_seen = transport_rtp->strict_rtp_state == STRICT_RTP_OPEN;
6583
6584 position = 0;
6585 while (position < packetwords) {
6586 unsigned int i;
6587 unsigned int pt;
6588 unsigned int rc;
6589 unsigned int ssrc;
6590 /*! True if the ssrc value we have is valid and not garbage because it doesn't exist. */
6591 unsigned int ssrc_valid;
6592 unsigned int length;
6593 unsigned int min_length;
6594 /*! Always use packet source SSRC to find the rtp instance unless explicitly told not to. */
6595 unsigned int use_packet_source = 1;
6596
6597 struct ast_json *message_blob;
6598 RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report, NULL, ao2_cleanup);
6599 struct ast_rtp_instance *child;
6600 struct ast_rtp *rtp;
6601 struct ast_rtp_rtcp_feedback *feedback;
6602
6603 i = position;
6604 first_word = ntohl(rtcpheader[i]);
6605 pt = (first_word >> RTCP_PAYLOAD_TYPE_SHIFT) & RTCP_PAYLOAD_TYPE_MASK;
6606 rc = (first_word >> RTCP_REPORT_COUNT_SHIFT) & RTCP_REPORT_COUNT_MASK;
6607 /* RFC3550 says 'length' is the number of words in the packet - 1 */
6608 length = ((first_word >> RTCP_LENGTH_SHIFT) & RTCP_LENGTH_MASK) + 1;
6609
6610 /* Check expected RTCP packet record length */
6611 min_length = RTCP_HEADER_SSRC_LENGTH;
6612 switch (pt) {
6613 case RTCP_PT_SR:
6614 min_length += RTCP_SR_BLOCK_WORD_LENGTH;
6615 /* fall through */
6616 case RTCP_PT_RR:
6617 min_length += (rc * RTCP_RR_BLOCK_WORD_LENGTH);
6618 use_packet_source = 0;
6619 break;
6620 case RTCP_PT_FUR:
6621 break;
6622 case AST_RTP_RTCP_RTPFB:
6623 switch (rc) {
6625 min_length += RTCP_FB_NACK_BLOCK_WORD_LENGTH;
6626 break;
6627 default:
6628 break;
6629 }
6630 use_packet_source = 0;
6631 break;
6632 case RTCP_PT_PSFB:
6633 switch (rc) {
6635 min_length += RTCP_FB_REMB_BLOCK_WORD_LENGTH;
6636 break;
6637 default:
6638 break;
6639 }
6640 break;
6641 case RTCP_PT_SDES:
6642 case RTCP_PT_BYE:
6643 /*
6644 * There may not be a SSRC/CSRC present. The packet is
6645 * useless but still valid if it isn't present.
6646 *
6647 * We don't know what min_length should be so disable the check
6648 */
6649 min_length = length;
6650 break;
6651 default:
6652 ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: %u(%s) skipping record\n",
6653 instance, transport_rtp, ast_sockaddr_stringify(addr), pt, rtcp_payload_type2str(pt));
6654 if (rtcp_debug_test_addr(addr)) {
6655 ast_verbose("\n");
6656 ast_verbose("RTCP from %s: %u(%s) skipping record\n",
6658 }
6659 position += length;
6660 continue;
6661 }
6662 if (length < min_length) {
6663 ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: %u(%s) length field less than expected minimum. Min:%u Got:%u\n",
6664 instance, transport_rtp, ast_sockaddr_stringify(addr), pt, rtcp_payload_type2str(pt),
6665 min_length - 1, length - 1);
6666 return &ast_null_frame;
6667 }
6668
6669 /* Get the RTCP record SSRC if defined for the record */
6670 ssrc_valid = 1;
6671 switch (pt) {
6672 case RTCP_PT_SR:
6673 case RTCP_PT_RR:
6674 rtcp_report = ast_rtp_rtcp_report_alloc(rc);
6675 if (!rtcp_report) {
6676 return &ast_null_frame;
6677 }
6678 rtcp_report->reception_report_count = rc;
6679
6680 ssrc = ntohl(rtcpheader[i + 2]);
6681 rtcp_report->ssrc = ssrc;
6682 break;
6683 case RTCP_PT_FUR:
6684 case RTCP_PT_PSFB:
6685 ssrc = ntohl(rtcpheader[i + 1]);
6686 break;
6687 case AST_RTP_RTCP_RTPFB:
6688 ssrc = ntohl(rtcpheader[i + 2]);
6689 break;
6690 case RTCP_PT_SDES:
6691 case RTCP_PT_BYE:
6692 default:
6693 ssrc = 0;
6694 ssrc_valid = 0;
6695 break;
6696 }
6697
6698 if (rtcp_debug_test_addr(addr)) {
6699 const char *subtype = rtcp_payload_subtype2str(pt, rc);
6700
6701 ast_verbose("\n");
6702 ast_verbose("RTCP from %s\n", ast_sockaddr_stringify(addr));
6703 ast_verbose("PT: %u (%s)\n", pt, rtcp_payload_type2str(pt));
6704 if (subtype) {
6705 ast_verbose("Packet Subtype: %u (%s)\n", rc, subtype);
6706 } else {
6707 ast_verbose("Reception reports: %u\n", rc);
6708 }
6709 ast_verbose("SSRC of sender: %u\n", ssrc);
6710 }
6711
6712 /* Determine the appropriate instance for this */
6713 if (ssrc_valid) {
6714 /*
6715 * Depending on the payload type, either the packet source or media source
6716 * SSRC is used.
6717 */
6718 if (use_packet_source) {
6719 child = rtp_find_instance_by_packet_source_ssrc(transport, transport_rtp, ssrc);
6720 } else {
6721 child = rtp_find_instance_by_media_source_ssrc(transport, transport_rtp, ssrc);
6722 }
6723 if (child && child != transport) {
6724 /*
6725 * It is safe to hold the child lock while holding the parent lock.
6726 * We guarantee that the locking order is always parent->child or
6727 * that the child lock is not held when acquiring the parent lock.
6728 */
6729 ao2_lock(child);
6730 instance = child;
6731 rtp = ast_rtp_instance_get_data(instance);
6732 } else {
6733 /* The child is the parent! We don't need to unlock it. */
6734 child = NULL;
6735 rtp = transport_rtp;
6736 }
6737 } else {
6738 child = NULL;
6739 rtp = transport_rtp;
6740 }
6741
6742 if (ssrc_valid && rtp->themssrc_valid) {
6743 /*
6744 * If the SSRC is 1, we still need to handle RTCP since this could be a
6745 * special case. For example, if we have a unidirectional video stream, the
6746 * SSRC may be set to 1 by the browser (in the case of chromium), and requests
6747 * will still need to be processed so that video can flow as expected. This
6748 * should only be done for PLI and FUR, since there is not a way to get the
6749 * appropriate rtp instance when the SSRC is 1.
6750 */
6751 int exception = (ssrc == 1 && !((pt == RTCP_PT_PSFB && rc == AST_RTP_RTCP_FMT_PLI) || pt == RTCP_PT_FUR));
6752 if ((ssrc != rtp->themssrc && use_packet_source && ssrc != 1)
6753 || exception) {
6754 /*
6755 * Skip over this RTCP record as it does not contain the
6756 * correct SSRC. We should not act upon RTCP records
6757 * for a different stream.
6758 */
6759 position += length;
6760 ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: Skipping record, received SSRC '%u' != expected '%u'\n",
6761 instance, rtp, ast_sockaddr_stringify(addr), ssrc, rtp->themssrc);
6762 if (child) {
6763 ao2_unlock(child);
6764 }
6765 continue;
6766 }
6767 ssrc_seen = 1;
6768 }
6769
6770 if (ssrc_seen && ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_NAT)) {
6771 /* Send to whoever sent to us */
6772 if (ast_sockaddr_cmp(&rtp->rtcp->them, addr)) {
6773 ast_sockaddr_copy(&rtp->rtcp->them, addr);
6775 ast_debug(0, "(%p) RTCP NAT: Got RTCP from other end. Now sending to address %s\n",
6776 instance, ast_sockaddr_stringify(addr));
6777 }
6778 }
6779 }
6780
6781 i += RTCP_HEADER_SSRC_LENGTH; /* Advance past header and ssrc */
6782 switch (pt) {
6783 case RTCP_PT_SR:
6784 gettimeofday(&rtp->rtcp->rxlsr, NULL);
6785 rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16);
6786 rtp->rtcp->spc = ntohl(rtcpheader[i + 3]);
6787 rtp->rtcp->soc = ntohl(rtcpheader[i + 4]);
6788
6789 rtcp_report->type = RTCP_PT_SR;
6790 rtcp_report->sender_information.packet_count = rtp->rtcp->spc;
6791 rtcp_report->sender_information.octet_count = rtp->rtcp->soc;
6792 ntp2timeval((unsigned int)ntohl(rtcpheader[i]),
6793 (unsigned int)ntohl(rtcpheader[i + 1]),
6794 &rtcp_report->sender_information.ntp_timestamp);
6795 rtcp_report->sender_information.rtp_timestamp = ntohl(rtcpheader[i + 2]);
6796 if (rtcp_debug_test_addr(addr)) {
6797 ast_verbose("NTP timestamp: %u.%06u\n",
6798 (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_sec,
6799 (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_usec);
6800 ast_verbose("RTP timestamp: %u\n", rtcp_report->sender_information.rtp_timestamp);
6801 ast_verbose("SPC: %u\tSOC: %u\n",
6802 rtcp_report->sender_information.packet_count,
6803 rtcp_report->sender_information.octet_count);
6804 }
6806 /* Intentional fall through */
6807 case RTCP_PT_RR:
6808 if (rtcp_report->type != RTCP_PT_SR) {
6809 rtcp_report->type = RTCP_PT_RR;
6810 }
6811
6812 if (rc > 0) {
6813 /* Don't handle multiple reception reports (rc > 1) yet */
6814 report_block = ast_calloc(1, sizeof(*report_block));
6815 if (!report_block) {
6816 if (child) {
6817 ao2_unlock(child);
6818 }
6819 return &ast_null_frame;
6820 }
6821 rtcp_report->report_block[0] = report_block;
6822 report_block->source_ssrc = ntohl(rtcpheader[i]);
6823 report_block->lost_count.packets = ntohl(rtcpheader[i + 1]) & 0x00ffffff;
6824 report_block->lost_count.fraction = ((ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24);
6825 report_block->highest_seq_no = ntohl(rtcpheader[i + 2]);
6826 report_block->ia_jitter = ntohl(rtcpheader[i + 3]);
6827 report_block->lsr = ntohl(rtcpheader[i + 4]);
6828 report_block->dlsr = ntohl(rtcpheader[i + 5]);
6829 if (report_block->lsr) {
6830 int skewed = update_rtt_stats(rtp, report_block->lsr, report_block->dlsr);
6831 if (skewed && rtcp_debug_test_addr(addr)) {
6832 struct timeval now;
6833 unsigned int lsr_now, lsw, msw;
6834 gettimeofday(&now, NULL);
6835 timeval2ntp(now, &msw, &lsw);
6836 lsr_now = (((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16));
6837 ast_verbose("Internal RTCP NTP clock skew detected: "
6838 "lsr=%u, now=%u, dlsr=%u (%u:%03ums), "
6839 "diff=%u\n",
6840 report_block->lsr, lsr_now, report_block->dlsr, report_block->dlsr / 65536,
6841 (report_block->dlsr % 65536) * 1000 / 65536,
6842 report_block->dlsr - (lsr_now - report_block->lsr));
6843 }
6844 }
6845 update_jitter_stats(rtp, report_block->ia_jitter);
6846 update_lost_stats(rtp, report_block->lost_count.packets);
6847 /*
6848 * update_reported_mes_stats must be called AFTER
6849 * update_rtt_stats, update_jitter_stats and
6850 * update_lost_stats.
6851 */
6853
6854 if (rtcp_debug_test_addr(addr)) {
6855 int rate = ast_rtp_get_rate(rtp->f.subclass.format);
6856
6857 ast_verbose(" Fraction lost: %d\n", report_block->lost_count.fraction);
6858 ast_verbose(" Packets lost so far: %u\n", report_block->lost_count.packets);
6859 ast_verbose(" Highest sequence number: %u\n", report_block->highest_seq_no & 0x0000ffff);
6860 ast_verbose(" Sequence number cycles: %u\n", report_block->highest_seq_no >> 16);
6861 ast_verbose(" Interarrival jitter (samp): %u\n", report_block->ia_jitter);
6862 ast_verbose(" Interarrival jitter (secs): %.6f\n", ast_samp2sec(report_block->ia_jitter, rate));
6863 ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long)(report_block->lsr) >> 16,((unsigned long)(report_block->lsr) << 16) * 4096);
6864 ast_verbose(" DLSR: %4.4f (sec)\n",(double)report_block->dlsr / 65536.0);
6865 ast_verbose(" RTT: %4.4f(sec)\n", rtp->rtcp->rtt);
6866 ast_verbose(" MES: %4.1f\n", rtp->rtcp->reported_mes);
6867 }
6868 }
6869 /* If and when we handle more than one report block, this should occur outside
6870 * this loop.
6871 */
6872
6873 message_blob = ast_json_pack("{s: s, s: s, s: f, s: f}",
6874 "from", ast_sockaddr_stringify(addr),
6875 "to", transport_rtp->rtcp->local_addr_str,
6876 "rtt", rtp->rtcp->rtt,
6877 "mes", rtp->rtcp->reported_mes);
6879 rtcp_report,
6880 message_blob);
6881 ast_json_unref(message_blob);
6882
6883 /* Return an AST_FRAME_RTCP frame with the ast_rtp_rtcp_report
6884 * object as a its data */
6885 transport_rtp->f.frametype = AST_FRAME_RTCP;
6886 transport_rtp->f.subclass.integer = pt;
6887 transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
6888 memcpy(transport_rtp->f.data.ptr, rtcp_report, sizeof(struct ast_rtp_rtcp_report));
6889 transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_report);
6890 if (rc > 0) {
6891 /* There's always a single report block stored, here */
6892 struct ast_rtp_rtcp_report *rtcp_report2;
6893 report_block = transport_rtp->f.data.ptr + transport_rtp->f.datalen + sizeof(struct ast_rtp_rtcp_report_block *);
6894 memcpy(report_block, rtcp_report->report_block[0], sizeof(struct ast_rtp_rtcp_report_block));
6895 rtcp_report2 = (struct ast_rtp_rtcp_report *)transport_rtp->f.data.ptr;
6896 rtcp_report2->report_block[0] = report_block;
6897 transport_rtp->f.datalen += sizeof(struct ast_rtp_rtcp_report_block);
6898 }
6899 transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
6900 transport_rtp->f.samples = 0;
6901 transport_rtp->f.mallocd = 0;
6902 transport_rtp->f.delivery.tv_sec = 0;
6903 transport_rtp->f.delivery.tv_usec = 0;
6904 transport_rtp->f.src = "RTP";
6905 transport_rtp->f.stream_num = rtp->stream_num;
6906 f = &transport_rtp->f;
6907 break;
6908 case AST_RTP_RTCP_RTPFB:
6909 switch (rc) {
6911 /* If retransmissions are not enabled ignore this message */
6912 if (!rtp->send_buffer) {
6913 break;
6914 }
6915
6916 if (rtcp_debug_test_addr(addr)) {
6917 ast_verbose("Received generic RTCP NACK message\n");
6918 }
6919
6920 ast_rtp_rtcp_handle_nack(instance, rtcpheader, position, length);
6921 break;
6922 default:
6923 break;
6924 }
6925 break;
6926 case RTCP_PT_FUR:
6927 /* Handle RTCP FUR as FIR by setting the format to 4 */
6929 case RTCP_PT_PSFB:
6930 switch (rc) {
6933 if (rtcp_debug_test_addr(addr)) {
6934 ast_verbose("Received an RTCP Fast Update Request\n");
6935 }
6936 transport_rtp->f.frametype = AST_FRAME_CONTROL;
6937 transport_rtp->f.subclass.integer = AST_CONTROL_VIDUPDATE;
6938 transport_rtp->f.datalen = 0;
6939 transport_rtp->f.samples = 0;
6940 transport_rtp->f.mallocd = 0;
6941 transport_rtp->f.src = "RTP";
6942 f = &transport_rtp->f;
6943 break;
6945 /* If REMB support is not enabled ignore this message */
6947 break;
6948 }
6949
6950 if (rtcp_debug_test_addr(addr)) {
6951 ast_verbose("Received REMB report\n");
6952 }
6953 transport_rtp->f.frametype = AST_FRAME_RTCP;
6954 transport_rtp->f.subclass.integer = pt;
6955 transport_rtp->f.stream_num = rtp->stream_num;
6956 transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
6957 feedback = transport_rtp->f.data.ptr;
6958 feedback->fmt = rc;
6959
6960 /* We don't actually care about the SSRC information in the feedback message */
6961 first_word = ntohl(rtcpheader[i + 2]);
6962 feedback->remb.br_exp = (first_word >> 18) & ((1 << 6) - 1);
6963 feedback->remb.br_mantissa = first_word & ((1 << 18) - 1);
6964
6965 transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_feedback);
6966 transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
6967 transport_rtp->f.samples = 0;
6968 transport_rtp->f.mallocd = 0;
6969 transport_rtp->f.delivery.tv_sec = 0;
6970 transport_rtp->f.delivery.tv_usec = 0;
6971 transport_rtp->f.src = "RTP";
6972 f = &transport_rtp->f;
6973 break;
6974 default:
6975 break;
6976 }
6977 break;
6978 case RTCP_PT_SDES:
6979 if (rtcp_debug_test_addr(addr)) {
6980 ast_verbose("Received an SDES from %s\n",
6982 }
6983#ifdef TEST_FRAMEWORK
6984 if ((test_engine = ast_rtp_instance_get_test(instance))) {
6985 test_engine->sdes_received = 1;
6986 }
6987#endif
6988 break;
6989 case RTCP_PT_BYE:
6990 if (rtcp_debug_test_addr(addr)) {
6991 ast_verbose("Received a BYE from %s\n",
6993 }
6994 break;
6995 default:
6996 break;
6997 }
6998 position += length;
6999 rtp->rtcp->rtcp_info = 1;
7000
7001 if (child) {
7002 ao2_unlock(child);
7003 }
7004 }
7005
7006 return f;
7007}
#define ao2_cleanup(obj)
Definition: astobj2.h:1934
struct stasis_message_type * ast_rtp_rtcp_received_type(void)
Message type for an RTCP message received from some external source.
#define AST_FRIENDLY_OFFSET
Offset into a frame's data buffer.
@ AST_FRAME_RTCP
@ AST_FRAME_CONTROL
@ AST_CONTROL_VIDUPDATE
struct ast_frame ast_null_frame
Definition: main/frame.c:79
#define ast_debug(level,...)
Log a DEBUG message.
#define RTCP_LENGTH_SHIFT
static int ast_rtp_rtcp_handle_nack(struct ast_rtp_instance *instance, unsigned int *nackdata, unsigned int position, unsigned int length)
#define RTCP_PAYLOAD_TYPE_SHIFT
static void ntp2timeval(unsigned int msw, unsigned int lsw, struct timeval *tv)
#define RTCP_VALID_VALUE
#define RTCP_FB_NACK_BLOCK_WORD_LENGTH
#define RTCP_RR_BLOCK_WORD_LENGTH
static const char * rtcp_payload_subtype2str(unsigned int pt, unsigned int subtype)
#define RTCP_SR_BLOCK_WORD_LENGTH
static struct ast_rtp_instance * rtp_find_instance_by_packet_source_ssrc(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
#define RTCP_REPORT_COUNT_SHIFT
#define RTCP_PT_FUR
static const char * rtcp_payload_type2str(unsigned int pt)
#define RTCP_PT_BYE
#define RTCP_HEADER_SSRC_LENGTH
#define RTCP_VALID_MASK
static int srtp_replay_protection
static void update_jitter_stats(struct ast_rtp *rtp, unsigned int ia_jitter)
#define RTCP_FB_REMB_BLOCK_WORD_LENGTH
#define RTCP_PT_PSFB
static int update_rtt_stats(struct ast_rtp *rtp, unsigned int lsr, unsigned int dlsr)
static struct ast_rtp_instance * rtp_find_instance_by_media_source_ssrc(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned int ssrc)
#define RTCP_VERSION_SHIFTED
#define RTCP_REPORT_COUNT_MASK
#define RTCP_PAYLOAD_TYPE_MASK
#define RTCP_VERSION_MASK_SHIFTED
static void update_reported_mes_stats(struct ast_rtp *rtp)
static void update_lost_stats(struct ast_rtp *rtp, unsigned int lost_packets)
#define RTCP_LENGTH_MASK
#define AST_RTP_RTCP_FMT_FIR
Definition: rtp_engine.h:332
struct ast_rtp_rtcp_report * ast_rtp_rtcp_report_alloc(unsigned int report_blocks)
Allocate an ao2 ref counted instance of ast_rtp_rtcp_report.
Definition: rtp_engine.c:3512
int ast_rtp_instance_get_prop(struct ast_rtp_instance *instance, enum ast_rtp_property property)
Get the value of an RTP instance property.
Definition: rtp_engine.c:737
#define ast_debug_rtp_packet_is_allowed
Definition: rtp_engine.h:2914
#define AST_RTP_RTCP_FMT_REMB
Definition: rtp_engine.h:334
@ AST_RTP_PROPERTY_NAT
Definition: rtp_engine.h:115
@ AST_RTP_PROPERTY_REMB
Definition: rtp_engine.h:131
const char * ast_rtp_instance_get_channel_id(struct ast_rtp_instance *instance)
Get the unique ID of the channel that owns this RTP instance.
Definition: rtp_engine.c:569
#define AST_RTP_RTCP_FMT_PLI
Definition: rtp_engine.h:330
Data structure associated with a single frame of data.
union ast_frame::@226 data
struct timeval delivery
enum ast_frame_type frametype
const char * src
double reported_mes
unsigned char frame_buf[512+AST_FRIENDLY_OFFSET]
unsigned int soc
unsigned int spc
An object that represents data received in a feedback report.
Definition: rtp_engine.h:383
unsigned int fmt
Definition: rtp_engine.h:384
struct ast_rtp_rtcp_feedback_remb remb
Definition: rtp_engine.h:386
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:356
enum strict_rtp_state strict_rtp_state
struct ast_data_buffer * send_buffer
int(* unprotect)(struct ast_srtp *srtp, void *buf, int *size, int rtcp)
Definition: res_srtp.h:48

References ao2_cleanup, ao2_lock, ao2_unlock, ast_calloc, AST_CONTROL_VIDUPDATE, ast_debug, ast_debug_rtcp, ast_debug_rtp_packet_is_allowed, AST_FRAME_CONTROL, AST_FRAME_RTCP, AST_FRIENDLY_OFFSET, ast_json_pack(), ast_json_unref(), ast_null_frame, ast_rtp_get_rate(), ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), AST_RTP_PROPERTY_NAT, AST_RTP_PROPERTY_REMB, ast_rtp_publish_rtcp_message(), AST_RTP_RTCP_FMT_FIR, AST_RTP_RTCP_FMT_NACK, AST_RTP_RTCP_FMT_PLI, AST_RTP_RTCP_FMT_REMB, ast_rtp_rtcp_handle_nack(), ast_rtp_rtcp_received_type(), ast_rtp_rtcp_report_alloc(), AST_RTP_RTCP_RTPFB, ast_samp2sec(), ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_verbose(), ast_rtp_rtcp_feedback_remb::br_exp, ast_rtp_rtcp_feedback_remb::br_mantissa, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_rtp_rtcp_report_block::dlsr, ast_rtp::f, ast_rtp_rtcp_feedback::fmt, ast_frame_subclass::format, ast_rtp_rtcp_report_block::fraction, ast_rtcp::frame_buf, ast_frame::frametype, ast_rtp_rtcp_report_block::highest_seq_no, ast_rtp_rtcp_report_block::ia_jitter, ast_frame_subclass::integer, len(), ast_rtcp::local_addr_str, ast_rtp_rtcp_report_block::lost_count, ast_rtp_rtcp_report_block::lsr, ast_frame::mallocd, ntp2timeval(), NULL, ast_frame::offset, ast_rtp_rtcp_report_block::packets, ast_frame::ptr, RAII_VAR, ast_rtp_rtcp_feedback::remb, ast_rtp_rtcp_report::report_block, ast_rtcp::reported_mes, res_srtp, ast_rtp::rtcp, rtcp_debug_test_addr(), RTCP_FB_NACK_BLOCK_WORD_LENGTH, RTCP_FB_REMB_BLOCK_WORD_LENGTH, RTCP_HEADER_SSRC_LENGTH, ast_rtcp::rtcp_info, RTCP_LENGTH_MASK, RTCP_LENGTH_SHIFT, rtcp_payload_subtype2str(), rtcp_payload_type2str(), RTCP_PAYLOAD_TYPE_MASK, RTCP_PAYLOAD_TYPE_SHIFT, RTCP_PT_BYE, RTCP_PT_FUR, RTCP_PT_PSFB, RTCP_PT_RR, RTCP_PT_SDES, RTCP_PT_SR, RTCP_REPORT_COUNT_MASK, RTCP_REPORT_COUNT_SHIFT, RTCP_RR_BLOCK_WORD_LENGTH, RTCP_SR_BLOCK_WORD_LENGTH, RTCP_VALID_MASK, RTCP_VALID_VALUE, RTCP_VERSION_MASK_SHIFTED, RTCP_VERSION_SHIFTED, rtp_find_instance_by_media_source_ssrc(), rtp_find_instance_by_packet_source_ssrc(), ast_rtcp::rtt, ast_rtcp::rxlsr, ast_frame::samples, ast_rtp::send_buffer, ast_rtcp::soc, ast_rtp_rtcp_report_block::source_ssrc, ast_rtcp::spc, ast_frame::src, srtp_replay_protection, ast_frame::stream_num, ast_rtp::stream_num, STRICT_RTP_OPEN, ast_rtp::strict_rtp_state, ast_frame::subclass, ast_rtcp::them, ast_rtcp::themrxlsr, ast_rtp::themssrc, ast_rtp::themssrc_valid, timeval2ntp(), ast_srtp_res::unprotect, update_jitter_stats(), update_lost_stats(), update_reported_mes_stats(), and update_rtt_stats().

Referenced by ast_rtcp_read(), and ast_rtp_read().

◆ ast_rtcp_read()

static struct ast_frame * ast_rtcp_read ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 7010 of file res_rtp_asterisk.c.

7011{
7012 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
7013 struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance, 1);
7014 struct ast_sockaddr addr;
7015 unsigned char rtcpdata[8192 + AST_FRIENDLY_OFFSET];
7016 unsigned char *read_area = rtcpdata + AST_FRIENDLY_OFFSET;
7017 size_t read_area_size = sizeof(rtcpdata) - AST_FRIENDLY_OFFSET;
7018 int res;
7019
7020 /* Read in RTCP data from the socket */
7021 if ((res = rtcp_recvfrom(instance, read_area, read_area_size,
7022 0, &addr)) < 0) {
7023 if (res == RTP_DTLS_ESTABLISHED) {
7026 return &rtp->f;
7027 }
7028
7029 ast_assert(errno != EBADF);
7030 if (errno != EAGAIN) {
7031 ast_log(LOG_WARNING, "RTCP Read error: %s. Hanging up.\n",
7032 (errno) ? strerror(errno) : "Unspecified");
7033 return NULL;
7034 }
7035 return &ast_null_frame;
7036 }
7037
7038 /* If this was handled by the ICE session don't do anything further */
7039 if (!res) {
7040 return &ast_null_frame;
7041 }
7042
7043 if (!*read_area) {
7044 struct sockaddr_in addr_tmp;
7045 struct ast_sockaddr addr_v4;
7046
7047 if (ast_sockaddr_is_ipv4(&addr)) {
7048 ast_sockaddr_to_sin(&addr, &addr_tmp);
7049 } else if (ast_sockaddr_ipv4_mapped(&addr, &addr_v4)) {
7050 ast_debug_stun(2, "(%p) STUN using IPv6 mapped address %s\n",
7051 instance, ast_sockaddr_stringify(&addr));
7052 ast_sockaddr_to_sin(&addr_v4, &addr_tmp);
7053 } else {
7054 ast_debug_stun(2, "(%p) STUN cannot do for non IPv4 address %s\n",
7055 instance, ast_sockaddr_stringify(&addr));
7056 return &ast_null_frame;
7057 }
7058 if ((ast_stun_handle_packet(rtp->rtcp->s, &addr_tmp, read_area, res, NULL, NULL) == AST_STUN_ACCEPT)) {
7059 ast_sockaddr_from_sin(&addr, &addr_tmp);
7060 ast_sockaddr_copy(&rtp->rtcp->them, &addr);
7061 }
7062 return &ast_null_frame;
7063 }
7064
7065 return ast_rtcp_interpret(instance, srtp, read_area, res, &addr);
7066}
@ AST_CONTROL_SRCCHANGE
int errno
int ast_sockaddr_ipv4_mapped(const struct ast_sockaddr *addr, struct ast_sockaddr *ast_mapped)
Convert an IPv4-mapped IPv6 address into an IPv4 address.
Definition: netsock2.c:37
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:765
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:778
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:497
static struct ast_frame * ast_rtcp_interpret(struct ast_rtp_instance *instance, struct ast_srtp *srtp, const unsigned char *rtcpdata, size_t size, struct ast_sockaddr *addr)
static int rtcp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
int ast_stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len, stun_cb_f *stun_cb, void *arg)
handle an incoming STUN message.
Definition: stun.c:293
#define ast_debug_stun(sublevel,...)
Log debug level STUN information.
Definition: stun.h:54
@ AST_STUN_ACCEPT
Definition: stun.h:65
#define ast_assert(a)
Definition: utils.h:739

References ast_assert, AST_CONTROL_SRCCHANGE, ast_debug_stun, AST_FRAME_CONTROL, AST_FRIENDLY_OFFSET, ast_log, ast_null_frame, ast_rtcp_interpret(), ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_sockaddr_copy(), ast_sockaddr_from_sin, ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_ipv4(), ast_sockaddr_stringify(), ast_sockaddr_to_sin, AST_STUN_ACCEPT, ast_stun_handle_packet(), errno, ast_rtp::f, ast_frame::frametype, ast_frame_subclass::integer, LOG_WARNING, NULL, ast_rtp::rtcp, rtcp_recvfrom(), RTP_DTLS_ESTABLISHED, ast_rtcp::s, ast_frame::subclass, and ast_rtcp::them.

Referenced by ast_rtp_read().

◆ ast_rtcp_write()

static int ast_rtcp_write ( const void *  data)
static

Write a RTCP packet to the far end.

Note
Decide if we are going to send an SR (with Reception Block) or RR RR is sent if we have not sent any rtp packets in the previous interval

Scheduler callback

Definition at line 4921 of file res_rtp_asterisk.c.

4922{
4923 struct ast_rtp_instance *instance = (struct ast_rtp_instance *) data;
4924 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4925 int res;
4926 int sr = 0;
4927 int packet_len = 0;
4928 int ice;
4929 struct ast_sockaddr remote_address = { { 0, } };
4930 unsigned char *rtcpheader;
4931 unsigned char bdata[AST_UUID_STR_LEN + 128] = ""; /* More than enough */
4932 RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report, NULL, ao2_cleanup);
4933
4934 if (!rtp || !rtp->rtcp || rtp->rtcp->schedid == -1) {
4935 ao2_ref(instance, -1);
4936 return 0;
4937 }
4938
4939 ao2_lock(instance);
4940 rtcpheader = bdata;
4941 rtcp_report = ast_rtp_rtcp_report_alloc(rtp->themssrc_valid ? 1 : 0);
4942 res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
4943
4944 if (res == 0 || res == 1) {
4945 goto cleanup;
4946 }
4947
4948 packet_len += res;
4949
4950 if (rtp->bundled) {
4951 ast_rtp_instance_get_remote_address(instance, &remote_address);
4952 } else {
4953 ast_sockaddr_copy(&remote_address, &rtp->rtcp->them);
4954 }
4955
4956 res = rtcp_sendto(instance, (unsigned int *)rtcpheader, packet_len, 0, &remote_address, &ice);
4957 if (res < 0) {
4958 ast_log(LOG_ERROR, "RTCP %s transmission error to %s, rtcp halted %s\n",
4959 sr ? "SR" : "RR",
4961 strerror(errno));
4962 res = 0;
4963 } else {
4964 ast_rtcp_calculate_sr_rr_statistics(instance, rtcp_report, remote_address, ice, sr);
4965 }
4966
4967cleanup:
4968 ao2_unlock(instance);
4969
4970 if (!res) {
4971 /*
4972 * Not being rescheduled.
4973 */
4974 rtp->rtcp->schedid = -1;
4975 ao2_ref(instance, -1);
4976 }
4977
4978 return res;
4979}
static void * cleanup(void *unused)
Definition: pbx_realtime.c:124
static int ast_rtcp_generate_compound_prefix(struct ast_rtp_instance *instance, unsigned char *rtcpheader, struct ast_rtp_rtcp_report *report, int *sr)
static int rtcp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
static int ast_rtcp_calculate_sr_rr_statistics(struct ast_rtp_instance *instance, struct ast_rtp_rtcp_report *rtcp_report, struct ast_sockaddr remote_address, int ice, int sr)

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_log, ast_rtcp_calculate_sr_rr_statistics(), ast_rtcp_generate_compound_prefix(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_rtp_rtcp_report_alloc(), ast_sockaddr_copy(), ast_sockaddr_stringify(), AST_UUID_STR_LEN, ast_rtp::bundled, cleanup(), ast_rtp_instance::data, errno, LOG_ERROR, NULL, RAII_VAR, ast_rtp::rtcp, rtcp_sendto(), ast_rtcp::schedid, ast_rtcp::them, and ast_rtp::themssrc_valid.

Referenced by ast_rtp_interpret(), and rtp_raw_write().

◆ ast_rtp_bundle()

static int ast_rtp_bundle ( struct ast_rtp_instance child,
struct ast_rtp_instance parent 
)
static
Precondition
child is locked

Definition at line 9379 of file res_rtp_asterisk.c.

9380{
9381 struct ast_rtp *child_rtp = ast_rtp_instance_get_data(child);
9382 struct ast_rtp *parent_rtp;
9383 struct rtp_ssrc_mapping mapping;
9384 struct ast_sockaddr them = { { 0, } };
9385
9386 if (child_rtp->bundled == parent) {
9387 return 0;
9388 }
9389
9390 /* If this instance was already bundled then remove the SSRC mapping */
9391 if (child_rtp->bundled) {
9392 struct ast_rtp *bundled_rtp;
9393
9394 ao2_unlock(child);
9395
9396 /* The child lock can't be held while accessing the parent */
9397 ao2_lock(child_rtp->bundled);
9398 bundled_rtp = ast_rtp_instance_get_data(child_rtp->bundled);
9400 ao2_unlock(child_rtp->bundled);
9401
9402 ao2_lock(child);
9403 ao2_ref(child_rtp->bundled, -1);
9404 child_rtp->bundled = NULL;
9405 }
9406
9407 if (!parent) {
9408 /* We transitioned away from bundle so we need our own transport resources once again */
9409 rtp_allocate_transport(child, child_rtp);
9410 return 0;
9411 }
9412
9413 parent_rtp = ast_rtp_instance_get_data(parent);
9414
9415 /* We no longer need any transport related resources as we will use our parent RTP instance instead */
9416 rtp_deallocate_transport(child, child_rtp);
9417
9418 /* Children maintain a reference to the parent to guarantee that the transport doesn't go away on them */
9419 child_rtp->bundled = ao2_bump(parent);
9420
9421 mapping.ssrc = child_rtp->themssrc;
9422 mapping.ssrc_valid = child_rtp->themssrc_valid;
9423 mapping.instance = child;
9424
9425 ao2_unlock(child);
9426
9427 ao2_lock(parent);
9428
9429 AST_VECTOR_APPEND(&parent_rtp->ssrc_mapping, mapping);
9430
9431#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
9432 /* If DTLS-SRTP is already in use then add the local SSRC to it, otherwise it will get added once DTLS
9433 * negotiation has been completed.
9434 */
9435 if (parent_rtp->dtls.connection == AST_RTP_DTLS_CONNECTION_EXISTING) {
9436 dtls_srtp_add_local_ssrc(parent_rtp, parent, 0, child_rtp->ssrc, 0);
9437 }
9438#endif
9439
9440 /* Bundle requires that RTCP-MUX be in use so only the main remote address needs to match */
9442
9443 ao2_unlock(parent);
9444
9445 ao2_lock(child);
9446
9448
9449 return 0;
9450}
#define ao2_bump(obj)
Bump refcount on an AO2 object by one, returning the object.
Definition: astobj2.h:480
static void rtp_deallocate_transport(struct ast_rtp_instance *instance, struct ast_rtp *rtp)
static int rtp_allocate_transport(struct ast_rtp_instance *instance, struct ast_rtp *rtp)
#define SSRC_MAPPING_ELEM_CMP(elem, value)
SSRC mapping comparator for AST_VECTOR_REMOVE_CMP_UNORDERED()
#define AST_VECTOR_ELEM_CLEANUP_NOOP(elem)
Vector element cleanup that does nothing.
Definition: vector.h:571
#define AST_VECTOR_REMOVE_CMP_UNORDERED(vec, value, cmp, cleanup)
Remove an element from a vector that matches the given comparison.
Definition: vector.h:488
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Definition: vector.h:256

References ao2_bump, ao2_lock, ao2_ref, ao2_unlock, AST_RTP_DTLS_CONNECTION_EXISTING, ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_rtp_instance_set_remote_address, AST_VECTOR_APPEND, AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_REMOVE_CMP_UNORDERED, ast_rtp::bundled, rtp_ssrc_mapping::instance, NULL, rtp_allocate_transport(), rtp_deallocate_transport(), rtp_ssrc_mapping::ssrc, ast_rtp::ssrc, ast_rtp::ssrc_mapping, SSRC_MAPPING_ELEM_CMP, rtp_ssrc_mapping::ssrc_valid, ast_rtp::themssrc, and ast_rtp::themssrc_valid.

◆ ast_rtp_change_source()

static void ast_rtp_change_source ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4458 of file res_rtp_asterisk.c.

4459{
4460 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4461 struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance, 0);
4462 struct ast_srtp *rtcp_srtp = ast_rtp_instance_get_srtp(instance, 1);
4463 unsigned int ssrc = ast_random();
4464
4465 if (rtp->lastts) {
4466 /* We simply set this bit so that the next packet sent will have the marker bit turned on */
4468 }
4469
4470 ast_debug_rtp(3, "(%p) RTP changing ssrc from %u to %u due to a source change\n",
4471 instance, rtp->ssrc, ssrc);
4472
4473 if (srtp) {
4474 ast_debug_rtp(3, "(%p) RTP changing ssrc for SRTP from %u to %u\n",
4475 instance, rtp->ssrc, ssrc);
4476 res_srtp->change_source(srtp, rtp->ssrc, ssrc);
4477 if (rtcp_srtp != srtp) {
4478 res_srtp->change_source(rtcp_srtp, rtp->ssrc, ssrc);
4479 }
4480 }
4481
4482 rtp->ssrc = ssrc;
4483
4484 /* Since the source is changing, we don't know what sequence number to expect next */
4485 rtp->expectedrxseqno = -1;
4486
4487 return;
4488}
#define FLAG_NEED_MARKER_BIT
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:2906
int(* change_source)(struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc)
Definition: res_srtp.h:44
struct ast_rtp_instance * rtp
Definition: res_srtp.c:67
long int ast_random(void)
Definition: utils.c:2310
#define ast_set_flag(p, flag)
Definition: utils.h:70

References ast_debug_rtp, ast_random(), ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_set_flag, ast_srtp_res::change_source, FLAG_NEED_MARKER_BIT, res_srtp, and ast_srtp::rtp.

◆ ast_rtp_destroy()

static int ast_rtp_destroy ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4142 of file res_rtp_asterisk.c.

4143{
4144 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4145
4146 if (rtp->bundled) {
4147 struct ast_rtp *bundled_rtp;
4148
4149 /* We can't hold our instance lock while removing ourselves from the parent */
4150 ao2_unlock(instance);
4151
4152 ao2_lock(rtp->bundled);
4153 bundled_rtp = ast_rtp_instance_get_data(rtp->bundled);
4155 ao2_unlock(rtp->bundled);
4156
4157 ao2_lock(instance);
4158 ao2_ref(rtp->bundled, -1);
4159 }
4160
4161 rtp_deallocate_transport(instance, rtp);
4162
4163 /* Destroy the smoother that was smoothing out audio if present */
4164 if (rtp->smoother) {
4166 }
4167
4168 /* Destroy RTCP if it was being used */
4169 if (rtp->rtcp) {
4170 /*
4171 * It is not possible for there to be an active RTCP scheduler
4172 * entry at this point since it holds a reference to the
4173 * RTP instance while it's active.
4174 */
4176 ast_free(rtp->rtcp);
4177 }
4178
4179 /* Destroy RED if it was being used */
4180 if (rtp->red) {
4181 ao2_unlock(instance);
4182 AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
4183 ao2_lock(instance);
4184 ast_free(rtp->red);
4185 rtp->red = NULL;
4186 }
4187
4188 /* Destroy the send buffer if it was being used */
4189 if (rtp->send_buffer) {
4191 }
4192
4193 /* Destroy the recv buffer if it was being used */
4194 if (rtp->recv_buffer) {
4196 }
4197
4199
4205
4206 /* Finally destroy ourselves */
4207 rtp->owner = NULL;
4208 ast_free(rtp);
4209
4210 return 0;
4211}
#define ast_free(a)
Definition: astmm.h:180
void ast_data_buffer_free(struct ast_data_buffer *buffer)
Free a data buffer (and all held data payloads)
Definition: data_buffer.c:338
#define AST_SCHED_DEL(sched, id)
Remove a scheduler entry.
Definition: sched.h:46
void ast_smoother_free(struct ast_smoother *s)
Definition: smoother.c:220
struct ast_format * lasttxformat
struct rtp_transport_wide_cc_statistics transport_wide_cc
struct ast_smoother * smoother
struct ast_sched_context * sched
struct ast_data_buffer * recv_buffer
struct ast_rtp_instance * owner
The RTP instance owning us (used for debugging purposes) We don't hold a reference to the instance be...
struct rtp_red * red
struct ast_format * lastrxformat
struct rtp_transport_wide_cc_statistics::@470 packet_statistics
#define AST_VECTOR_FREE(vec)
Deallocates this vector.
Definition: vector.h:174

References ao2_cleanup, ao2_lock, ao2_ref, ao2_unlock, ast_data_buffer_free(), ast_free, ast_rtp_instance_get_data(), AST_SCHED_DEL, ast_smoother_free(), AST_VECTOR_ELEM_CLEANUP_NOOP, AST_VECTOR_FREE, AST_VECTOR_REMOVE_CMP_UNORDERED, ast_rtp::bundled, ast_rtp::f, ast_frame_subclass::format, ast_rtp::lastrxformat, ast_rtp::lasttxformat, ast_rtcp::local_addr_str, ast_rtp::missing_seqno, NULL, ast_rtp::owner, rtp_transport_wide_cc_statistics::packet_statistics, ast_rtp::recv_buffer, ast_rtp::red, ast_rtp::rtcp, rtp_deallocate_transport(), ast_rtp::sched, rtp_red::schedid, ast_rtp::send_buffer, ast_rtp::smoother, ast_rtp::ssrc_mapping, SSRC_MAPPING_ELEM_CMP, ast_frame::subclass, and ast_rtp::transport_wide_cc.

◆ ast_rtp_dtmf_begin()

static int ast_rtp_dtmf_begin ( struct ast_rtp_instance instance,
char  digit 
)
static
Precondition
instance is locked

Definition at line 4229 of file res_rtp_asterisk.c.

4230{
4231 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4232 struct ast_sockaddr remote_address = { {0,} };
4233 int hdrlen = 12, res = 0, i = 0, payload = 101;
4234 char data[256];
4235 unsigned int *rtpheader = (unsigned int*)data;
4236
4237 ast_rtp_instance_get_remote_address(instance, &remote_address);
4238
4239 /* If we have no remote address information bail out now */
4240 if (ast_sockaddr_isnull(&remote_address)) {
4241 return -1;
4242 }
4243
4244 /* Convert given digit into what we want to transmit */
4245 if ((digit <= '9') && (digit >= '0')) {
4246 digit -= '0';
4247 } else if (digit == '*') {
4248 digit = 10;
4249 } else if (digit == '#') {
4250 digit = 11;
4251 } else if ((digit >= 'A') && (digit <= 'D')) {
4252 digit = digit - 'A' + 12;
4253 } else if ((digit >= 'a') && (digit <= 'd')) {
4254 digit = digit - 'a' + 12;
4255 } else {
4256 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
4257 return -1;
4258 }
4259
4260 /* Grab the payload that they expect the RFC2833 packet to be received in */
4262
4263 rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
4264 rtp->send_duration = 160;
4266 rtp->lastdigitts = rtp->lastts + rtp->send_duration;
4267
4268 /* Create the actual packet that we will be sending */
4269 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
4270 rtpheader[1] = htonl(rtp->lastdigitts);
4271 rtpheader[2] = htonl(rtp->ssrc);
4272
4273 /* Actually send the packet */
4274 for (i = 0; i < 2; i++) {
4275 int ice;
4276
4277 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
4278 res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4279 if (res < 0) {
4280 ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4281 ast_sockaddr_stringify(&remote_address),
4282 strerror(errno));
4283 }
4284 if (rtp_debug_test_addr(&remote_address)) {
4285 ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4286 ast_sockaddr_stringify(&remote_address),
4287 ice ? " (via ICE)" : "",
4288 payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4289 }
4290 rtp->seqno++;
4291 rtp->send_duration += 160;
4292 rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
4293 }
4294
4295 /* Record that we are in the process of sending a digit and information needed to continue doing so */
4296 rtp->sending_digit = 1;
4297 rtp->send_digit = digit;
4298 rtp->send_payload = payload;
4299
4300 return 0;
4301}
char digit
#define DTMF_SAMPLE_RATE_MS
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int *ice)
#define AST_RTP_DTMF
Definition: rtp_engine.h:291
int ast_rtp_codecs_payload_code_tx(struct ast_rtp_codecs *codecs, int asterisk_format, const struct ast_format *format, int code)
Retrieve a tx mapped payload type based on whether it is an Asterisk format and the code.
Definition: rtp_engine.c:1941
struct ast_rtp_codecs * ast_rtp_instance_get_codecs(struct ast_rtp_instance *instance)
Get the codecs structure of an RTP instance.
Definition: rtp_engine.c:748
unsigned short seqno
struct timeval dtmfmute
unsigned int lastdigitts
char sending_digit
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: extconf.c:2282
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:159
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:235

References ast_log, ast_rtp_codecs_payload_code_tx(), AST_RTP_DTMF, ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_tv(), ast_tvadd(), ast_tvnow(), ast_verbose(), calc_txstamp(), digit, DTMF_SAMPLE_RATE_MS, ast_rtp::dtmfmute, errno, ast_rtp::lastdigitts, ast_rtp::lastts, LOG_ERROR, LOG_WARNING, NULL, rtp_debug_test_addr(), rtp_sendto(), ast_rtp::send_digit, ast_rtp::send_duration, ast_rtp::send_payload, ast_rtp::sending_digit, ast_rtp::seqno, and ast_rtp::ssrc.

◆ ast_rtp_dtmf_compatible()

static int ast_rtp_dtmf_compatible ( struct ast_channel chan0,
struct ast_rtp_instance instance0,
struct ast_channel chan1,
struct ast_rtp_instance instance1 
)
static
Precondition
Neither instance0 nor instance1 are locked

Definition at line 9162 of file res_rtp_asterisk.c.

9163{
9164 /* If both sides are not using the same method of DTMF transmission
9165 * (ie: one is RFC2833, other is INFO... then we can not do direct media.
9166 * --------------------------------------------------
9167 * | DTMF Mode | HAS_DTMF | Accepts Begin Frames |
9168 * |-----------|------------|-----------------------|
9169 * | Inband | False | True |
9170 * | RFC2833 | True | True |
9171 * | SIP INFO | False | False |
9172 * --------------------------------------------------
9173 */
9175 (!ast_channel_tech(chan0)->send_digit_begin != !ast_channel_tech(chan1)->send_digit_begin)) ? 0 : 1);
9176}
const struct ast_channel_tech * ast_channel_tech(const struct ast_channel *chan)
@ AST_RTP_PROPERTY_DTMF
Definition: rtp_engine.h:117

References ast_channel_tech(), ast_rtp_instance_get_prop(), and AST_RTP_PROPERTY_DTMF.

◆ ast_rtp_dtmf_continuation()

static int ast_rtp_dtmf_continuation ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4304 of file res_rtp_asterisk.c.

4305{
4306 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4307 struct ast_sockaddr remote_address = { {0,} };
4308 int hdrlen = 12, res = 0;
4309 char data[256];
4310 unsigned int *rtpheader = (unsigned int*)data;
4311 int ice;
4312
4313 ast_rtp_instance_get_remote_address(instance, &remote_address);
4314
4315 /* Make sure we know where the other side is so we can send them the packet */
4316 if (ast_sockaddr_isnull(&remote_address)) {
4317 return -1;
4318 }
4319
4320 /* Actually create the packet we will be sending */
4321 rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
4322 rtpheader[1] = htonl(rtp->lastdigitts);
4323 rtpheader[2] = htonl(rtp->ssrc);
4324 rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration));
4325
4326 /* Boom, send it on out */
4327 res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4328 if (res < 0) {
4329 ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4330 ast_sockaddr_stringify(&remote_address),
4331 strerror(errno));
4332 }
4333
4334 if (rtp_debug_test_addr(&remote_address)) {
4335 ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4336 ast_sockaddr_stringify(&remote_address),
4337 ice ? " (via ICE)" : "",
4338 rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4339 }
4340
4341 /* And now we increment some values for the next time we swing by */
4342 rtp->seqno++;
4343 rtp->send_duration += 160;
4345
4346 return 0;
4347}

References ast_log, ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verbose(), calc_txstamp(), DTMF_SAMPLE_RATE_MS, errno, ast_rtp::lastdigitts, ast_rtp::lastts, LOG_ERROR, NULL, rtp_debug_test_addr(), rtp_sendto(), ast_rtp::send_digit, ast_rtp::send_duration, ast_rtp::send_payload, ast_rtp::seqno, and ast_rtp::ssrc.

Referenced by ast_rtp_interpret().

◆ ast_rtp_dtmf_end()

static int ast_rtp_dtmf_end ( struct ast_rtp_instance instance,
char  digit 
)
static
Precondition
instance is locked

Definition at line 4440 of file res_rtp_asterisk.c.

4441{
4442 return ast_rtp_dtmf_end_with_duration(instance, digit, 0);
4443}
static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)

References ast_rtp_dtmf_end_with_duration(), and digit.

◆ ast_rtp_dtmf_end_with_duration()

static int ast_rtp_dtmf_end_with_duration ( struct ast_rtp_instance instance,
char  digit,
unsigned int  duration 
)
static
Precondition
instance is locked

Definition at line 4350 of file res_rtp_asterisk.c.

4351{
4352 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4353 struct ast_sockaddr remote_address = { {0,} };
4354 int hdrlen = 12, res = -1, i = 0;
4355 char data[256];
4356 unsigned int *rtpheader = (unsigned int*)data;
4357 unsigned int measured_samples;
4358
4359 ast_rtp_instance_get_remote_address(instance, &remote_address);
4360
4361 /* Make sure we know where the remote side is so we can send them the packet we construct */
4362 if (ast_sockaddr_isnull(&remote_address)) {
4363 goto cleanup;
4364 }
4365
4366 /* Convert the given digit to the one we are going to send */
4367 if ((digit <= '9') && (digit >= '0')) {
4368 digit -= '0';
4369 } else if (digit == '*') {
4370 digit = 10;
4371 } else if (digit == '#') {
4372 digit = 11;
4373 } else if ((digit >= 'A') && (digit <= 'D')) {
4374 digit = digit - 'A' + 12;
4375 } else if ((digit >= 'a') && (digit <= 'd')) {
4376 digit = digit - 'a' + 12;
4377 } else {
4378 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
4379 goto cleanup;
4380 }
4381
4382 rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
4383
4384 if (duration > 0 && (measured_samples = duration * ast_rtp_get_rate(rtp->f.subclass.format) / 1000) > rtp->send_duration) {
4385 ast_debug_rtp(2, "(%p) RTP adjusting final end duration from %d to %u\n",
4386 instance, rtp->send_duration, measured_samples);
4387 rtp->send_duration = measured_samples;
4388 }
4389
4390 /* Construct the packet we are going to send */
4391 rtpheader[1] = htonl(rtp->lastdigitts);
4392 rtpheader[2] = htonl(rtp->ssrc);
4393 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
4394 rtpheader[3] |= htonl((1 << 23));
4395
4396 /* Send it 3 times, that's the magical number */
4397 for (i = 0; i < 3; i++) {
4398 int ice;
4399
4400 rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
4401
4402 res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4403
4404 if (res < 0) {
4405 ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4406 ast_sockaddr_stringify(&remote_address),
4407 strerror(errno));
4408 }
4409
4410 if (rtp_debug_test_addr(&remote_address)) {
4411 ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4412 ast_sockaddr_stringify(&remote_address),
4413 ice ? " (via ICE)" : "",
4414 rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4415 }
4416
4417 rtp->seqno++;
4418 }
4419 res = 0;
4420
4421 /* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
4423
4424 /* Reset the smoother as the delivery time stored in it is now out of date */
4425 if (rtp->smoother) {
4427 rtp->smoother = NULL;
4428 }
4429cleanup:
4430 rtp->sending_digit = 0;
4431 rtp->send_digit = 0;
4432
4433 /* Re-Learn expected seqno */
4434 rtp->expectedseqno = -1;
4435
4436 return res;
4437}

References ast_debug_rtp, ast_log, ast_rtp_get_rate(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address, ast_smoother_free(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_tv(), ast_tvadd(), ast_tvnow(), ast_verbose(), calc_txstamp(), cleanup(), digit, DTMF_SAMPLE_RATE_MS, ast_rtp::dtmfmute, errno, ast_rtp::expectedseqno, ast_rtp::f, ast_frame_subclass::format, ast_rtp::lastdigitts, ast_rtp::lastts, LOG_ERROR, LOG_WARNING, NULL, rtp_debug_test_addr(), rtp_sendto(), ast_rtp::send_digit, ast_rtp::send_duration, ast_rtp::send_payload, ast_rtp::sending_digit, ast_rtp::seqno, ast_rtp::smoother, ast_rtp::ssrc, and ast_frame::subclass.

Referenced by ast_rtp_dtmf_end().

◆ ast_rtp_dtmf_mode_get()

static enum ast_rtp_dtmf_mode ast_rtp_dtmf_mode_get ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 4222 of file res_rtp_asterisk.c.

4223{
4224 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4225 return rtp->dtmfmode;
4226}
enum ast_rtp_dtmf_mode dtmfmode

References ast_rtp_instance_get_data(), and ast_rtp::dtmfmode.

◆ ast_rtp_dtmf_mode_set()

static int ast_rtp_dtmf_mode_set ( struct ast_rtp_instance instance,
enum ast_rtp_dtmf_mode  dtmf_mode 
)
static
Precondition
instance is locked

Definition at line 4214 of file res_rtp_asterisk.c.

4215{
4216 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4217 rtp->dtmfmode = dtmf_mode;
4218 return 0;
4219}

References ast_rtp_instance_get_data(), and ast_rtp::dtmfmode.

◆ ast_rtp_extension_enable()

static int ast_rtp_extension_enable ( struct ast_rtp_instance instance,
enum ast_rtp_extension  extension 
)
static

Definition at line 9367 of file res_rtp_asterisk.c.

9368{
9369 switch (extension) {
9372 return 1;
9373 default:
9374 return 0;
9375 }
9376}
@ AST_RTP_EXTENSION_TRANSPORT_WIDE_CC
Definition: rtp_engine.h:594
@ AST_RTP_EXTENSION_ABS_SEND_TIME
Definition: rtp_engine.h:592
structure to hold extensions

References AST_RTP_EXTENSION_ABS_SEND_TIME, and AST_RTP_EXTENSION_TRANSPORT_WIDE_CC.

◆ ast_rtp_fd()

static int ast_rtp_fd ( struct ast_rtp_instance instance,
int  rtcp 
)
static
Precondition
instance is locked

Definition at line 8915 of file res_rtp_asterisk.c.

8916{
8917 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8918
8919 return rtcp ? (rtp->rtcp ? rtp->rtcp->s : -1) : rtp->s;
8920}

References ast_rtp_instance_get_data(), ast_rtp::rtcp, ast_rtp::s, and ast_rtcp::s.

◆ ast_rtp_get_cname()

static const char * ast_rtp_get_cname ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 9314 of file res_rtp_asterisk.c.

9315{
9316 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9317
9318 return rtp->cname;
9319}

References ast_rtp_instance_get_data(), and ast_rtp::cname.

◆ ast_rtp_get_ssrc()

static unsigned int ast_rtp_get_ssrc ( struct ast_rtp_instance instance)
static
Precondition
instance is locked

Definition at line 9306 of file res_rtp_asterisk.c.

9307{
9308 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9309
9310 return rtp->ssrc;
9311}

References ast_rtp_instance_get_data(), and ast_rtp::ssrc.

Referenced by __rtp_find_instance_by_ssrc().

◆ ast_rtp_get_stat()

static int ast_rtp_get_stat ( struct ast_rtp_instance instance,
struct ast_rtp_instance_stats stats,
enum ast_rtp_instance_stat  stat 
)
static
Precondition
instance is locked

Definition at line 9097 of file res_rtp_asterisk.c.

9098{
9099 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9100
9101 if (!rtp->rtcp) {
9102 return -1;
9103 }
9104
9109
9121
9133
9140
9152
9153
9157
9158 return 0;
9159}
#define AST_RTP_STAT_TERMINATOR(combined)
Definition: rtp_engine.h:495
@ AST_RTP_INSTANCE_STAT_LOCAL_MAXRXPLOSS
Definition: rtp_engine.h:204
@ AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVRXPLOSS
Definition: rtp_engine.h:200
@ AST_RTP_INSTANCE_STAT_REMOTE_MAXRXPLOSS
Definition: rtp_engine.h:196
@ AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVMES
Definition: rtp_engine.h:267
@ AST_RTP_INSTANCE_STAT_REMOTE_MINJITTER
Definition: rtp_engine.h:220
@ AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVMES
Definition: rtp_engine.h:275
@ AST_RTP_INSTANCE_STAT_MIN_RTT
Definition: rtp_engine.h:240
@ AST_RTP_INSTANCE_STAT_TXMES
Definition: rtp_engine.h:259
@ AST_RTP_INSTANCE_STAT_CHANNEL_UNIQUEID
Definition: rtp_engine.h:250
@ AST_RTP_INSTANCE_STAT_TXPLOSS
Definition: rtp_engine.h:192
@ AST_RTP_INSTANCE_STAT_MAX_RTT
Definition: rtp_engine.h:238
@ AST_RTP_INSTANCE_STAT_RXPLOSS
Definition: rtp_engine.h:194
@ AST_RTP_INSTANCE_STAT_REMOTE_MAXJITTER
Definition: rtp_engine.h:218
@ AST_RTP_INSTANCE_STAT_LOCAL_MAXJITTER
Definition: rtp_engine.h:226
@ AST_RTP_INSTANCE_STAT_REMOTE_MINMES
Definition: rtp_engine.h:265
@ AST_RTP_INSTANCE_STAT_REMOTE_STDEVJITTER
Definition: rtp_engine.h:224
@ AST_RTP_INSTANCE_STAT_REMOTE_MINRXPLOSS
Definition: rtp_engine.h:198
@ AST_RTP_INSTANCE_STAT_LOCAL_MINMES
Definition: rtp_engine.h:273
@ AST_RTP_INSTANCE_STAT_TXOCTETCOUNT
Definition: rtp_engine.h:252
@ AST_RTP_INSTANCE_STAT_RXMES
Definition: rtp_engine.h:261
@ AST_RTP_INSTANCE_STAT_REMOTE_STDEVMES
Definition: rtp_engine.h:269
@ AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVRXPLOSS
Definition: rtp_engine.h:208
@ AST_RTP_INSTANCE_STAT_REMOTE_STDEVRXPLOSS
Definition: rtp_engine.h:202
@ AST_RTP_INSTANCE_STAT_LOCAL_STDEVRXPLOSS
Definition: rtp_engine.h:210
@ AST_RTP_INSTANCE_STAT_REMOTE_MAXMES
Definition: rtp_engine.h:263
@ AST_RTP_INSTANCE_STAT_TXCOUNT
Definition: rtp_engine.h:186
@ AST_RTP_INSTANCE_STAT_STDEVRTT
Definition: rtp_engine.h:244
@ AST_RTP_INSTANCE_STAT_COMBINED_MES
Definition: rtp_engine.h:257
@ AST_RTP_INSTANCE_STAT_LOCAL_MAXMES
Definition: rtp_engine.h:271
@ AST_RTP_INSTANCE_STAT_RXJITTER
Definition: rtp_engine.h:216
@ AST_RTP_INSTANCE_STAT_LOCAL_MINRXPLOSS
Definition: rtp_engine.h:206
@ AST_RTP_INSTANCE_STAT_LOCAL_SSRC
Definition: rtp_engine.h:246
@ AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVJITTER
Definition: rtp_engine.h:222
@ AST_RTP_INSTANCE_STAT_COMBINED_JITTER
Definition: rtp_engine.h:212
@ AST_RTP_INSTANCE_STAT_TXJITTER
Definition: rtp_engine.h:214
@ AST_RTP_INSTANCE_STAT_LOCAL_MINJITTER
Definition: rtp_engine.h:228
@ AST_RTP_INSTANCE_STAT_COMBINED_LOSS
Definition: rtp_engine.h:190
@ AST_RTP_INSTANCE_STAT_LOCAL_STDEVJITTER
Definition: rtp_engine.h:232
@ AST_RTP_INSTANCE_STAT_COMBINED_RTT
Definition: rtp_engine.h:234
@ AST_RTP_INSTANCE_STAT_NORMDEVRTT
Definition: rtp_engine.h:242
@ AST_RTP_INSTANCE_STAT_RTT
Definition: rtp_engine.h:236
@ AST_RTP_INSTANCE_STAT_RXOCTETCOUNT
Definition: rtp_engine.h:254
@ AST_RTP_INSTANCE_STAT_LOCAL_STDEVMES
Definition: rtp_engine.h:277
@ AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVJITTER
Definition: rtp_engine.h:230
@ AST_RTP_INSTANCE_STAT_RXCOUNT
Definition: rtp_engine.h:188
@ AST_RTP_INSTANCE_STAT_REMOTE_SSRC
Definition: rtp_engine.h:248
#define AST_RTP_STAT_STRCPY(current_stat, combined, placement, value)
Definition: rtp_engine.h:487
#define AST_RTP_STAT_SET(current_stat, combined, placement, value)
Definition: rtp_engine.h:479
double maxrxmes
double maxrxlost
unsigned int received_prior
double reported_maxjitter
double reported_normdev_lost
double reported_minlost
double normdevrtt
double reported_normdev_mes
double stdevrtt
double minrxjitter
double reported_maxmes
unsigned int reported_lost
double reported_stdev_jitter
double normdev_rxjitter
double reported_stdev_lost
double normdev_rxlost
double reported_stdev_mes
double normdev_rxmes
double maxrxjitter
double reported_normdev_jitter
double reported_maxlost
double stdev_rxjitter
double reported_jitter
double reported_minjitter
double minrxlost
double minrxmes
unsigned int expected_prior
double reported_minmes
double stdev_rxlost
unsigned int remote_ssrc
Definition: rtp_engine.h:449
unsigned int rxcount
Definition: rtp_engine.h:395
unsigned int local_ssrc
Definition: rtp_engine.h:447
unsigned int rxoctetcount
Definition: rtp_engine.h:455
unsigned int rxploss
Definition: rtp_engine.h:419
unsigned int txcount
Definition: rtp_engine.h:393
unsigned int txploss
Definition: rtp_engine.h:417
unsigned int txoctetcount
Definition: rtp_engine.h:453
char channel_uniqueid[MAX_CHANNEL_ID]
Definition: rtp_engine.h:451
unsigned int rxcount
unsigned int rxoctetcount
double rxjitter

References ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), AST_RTP_INSTANCE_STAT_CHANNEL_UNIQUEID, AST_RTP_INSTANCE_STAT_COMBINED_JITTER, AST_RTP_INSTANCE_STAT_COMBINED_LOSS, AST_RTP_INSTANCE_STAT_COMBINED_MES, AST_RTP_INSTANCE_STAT_COMBINED_RTT, AST_RTP_INSTANCE_STAT_LOCAL_MAXJITTER, AST_RTP_INSTANCE_STAT_LOCAL_MAXMES, AST_RTP_INSTANCE_STAT_LOCAL_MAXRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_MINJITTER, AST_RTP_INSTANCE_STAT_LOCAL_MINMES, AST_RTP_INSTANCE_STAT_LOCAL_MINRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVJITTER, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVMES, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_SSRC, AST_RTP_INSTANCE_STAT_LOCAL_STDEVJITTER, AST_RTP_INSTANCE_STAT_LOCAL_STDEVMES, AST_RTP_INSTANCE_STAT_LOCAL_STDEVRXPLOSS, AST_RTP_INSTANCE_STAT_MAX_RTT, AST_RTP_INSTANCE_STAT_MIN_RTT, AST_RTP_INSTANCE_STAT_NORMDEVRTT, AST_RTP_INSTANCE_STAT_REMOTE_MAXJITTER, AST_RTP_INSTANCE_STAT_REMOTE_MAXMES, AST_RTP_INSTANCE_STAT_REMOTE_MAXRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_MINJITTER, AST_RTP_INSTANCE_STAT_REMOTE_MINMES, AST_RTP_INSTANCE_STAT_REMOTE_MINRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVJITTER, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVMES, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_SSRC, AST_RTP_INSTANCE_STAT_REMOTE_STDEVJITTER, AST_RTP_INSTANCE_STAT_REMOTE_STDEVMES, AST_RTP_INSTANCE_STAT_REMOTE_STDEVRXPLOSS, AST_RTP_INSTANCE_STAT_RTT, AST_RTP_INSTANCE_STAT_RXCOUNT, AST_RTP_INSTANCE_STAT_RXJITTER, AST_RTP_INSTANCE_STAT_RXMES, AST_RTP_INSTANCE_STAT_RXOCTETCOUNT, AST_RTP_INSTANCE_STAT_RXPLOSS, AST_RTP_INSTANCE_STAT_STDEVRTT, AST_RTP_INSTANCE_STAT_TXCOUNT, AST_RTP_INSTANCE_STAT_TXJITTER, AST_RTP_INSTANCE_STAT_TXMES, AST_RTP_INSTANCE_STAT_TXOCTETCOUNT, AST_RTP_INSTANCE_STAT_TXPLOSS, AST_RTP_STAT_SET, AST_RTP_STAT_STRCPY, AST_RTP_STAT_TERMINATOR, ast_rtp_instance_stats::channel_uniqueid, ast_rtcp::expected_prior, ast_rtp_instance_stats::local_maxjitter, ast_rtp_instance_stats::local_maxmes, ast_rtp_instance_stats::local_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minmes, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevmes, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevmes, ast_rtp_instance_stats::local_stdevrxploss, ast_rtp_instance_stats::maxrtt, ast_rtcp::maxrtt, ast_rtcp::maxrxjitter, ast_rtcp::maxrxlost, ast_rtcp::maxrxmes, ast_rtp_instance_stats::minrtt, ast_rtcp::minrtt, ast_rtcp::minrxjitter, ast_rtcp::minrxlost, ast_rtcp::minrxmes, ast_rtcp::normdev_rxjitter, ast_rtcp::normdev_rxlost, ast_rtcp::normdev_rxmes, ast_rtp_instance_stats::normdevrtt, ast_rtcp::normdevrtt, ast_rtcp::received_prior, ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxmes, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minmes, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevmes, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, ast_rtp_instance_stats::remote_stdevmes, ast_rtp_instance_stats::remote_stdevrxploss, ast_rtcp::reported_jitter, ast_rtcp::reported_lost, ast_rtcp::reported_maxjitter, ast_rtcp::reported_maxlost, ast_rtcp::reported_maxmes, ast_rtcp::reported_mes, ast_rtcp::reported_minjitter, ast_rtcp::reported_minlost, ast_rtcp::reported_minmes, ast_rtcp::reported_normdev_jitter, ast_rtcp::reported_normdev_lost, ast_rtcp::reported_normdev_mes, ast_rtcp::reported_stdev_jitter, ast_rtcp::reported_stdev_lost, ast_rtcp::reported_stdev_mes, ast_rtp::rtcp, ast_rtp_instance_stats::rtt, ast_rtcp::rtt, ast_rtp_instance_stats::rxcount, ast_rtp::rxcount, ast_rtp_instance_stats::rxjitter, ast_rtp::rxjitter, ast_rtp_instance_stats::rxmes, ast_rtp::rxmes, ast_rtp_instance_stats::rxoctetcount, ast_rtp::rxoctetcount, ast_rtp_instance_stats::rxploss, ast_rtp::ssrc, ast_rtcp::stdev_rxjitter, ast_rtcp::stdev_rxlost, ast_rtp_instance_stats::stdevrtt, ast_rtcp::stdevrtt, ast_rtp::themssrc, ast_rtp_instance_stats::txcount, ast_rtp::txcount, ast_rtp_instance_stats::txjitter, ast_rtp_instance_stats::txmes, ast_rtp_instance_stats::txoctetcount, ast_rtp::txoctetcount, and ast_rtp_instance_stats::txploss.

◆ ast_rtp_interpret()

static struct ast_frame * ast_rtp_interpret ( struct ast_rtp_instance instance,
struct ast_srtp srtp,
const struct ast_sockaddr remote_address,
unsigned char *  read_area,
int  length,
int  prev_seqno,
unsigned int  bundled 
)
static

Definition at line 7620 of file res_rtp_asterisk.c.

7623{
7624 unsigned int *rtpheader = (unsigned int*)(read_area);
7625 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
7626 struct ast_rtp_instance *instance1;
7627 int res = length, hdrlen = 12, ssrc, seqno, payloadtype, padding, mark, ext, cc;
7628 unsigned int timestamp;
7629 RAII_VAR(struct ast_rtp_payload_type *, payload, NULL, ao2_cleanup);
7630 struct frame_list frames;
7631
7632 /* If this payload is encrypted then decrypt it using the given SRTP instance */
7633 if ((*read_area & 0xC0) && res_srtp && srtp && res_srtp->unprotect(
7634 srtp, read_area, &res, 0 | (srtp_replay_protection << 1)) < 0) {
7635 return &ast_null_frame;
7636 }
7637
7638 /* If we are currently sending DTMF to the remote party send a continuation packet */
7639 if (rtp->sending_digit) {
7640 ast_rtp_dtmf_continuation(instance);
7641 }
7642
7643 /* Pull out the various other fields we will need */
7644 ssrc = ntohl(rtpheader[2]);
7645 seqno = ntohl(rtpheader[0]);
7646 payloadtype = (seqno & 0x7f0000) >> 16;
7647 padding = seqno & (1 << 29);
7648 mark = seqno & (1 << 23);
7649 ext = seqno & (1 << 28);
7650 cc = (seqno & 0xF000000) >> 24;
7651 seqno &= 0xffff;
7652 timestamp = ntohl(rtpheader[1]);
7653
7655
7656 /* Remove any padding bytes that may be present */
7657 if (padding) {
7658 res -= read_area[res - 1];
7659 }
7660
7661 /* Skip over any CSRC fields */
7662 if (cc) {
7663 hdrlen += cc * 4;
7664 }
7665
7666 /* Look for any RTP extensions, currently we do not support any */
7667 if (ext) {
7668 int extensions_size = (ntohl(rtpheader[hdrlen/4]) & 0xffff) << 2;
7669 unsigned int profile;
7670 profile = (ntohl(rtpheader[3]) & 0xffff0000) >> 16;
7671
7672 if (profile == 0xbede) {
7673 /* We skip over the first 4 bytes as they are just for the one byte extension header */
7674 rtp_instance_parse_extmap_extensions(instance, rtp, read_area + hdrlen + 4, extensions_size);
7675 } else if (DEBUG_ATLEAST(1)) {
7676 if (profile == 0x505a) {
7677 ast_log(LOG_DEBUG, "Found Zfone extension in RTP stream - zrtp - not supported.\n");
7678 } else {
7679 /* SDP negotiated RTP extensions can not currently be output in logging */
7680 ast_log(LOG_DEBUG, "Found unknown RTP Extensions %x\n", profile);
7681 }
7682 }
7683
7684 hdrlen += extensions_size;
7685 hdrlen += 4;
7686 }
7687
7688 /* Make sure after we potentially mucked with the header length that it is once again valid */
7689 if (res < hdrlen) {
7690 ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d\n", res, hdrlen);
7692 }
7693
7694 /* Only non-bundled instances can change/learn the remote's SSRC implicitly. */
7695 if (!bundled) {
7696 /* Force a marker bit and change SSRC if the SSRC changes */
7697 if (rtp->themssrc_valid && rtp->themssrc != ssrc) {
7698 struct ast_frame *f, srcupdate = {
7700 .subclass.integer = AST_CONTROL_SRCCHANGE,
7701 };
7702
7703 if (!mark) {
7705 ast_debug(0, "(%p) RTP forcing Marker bit, because SSRC has changed\n", instance);
7706 }
7707 mark = 1;
7708 }
7709
7710 f = ast_frisolate(&srcupdate);
7712
7713 rtp->seedrxseqno = 0;
7714 rtp->rxcount = 0;
7715 rtp->rxoctetcount = 0;
7716 rtp->cycles = 0;
7717 prev_seqno = 0;
7718 rtp->last_seqno = 0;
7719 rtp->last_end_timestamp.ts = 0;
7720 rtp->last_end_timestamp.is_set = 0;
7721 if (rtp->rtcp) {
7722 rtp->rtcp->expected_prior = 0;
7723 rtp->rtcp->received_prior = 0;
7724 }
7725 }
7726
7727 rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */
7728 rtp->themssrc_valid = 1;
7729 }
7730
7731 rtp->rxcount++;
7732 rtp->rxoctetcount += (res - hdrlen);
7733 if (rtp->rxcount == 1) {
7734 rtp->seedrxseqno = seqno;
7735 }
7736
7737 /* Do not schedule RR if RTCP isn't run */
7738 if (rtp->rtcp && !ast_sockaddr_isnull(&rtp->rtcp->them) && rtp->rtcp->schedid < 0) {
7739 /* Schedule transmission of Receiver Report */
7740 ao2_ref(instance, +1);
7742 if (rtp->rtcp->schedid < 0) {
7743 ao2_ref(instance, -1);
7744 ast_log(LOG_WARNING, "scheduling RTCP transmission failed.\n");
7745 }
7746 }
7747 if ((int)prev_seqno - (int)seqno > 100) /* if so it would indicate that the sender cycled; allow for misordering */
7748 rtp->cycles += RTP_SEQ_MOD;
7749
7750 /* If we are directly bridged to another instance send the audio directly out,
7751 * but only after updating core information about the received traffic so that
7752 * outgoing RTCP reflects it.
7753 */
7754 instance1 = ast_rtp_instance_get_bridged(instance);
7755 if (instance1
7756 && !bridge_p2p_rtp_write(instance, instance1, rtpheader, res, hdrlen)) {
7757 struct timeval rxtime;
7758 struct ast_frame *f;
7759
7760 /* Update statistics for jitter so they are correct in RTCP */
7761 calc_rxstamp_and_jitter(&rxtime, rtp, timestamp, mark);
7762
7763
7764 /* When doing P2P we don't need to raise any frames about SSRC change to the core */
7765 while ((f = AST_LIST_REMOVE_HEAD(&frames, frame_list)) != NULL) {
7766 ast_frfree(f);
7767 }
7768
7769 return &ast_null_frame;
7770 }
7771
7772 payload = ast_rtp_codecs_get_payload(ast_rtp_instance_get_codecs(instance), payloadtype);
7773 if (!payload) {
7774 /* Unknown payload type. */
7776 }
7777
7778 /* If the payload is not actually an Asterisk one but a special one pass it off to the respective handler */
7779 if (!payload->asterisk_format) {
7780 struct ast_frame *f = NULL;
7781 if (payload->rtp_code == AST_RTP_DTMF) {
7782 /* process_dtmf_rfc2833 may need to return multiple frames. We do this
7783 * by passing the pointer to the frame list to it so that the method
7784 * can append frames to the list as needed.
7785 */
7786 process_dtmf_rfc2833(instance, read_area + hdrlen, res - hdrlen, seqno, timestamp, payloadtype, mark, &frames);
7787 } else if (payload->rtp_code == AST_RTP_CISCO_DTMF) {
7788 f = process_dtmf_cisco(instance, read_area + hdrlen, res - hdrlen, seqno, timestamp, payloadtype, mark);
7789 } else if (payload->rtp_code == AST_RTP_CN) {
7790 f = process_cn_rfc3389(instance, read_area + hdrlen, res - hdrlen, seqno, timestamp, payloadtype, mark);
7791 } else {
7792 ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n",
7793 payloadtype,
7794 ast_sockaddr_stringify(remote_address));
7795 }
7796
7797 if (f) {
7799 }
7800 /* Even if no frame was returned by one of the above methods,
7801 * we may have a frame to return in our frame list
7802 */
7804 }
7805
7806 ao2_replace(rtp->lastrxformat, payload->format);
7807 ao2_replace(rtp->f.subclass.format, payload->format);
7808 switch (ast_format_get_type(rtp->f.subclass.format)) {
7811 break;
7814 break;
7816 rtp->f.frametype = AST_FRAME_TEXT;
7817 break;
7819 /* Fall through */
7820 default:
7821 ast_log(LOG_WARNING, "Unknown or unsupported media type: %s\n",
7823 return &ast_null_frame;
7824 }
7825
7826 if (rtp->dtmf_timeout && rtp->dtmf_timeout < timestamp) {
7827 rtp->dtmf_timeout = 0;
7828
7829 if (rtp->resp) {
7830 struct ast_frame *f;
7831 f = create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0);
7833 rtp->resp = 0;
7834 rtp->dtmf_timeout = rtp->dtmf_duration = 0;
7836 return AST_LIST_FIRST(&frames);
7837 }
7838 }
7839
7840 rtp->f.src = "RTP";
7841 rtp->f.mallocd = 0;
7842 rtp->f.datalen = res - hdrlen;
7843 rtp->f.data.ptr = read_area + hdrlen;
7844 rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
7846 rtp->f.seqno = seqno;
7847 rtp->f.stream_num = rtp->stream_num;
7848
7850 && ((int)seqno - (prev_seqno + 1) > 0)
7851 && ((int)seqno - (prev_seqno + 1) < 10)) {
7852 unsigned char *data = rtp->f.data.ptr;
7853
7854 memmove(rtp->f.data.ptr+3, rtp->f.data.ptr, rtp->f.datalen);
7855 rtp->f.datalen +=3;
7856 *data++ = 0xEF;
7857 *data++ = 0xBF;
7858 *data = 0xBD;
7859 }
7860
7862 unsigned char *data = rtp->f.data.ptr;
7863 unsigned char *header_end;
7864 int num_generations;
7865 int header_length;
7866 int len;
7867 int diff =(int)seqno - (prev_seqno+1); /* if diff = 0, no drop*/
7868 int x;
7869
7871 header_end = memchr(data, ((*data) & 0x7f), rtp->f.datalen);
7872 if (header_end == NULL) {
7874 }
7875 header_end++;
7876
7877 header_length = header_end - data;
7878 num_generations = header_length / 4;
7879 len = header_length;
7880
7881 if (!diff) {
7882 for (x = 0; x < num_generations; x++)
7883 len += data[x * 4 + 3];
7884
7885 if (!(rtp->f.datalen - len))
7887
7888 rtp->f.data.ptr += len;
7889 rtp->f.datalen -= len;
7890 } else if (diff > num_generations && diff < 10) {
7891 len -= 3;
7892 rtp->f.data.ptr += len;
7893 rtp->f.datalen -= len;
7894
7895 data = rtp->f.data.ptr;
7896 *data++ = 0xEF;
7897 *data++ = 0xBF;
7898 *data = 0xBD;
7899 } else {
7900 for ( x = 0; x < num_generations - diff; x++)
7901 len += data[x * 4 + 3];
7902
7903 rtp->f.data.ptr += len;
7904 rtp->f.datalen -= len;
7905 }
7906 }
7907
7909 rtp->f.samples = ast_codec_samples_count(&rtp->f);
7911 ast_frame_byteswap_be(&rtp->f);
7912 }
7913 calc_rxstamp_and_jitter(&rtp->f.delivery, rtp, timestamp, mark);
7914 /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
7916 rtp->f.ts = timestamp / (ast_rtp_get_rate(rtp->f.subclass.format) / 1000);
7917 rtp->f.len = rtp->f.samples / ((ast_format_get_sample_rate(rtp->f.subclass.format) / 1000));
7919 /* Video -- samples is # of samples vs. 90000 */
7920 if (!rtp->lastividtimestamp)
7921 rtp->lastividtimestamp = timestamp;
7922 calc_rxstamp_and_jitter(&rtp->f.delivery, rtp, timestamp, mark);
7924 rtp->f.ts = timestamp / (ast_rtp_get_rate(rtp->f.subclass.format) / 1000);
7925 rtp->f.samples = timestamp - rtp->lastividtimestamp;
7926 rtp->lastividtimestamp = timestamp;
7927 rtp->f.delivery.tv_sec = 0;
7928 rtp->f.delivery.tv_usec = 0;
7929 /* Pass the RTP marker bit as bit */
7930 rtp->f.subclass.frame_ending = mark ? 1 : 0;
7932 /* TEXT -- samples is # of samples vs. 1000 */
7933 if (!rtp->lastitexttimestamp)
7934 rtp->lastitexttimestamp = timestamp;
7935 rtp->f.samples = timestamp - rtp->lastitexttimestamp;
7936 rtp->lastitexttimestamp = timestamp;
7937 rtp->f.delivery.tv_sec = 0;
7938 rtp->f.delivery.tv_usec = 0;
7939 } else {
7940 ast_log(LOG_WARNING, "Unknown or unsupported media type: %s\n",
7942 return &ast_null_frame;
7943 }
7944
7946 return AST_LIST_FIRST(&frames);
7947}
#define ao2_replace(dst, src)
Replace one object reference with another cleaning up the original.
Definition: astobj2.h:501
@ AST_MEDIA_TYPE_AUDIO
Definition: codec.h:32
@ AST_MEDIA_TYPE_VIDEO
Definition: codec.h:33
@ AST_MEDIA_TYPE_IMAGE
Definition: codec.h:34
@ AST_MEDIA_TYPE_TEXT
Definition: codec.h:35
unsigned int ast_codec_samples_count(struct ast_frame *frame)
Get the number of samples contained within a frame.
Definition: codec.c:379
const char * ast_codec_media_type2str(enum ast_media_type type)
Conversion function to take a media type and turn it into a string.
Definition: codec.c:348
enum ast_media_type ast_format_get_type(const struct ast_format *format)
Get the media type of a format.
Definition: format.c:354
unsigned int ast_format_get_sample_rate(const struct ast_format *format)
Get the sample rate of a media format.
Definition: format.c:379
enum ast_format_cmp_res ast_format_cmp(const struct ast_format *format1, const struct ast_format *format2)
Compare two formats.
Definition: format.c:201
@ AST_FORMAT_CMP_EQUAL
Definition: format.h:36
int ast_format_cache_is_slinear(struct ast_format *format)
Determines if a format is one of the cached slin formats.
Definition: format_cache.c:534
struct ast_format * ast_format_t140_red
Built-in cached t140 red format.
Definition: format_cache.c:236
struct ast_format * ast_format_t140
Built-in cached t140 format.
Definition: format_cache.c:231
const char * ext
Definition: http.c:150
@ AST_FRFLAG_HAS_SEQUENCE_NUMBER
@ AST_FRFLAG_HAS_TIMING_INFO
#define ast_frame_byteswap_be(fr)
#define ast_frisolate(fr)
Makes a frame independent of any static storage.
#define ast_frfree(fr)
@ AST_FRAME_VIDEO
@ AST_FRAME_DTMF_END
@ AST_FRAME_VOICE
@ AST_FRAME_TEXT
#define DEBUG_ATLEAST(level)
#define LOG_DEBUG
#define LOG_NOTICE
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:681
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:731
#define AST_LIST_REMOVE_HEAD(head, field)
Removes and returns the head entry from a list.
Definition: linkedlists.h:833
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:421
static int frames
Definition: parser.c:51
static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, struct ast_rtp_instance *instance1, unsigned int *rtpheader, int len, int hdrlen)
static void calc_rxstamp_and_jitter(struct timeval *tv, struct ast_rtp *rtp, unsigned int rx_rtp_ts, int mark)
static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark, struct frame_list *frames)
static struct ast_frame * process_cn_rfc3389(struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark)
static void rtp_instance_parse_extmap_extensions(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned char *extension, int len)
static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
static struct ast_frame * process_dtmf_cisco(struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, int payloadtype, int mark)
#define RTP_SEQ_MOD
static struct ast_frame * create_dtmf_frame(struct ast_rtp_instance *instance, enum ast_frame_type type, int compensate)
static int ast_rtcp_write(const void *data)
Write a RTCP packet to the far end.
struct ast_rtp_payload_type * ast_rtp_codecs_get_payload(struct ast_rtp_codecs *codecs, int payload)
Retrieve rx payload mapped information by payload type.
Definition: rtp_engine.c:1492
struct ast_rtp_instance * ast_rtp_instance_get_bridged(struct ast_rtp_instance *instance)
Get the other RTP instance that an instance is bridged to.
Definition: rtp_engine.c:2247
#define AST_RTP_CN
Definition: rtp_engine.h:293
#define AST_RTP_CISCO_DTMF
Definition: rtp_engine.h:295
int ast_sched_add(struct ast_sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event.
Definition: sched.c:567
unsigned int lastividtimestamp
unsigned int dtmf_duration
unsigned short seedrxseqno
unsigned int last_seqno
unsigned int dtmf_timeout
optional_ts last_end_timestamp
unsigned int lastitexttimestamp
unsigned int ts
unsigned char is_set
struct timeval ast_samp2tv(unsigned int _nsamp, unsigned int _rate)
Returns a timeval corresponding to the duration of n samples at rate r. Useful to convert samples to ...
Definition: time.h:282
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:107

References ao2_cleanup, ao2_ref, ao2_replace, ast_codec_media_type2str(), ast_codec_samples_count(), AST_CONTROL_SRCCHANGE, ast_debug, ast_debug_rtp_packet_is_allowed, ast_format_cache_is_slinear(), ast_format_cmp(), AST_FORMAT_CMP_EQUAL, ast_format_get_sample_rate(), ast_format_get_type(), ast_format_t140, ast_format_t140_red, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_FRFLAG_HAS_SEQUENCE_NUMBER, AST_FRFLAG_HAS_TIMING_INFO, ast_frfree, AST_FRIENDLY_OFFSET, ast_frisolate, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, AST_LIST_REMOVE_HEAD, ast_log, AST_MEDIA_TYPE_AUDIO, AST_MEDIA_TYPE_IMAGE, AST_MEDIA_TYPE_TEXT, AST_MEDIA_TYPE_VIDEO, ast_null_frame, ast_rtcp_calc_interval(), ast_rtcp_write(), AST_RTP_CISCO_DTMF, AST_RTP_CN, ast_rtp_codecs_get_payload(), AST_RTP_DTMF, ast_rtp_dtmf_continuation(), ast_rtp_get_rate(), ast_rtp_instance_get_bridged(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_samp2tv(), ast_sched_add(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_tv(), ast_tvdiff_ms(), bridge_p2p_rtp_write(), calc_rxstamp_and_jitter(), create_dtmf_frame(), ast_rtp::cycles, ast_frame::data, ast_frame::datalen, DEBUG_ATLEAST, ast_frame::delivery, ast_rtp::dtmf_duration, ast_rtp::dtmf_timeout, ast_rtcp::expected_prior, ext, ast_rtp::f, ast_frame_subclass::format, ast_frame_subclass::frame_ending, frames, ast_frame::frametype, optional_ts::is_set, ast_rtp::last_end_timestamp, ast_rtp::last_seqno, ast_rtp::lastitexttimestamp, ast_rtp::lastividtimestamp, ast_rtp::lastrxformat, len(), ast_frame::len, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, NULL, ast_frame::offset, process_cn_rfc3389(), process_dtmf_cisco(), process_dtmf_rfc2833(), ast_frame::ptr, RAII_VAR, ast_rtcp::received_prior, res_srtp, ast_rtp::resp, ast_rtp::rtcp, rtp_instance_parse_extmap_extensions(), RTP_SEQ_MOD, ast_rtp::rxcount, ast_rtp::rxoctetcount, ast_frame::samples, ast_rtp::sched, ast_rtcp::schedid, ast_rtp::seedrxseqno, ast_rtp::sending_digit, ast_frame::seqno, ast_frame::src, srtp_replay_protection, ast_frame::stream_num, ast_rtp::stream_num, ast_frame::subclass, ast_rtcp::them, ast_rtp::themssrc, ast_rtp::themssrc_valid, ast_frame::ts, optional_ts::ts, and ast_srtp_res::unprotect.

Referenced by ast_rtp_read().

◆ ast_rtp_local_bridge()

static int ast_rtp_local_bridge ( struct ast_rtp_instance instance0,
struct ast_rtp_instance instance1 
)
static
Precondition
Neither instance0 nor instance1 are locked

Definition at line 9069 of file res_rtp_asterisk.c.

9070{
9071 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance0);
9072
9073 ao2_lock(instance0);
9075 if (rtp->smoother) {
9077 rtp->smoother = NULL;
9078 }
9079
9080 /* We must use a new SSRC when local bridge ends */
9081 if (!instance1) {
9082 rtp->ssrc = rtp->ssrc_orig;
9083 rtp->ssrc_orig = 0;
9084 rtp->ssrc_saved = 0;
9085 } else if (!rtp->ssrc_saved) {
9086 /* In case ast_rtp_local_bridge is called multiple times, only save the ssrc from before local bridge began */
9087 rtp->ssrc_orig = rtp->ssrc;
9088 rtp->ssrc_saved = 1;
9089 }
9090
9091 ao2_unlock(instance0);
9092
9093 return 0;
9094}
#define FLAG_REQ_LOCAL_BRIDGE_BIT
unsigned int ssrc_orig
unsigned char ssrc_saved

References ao2_lock, ao2_unlock, ast_rtp_instance_get_data(), ast_set_flag, ast_smoother_free(), FLAG_NEED_MARKER_BIT, FLAG_REQ_LOCAL_BRIDGE_BIT, NULL, ast_rtp::smoother, ast_rtp::ssrc, ast_rtp::ssrc_orig, and ast_rtp::ssrc_saved.

◆ ast_rtp_new()

static int ast_rtp_new ( struct ast_rtp_instance instance,
struct ast_sched_context sched,
struct ast_sockaddr addr,
void *  data 
)
static
Precondition
instance is locked

Definition at line 4086 of file res_rtp_asterisk.c.

4089{
4090 struct ast_rtp *rtp = NULL;
4091
4092 /* Create a new RTP structure to hold all of our data */
4093 if (!(rtp = ast_calloc(1, sizeof(*rtp)))) {
4094 return -1;
4095 }
4096 rtp->owner = instance;
4097 /* Set default parameters on the newly created RTP structure */
4098 rtp->ssrc = ast_random();
4099 ast_uuid_generate_str(rtp->cname, sizeof(rtp->cname));
4100 rtp->seqno = ast_random() & 0x7fff;
4101 rtp->expectedrxseqno = -1;
4102 rtp->expectedseqno = -1;
4103 rtp->rxstart = -1;
4104 rtp->sched = sched;
4105 ast_sockaddr_copy(&rtp->bind_address, addr);
4106 /* Transport creation operations can grab the RTP data from the instance, so set it */
4107 ast_rtp_instance_set_data(instance, rtp);
4108
4109 if (rtp_allocate_transport(instance, rtp)) {
4110 return -1;
4111 }
4112
4113 if (AST_VECTOR_INIT(&rtp->ssrc_mapping, 1)) {
4114 return -1;
4115 }
4116
4118 return -1;
4119 }
4120 rtp->transport_wide_cc.schedid = -1;
4121
4125 rtp->stream_num = -1;
4126
4127 return 0;
4128}
static struct ast_sched_context * sched
Definition: chan_ooh323.c:400
struct ast_format * ast_format_none
Built-in "null" format.
Definition: format_cache.c:246
void ast_rtp_instance_set_data(struct ast_rtp_instance *instance, void *data)
Set the data portion of an RTP instance.
Definition: rtp_engine.c:579
double rxstart
struct ast_sockaddr bind_address
char * ast_uuid_generate_str(char *buf, size_t size)
Generate a UUID string.
Definition: uuid.c:141
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
Definition: vector.h:113

References ao2_bump, ast_calloc, ast_format_none, ast_random(), ast_rtp_instance_set_data(), ast_sockaddr_copy(), ast_uuid_generate_str(), AST_VECTOR_INIT, ast_rtp::bind_address, ast_rtp::cname, ast_rtp::expectedrxseqno, ast_rtp::expectedseqno, ast_rtp::f, ast_frame_subclass::format, ast_rtp::lastrxformat, ast_rtp::lasttxformat, NULL, ast_rtp::owner, rtp_transport_wide_cc_statistics::packet_statistics, rtp_allocate_transport(), ast_rtp::rxstart, sched, ast_rtp::sched, rtp_transport_wide_cc_statistics::schedid, ast_rtp::seqno, ast_rtp::ssrc, ast_rtp::ssrc_mapping, ast_rtp::stream_num, ast_frame::subclass, and ast_rtp::transport_wide_cc.

◆ ast_rtp_prop_set()

static void ast_rtp_prop_set ( struct ast_rtp_instance instance,
enum ast_rtp_property  property,
int  value 
)
static
Precondition
instance is locked

Definition at line 8726 of file res_rtp_asterisk.c.

8727{
8728 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8729
8730 if (property == AST_RTP_PROPERTY_RTCP) {
8731 if (value) {
8732 struct ast_sockaddr local_addr;
8733
8734 if (rtp->rtcp && rtp->rtcp->type == value) {
8735 ast_debug_rtcp(1, "(%p) RTCP ignoring duplicate property\n", instance);
8736 return;
8737 }
8738
8739 if (!rtp->rtcp) {
8740 rtp->rtcp = ast_calloc(1, sizeof(*rtp->rtcp));
8741 if (!rtp->rtcp) {
8742 return;
8743 }
8744 rtp->rtcp->s = -1;
8745#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8746 rtp->rtcp->dtls.timeout_timer = -1;
8747#endif
8748 rtp->rtcp->schedid = -1;
8749 }
8750
8751 rtp->rtcp->type = value;
8752
8753 /* Grab the IP address and port we are going to use */
8754 ast_rtp_instance_get_local_address(instance, &rtp->rtcp->us);
8757 ast_sockaddr_port(&rtp->rtcp->us) + 1);
8758 }
8759
8760 ast_sockaddr_copy(&local_addr, &rtp->rtcp->us);
8761 if (!ast_find_ourip(&local_addr, &rtp->rtcp->us, 0)) {
8762 ast_sockaddr_set_port(&local_addr, ast_sockaddr_port(&rtp->rtcp->us));
8763 } else {
8764 /* Failed to get local address reset to use default. */
8765 ast_sockaddr_copy(&local_addr, &rtp->rtcp->us);
8766 }
8767
8770 if (!rtp->rtcp->local_addr_str) {
8771 ast_free(rtp->rtcp);
8772 rtp->rtcp = NULL;
8773 return;
8774 }
8775
8777 /* We're either setting up RTCP from scratch or
8778 * switching from MUX. Either way, we won't have
8779 * a socket set up, and we need to set it up
8780 */
8781 if ((rtp->rtcp->s =
8782 create_new_socket("RTCP",
8783 ast_sockaddr_is_ipv4(&rtp->rtcp->us) ?
8784 AF_INET :
8785 ast_sockaddr_is_ipv6(&rtp->rtcp->us) ?
8786 AF_INET6 : -1)) < 0) {
8787 ast_debug_rtcp(1, "(%p) RTCP failed to create a new socket\n", instance);
8789 ast_free(rtp->rtcp);
8790 rtp->rtcp = NULL;
8791 return;
8792 }
8793
8794 /* Try to actually bind to the IP address and port we are going to use for RTCP, if this fails we have to bail out */
8795 if (ast_bind(rtp->rtcp->s, &rtp->rtcp->us)) {
8796 ast_debug_rtcp(1, "(%p) RTCP failed to setup RTP instance\n", instance);
8797 close(rtp->rtcp->s);
8799 ast_free(rtp->rtcp);
8800 rtp->rtcp = NULL;
8801 return;
8802 }
8803#ifdef HAVE_PJPROJECT
8804 if (rtp->ice) {
8805 rtp_add_candidates_to_ice(instance, rtp, &rtp->rtcp->us, ast_sockaddr_port(&rtp->rtcp->us), AST_RTP_ICE_COMPONENT_RTCP, TRANSPORT_SOCKET_RTCP);
8806 }
8807#endif
8808#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8809 dtls_setup_rtcp(instance);
8810#endif
8811 } else {
8812 struct ast_sockaddr addr;
8813 /* RTCPMUX uses the same socket as RTP. If we were previously using standard RTCP
8814 * then close the socket we previously created.
8815 *
8816 * It may seem as though there is a possible race condition here where we might try
8817 * to close the RTCP socket while it is being used to send data. However, this is not
8818 * a problem in practice since setting and adjusting of RTCP properties happens prior
8819 * to activating RTP. It is not until RTP is activated that timers start for RTCP
8820 * transmission
8821 */
8822 if (rtp->rtcp->s > -1 && rtp->rtcp->s != rtp->s) {
8823 close(rtp->rtcp->s);
8824 }
8825 rtp->rtcp->s = rtp->s;
8826 ast_rtp_instance_get_remote_address(instance, &addr);
8827 ast_sockaddr_copy(&rtp->rtcp->them, &addr);
8828#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8829 if (rtp->rtcp->dtls.ssl && rtp->rtcp->dtls.ssl != rtp->dtls.ssl) {
8830 SSL_free(rtp->rtcp->dtls.ssl);
8831 }
8832 rtp->rtcp->dtls.ssl = rtp->dtls.ssl;
8833#endif
8834 }
8835
8836 ast_debug_rtcp(1, "(%s) RTCP setup on RTP instance\n",
8838 } else {
8839 if (rtp->rtcp) {
8840 if (rtp->rtcp->schedid > -1) {
8841 ao2_unlock(instance);
8842 if (!ast_sched_del(rtp->sched, rtp->rtcp->schedid)) {
8843 /* Successfully cancelled scheduler entry. */
8844 ao2_ref(instance, -1);
8845 } else {
8846 /* Unable to cancel scheduler entry */
8847 ast_debug_rtcp(1, "(%p) RTCP failed to tear down RTCP\n", instance);
8848 ao2_lock(instance);
8849 return;
8850 }
8851 ao2_lock(instance);
8852 rtp->rtcp->schedid = -1;
8853 }
8854 if (rtp->transport_wide_cc.schedid > -1) {
8855 ao2_unlock(instance);
8856 if (!ast_sched_del(rtp->sched, rtp->transport_wide_cc.schedid)) {
8857 ao2_ref(instance, -1);
8858 } else {
8859 ast_debug_rtcp(1, "(%p) RTCP failed to tear down transport-cc feedback\n", instance);
8860 ao2_lock(instance);
8861 return;
8862 }
8863 ao2_lock(instance);
8864 rtp->transport_wide_cc.schedid = -1;
8865 }
8866 if (rtp->rtcp->s > -1 && rtp->rtcp->s != rtp->s) {
8867 close(rtp->rtcp->s);
8868 }
8869#if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8870 ao2_unlock(instance);
8871 dtls_srtp_stop_timeout_timer(instance, rtp, 1);
8872 ao2_lock(instance);
8873
8874 if (rtp->rtcp->dtls.ssl && rtp->rtcp->dtls.ssl != rtp->dtls.ssl) {
8875 SSL_free(rtp->rtcp->dtls.ssl);
8876 }
8877#endif
8879 ast_free(rtp->rtcp);
8880 rtp->rtcp = NULL;
8881 ast_debug_rtcp(1, "(%s) RTCP torn down on RTP instance\n",
8883 }
8884 }
8885 } else if (property == AST_RTP_PROPERTY_ASYMMETRIC_CODEC) {
8886 rtp->asymmetric_codec = value;
8887 } else if (property == AST_RTP_PROPERTY_RETRANS_SEND) {
8888 if (value) {
8889 if (!rtp->send_buffer) {
8891 }
8892 } else {
8893 if (rtp->send_buffer) {
8895 rtp->send_buffer = NULL;
8896 }
8897 }
8898 } else if (property == AST_RTP_PROPERTY_RETRANS_RECV) {
8899 if (value) {
8900 if (!rtp->recv_buffer) {
8903 }
8904 } else {
8905 if (rtp->recv_buffer) {
8907 rtp->recv_buffer = NULL;
8909 }
8910 }
8911 }
8912}
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
Definition: acl.c:1051
#define ast_strdup(str)
A wrapper for strdup()
Definition: astmm.h:241
void ast_free_ptr(void *ptr)
free() wrapper
Definition: astmm.c:1739
struct ast_data_buffer * ast_data_buffer_alloc(ast_data_buffer_free_callback free_fn, size_t size)
Allocate a data buffer.
Definition: data_buffer.c:145
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:517
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:524
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:590
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:532
#define DEFAULT_RTP_RECV_BUFFER_SIZE
static int create_new_socket(const char *type, int af)
#define DEFAULT_RTP_SEND_BUFFER_SIZE
@ AST_RTP_INSTANCE_RTCP_STANDARD
Definition: rtp_engine.h:284
void ast_rtp_instance_get_local_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the local address that we are expecting RTP on.
Definition: rtp_engine.c:664
@ AST_RTP_PROPERTY_RETRANS_RECV
Definition: rtp_engine.h:127
@ AST_RTP_PROPERTY_RETRANS_SEND
Definition: rtp_engine.h:129
@ AST_RTP_PROPERTY_RTCP
Definition: rtp_engine.h:123
@ AST_RTP_PROPERTY_ASYMMETRIC_CODEC
Definition: rtp_engine.h:125
int ast_sched_del(struct ast_sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event.
Definition: sched.c:614
enum ast_rtp_instance_rtcp type
struct ast_sockaddr us
unsigned int asymmetric_codec
int value
Definition: syslog.c:37

References ao2_lock, ao2_ref, ao2_unlock, ast_bind(), ast_calloc, ast_data_buffer_alloc(), ast_data_buffer_free(), ast_debug_rtcp, ast_find_ourip(), ast_free, ast_free_ptr(), AST_RTP_ICE_COMPONENT_RTCP, ast_rtp_instance_get_channel_id(), ast_rtp_instance_get_data(), ast_rtp_instance_get_local_address(), ast_rtp_instance_get_remote_address, AST_RTP_INSTANCE_RTCP_STANDARD, AST_RTP_PROPERTY_ASYMMETRIC_CODEC, AST_RTP_PROPERTY_RETRANS_RECV, AST_RTP_PROPERTY_RETRANS_SEND, AST_RTP_PROPERTY_RTCP, ast_sched_del(), ast_sockaddr_copy(), ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv6(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_strdup, AST_VECTOR_FREE, AST_VECTOR_INIT, ast_rtp::asymmetric_codec, create_new_socket(), DEFAULT_RTP_RECV_BUFFER_SIZE, DEFAULT_RTP_SEND_BUFFER_SIZE, ast_rtcp::local_addr_str, ast_rtp::missing_seqno, NULL, ast_rtp::recv_buffer, ast_rtp::rtcp, ast_rtp::s, ast_rtcp::s, ast_rtp::sched, rtp_transport_wide_cc_statistics::schedid, ast_rtcp::schedid, ast_rtp::send_buffer, ast_rtcp::them, TRANSPORT_SOCKET_RTCP, ast_rtp::transport_wide_cc, ast_rtcp::type, ast_rtcp::us, and value.

◆ ast_rtp_qos_set()

static int ast_rtp_qos_set ( struct ast_rtp_instance instance,
int  tos,
int  cos,
const char *  desc 
)
static
Precondition
instance is locked

Definition at line 9245 of file res_rtp_asterisk.c.

9246{
9247 struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
9248
9249 return ast_set_qos(rtp->s, tos, cos, desc);
9250}
static const char desc[]
Definition: cdr_radius.c:84
unsigned int tos
Definition: chan_iax2.c:358
unsigned int cos
Definition: chan_iax2.c:359
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:621

References ast_rtp_instance_get_data(), ast_set_qos(), cos, desc, ast_rtp::s, and tos.

◆ ast_rtp_read()

static struct