Asterisk - The Open Source Telephony Project  GIT-master-a24979a
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 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_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 void calc_rxstamp (struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, 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_lost_stats (struct ast_rtp *rtp, unsigned int lost_packets)
 
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 161 of file res_rtp_asterisk.c.

◆ DEFAULT_DTLS_MTU

#define DEFAULT_DTLS_MTU   1200

Definition at line 195 of file res_rtp_asterisk.c.

◆ DEFAULT_DTMF_TIMEOUT

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

samples

Definition at line 144 of file res_rtp_asterisk.c.

◆ DEFAULT_ICESUPPORT

#define DEFAULT_ICESUPPORT   1

Definition at line 193 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 162 of file res_rtp_asterisk.c.

◆ DEFAULT_LEARNING_MIN_SEQUENTIAL

#define DEFAULT_LEARNING_MIN_SEQUENTIAL   4

Definition at line 148 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 107 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 118 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 116 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 106 of file res_rtp_asterisk.c.

◆ DEFAULT_SRTP_REPLAY_PROTECTION

#define DEFAULT_SRTP_REPLAY_PROTECTION   1

Definition at line 192 of file res_rtp_asterisk.c.

◆ DEFAULT_STRICT_RTP

#define DEFAULT_STRICT_RTP   STRICT_RTP_YES

Enabled by default

Definition at line 191 of file res_rtp_asterisk.c.

◆ DEFAULT_STUN_SOFTWARE_ATTRIBUTE

#define DEFAULT_STUN_SOFTWARE_ATTRIBUTE   1

Definition at line 194 of file res_rtp_asterisk.c.

◆ DEFAULT_TURN_PORT

#define DEFAULT_TURN_PORT   3478

Definition at line 112 of file res_rtp_asterisk.c.

◆ DTMF_SAMPLE_RATE_MS

#define DTMF_SAMPLE_RATE_MS   8

DTMF samples per millisecond

Definition at line 142 of file res_rtp_asterisk.c.

◆ FLAG_3389_WARNING

#define FLAG_3389_WARNING   (1 << 0)

Definition at line 294 of file res_rtp_asterisk.c.

◆ FLAG_DTMF_COMPENSATE

#define FLAG_DTMF_COMPENSATE   (1 << 4)

Definition at line 299 of file res_rtp_asterisk.c.

◆ FLAG_NAT_ACTIVE

#define FLAG_NAT_ACTIVE   (3 << 1)

Definition at line 295 of file res_rtp_asterisk.c.

◆ FLAG_NAT_INACTIVE

#define FLAG_NAT_INACTIVE   (0 << 1)

Definition at line 296 of file res_rtp_asterisk.c.

◆ FLAG_NAT_INACTIVE_NOWARN

#define FLAG_NAT_INACTIVE_NOWARN   (1 << 1)

Definition at line 297 of file res_rtp_asterisk.c.

◆ FLAG_NEED_MARKER_BIT

#define FLAG_NEED_MARKER_BIT   (1 << 3)

Definition at line 298 of file res_rtp_asterisk.c.

◆ FLAG_REQ_LOCAL_BRIDGE_BIT

#define FLAG_REQ_LOCAL_BRIDGE_BIT   (1 << 5)

Definition at line 300 of file res_rtp_asterisk.c.

◆ MAX_TIMESTAMP_SKEW

#define MAX_TIMESTAMP_SKEW   640

Definition at line 99 of file res_rtp_asterisk.c.

◆ MAXIMUM_RTP_PORT

#define MAXIMUM_RTP_PORT   65535

Maximum port number to accept

Definition at line 110 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 119 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 117 of file res_rtp_asterisk.c.

◆ MINIMUM_RTP_PORT

#define MINIMUM_RTP_PORT   1024

Minimum port number to accept

Definition at line 109 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 121 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 120 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 102 of file res_rtp_asterisk.c.

◆ RTCP_FB_NACK_BLOCK_WORD_LENGTH

#define RTCP_FB_NACK_BLOCK_WORD_LENGTH   2

Definition at line 6126 of file res_rtp_asterisk.c.

◆ RTCP_FB_REMB_BLOCK_WORD_LENGTH

#define RTCP_FB_REMB_BLOCK_WORD_LENGTH   4

Definition at line 6125 of file res_rtp_asterisk.c.

◆ RTCP_HEADER_SSRC_LENGTH

#define RTCP_HEADER_SSRC_LENGTH   2

Definition at line 6124 of file res_rtp_asterisk.c.

◆ RTCP_LENGTH_MASK

#define RTCP_LENGTH_MASK   0xFFFF

Definition at line 6089 of file res_rtp_asterisk.c.

◆ RTCP_LENGTH_SHIFT

#define RTCP_LENGTH_SHIFT   0

Definition at line 6098 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 104 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 103 of file res_rtp_asterisk.c.

◆ RTCP_PADDING_MASK

#define RTCP_PADDING_MASK   0x01

Definition at line 6092 of file res_rtp_asterisk.c.

◆ RTCP_PADDING_SHIFT

#define RTCP_PADDING_SHIFT   29

Definition at line 6101 of file res_rtp_asterisk.c.

◆ RTCP_PAYLOAD_TYPE_MASK

#define RTCP_PAYLOAD_TYPE_MASK   0xFF

Definition at line 6090 of file res_rtp_asterisk.c.

◆ RTCP_PAYLOAD_TYPE_SHIFT

#define RTCP_PAYLOAD_TYPE_SHIFT   16

Definition at line 6099 of file res_rtp_asterisk.c.

◆ RTCP_PT_APP

#define RTCP_PT_APP   204

Application defined (From RFC3550)

Definition at line 136 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 134 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 126 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 139 of file res_rtp_asterisk.c.

◆ RTCP_PT_RR

#define RTCP_PT_RR   AST_RTP_RTCP_RR

Receiver Report (From RFC3550)

Definition at line 130 of file res_rtp_asterisk.c.

◆ RTCP_PT_SDES

#define RTCP_PT_SDES   202

Source Description (From RFC3550)

Definition at line 132 of file res_rtp_asterisk.c.

◆ RTCP_PT_SR

#define RTCP_PT_SR   AST_RTP_RTCP_SR

Sender Report (From RFC3550)

Definition at line 128 of file res_rtp_asterisk.c.

◆ RTCP_REPORT_COUNT_MASK

#define RTCP_REPORT_COUNT_MASK   0x1F

Definition at line 6091 of file res_rtp_asterisk.c.

◆ RTCP_REPORT_COUNT_SHIFT

#define RTCP_REPORT_COUNT_SHIFT   24

Definition at line 6100 of file res_rtp_asterisk.c.

◆ RTCP_RR_BLOCK_WORD_LENGTH

#define RTCP_RR_BLOCK_WORD_LENGTH   6

Definition at line 6123 of file res_rtp_asterisk.c.

◆ RTCP_SR_BLOCK_WORD_LENGTH

#define RTCP_SR_BLOCK_WORD_LENGTH   5

Definition at line 6122 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 6119 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 6120 of file res_rtp_asterisk.c.

◆ RTCP_VERSION

#define RTCP_VERSION   2U

Definition at line 6104 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_MASK

#define RTCP_VERSION_MASK   0x03

Definition at line 6093 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_MASK_SHIFTED

#define RTCP_VERSION_MASK_SHIFTED   (RTCP_VERSION_MASK << RTCP_VERSION_SHIFT)

Definition at line 6106 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_SHIFT

#define RTCP_VERSION_SHIFT   30

Definition at line 6102 of file res_rtp_asterisk.c.

◆ RTCP_VERSION_SHIFTED

#define RTCP_VERSION_SHIFTED   (RTCP_VERSION << RTCP_VERSION_SHIFT)

Definition at line 6105 of file res_rtp_asterisk.c.

◆ RTP_DTLS_ESTABLISHED

#define RTP_DTLS_ESTABLISHED   -37

Definition at line 168 of file res_rtp_asterisk.c.

◆ RTP_MTU

#define RTP_MTU   1200

Definition at line 141 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 101 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 123 of file res_rtp_asterisk.c.

◆ SRTP_MASTER_KEY_LEN

#define SRTP_MASTER_KEY_LEN   16

Definition at line 164 of file res_rtp_asterisk.c.

◆ SRTP_MASTER_LEN

#define SRTP_MASTER_LEN   (SRTP_MASTER_KEY_LEN + SRTP_MASTER_SALT_LEN)

Definition at line 166 of file res_rtp_asterisk.c.

◆ SRTP_MASTER_SALT_LEN

#define SRTP_MASTER_SALT_LEN   14

Definition at line 165 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 4070 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 189 of file res_rtp_asterisk.c.

◆ TRANSPORT_SOCKET_RTCP

#define TRANSPORT_SOCKET_RTCP   1

Definition at line 303 of file res_rtp_asterisk.c.

◆ TRANSPORT_SOCKET_RTP

#define TRANSPORT_SOCKET_RTP   0

Definition at line 302 of file res_rtp_asterisk.c.

◆ TRANSPORT_TURN_RTCP

#define TRANSPORT_TURN_RTCP   3

Definition at line 305 of file res_rtp_asterisk.c.

◆ TRANSPORT_TURN_RTP

#define TRANSPORT_TURN_RTP   2

Definition at line 304 of file res_rtp_asterisk.c.

◆ TURN_STATE_WAIT_TIME

#define TURN_STATE_WAIT_TIME   2000

Definition at line 114 of file res_rtp_asterisk.c.

◆ ZFONE_PROFILE_ID

#define ZFONE_PROFILE_ID   0x505a

Definition at line 146 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 176 of file res_rtp_asterisk.c.

176  {
177  STRICT_RTP_NO = 0, /*! Don't adhere to any strict RTP rules */
178  STRICT_RTP_YES, /*! Strict RTP that restricts packets based on time and sequence number */
179  STRICT_RTP_SEQNO, /*! Strict RTP that restricts packets based on sequence number */
180 };
@ 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 170 of file res_rtp_asterisk.c.

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

Function Documentation

◆ __reg_module()

static void __reg_module ( void  )
static

Definition at line 9880 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 5897 of file res_rtp_asterisk.c.

5899 {
5900  int index;
5901 
5902  if (!AST_VECTOR_SIZE(&rtp->ssrc_mapping)) {
5903  /* This instance is not bundled */
5904  return instance;
5905  }
5906 
5907  /* Find the bundled child instance */
5908  for (index = 0; index < AST_VECTOR_SIZE(&rtp->ssrc_mapping); ++index) {
5909  struct rtp_ssrc_mapping *mapping = AST_VECTOR_GET_ADDR(&rtp->ssrc_mapping, index);
5910  unsigned int mapping_ssrc = source ? ast_rtp_get_ssrc(mapping->instance) : mapping->ssrc;
5911 
5912  if (mapping->ssrc_valid && mapping_ssrc == ssrc) {
5913  return mapping->instance;
5914  }
5915  }
5916 
5917  /* Does the SSRC match the bundled parent? */
5918  if (rtp->themssrc_valid && rtp->themssrc == ssrc) {
5919  return instance;
5920  }
5921  return NULL;
5922 }
static unsigned int ast_rtp_get_ssrc(struct ast_rtp_instance *instance)
#define NULL
Definition: resample.c:96
struct ast_rtp::@502 ssrc_mapping
unsigned int themssrc_valid
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 3100 of file res_rtp_asterisk.c.

3101 {
3102  int len;
3103  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
3104 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
3105  char *in = buf;
3106 #endif
3107 #ifdef HAVE_PJPROJECT
3108  struct ast_sockaddr *loop = rtcp ? &rtp->rtcp_loop : &rtp->rtp_loop;
3109 #endif
3110 #ifdef TEST_FRAMEWORK
3111  struct ast_rtp_engine_test *test = ast_rtp_instance_get_test(instance);
3112 #endif
3113 
3114  if ((len = ast_recvfrom(rtcp ? rtp->rtcp->s : rtp->s, buf, size, flags, sa)) < 0) {
3115  return len;
3116  }
3117 
3118 #ifdef TEST_FRAMEWORK
3119  if (test && test->packets_to_drop > 0) {
3120  test->packets_to_drop--;
3121  return 0;
3122  }
3123 #endif
3124 
3125 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
3126  /* If this is an SSL packet pass it to OpenSSL for processing. RFC section for first byte value:
3127  * https://tools.ietf.org/html/rfc5764#section-5.1.2 */
3128  if ((*in >= 20) && (*in <= 63)) {
3129  struct dtls_details *dtls = !rtcp ? &rtp->dtls : &rtp->rtcp->dtls;
3130  int res = 0;
3131 
3132  /* If no SSL session actually exists terminate things */
3133  if (!dtls->ssl) {
3134  ast_log(LOG_ERROR, "Received SSL traffic on RTP instance '%p' without an SSL session\n",
3135  instance);
3136  return -1;
3137  }
3138 
3139  ast_debug_dtls(3, "(%p) DTLS - __rtp_recvfrom rtp=%p - Got SSL packet '%d'\n", instance, rtp, *in);
3140 
3141  /*
3142  * A race condition is prevented between dtls_perform_handshake()
3143  * and this function because both functions have to get the
3144  * instance lock before they can do anything. The
3145  * dtls_perform_handshake() function needs to start the timer
3146  * before we stop it below.
3147  */
3148 
3149  /* Before we feed data into OpenSSL ensure that the timeout timer is either stopped or completed */
3150  ao2_unlock(instance);
3151  dtls_srtp_stop_timeout_timer(instance, rtp, rtcp);
3152  ao2_lock(instance);
3153 
3154  /* If we don't yet know if we are active or passive and we receive a packet... we are obviously passive */
3155  if (dtls->dtls_setup == AST_RTP_DTLS_SETUP_ACTPASS) {
3156  dtls->dtls_setup = AST_RTP_DTLS_SETUP_PASSIVE;
3157  SSL_set_accept_state(dtls->ssl);
3158  }
3159 
3160  BIO_write(dtls->read_bio, buf, len);
3161 
3162  len = SSL_read(dtls->ssl, buf, len);
3163 
3164  if ((len < 0) && (SSL_get_error(dtls->ssl, len) == SSL_ERROR_SSL)) {
3165  unsigned long error = ERR_get_error();
3166  ast_log(LOG_ERROR, "DTLS failure occurred on RTP instance '%p' due to reason '%s', terminating\n",
3167  instance, ERR_reason_error_string(error));
3168  return -1;
3169  }
3170 
3171  if (SSL_is_init_finished(dtls->ssl)) {
3172  /* Any further connections will be existing since this is now established */
3173  dtls->connection = AST_RTP_DTLS_CONNECTION_EXISTING;
3174  /* Use the keying material to set up key/salt information */
3175  if ((res = dtls_srtp_setup(rtp, instance, rtcp))) {
3176  return res;
3177  }
3178  /* Notify that dtls has been established */
3179  res = RTP_DTLS_ESTABLISHED;
3180 
3181  ast_debug_dtls(3, "(%p) DTLS - __rtp_recvfrom rtp=%p - established'\n", instance, rtp);
3182  } else {
3183  /* Since we've sent additional traffic start the timeout timer for retransmission */
3184  dtls_srtp_start_timeout_timer(instance, rtp, rtcp);
3185  }
3186 
3187  return res;
3188  }
3189 #endif
3190 
3191 #ifdef HAVE_PJPROJECT
3192  if (!ast_sockaddr_isnull(loop) && !ast_sockaddr_cmp(loop, sa)) {
3193  /* ICE traffic will have been handled in the TURN callback, so skip it but update the address
3194  * so it reflects the actual source and not the loopback
3195  */
3196  if (rtcp) {
3197  ast_sockaddr_copy(sa, &rtp->rtcp->them);
3198  } else {
3200  }
3201  } else if (rtp->ice) {
3202  pj_str_t combined = pj_str(ast_sockaddr_stringify(sa));
3203  pj_sockaddr address;
3204  pj_status_t status;
3205  struct ice_wrap *ice;
3206 
3207  pj_thread_register_check();
3208 
3209  pj_sockaddr_parse(pj_AF_UNSPEC(), 0, &combined, &address);
3210 
3211  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
3212  ice = rtp->ice;
3213  ao2_ref(ice, +1);
3214  ao2_unlock(instance);
3215  status = pj_ice_sess_on_rx_pkt(ice->real_ice,
3218  pj_sockaddr_get_len(&address));
3219  ao2_ref(ice, -1);
3220  ao2_lock(instance);
3221  if (status != PJ_SUCCESS) {
3222  char err_buf[100];
3223 
3224  pj_strerror(status, err_buf, sizeof(err_buf));
3225  ast_log(LOG_WARNING, "PJ ICE Rx error status code: %d '%s'.\n",
3226  (int)status, err_buf);
3227  return -1;
3228  }
3229  if (!rtp->passthrough) {
3230  /* If a unidirectional ICE negotiation occurs then lock on to the source of the
3231  * ICE traffic and use it as the target. This will occur if the remote side only
3232  * wants to receive media but never send to us.
3233  */
3234  if (!rtp->ice_active_remote_candidates && !rtp->ice_proposed_remote_candidates) {
3235  if (rtcp) {
3236  ast_sockaddr_copy(&rtp->rtcp->them, sa);
3237  } else {
3239  }
3240  }
3241  return 0;
3242  }
3243  rtp->passthrough = 0;
3244  }
3245 #endif
3246 
3247  return len;
3248 }
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 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
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:256
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:515
@ AST_RTP_DTLS_SETUP_ACTPASS
Definition: rtp_engine.h:516
@ AST_RTP_ICE_COMPONENT_RTCP
Definition: rtp_engine.h:464
@ AST_RTP_ICE_COMPONENT_RTP
Definition: rtp_engine.h:463
#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:1192
#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:1080
@ AST_RTP_DTLS_CONNECTION_EXISTING
Definition: rtp_engine.h:523
#define ast_debug_dtls(sublevel,...)
Log debug level DTLS information.
Definition: rtp_engine.h:2886
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:563
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 3263 of file res_rtp_asterisk.c.

3264 {
3265  int len = size;
3266  void *temp = buf;
3267  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
3268  struct ast_rtp_instance *transport = rtp->bundled ? rtp->bundled : instance;
3269  struct ast_rtp *transport_rtp = ast_rtp_instance_get_data(transport);
3270  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(transport, rtcp);
3271  int res;
3272 
3273  *via_ice = 0;
3274 
3275  if (use_srtp && res_srtp && srtp && res_srtp->protect(srtp, &temp, &len, rtcp) < 0) {
3276  return -1;
3277  }
3278 
3279 #ifdef HAVE_PJPROJECT
3280  if (transport_rtp->ice) {
3282  pj_status_t status;
3283  struct ice_wrap *ice;
3284 
3285  /* If RTCP is sharing the same socket then use the same component */
3286  if (rtcp && rtp->rtcp->s == rtp->s) {
3287  component = AST_RTP_ICE_COMPONENT_RTP;
3288  }
3289 
3290  pj_thread_register_check();
3291 
3292  /* Release the instance lock to avoid deadlock with PJPROJECT group lock */
3293  ice = transport_rtp->ice;
3294  ao2_ref(ice, +1);
3295  if (instance == transport) {
3296  ao2_unlock(instance);
3297  }
3298  status = pj_ice_sess_send_data(ice->real_ice, component, temp, len);
3299  ao2_ref(ice, -1);
3300  if (instance == transport) {
3301  ao2_lock(instance);
3302  }
3303  if (status == PJ_SUCCESS) {
3304  *via_ice = 1;
3305  return len;
3306  }
3307  }
3308 #endif
3309 
3310  res = ast_sendto(rtcp ? transport_rtp->rtcp->s : transport_rtp->s, temp, len, flags, sa);
3311  if (res > 0) {
3312  ast_rtp_instance_set_last_tx(instance, time(NULL));
3313  }
3314 
3315  return res;
3316 }
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:177
ast_rtp_ice_component_type
ICE component types.
Definition: rtp_engine.h:462
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:2755
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:3756
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 9880 of file res_rtp_asterisk.c.

◆ AST_MODULE_SELF_SYM()

struct ast_module* AST_MODULE_SELF_SYM ( void  )

Definition at line 9880 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 3339 of file res_rtp_asterisk.c.

3340 {
3341  unsigned int interval;
3342  /*! \todo XXX Do a more reasonable calculation on this one
3343  * Look in RFC 3550 Section A.7 for an example*/
3344  interval = rtcpinterval;
3345  return interval;
3346 }
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 4607 of file res_rtp_asterisk.c.

4609 {
4610  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4611  struct ast_rtp_rtcp_report_block *report_block = NULL;
4612  RAII_VAR(struct ast_json *, message_blob, NULL, ast_json_unref);
4613 
4614  if (!rtp || !rtp->rtcp) {
4615  return 0;
4616  }
4617 
4618  if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
4619  return 0;
4620  }
4621 
4622  if (!rtcp_report) {
4623  return -1;
4624  }
4625 
4626  report_block = rtcp_report->report_block[0];
4627 
4628  if (sr) {
4629  rtp->rtcp->txlsr = rtcp_report->sender_information.ntp_timestamp;
4630  rtp->rtcp->sr_count++;
4631  rtp->rtcp->lastsrtxcount = rtp->txcount;
4632  } else {
4633  rtp->rtcp->rr_count++;
4634  }
4635 
4636  if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
4637  ast_verbose("* Sent RTCP %s to %s%s\n", sr ? "SR" : "RR",
4638  ast_sockaddr_stringify(&remote_address), ice ? " (via ICE)" : "");
4639  ast_verbose(" Our SSRC: %u\n", rtcp_report->ssrc);
4640  if (sr) {
4641  ast_verbose(" Sent(NTP): %u.%06u\n",
4642  (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_sec,
4643  (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_usec);
4644  ast_verbose(" Sent(RTP): %u\n", rtcp_report->sender_information.rtp_timestamp);
4645  ast_verbose(" Sent packets: %u\n", rtcp_report->sender_information.packet_count);
4646  ast_verbose(" Sent octets: %u\n", rtcp_report->sender_information.octet_count);
4647  }
4648  if (report_block) {
4649  ast_verbose(" Report block:\n");
4650  ast_verbose(" Their SSRC: %u\n", report_block->source_ssrc);
4651  ast_verbose(" Fraction lost: %d\n", report_block->lost_count.fraction);
4652  ast_verbose(" Cumulative loss: %u\n", report_block->lost_count.packets);
4653  ast_verbose(" Highest seq no: %u\n", report_block->highest_seq_no);
4654  ast_verbose(" IA jitter: %.4f\n", (double)report_block->ia_jitter / ast_rtp_get_rate(rtp->f.subclass.format));
4655  ast_verbose(" Their last SR: %u\n", report_block->lsr);
4656  ast_verbose(" DLSR: %4.4f (sec)\n\n", (double)(report_block->dlsr / 65536.0));
4657  }
4658  }
4659 
4660  message_blob = ast_json_pack("{s: s, s: s}",
4661  "to", ast_sockaddr_stringify(&remote_address),
4662  "from", rtp->rtcp->local_addr_str);
4664  rtcp_report, message_blob);
4665 
4666  return 1;
4667 }
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:591
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:3478
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:4023
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:316
unsigned int highest_seq_no
Definition: rtp_engine.h:322
unsigned short fraction
Definition: rtp_engine.h:319
struct ast_rtp_rtcp_report_block::@302 lost_count
unsigned int source_ssrc
Definition: rtp_engine.h:317
unsigned int rtp_timestamp
Definition: rtp_engine.h:337
struct ast_rtp_rtcp_report_block * report_block[0]
Definition: rtp_engine.h:344
struct timeval ntp_timestamp
Definition: rtp_engine.h:336
unsigned int octet_count
Definition: rtp_engine.h:339
unsigned int ssrc
Definition: rtp_engine.h:333
struct ast_rtp_rtcp_report::@303 sender_information
unsigned int packet_count
Definition: rtp_engine.h:338
struct ast_frame f
unsigned int txcount
#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:936

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_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_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 4727 of file res_rtp_asterisk.c.

4729 {
4730  int packet_len = 0;
4731  int res;
4732 
4733  /* Every RTCP packet needs to be sent out with a SR/RR and SDES prefixing it.
4734  * At the end of this function, rtcpheader should contain both of those packets,
4735  * and will return the length of the overall packet. This can be used to determine
4736  * where further packets can be inserted in the compound packet.
4737  */
4738  res = ast_rtcp_generate_report(instance, rtcpheader, report, sr);
4739 
4740  if (res == 0 || res == 1) {
4741  ast_debug_rtcp(1, "(%p) RTCP failed to generate %s report!\n", instance, sr ? "SR" : "RR");
4742  return 0;
4743  }
4744 
4745  packet_len += res;
4746 
4747  res = ast_rtcp_generate_sdes(instance, rtcpheader + packet_len, report);
4748 
4749  if (res == 0 || res == 1) {
4750  ast_debug_rtcp(1, "(%p) RTCP failed to generate SDES!\n", instance);
4751  return 0;
4752  }
4753 
4754  return packet_len + res;
4755 }
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:2873

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 4757 of file res_rtp_asterisk.c.

4758 {
4759  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4760  int packet_len;
4761  int blp_index = -1;
4762  int current_seqno;
4763  unsigned int fci = 0;
4764  size_t remaining_missing_seqno;
4765 
4766  if (!rtp || !rtp->rtcp) {
4767  return 0;
4768  }
4769 
4770  if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
4771  return 0;
4772  }
4773 
4774  current_seqno = rtp->expectedrxseqno;
4775  remaining_missing_seqno = AST_VECTOR_SIZE(&rtp->missing_seqno);
4776  packet_len = 12; /* The header length is 12 (version line, packet source SSRC, media source SSRC) */
4777 
4778  /* If there are no missing sequence numbers then don't bother sending a NACK needlessly */
4779  if (!remaining_missing_seqno) {
4780  return 0;
4781  }
4782 
4783  /* This iterates through the possible forward sequence numbers seeing which ones we
4784  * have no packet for, adding it to the NACK until we are out of missing packets.
4785  */
4786  while (remaining_missing_seqno) {
4787  int *missing_seqno;
4788 
4789  /* On the first entry to this loop blp_index will be -1, so this will become 0
4790  * and the sequence number will be placed into the packet as the PID.
4791  */
4792  blp_index++;
4793 
4794  missing_seqno = AST_VECTOR_GET_CMP(&rtp->missing_seqno, current_seqno,
4795  find_by_value);
4796  if (missing_seqno) {
4797  /* We hit the max blp size, reset */
4798  if (blp_index >= 17) {
4799  put_unaligned_uint32(rtcpheader + packet_len, htonl(fci));
4800  fci = 0;
4801  blp_index = 0;
4802  packet_len += 4;
4803  }
4804 
4805  if (blp_index == 0) {
4806  fci |= (current_seqno << 16);
4807  } else {
4808  fci |= (1 << (blp_index - 1));
4809  }
4810 
4811  /* Since we've used a missing sequence number, we're down one */
4812  remaining_missing_seqno--;
4813  }
4814 
4815  /* Handle cycling of the sequence number */
4816  current_seqno++;
4817  if (current_seqno == SEQNO_CYCLE_OVER) {
4818  current_seqno = 0;
4819  }
4820  }
4821 
4822  put_unaligned_uint32(rtcpheader + packet_len, htonl(fci));
4823  packet_len += 4;
4824 
4825  /* Length MUST be 2+n, where n is the number of NACKs. Same as length in words minus 1 */
4826  put_unaligned_uint32(rtcpheader, htonl((2 << 30) | (AST_RTP_RTCP_FMT_NACK << 24)
4827  | (AST_RTP_RTCP_RTPFB << 16) | ((packet_len / 4) - 1)));
4828  put_unaligned_uint32(rtcpheader + 4, htonl(rtp->ssrc));
4829  put_unaligned_uint32(rtcpheader + 8, htonl(rtp->themssrc));
4830 
4831  return packet_len;
4832 }
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:297
#define AST_RTP_RTCP_FMT_NACK
Definition: rtp_engine.h:303
int expectedrxseqno
unsigned int ssrc
struct ast_rtp::@501 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 4519 of file res_rtp_asterisk.c.

4521 {
4522  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4523  int len = 0;
4524  struct timeval now;
4525  unsigned int now_lsw;
4526  unsigned int now_msw;
4527  unsigned int lost_packets;
4528  int fraction_lost;
4529  struct timeval dlsr = { 0, };
4530  struct ast_rtp_rtcp_report_block *report_block = NULL;
4531 
4532  if (!rtp || !rtp->rtcp) {
4533  return 0;
4534  }
4535 
4536  if (ast_sockaddr_isnull(&rtp->rtcp->them)) { /* This'll stop rtcp for this rtp session */
4537  /* RTCP was stopped. */
4538  return 0;
4539  }
4540 
4541  if (!rtcp_report) {
4542  return 1;
4543  }
4544 
4545  *sr = rtp->txcount > rtp->rtcp->lastsrtxcount ? 1 : 0;
4546 
4547  /* Compute statistics */
4548  calculate_lost_packet_statistics(rtp, &lost_packets, &fraction_lost);
4549 
4550  gettimeofday(&now, NULL);
4551  rtcp_report->reception_report_count = rtp->themssrc_valid ? 1 : 0;
4552  rtcp_report->ssrc = rtp->ssrc;
4553  rtcp_report->type = *sr ? RTCP_PT_SR : RTCP_PT_RR;
4554  if (*sr) {
4555  rtcp_report->sender_information.ntp_timestamp = now;
4556  rtcp_report->sender_information.rtp_timestamp = rtp->lastts;
4557  rtcp_report->sender_information.packet_count = rtp->txcount;
4558  rtcp_report->sender_information.octet_count = rtp->txoctetcount;
4559  }
4560 
4561  if (rtp->themssrc_valid) {
4562  report_block = ast_calloc(1, sizeof(*report_block));
4563  if (!report_block) {
4564  return 1;
4565  }
4566 
4567  rtcp_report->report_block[0] = report_block;
4568  report_block->source_ssrc = rtp->themssrc;
4569  report_block->lost_count.fraction = (fraction_lost & 0xff);
4570  report_block->lost_count.packets = (lost_packets & 0xffffff);
4571  report_block->highest_seq_no = (rtp->cycles | (rtp->lastrxseqno & 0xffff));
4572  report_block->ia_jitter = (unsigned int)(rtp->rxjitter * ast_rtp_get_rate(rtp->f.subclass.format));
4573  report_block->lsr = rtp->rtcp->themrxlsr;
4574  /* If we haven't received an SR report, DLSR should be 0 */
4575  if (!ast_tvzero(rtp->rtcp->rxlsr)) {
4576  timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
4577  report_block->dlsr = (((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000;
4578  }
4579  }
4580  timeval2ntp(rtcp_report->sender_information.ntp_timestamp, &now_msw, &now_lsw);
4581  put_unaligned_uint32(rtcpheader + 4, htonl(rtcp_report->ssrc)); /* Our SSRC */
4582  len += 8;
4583  if (*sr) {
4584  put_unaligned_uint32(rtcpheader + len, htonl(now_msw)); /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970 */
4585  put_unaligned_uint32(rtcpheader + len + 4, htonl(now_lsw)); /* now, LSW */
4586  put_unaligned_uint32(rtcpheader + len + 8, htonl(rtcp_report->sender_information.rtp_timestamp));
4587  put_unaligned_uint32(rtcpheader + len + 12, htonl(rtcp_report->sender_information.packet_count));
4588  put_unaligned_uint32(rtcpheader + len + 16, htonl(rtcp_report->sender_information.octet_count));
4589  len += 20;
4590  }
4591  if (report_block) {
4592  put_unaligned_uint32(rtcpheader + len, htonl(report_block->source_ssrc)); /* Their SSRC */
4593  put_unaligned_uint32(rtcpheader + len + 4, htonl((report_block->lost_count.fraction << 24) | report_block->lost_count.packets));
4594  put_unaligned_uint32(rtcpheader + len + 8, htonl(report_block->highest_seq_no));
4595  put_unaligned_uint32(rtcpheader + len + 12, htonl(report_block->ia_jitter));
4596  put_unaligned_uint32(rtcpheader + len + 16, htonl(report_block->lsr));
4597  put_unaligned_uint32(rtcpheader + len + 20, htonl(report_block->dlsr));
4598  len += 24;
4599  }
4600 
4601  put_unaligned_uint32(rtcpheader, htonl((2 << 30) | (rtcp_report->reception_report_count << 24)
4602  | ((*sr ? RTCP_PT_SR : RTCP_PT_RR) << 16) | ((len/4)-1)));
4603 
4604  return len;
4605 }
#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)
unsigned int themrxlsr
struct timeval rxlsr
unsigned int type
Definition: rtp_engine.h:334
unsigned short reception_report_count
Definition: rtp_engine.h:332
unsigned int lastts
double rxjitter
unsigned int cycles
unsigned int txoctetcount
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:115

References ast_calloc, ast_rtp_get_rate(), 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::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_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, 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_frame::subclass, ast_rtcp::them, ast_rtcp::themrxlsr, ast_rtp::themssrc, ast_rtp::themssrc_valid, timersub(), timeval2ntp(), ast_rtp::txcount, ast_rtp::txoctetcount, and ast_rtp_rtcp_report::type.

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 4669 of file res_rtp_asterisk.c.

4671 {
4672  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4673  int len = 0;
4674  uint16_t sdes_packet_len_bytes;
4675  uint16_t sdes_packet_len_rounded;
4676 
4677  if (!rtp || !rtp->rtcp) {
4678  return 0;
4679  }
4680 
4681  if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
4682  return 0;
4683  }
4684 
4685  if (!rtcp_report) {
4686  return -1;
4687  }
4688 
4689  sdes_packet_len_bytes =
4690  4 + /* RTCP Header */
4691  4 + /* SSRC */
4692  1 + /* Type (CNAME) */
4693  1 + /* Text Length */
4694  AST_UUID_STR_LEN /* Text and NULL terminator */
4695  ;
4696 
4697  /* Round to 32 bit boundary */
4698  sdes_packet_len_rounded = (sdes_packet_len_bytes + 3) & ~0x3;
4699 
4700  put_unaligned_uint32(rtcpheader, htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | ((sdes_packet_len_rounded / 4) - 1)));
4701  put_unaligned_uint32(rtcpheader + 4, htonl(rtcp_report->ssrc));
4702  rtcpheader[8] = 0x01; /* CNAME */
4703  rtcpheader[9] = AST_UUID_STR_LEN - 1; /* Number of bytes of text */
4704  memcpy(rtcpheader + 10, rtp->cname, AST_UUID_STR_LEN);
4705  len += 10 + AST_UUID_STR_LEN;
4706 
4707  /* Padding - Note that we don't set the padded bit on the packet. From
4708  * RFC 3550 Section 6.5:
4709  *
4710  * No length octet follows the null item type octet, but additional null
4711  * octets MUST be included if needd to pad until the next 32-bit
4712  * boundary. Note that this padding is separate from that indicated by
4713  * the P bit in the RTCP header.
4714  *
4715  * These bytes will already be zeroed out during array initialization.
4716  */
4717  len += (sdes_packet_len_rounded - sdes_packet_len_bytes);
4718 
4719  return len;
4720 }
#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 6128 of file res_rtp_asterisk.c.

6130 {
6131  struct ast_rtp_instance *transport = instance;
6132  struct ast_rtp *transport_rtp = ast_rtp_instance_get_data(instance);
6133  int len = size;
6134  unsigned int *rtcpheader = (unsigned int *)(rtcpdata);
6135  unsigned int packetwords;
6136  unsigned int position;
6137  unsigned int first_word;
6138  /*! True if we have seen an acceptable SSRC to learn the remote RTCP address */
6139  unsigned int ssrc_seen;
6140  struct ast_rtp_rtcp_report_block *report_block;
6141  struct ast_frame *f = &ast_null_frame;
6142 #ifdef TEST_FRAMEWORK
6143  struct ast_rtp_engine_test *test_engine;
6144 #endif
6145 
6146  /* If this is encrypted then decrypt the payload */
6147  if ((*rtcpheader & 0xC0) && res_srtp && srtp && res_srtp->unprotect(
6148  srtp, rtcpheader, &len, 1 | (srtp_replay_protection << 1)) < 0) {
6149  return &ast_null_frame;
6150  }
6151 
6152  packetwords = len / 4;
6153 
6154  ast_debug_rtcp(1, "(%p) RTCP got report of %d bytes from %s\n",
6155  instance, len, ast_sockaddr_stringify(addr));
6156 
6157  /*
6158  * Validate the RTCP packet according to an adapted and slightly
6159  * modified RFC3550 validation algorithm.
6160  */
6161  if (packetwords < RTCP_HEADER_SSRC_LENGTH) {
6162  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: Frame size (%u words) is too short\n",
6163  instance, transport_rtp, ast_sockaddr_stringify(addr), packetwords);
6164  return &ast_null_frame;
6165  }
6166  position = 0;
6167  first_word = ntohl(rtcpheader[position]);
6168  if ((first_word & RTCP_VALID_MASK) != RTCP_VALID_VALUE) {
6169  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: Failed first packet validity check\n",
6170  instance, transport_rtp, ast_sockaddr_stringify(addr));
6171  return &ast_null_frame;
6172  }
6173  do {
6174  position += ((first_word >> RTCP_LENGTH_SHIFT) & RTCP_LENGTH_MASK) + 1;
6175  if (packetwords <= position) {
6176  break;
6177  }
6178  first_word = ntohl(rtcpheader[position]);
6179  } while ((first_word & RTCP_VERSION_MASK_SHIFTED) == RTCP_VERSION_SHIFTED);
6180  if (position != packetwords) {
6181  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: Failed packet version or length check\n",
6182  instance, transport_rtp, ast_sockaddr_stringify(addr));
6183  return &ast_null_frame;
6184  }
6185 
6186  /*
6187  * Note: RFC3605 points out that true NAT (vs NAPT) can cause RTCP
6188  * to have a different IP address and port than RTP. Otherwise, when
6189  * strictrtp is enabled we could reject RTCP packets not coming from
6190  * the learned RTP IP address if it is available.
6191  */
6192 
6193  /*
6194  * strictrtp safety needs SSRC to match before we use the
6195  * sender's address for symmetrical RTP to send our RTCP
6196  * reports.
6197  *
6198  * If strictrtp is not enabled then claim to have already seen
6199  * a matching SSRC so we'll accept this packet's address for
6200  * symmetrical RTP.
6201  */
6202  ssrc_seen = transport_rtp->strict_rtp_state == STRICT_RTP_OPEN;
6203 
6204  position = 0;
6205  while (position < packetwords) {
6206  unsigned int i;
6207  unsigned int pt;
6208  unsigned int rc;
6209  unsigned int ssrc;
6210  /*! True if the ssrc value we have is valid and not garbage because it doesn't exist. */
6211  unsigned int ssrc_valid;
6212  unsigned int length;
6213  unsigned int min_length;
6214  /*! Always use packet source SSRC to find the rtp instance unless explicitly told not to. */
6215  unsigned int use_packet_source = 1;
6216 
6217  struct ast_json *message_blob;
6218  RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report, NULL, ao2_cleanup);
6219  struct ast_rtp_instance *child;
6220  struct ast_rtp *rtp;
6221  struct ast_rtp_rtcp_feedback *feedback;
6222 
6223  i = position;
6224  first_word = ntohl(rtcpheader[i]);
6225  pt = (first_word >> RTCP_PAYLOAD_TYPE_SHIFT) & RTCP_PAYLOAD_TYPE_MASK;
6226  rc = (first_word >> RTCP_REPORT_COUNT_SHIFT) & RTCP_REPORT_COUNT_MASK;
6227  /* RFC3550 says 'length' is the number of words in the packet - 1 */
6228  length = ((first_word >> RTCP_LENGTH_SHIFT) & RTCP_LENGTH_MASK) + 1;
6229 
6230  /* Check expected RTCP packet record length */
6231  min_length = RTCP_HEADER_SSRC_LENGTH;
6232  switch (pt) {
6233  case RTCP_PT_SR:
6234  min_length += RTCP_SR_BLOCK_WORD_LENGTH;
6235  /* fall through */
6236  case RTCP_PT_RR:
6237  min_length += (rc * RTCP_RR_BLOCK_WORD_LENGTH);
6238  use_packet_source = 0;
6239  break;
6240  case RTCP_PT_FUR:
6241  break;
6242  case AST_RTP_RTCP_RTPFB:
6243  switch (rc) {
6244  case AST_RTP_RTCP_FMT_NACK:
6245  min_length += RTCP_FB_NACK_BLOCK_WORD_LENGTH;
6246  break;
6247  default:
6248  break;
6249  }
6250  use_packet_source = 0;
6251  break;
6252  case RTCP_PT_PSFB:
6253  switch (rc) {
6254  case AST_RTP_RTCP_FMT_REMB:
6255  min_length += RTCP_FB_REMB_BLOCK_WORD_LENGTH;
6256  break;
6257  default:
6258  break;
6259  }
6260  break;
6261  case RTCP_PT_SDES:
6262  case RTCP_PT_BYE:
6263  /*
6264  * There may not be a SSRC/CSRC present. The packet is
6265  * useless but still valid if it isn't present.
6266  *
6267  * We don't know what min_length should be so disable the check
6268  */
6269  min_length = length;
6270  break;
6271  default:
6272  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: %u(%s) skipping record\n",
6273  instance, transport_rtp, ast_sockaddr_stringify(addr), pt, rtcp_payload_type2str(pt));
6274  if (rtcp_debug_test_addr(addr)) {
6275  ast_verbose("\n");
6276  ast_verbose("RTCP from %s: %u(%s) skipping record\n",
6278  }
6279  position += length;
6280  continue;
6281  }
6282  if (length < min_length) {
6283  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: %u(%s) length field less than expected minimum. Min:%u Got:%u\n",
6284  instance, transport_rtp, ast_sockaddr_stringify(addr), pt, rtcp_payload_type2str(pt),
6285  min_length - 1, length - 1);
6286  return &ast_null_frame;
6287  }
6288 
6289  /* Get the RTCP record SSRC if defined for the record */
6290  ssrc_valid = 1;
6291  switch (pt) {
6292  case RTCP_PT_SR:
6293  case RTCP_PT_RR:
6294  rtcp_report = ast_rtp_rtcp_report_alloc(rc);
6295  if (!rtcp_report) {
6296  return &ast_null_frame;
6297  }
6298  rtcp_report->reception_report_count = rc;
6299 
6300  ssrc = ntohl(rtcpheader[i + 2]);
6301  rtcp_report->ssrc = ssrc;
6302  break;
6303  case RTCP_PT_FUR:
6304  case RTCP_PT_PSFB:
6305  ssrc = ntohl(rtcpheader[i + 1]);
6306  break;
6307  case AST_RTP_RTCP_RTPFB:
6308  ssrc = ntohl(rtcpheader[i + 2]);
6309  break;
6310  case RTCP_PT_SDES:
6311  case RTCP_PT_BYE:
6312  default:
6313  ssrc = 0;
6314  ssrc_valid = 0;
6315  break;
6316  }
6317 
6318  if (rtcp_debug_test_addr(addr)) {
6319  const char *subtype = rtcp_payload_subtype2str(pt, rc);
6320 
6321  ast_verbose("\n");
6322  ast_verbose("RTCP from %s\n", ast_sockaddr_stringify(addr));
6323  ast_verbose("PT: %u (%s)\n", pt, rtcp_payload_type2str(pt));
6324  if (subtype) {
6325  ast_verbose("Packet Subtype: %u (%s)\n", rc, subtype);
6326  } else {
6327  ast_verbose("Reception reports: %u\n", rc);
6328  }
6329  ast_verbose("SSRC of sender: %u\n", ssrc);
6330  }
6331 
6332  /* Determine the appropriate instance for this */
6333  if (ssrc_valid) {
6334  /*
6335  * Depending on the payload type, either the packet source or media source
6336  * SSRC is used.
6337  */
6338  if (use_packet_source) {
6339  child = rtp_find_instance_by_packet_source_ssrc(transport, transport_rtp, ssrc);
6340  } else {
6341  child = rtp_find_instance_by_media_source_ssrc(transport, transport_rtp, ssrc);
6342  }
6343  if (child && child != transport) {
6344  /*
6345  * It is safe to hold the child lock while holding the parent lock.
6346  * We guarantee that the locking order is always parent->child or
6347  * that the child lock is not held when acquiring the parent lock.
6348  */
6349  ao2_lock(child);
6350  instance = child;
6351  rtp = ast_rtp_instance_get_data(instance);
6352  } else {
6353  /* The child is the parent! We don't need to unlock it. */
6354  child = NULL;
6355  rtp = transport_rtp;
6356  }
6357  } else {
6358  child = NULL;
6359  rtp = transport_rtp;
6360  }
6361 
6362  if (ssrc_valid && rtp->themssrc_valid) {
6363  /*
6364  * If the SSRC is 1, we still need to handle RTCP since this could be a
6365  * special case. For example, if we have a unidirectional video stream, the
6366  * SSRC may be set to 1 by the browser (in the case of chromium), and requests
6367  * will still need to be processed so that video can flow as expected. This
6368  * should only be done for PLI and FUR, since there is not a way to get the
6369  * appropriate rtp instance when the SSRC is 1.
6370  */
6371  int exception = (ssrc == 1 && !((pt == RTCP_PT_PSFB && rc == AST_RTP_RTCP_FMT_PLI) || pt == RTCP_PT_FUR));
6372  if ((ssrc != rtp->themssrc && use_packet_source && ssrc != 1)
6373  || exception) {
6374  /*
6375  * Skip over this RTCP record as it does not contain the
6376  * correct SSRC. We should not act upon RTCP records
6377  * for a different stream.
6378  */
6379  position += length;
6380  ast_debug_rtcp(1, "(%p) RTCP %p -- from %s: Skipping record, received SSRC '%u' != expected '%u'\n",
6381  instance, rtp, ast_sockaddr_stringify(addr), ssrc, rtp->themssrc);
6382  if (child) {
6383  ao2_unlock(child);
6384  }
6385  continue;
6386  }
6387  ssrc_seen = 1;
6388  }
6389 
6390  if (ssrc_seen && ast_rtp_instance_get_prop(instance, AST_RTP_PROPERTY_NAT)) {
6391  /* Send to whoever sent to us */
6392  if (ast_sockaddr_cmp(&rtp->rtcp->them, addr)) {
6393  ast_sockaddr_copy(&rtp->rtcp->them, addr);
6395  ast_debug(0, "(%p) RTCP NAT: Got RTCP from other end. Now sending to address %s\n",
6396  instance, ast_sockaddr_stringify(addr));
6397  }
6398  }
6399  }
6400 
6401  i += RTCP_HEADER_SSRC_LENGTH; /* Advance past header and ssrc */
6402  switch (pt) {
6403  case RTCP_PT_SR:
6404  gettimeofday(&rtp->rtcp->rxlsr, NULL);
6405  rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16);
6406  rtp->rtcp->spc = ntohl(rtcpheader[i + 3]);
6407  rtp->rtcp->soc = ntohl(rtcpheader[i + 4]);
6408 
6409  rtcp_report->type = RTCP_PT_SR;
6410  rtcp_report->sender_information.packet_count = rtp->rtcp->spc;
6411  rtcp_report->sender_information.octet_count = rtp->rtcp->soc;
6412  ntp2timeval((unsigned int)ntohl(rtcpheader[i]),
6413  (unsigned int)ntohl(rtcpheader[i + 1]),
6414  &rtcp_report->sender_information.ntp_timestamp);
6415  rtcp_report->sender_information.rtp_timestamp = ntohl(rtcpheader[i + 2]);
6416  if (rtcp_debug_test_addr(addr)) {
6417  ast_verbose("NTP timestamp: %u.%06u\n",
6418  (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_sec,
6419  (unsigned int)rtcp_report->sender_information.ntp_timestamp.tv_usec);
6420  ast_verbose("RTP timestamp: %u\n", rtcp_report->sender_information.rtp_timestamp);
6421  ast_verbose("SPC: %u\tSOC: %u\n",
6422  rtcp_report->sender_information.packet_count,
6423  rtcp_report->sender_information.octet_count);
6424  }
6426  /* Intentional fall through */
6427  case RTCP_PT_RR:
6428  if (rtcp_report->type != RTCP_PT_SR) {
6429  rtcp_report->type = RTCP_PT_RR;
6430  }
6431 
6432  if (rc > 0) {
6433  /* Don't handle multiple reception reports (rc > 1) yet */
6434  report_block = ast_calloc(1, sizeof(*report_block));
6435  if (!report_block) {
6436  if (child) {
6437  ao2_unlock(child);
6438  }
6439  return &ast_null_frame;
6440  }
6441  rtcp_report->report_block[0] = report_block;
6442  report_block->source_ssrc = ntohl(rtcpheader[i]);
6443  report_block->lost_count.packets = ntohl(rtcpheader[i + 1]) & 0x00ffffff;
6444  report_block->lost_count.fraction = ((ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24);
6445  report_block->highest_seq_no = ntohl(rtcpheader[i + 2]);
6446  report_block->ia_jitter = ntohl(rtcpheader[i + 3]);
6447  report_block->lsr = ntohl(rtcpheader[i + 4]);
6448  report_block->dlsr = ntohl(rtcpheader[i + 5]);
6449  if (report_block->lsr
6450  && update_rtt_stats(rtp, report_block->lsr, report_block->dlsr)
6451  && rtcp_debug_test_addr(addr)) {
6452  struct timeval now;
6453  unsigned int lsr_now, lsw, msw;
6454  gettimeofday(&now, NULL);
6455  timeval2ntp(now, &msw, &lsw);
6456  lsr_now = (((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16));
6457  ast_verbose("Internal RTCP NTP clock skew detected: "
6458  "lsr=%u, now=%u, dlsr=%u (%u:%03ums), "
6459  "diff=%u\n",
6460  report_block->lsr, lsr_now, report_block->dlsr, report_block->dlsr / 65536,
6461  (report_block->dlsr % 65536) * 1000 / 65536,
6462  report_block->dlsr - (lsr_now - report_block->lsr));
6463  }
6464  update_jitter_stats(rtp, report_block->ia_jitter);
6465  update_lost_stats(rtp, report_block->lost_count.packets);
6466 
6467  if (rtcp_debug_test_addr(addr)) {
6468  ast_verbose(" Fraction lost: %d\n", report_block->lost_count.fraction);
6469  ast_verbose(" Packets lost so far: %u\n", report_block->lost_count.packets);
6470  ast_verbose(" Highest sequence number: %u\n", report_block->highest_seq_no & 0x0000ffff);
6471  ast_verbose(" Sequence number cycles: %u\n", report_block->highest_seq_no >> 16);
6472  ast_verbose(" Interarrival jitter: %u\n", report_block->ia_jitter);
6473  ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long)(report_block->lsr) >> 16,((unsigned long)(report_block->lsr) << 16) * 4096);
6474  ast_verbose(" DLSR: %4.4f (sec)\n",(double)report_block->dlsr / 65536.0);
6475  ast_verbose(" RTT: %4.4f(sec)\n", rtp->rtcp->rtt);
6476  }
6477  }
6478  /* If and when we handle more than one report block, this should occur outside
6479  * this loop.
6480  */
6481 
6482  message_blob = ast_json_pack("{s: s, s: s, s: f}",
6483  "from", ast_sockaddr_stringify(addr),
6484  "to", transport_rtp->rtcp->local_addr_str,
6485  "rtt", rtp->rtcp->rtt);
6487  rtcp_report,
6488  message_blob);
6489  ast_json_unref(message_blob);
6490 
6491  /* Return an AST_FRAME_RTCP frame with the ast_rtp_rtcp_report
6492  * object as a its data */
6493  transport_rtp->f.frametype = AST_FRAME_RTCP;
6494  transport_rtp->f.subclass.integer = pt;
6495  transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
6496  memcpy(transport_rtp->f.data.ptr, rtcp_report, sizeof(struct ast_rtp_rtcp_report));
6497  transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_report);
6498  if (rc > 0) {
6499  /* There's always a single report block stored, here */
6500  struct ast_rtp_rtcp_report *rtcp_report2;
6501  report_block = transport_rtp->f.data.ptr + transport_rtp->f.datalen + sizeof(struct ast_rtp_rtcp_report_block *);
6502  memcpy(report_block, rtcp_report->report_block[0], sizeof(struct ast_rtp_rtcp_report_block));
6503  rtcp_report2 = (struct ast_rtp_rtcp_report *)transport_rtp->f.data.ptr;
6504  rtcp_report2->report_block[0] = report_block;
6505  transport_rtp->f.datalen += sizeof(struct ast_rtp_rtcp_report_block);
6506  }
6507  transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
6508  transport_rtp->f.samples = 0;
6509  transport_rtp->f.mallocd = 0;
6510  transport_rtp->f.delivery.tv_sec = 0;
6511  transport_rtp->f.delivery.tv_usec = 0;
6512  transport_rtp->f.src = "RTP";
6513  transport_rtp->f.stream_num = rtp->stream_num;
6514  f = &transport_rtp->f;
6515  break;
6516  case AST_RTP_RTCP_RTPFB:
6517  switch (rc) {
6518  case AST_RTP_RTCP_FMT_NACK:
6519  /* If retransmissions are not enabled ignore this message */
6520  if (!rtp->send_buffer) {
6521  break;
6522  }
6523 
6524  if (rtcp_debug_test_addr(addr)) {
6525  ast_verbose("Received generic RTCP NACK message\n");
6526  }
6527 
6528  ast_rtp_rtcp_handle_nack(instance, rtcpheader, position, length);
6529  break;
6530  default:
6531  break;
6532  }
6533  break;
6534  case RTCP_PT_FUR:
6535  /* Handle RTCP FUR as FIR by setting the format to 4 */
6536  rc = AST_RTP_RTCP_FMT_FIR;
6537  case RTCP_PT_PSFB:
6538  switch (rc) {
6539  case AST_RTP_RTCP_FMT_PLI:
6540  case AST_RTP_RTCP_FMT_FIR:
6541  if (rtcp_debug_test_addr(addr)) {
6542  ast_verbose("Received an RTCP Fast Update Request\n");
6543  }
6544  transport_rtp->f.frametype = AST_FRAME_CONTROL;
6545  transport_rtp->f.subclass.integer = AST_CONTROL_VIDUPDATE;
6546  transport_rtp->f.datalen = 0;
6547  transport_rtp->f.samples = 0;
6548  transport_rtp->f.mallocd = 0;
6549  transport_rtp->f.src = "RTP";
6550  f = &transport_rtp->f;
6551  break;
6552  case AST_RTP_RTCP_FMT_REMB:
6553  /* If REMB support is not enabled ignore this message */
6555  break;
6556  }
6557 
6558  if (rtcp_debug_test_addr(addr)) {
6559  ast_verbose("Received REMB report\n");
6560  }
6561  transport_rtp->f.frametype = AST_FRAME_RTCP;
6562  transport_rtp->f.subclass.integer = pt;
6563  transport_rtp->f.stream_num = rtp->stream_num;
6564  transport_rtp->f.data.ptr = rtp->rtcp->frame_buf + AST_FRIENDLY_OFFSET;
6565  feedback = transport_rtp->f.data.ptr;
6566  feedback->fmt = rc;
6567 
6568  /* We don't actually care about the SSRC information in the feedback message */
6569  first_word = ntohl(rtcpheader[i + 2]);
6570  feedback->remb.br_exp = (first_word >> 18) & ((1 << 6) - 1);
6571  feedback->remb.br_mantissa = first_word & ((1 << 18) - 1);
6572 
6573  transport_rtp->f.datalen = sizeof(struct ast_rtp_rtcp_feedback);
6574  transport_rtp->f.offset = AST_FRIENDLY_OFFSET;
6575  transport_rtp->f.samples = 0;
6576  transport_rtp->f.mallocd = 0;
6577  transport_rtp->f.delivery.tv_sec = 0;
6578  transport_rtp->f.delivery.tv_usec = 0;
6579  transport_rtp->f.src = "RTP";
6580  f = &transport_rtp->f;
6581  break;
6582  default:
6583  break;
6584  }
6585  break;
6586  case RTCP_PT_SDES:
6587  if (rtcp_debug_test_addr(addr)) {
6588  ast_verbose("Received an SDES from %s\n",
6589  ast_sockaddr_stringify(addr));
6590  }
6591 #ifdef TEST_FRAMEWORK
6592  if ((test_engine = ast_rtp_instance_get_test(instance))) {
6593  test_engine->sdes_received = 1;
6594  }
6595 #endif
6596  break;
6597  case RTCP_PT_BYE:
6598  if (rtcp_debug_test_addr(addr)) {
6599  ast_verbose("Received a BYE from %s\n",
6600  ast_sockaddr_stringify(addr));
6601  }
6602  break;
6603  default:
6604  break;
6605  }
6606  position += length;
6607  rtp->rtcp->rtcp_info = 1;
6608 
6609  if (child) {
6610  ao2_unlock(child);
6611  }
6612  }
6613 
6614  return f;
6615 }
#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_type2str(unsigned int pt)
#define RTCP_SR_BLOCK_WORD_LENGTH
#define RTCP_REPORT_COUNT_SHIFT
#define RTCP_PT_FUR
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_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)
#define RTCP_VERSION_SHIFTED
#define RTCP_REPORT_COUNT_MASK
#define RTCP_PAYLOAD_TYPE_MASK
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_MASK_SHIFTED
static void update_lost_stats(struct ast_rtp *rtp, unsigned int lost_packets)
#define RTCP_LENGTH_MASK
static const char * rtcp_payload_subtype2str(unsigned int pt, unsigned int subtype)
#define AST_RTP_RTCP_FMT_FIR
Definition: rtp_engine.h:307
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:3467
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:716
#define ast_debug_rtp_packet_is_allowed
Definition: rtp_engine.h:2864
#define AST_RTP_RTCP_FMT_REMB
Definition: rtp_engine.h:309
@ AST_RTP_PROPERTY_NAT
Definition: rtp_engine.h:115
@ AST_RTP_PROPERTY_REMB
Definition: rtp_engine.h:131
#define AST_RTP_RTCP_FMT_PLI
Definition: rtp_engine.h:305
Data structure associated with a single frame of data.
union ast_frame::@254 data
struct timeval delivery
enum ast_frame_type frametype
const char * src
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:358
unsigned int fmt
Definition: rtp_engine.h:359
struct ast_rtp_rtcp_feedback_remb remb
Definition: rtp_engine.h:361
An object that represents data sent during a SR/RR RTCP report.
Definition: rtp_engine.h:331
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_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_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_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, 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(), 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 6618 of file res_rtp_asterisk.c.

6619 {
6620  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
6621  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance, 1);
6622  struct ast_sockaddr addr;
6623  unsigned char rtcpdata[8192 + AST_FRIENDLY_OFFSET];
6624  unsigned char *read_area = rtcpdata + AST_FRIENDLY_OFFSET;
6625  size_t read_area_size = sizeof(rtcpdata) - AST_FRIENDLY_OFFSET;
6626  int res;
6627 
6628  /* Read in RTCP data from the socket */
6629  if ((res = rtcp_recvfrom(instance, read_area, read_area_size,
6630  0, &addr)) < 0) {
6631  if (res == RTP_DTLS_ESTABLISHED) {
6632  rtp->f.frametype = AST_FRAME_CONTROL;
6634  return &rtp->f;
6635  }
6636 
6637  ast_assert(errno != EBADF);
6638  if (errno != EAGAIN) {
6639  ast_log(LOG_WARNING, "RTCP Read error: %s. Hanging up.\n",
6640  (errno) ? strerror(errno) : "Unspecified");
6641  return NULL;
6642  }
6643  return &ast_null_frame;
6644  }
6645 
6646  /* If this was handled by the ICE session don't do anything further */
6647  if (!res) {
6648  return &ast_null_frame;
6649  }
6650 
6651  if (!*read_area) {
6652  struct sockaddr_in addr_tmp;
6653  struct ast_sockaddr addr_v4;
6654 
6655  if (ast_sockaddr_is_ipv4(&addr)) {
6656  ast_sockaddr_to_sin(&addr, &addr_tmp);
6657  } else if (ast_sockaddr_ipv4_mapped(&addr, &addr_v4)) {
6658  ast_debug_stun(2, "(%p) STUN using IPv6 mapped address %s\n",
6659  instance, ast_sockaddr_stringify(&addr));
6660  ast_sockaddr_to_sin(&addr_v4, &addr_tmp);
6661  } else {
6662  ast_debug_stun(2, "(%p) STUN cannot do for non IPv4 address %s\n",
6663  instance, ast_sockaddr_stringify(&addr));
6664  return &ast_null_frame;
6665  }
6666  if ((ast_stun_handle_packet(rtp->rtcp->s, &addr_tmp, read_area, res, NULL, NULL) == AST_STUN_ACCEPT)) {
6667  ast_sockaddr_from_sin(&addr, &addr_tmp);
6668  ast_sockaddr_copy(&rtp->rtcp->them, &addr);
6669  }
6670  return &ast_null_frame;
6671  }
6672 
6673  return ast_rtcp_interpret(instance, srtp, read_area, res, &addr);
6674 }
@ 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 int rtcp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
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)
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:734

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 4842 of file res_rtp_asterisk.c.

4843 {
4844  struct ast_rtp_instance *instance = (struct ast_rtp_instance *) data;
4845  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4846  int res;
4847  int sr = 0;
4848  int packet_len = 0;
4849  int ice;
4850  struct ast_sockaddr remote_address = { { 0, } };
4851  unsigned char *rtcpheader;
4852  unsigned char bdata[AST_UUID_STR_LEN + 128] = ""; /* More than enough */
4853  RAII_VAR(struct ast_rtp_rtcp_report *, rtcp_report,
4855  ao2_cleanup);
4856 
4857  if (!rtp || !rtp->rtcp || rtp->rtcp->schedid == -1) {
4858  ao2_ref(instance, -1);
4859  return 0;
4860  }
4861 
4862  ao2_lock(instance);
4863  rtcpheader = bdata;
4864 
4865  res = ast_rtcp_generate_compound_prefix(instance, rtcpheader, rtcp_report, &sr);
4866 
4867  if (res == 0 || res == 1) {
4868  goto cleanup;
4869  }
4870 
4871  packet_len += res;
4872 
4873  if (rtp->bundled) {
4874  ast_rtp_instance_get_remote_address(instance, &remote_address);
4875  } else {
4876  ast_sockaddr_copy(&remote_address, &rtp->rtcp->them);
4877  }
4878 
4879  res = rtcp_sendto(instance, (unsigned int *)rtcpheader, packet_len, 0, &remote_address, &ice);
4880  if (res < 0) {
4881  ast_log(LOG_ERROR, "RTCP %s transmission error to %s, rtcp halted %s\n",
4882  sr ? "SR" : "RR",
4884  strerror(errno));
4885  res = 0;
4886  } else {
4887  ast_rtcp_calculate_sr_rr_statistics(instance, rtcp_report, remote_address, ice, sr);
4888  }
4889 
4890 cleanup:
4891  ao2_unlock(instance);
4892 
4893  if (!res) {
4894  /*
4895  * Not being rescheduled.
4896  */
4897  rtp->rtcp->schedid = -1;
4898  ao2_ref(instance, -1);
4899  }
4900 
4901  return res;
4902 }
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, 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 8966 of file res_rtp_asterisk.c.

8967 {
8968  struct ast_rtp *child_rtp = ast_rtp_instance_get_data(child);
8969  struct ast_rtp *parent_rtp;
8970  struct rtp_ssrc_mapping mapping;
8971  struct ast_sockaddr them = { { 0, } };
8972 
8973  if (child_rtp->bundled == parent) {
8974  return 0;
8975  }
8976 
8977  /* If this instance was already bundled then remove the SSRC mapping */
8978  if (child_rtp->bundled) {
8979  struct ast_rtp *bundled_rtp;
8980 
8981  ao2_unlock(child);
8982 
8983  /* The child lock can't be held while accessing the parent */
8984  ao2_lock(child_rtp->bundled);
8985  bundled_rtp = ast_rtp_instance_get_data(child_rtp->bundled);
8987  ao2_unlock(child_rtp->bundled);
8988 
8989  ao2_lock(child);
8990  ao2_ref(child_rtp->bundled, -1);
8991  child_rtp->bundled = NULL;
8992  }
8993 
8994  if (!parent) {
8995  /* We transitioned away from bundle so we need our own transport resources once again */
8996  rtp_allocate_transport(child, child_rtp);
8997  return 0;
8998  }
8999 
9000  parent_rtp = ast_rtp_instance_get_data(parent);
9001 
9002  /* We no longer need any transport related resources as we will use our parent RTP instance instead */
9003  rtp_deallocate_transport(child, child_rtp);
9004 
9005  /* Children maintain a reference to the parent to guarantee that the transport doesn't go away on them */
9006  child_rtp->bundled = ao2_bump(parent);
9007 
9008  mapping.ssrc = child_rtp->themssrc;
9009  mapping.ssrc_valid = child_rtp->themssrc_valid;
9010  mapping.instance = child;
9011 
9012  ao2_unlock(child);
9013 
9014  ao2_lock(parent);
9015 
9016  AST_VECTOR_APPEND(&parent_rtp->ssrc_mapping, mapping);
9017 
9018 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
9019  /* If DTLS-SRTP is already in use then add the local SSRC to it, otherwise it will get added once DTLS
9020  * negotiation has been completed.
9021  */
9022  if (parent_rtp->dtls.connection == AST_RTP_DTLS_CONNECTION_EXISTING) {
9023  dtls_srtp_add_local_ssrc(parent_rtp, parent, 0, child_rtp->ssrc, 0);
9024  }
9025 #endif
9026 
9027  /* Bundle requires that RTCP-MUX be in use so only the main remote address needs to match */
9028  ast_rtp_instance_get_remote_address(parent, &them);
9029 
9030  ao2_unlock(parent);
9031 
9032  ao2_lock(child);
9033 
9035 
9036  return 0;
9037 }
#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 4388 of file res_rtp_asterisk.c.

4389 {
4390  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4391  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance, 0);
4392  struct ast_srtp *rtcp_srtp = ast_rtp_instance_get_srtp(instance, 1);
4393  unsigned int ssrc = ast_random();
4394 
4395  if (rtp->lastts) {
4396  /* We simply set this bit so that the next packet sent will have the marker bit turned on */
4398  }
4399 
4400  ast_debug_rtp(3, "(%p) RTP changing ssrc from %u to %u due to a source change\n",
4401  instance, rtp->ssrc, ssrc);
4402 
4403  if (srtp) {
4404  ast_debug_rtp(3, "(%p) RTP changing ssrc for SRTP from %u to %u\n",
4405  instance, rtp->ssrc, ssrc);
4406  res_srtp->change_source(srtp, rtp->ssrc, ssrc);
4407  if (rtcp_srtp != srtp) {
4408  res_srtp->change_source(rtcp_srtp, rtp->ssrc, ssrc);
4409  }
4410  }
4411 
4412  rtp->ssrc = ssrc;
4413 
4414  /* Since the source is changing, we don't know what sequence number to expect next */
4415  rtp->expectedrxseqno = -1;
4416 
4417  return;
4418 }
#define FLAG_NEED_MARKER_BIT
#define ast_debug_rtp(sublevel,...)
Log debug level RTP information.
Definition: rtp_engine.h:2860
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: main/utils.c:2210
#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 4073 of file res_rtp_asterisk.c.

4074 {
4075  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4076 
4077  if (rtp->bundled) {
4078  struct ast_rtp *bundled_rtp;
4079 
4080  /* We can't hold our instance lock while removing ourselves from the parent */
4081  ao2_unlock(instance);
4082 
4083  ao2_lock(rtp->bundled);
4084  bundled_rtp = ast_rtp_instance_get_data(rtp->bundled);
4086  ao2_unlock(rtp->bundled);
4087 
4088  ao2_lock(instance);
4089  ao2_ref(rtp->bundled, -1);
4090  }
4091 
4092  rtp_deallocate_transport(instance, rtp);
4093 
4094  /* Destroy the smoother that was smoothing out audio if present */
4095  if (rtp->smoother) {
4097  }
4098 
4099  /* Destroy RTCP if it was being used */
4100  if (rtp->rtcp) {
4101  /*
4102  * It is not possible for there to be an active RTCP scheduler
4103  * entry at this point since it holds a reference to the
4104  * RTP instance while it's active.
4105  */
4106  ast_free(rtp->rtcp->local_addr_str);
4107  ast_free(rtp->rtcp);
4108  }
4109 
4110  /* Destroy RED if it was being used */
4111  if (rtp->red) {
4112  ao2_unlock(instance);
4113  AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
4114  ao2_lock(instance);
4115  ast_free(rtp->red);
4116  rtp->red = NULL;
4117  }
4118 
4119  /* Destroy the send buffer if it was being used */
4120  if (rtp->send_buffer) {
4122  }
4123 
4124  /* Destroy the recv buffer if it was being used */
4125  if (rtp->recv_buffer) {
4127  }
4128 
4130 
4131  ao2_cleanup(rtp->lasttxformat);
4132  ao2_cleanup(rtp->lastrxformat);
4133  ao2_cleanup(rtp->f.subclass.format);
4136 
4137  /* Finally destroy ourselves */
4138  ast_free(rtp);
4139 
4140  return 0;
4141 }
#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 rtp_red * red
struct ast_format * lastrxformat
struct rtp_transport_wide_cc_statistics::@500 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, 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 4159 of file res_rtp_asterisk.c.

4160 {
4161  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4162  struct ast_sockaddr remote_address = { {0,} };
4163  int hdrlen = 12, res = 0, i = 0, payload = 101;
4164  char data[256];
4165  unsigned int *rtpheader = (unsigned int*)data;
4166 
4167  ast_rtp_instance_get_remote_address(instance, &remote_address);
4168 
4169  /* If we have no remote address information bail out now */
4170  if (ast_sockaddr_isnull(&remote_address)) {
4171  return -1;
4172  }
4173 
4174  /* Convert given digit into what we want to transmit */
4175  if ((digit <= '9') && (digit >= '0')) {
4176  digit -= '0';
4177  } else if (digit == '*') {
4178  digit = 10;
4179  } else if (digit == '#') {
4180  digit = 11;
4181  } else if ((digit >= 'A') && (digit <= 'D')) {
4182  digit = digit - 'A' + 12;
4183  } else if ((digit >= 'a') && (digit <= 'd')) {
4184  digit = digit - 'a' + 12;
4185  } else {
4186  ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
4187  return -1;
4188  }
4189 
4190  /* Grab the payload that they expect the RFC2833 packet to be received in */
4192 
4193  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
4194  rtp->send_duration = 160;
4195  rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
4196  rtp->lastdigitts = rtp->lastts + rtp->send_duration;
4197 
4198  /* Create the actual packet that we will be sending */
4199  rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
4200  rtpheader[1] = htonl(rtp->lastdigitts);
4201  rtpheader[2] = htonl(rtp->ssrc);
4202 
4203  /* Actually send the packet */
4204  for (i = 0; i < 2; i++) {
4205  int ice;
4206 
4207  rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
4208  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4209  if (res < 0) {
4210  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4211  ast_sockaddr_stringify(&remote_address),
4212  strerror(errno));
4213  }
4214  if (rtp_debug_test_addr(&remote_address)) {
4215  ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4216  ast_sockaddr_stringify(&remote_address),
4217  ice ? " (via ICE)" : "",
4218  payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4219  }
4220  rtp->seqno++;
4221  rtp->send_duration += 160;
4222  rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
4223  }
4224 
4225  /* Record that we are in the process of sending a digit and information needed to continue doing so */
4226  rtp->sending_digit = 1;
4227  rtp->send_digit = digit;
4228  rtp->send_payload = payload;
4229 
4230  return 0;
4231 }
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)
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:727
#define AST_RTP_DTMF
Definition: rtp_engine.h:266
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:1920
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:157
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:233

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 8751 of file res_rtp_asterisk.c.

8752 {
8753  /* If both sides are not using the same method of DTMF transmission
8754  * (ie: one is RFC2833, other is INFO... then we can not do direct media.
8755  * --------------------------------------------------
8756  * | DTMF Mode | HAS_DTMF | Accepts Begin Frames |
8757  * |-----------|------------|-----------------------|
8758  * | Inband | False | True |
8759  * | RFC2833 | True | True |
8760  * | SIP INFO | False | False |
8761  * --------------------------------------------------
8762  */
8764  (!ast_channel_tech(chan0)->send_digit_begin != !ast_channel_tech(chan1)->send_digit_begin)) ? 0 : 1);
8765 }
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 4234 of file res_rtp_asterisk.c.

4235 {
4236  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4237  struct ast_sockaddr remote_address = { {0,} };
4238  int hdrlen = 12, res = 0;
4239  char data[256];
4240  unsigned int *rtpheader = (unsigned int*)data;
4241  int ice;
4242 
4243  ast_rtp_instance_get_remote_address(instance, &remote_address);
4244 
4245  /* Make sure we know where the other side is so we can send them the packet */
4246  if (ast_sockaddr_isnull(&remote_address)) {
4247  return -1;
4248  }
4249 
4250  /* Actually create the packet we will be sending */
4251  rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
4252  rtpheader[1] = htonl(rtp->lastdigitts);
4253  rtpheader[2] = htonl(rtp->ssrc);
4254  rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration));
4255 
4256  /* Boom, send it on out */
4257  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4258  if (res < 0) {
4259  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4260  ast_sockaddr_stringify(&remote_address),
4261  strerror(errno));
4262  }
4263 
4264  if (rtp_debug_test_addr(&remote_address)) {
4265  ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4266  ast_sockaddr_stringify(&remote_address),
4267  ice ? " (via ICE)" : "",
4268  rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4269  }
4270 
4271  /* And now we increment some values for the next time we swing by */
4272  rtp->seqno++;
4273  rtp->send_duration += 160;
4274  rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
4275 
4276  return 0;
4277 }

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 4370 of file res_rtp_asterisk.c.

4371 {
4372  return ast_rtp_dtmf_end_with_duration(instance, digit, 0);
4373 }
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 4280 of file res_rtp_asterisk.c.

4281 {
4282  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4283  struct ast_sockaddr remote_address = { {0,} };
4284  int hdrlen = 12, res = -1, i = 0;
4285  char data[256];
4286  unsigned int *rtpheader = (unsigned int*)data;
4287  unsigned int measured_samples;
4288 
4289  ast_rtp_instance_get_remote_address(instance, &remote_address);
4290 
4291  /* Make sure we know where the remote side is so we can send them the packet we construct */
4292  if (ast_sockaddr_isnull(&remote_address)) {
4293  goto cleanup;
4294  }
4295 
4296  /* Convert the given digit to the one we are going to send */
4297  if ((digit <= '9') && (digit >= '0')) {
4298  digit -= '0';
4299  } else if (digit == '*') {
4300  digit = 10;
4301  } else if (digit == '#') {
4302  digit = 11;
4303  } else if ((digit >= 'A') && (digit <= 'D')) {
4304  digit = digit - 'A' + 12;
4305  } else if ((digit >= 'a') && (digit <= 'd')) {
4306  digit = digit - 'a' + 12;
4307  } else {
4308  ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
4309  goto cleanup;
4310  }
4311 
4312  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
4313 
4314  if (duration > 0 && (measured_samples = duration * ast_rtp_get_rate(rtp->f.subclass.format) / 1000) > rtp->send_duration) {
4315  ast_debug_rtp(2, "(%p) RTP adjusting final end duration from %d to %u\n",
4316  instance, rtp->send_duration, measured_samples);
4317  rtp->send_duration = measured_samples;
4318  }
4319 
4320  /* Construct the packet we are going to send */
4321  rtpheader[1] = htonl(rtp->lastdigitts);
4322  rtpheader[2] = htonl(rtp->ssrc);
4323  rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
4324  rtpheader[3] |= htonl((1 << 23));
4325 
4326  /* Send it 3 times, that's the magical number */
4327  for (i = 0; i < 3; i++) {
4328  int ice;
4329 
4330  rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
4331 
4332  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address, &ice);
4333 
4334  if (res < 0) {
4335  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
4336  ast_sockaddr_stringify(&remote_address),
4337  strerror(errno));
4338  }
4339 
4340  if (rtp_debug_test_addr(&remote_address)) {
4341  ast_verbose("Sent RTP DTMF packet to %s%s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
4342  ast_sockaddr_stringify(&remote_address),
4343  ice ? " (via ICE)" : "",
4344  rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
4345  }
4346 
4347  rtp->seqno++;
4348  }
4349  res = 0;
4350 
4351  /* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
4352  rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
4353 
4354  /* Reset the smoother as the delivery time stored in it is now out of date */
4355  if (rtp->smoother) {
4357  rtp->smoother = NULL;
4358  }
4359 cleanup:
4360  rtp->sending_digit = 0;
4361  rtp->send_digit = 0;
4362 
4363  /* Re-Learn expected seqno */
4364  rtp->expectedseqno = -1;
4365 
4366  return res;
4367 }

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 4144 of file res_rtp_asterisk.c.

4153 {
4154  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4155  return rtp->dtmfmode;
4156 }
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 4144 of file res_rtp_asterisk.c.

4145 {
4146  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
4147  rtp->dtmfmode = dtmf_mode;
4148  return 0;
4149 }

◆ ast_rtp_extension_enable()

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

Definition at line 8954 of file res_rtp_asterisk.c.

8955 {
8956  switch (extension) {
8959  return 1;
8960  default:
8961  return 0;
8962  }
8963 }
@ AST_RTP_EXTENSION_TRANSPORT_WIDE_CC
Definition: rtp_engine.h:548
@ AST_RTP_EXTENSION_ABS_SEND_TIME
Definition: rtp_engine.h:546
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 8517 of file res_rtp_asterisk.c.

8518 {
8519  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8520 
8521  return rtcp ? (rtp->rtcp ? rtp->rtcp->s : -1) : rtp->s;
8522 }

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 8901 of file res_rtp_asterisk.c.

8902 {
8903  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8904 
8905  return rtp->cname;
8906 }

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 8893 of file res_rtp_asterisk.c.

8894 {
8895  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8896 
8897  return rtp->ssrc;
8898 }

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 8699 of file res_rtp_asterisk.c.

8700 {
8701  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8702 
8703  if (!rtp->rtcp) {
8704  return -1;
8705  }
8706 
8711 
8723 
8735 
8742 
8746 
8747  return 0;
8748 }
#define AST_RTP_STAT_TERMINATOR(combined)
Definition: rtp_engine.h:449
@ AST_RTP_INSTANCE_STAT_LOCAL_MAXRXPLOSS
Definition: rtp_engine.h:202
@ AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVRXPLOSS
Definition: rtp_engine.h:198
@ AST_RTP_INSTANCE_STAT_REMOTE_MAXRXPLOSS
Definition: rtp_engine.h:194
@ AST_RTP_INSTANCE_STAT_REMOTE_MINJITTER
Definition: rtp_engine.h:218
@ AST_RTP_INSTANCE_STAT_MIN_RTT
Definition: rtp_engine.h:238
@ AST_RTP_INSTANCE_STAT_CHANNEL_UNIQUEID
Definition: rtp_engine.h:248
@ AST_RTP_INSTANCE_STAT_TXPLOSS
Definition: rtp_engine.h:190
@ AST_RTP_INSTANCE_STAT_MAX_RTT
Definition: rtp_engine.h:236
@ AST_RTP_INSTANCE_STAT_RXPLOSS
Definition: rtp_engine.h:192
@ AST_RTP_INSTANCE_STAT_REMOTE_MAXJITTER
Definition: rtp_engine.h:216
@ AST_RTP_INSTANCE_STAT_LOCAL_MAXJITTER
Definition: rtp_engine.h:224
@ AST_RTP_INSTANCE_STAT_REMOTE_STDEVJITTER
Definition: rtp_engine.h:222
@ AST_RTP_INSTANCE_STAT_REMOTE_MINRXPLOSS
Definition: rtp_engine.h:196
@ AST_RTP_INSTANCE_STAT_TXOCTETCOUNT
Definition: rtp_engine.h:250
@ AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVRXPLOSS
Definition: rtp_engine.h:206
@ AST_RTP_INSTANCE_STAT_REMOTE_STDEVRXPLOSS
Definition: rtp_engine.h:200
@ AST_RTP_INSTANCE_STAT_LOCAL_STDEVRXPLOSS
Definition: rtp_engine.h:208
@ AST_RTP_INSTANCE_STAT_TXCOUNT
Definition: rtp_engine.h:184
@ AST_RTP_INSTANCE_STAT_STDEVRTT
Definition: rtp_engine.h:242
@ AST_RTP_INSTANCE_STAT_RXJITTER
Definition: rtp_engine.h:214
@ AST_RTP_INSTANCE_STAT_LOCAL_MINRXPLOSS
Definition: rtp_engine.h:204
@ AST_RTP_INSTANCE_STAT_LOCAL_SSRC
Definition: rtp_engine.h:244
@ AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVJITTER
Definition: rtp_engine.h:220
@ AST_RTP_INSTANCE_STAT_COMBINED_JITTER
Definition: rtp_engine.h:210
@ AST_RTP_INSTANCE_STAT_TXJITTER
Definition: rtp_engine.h:212
@ AST_RTP_INSTANCE_STAT_LOCAL_MINJITTER
Definition: rtp_engine.h:226
@ AST_RTP_INSTANCE_STAT_COMBINED_LOSS
Definition: rtp_engine.h:188
@ AST_RTP_INSTANCE_STAT_LOCAL_STDEVJITTER
Definition: rtp_engine.h:230
@ AST_RTP_INSTANCE_STAT_COMBINED_RTT
Definition: rtp_engine.h:232
@ AST_RTP_INSTANCE_STAT_NORMDEVRTT
Definition: rtp_engine.h:240
@ AST_RTP_INSTANCE_STAT_RTT
Definition: rtp_engine.h:234
@ AST_RTP_INSTANCE_STAT_RXOCTETCOUNT
Definition: rtp_engine.h:252
@ AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVJITTER
Definition: rtp_engine.h:228
@ AST_RTP_INSTANCE_STAT_RXCOUNT
Definition: rtp_engine.h:186
@ AST_RTP_INSTANCE_STAT_REMOTE_SSRC
Definition: rtp_engine.h:246
#define AST_RTP_STAT_STRCPY(current_stat, combined, placement, value)
Definition: rtp_engine.h:441
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:548
#define AST_RTP_STAT_SET(current_stat, combined, placement, value)
Definition: rtp_engine.h:433
double maxrxlost
unsigned int reported_jitter
unsigned int received_prior
double reported_maxjitter
double reported_normdev_lost
double reported_minlost
double normdevrtt
double stdevrtt
double minrxjitter
unsigned int reported_lost
double reported_stdev_jitter
double normdev_rxjitter
double reported_stdev_lost
double normdev_rxlost
double maxrxjitter
double reported_normdev_jitter
double reported_maxlost
double stdev_rxjitter
double reported_minjitter
double minrxlost
unsigned int expected_prior
double stdev_rxlost
unsigned int remote_ssrc
Definition: rtp_engine.h:424
unsigned int rxcount
Definition: rtp_engine.h:370
unsigned int local_ssrc
Definition: rtp_engine.h:422
unsigned int rxoctetcount
Definition: rtp_engine.h:430
unsigned int rxploss
Definition: rtp_engine.h:394
unsigned int txcount
Definition: rtp_engine.h:368
unsigned int txploss
Definition: rtp_engine.h:392
unsigned int txoctetcount
Definition: rtp_engine.h:428
char channel_uniqueid[MAX_CHANNEL_ID]
Definition: rtp_engine.h:426
unsigned int rxcount
unsigned int rxoctetcount

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_RTT, AST_RTP_INSTANCE_STAT_LOCAL_MAXJITTER, AST_RTP_INSTANCE_STAT_LOCAL_MAXRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_MINJITTER, AST_RTP_INSTANCE_STAT_LOCAL_MINRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVJITTER, AST_RTP_INSTANCE_STAT_LOCAL_NORMDEVRXPLOSS, AST_RTP_INSTANCE_STAT_LOCAL_SSRC, AST_RTP_INSTANCE_STAT_LOCAL_STDEVJITTER, 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_MAXRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_MINJITTER, AST_RTP_INSTANCE_STAT_REMOTE_MINRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVJITTER, AST_RTP_INSTANCE_STAT_REMOTE_NORMDEVRXPLOSS, AST_RTP_INSTANCE_STAT_REMOTE_SSRC, AST_RTP_INSTANCE_STAT_REMOTE_STDEVJITTER, 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_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_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_maxrxploss, ast_rtp_instance_stats::local_minjitter, ast_rtp_instance_stats::local_minrxploss, ast_rtp_instance_stats::local_normdevjitter, ast_rtp_instance_stats::local_normdevrxploss, ast_rtp_instance_stats::local_ssrc, ast_rtp_instance_stats::local_stdevjitter, ast_rtp_instance_stats::local_stdevrxploss, ast_rtp_instance_stats::maxrtt, ast_rtcp::maxrtt, ast_rtcp::maxrxjitter, ast_rtcp::maxrxlost, ast_rtp_instance_stats::minrtt, ast_rtcp::minrtt, ast_rtcp::minrxjitter, ast_rtcp::minrxlost, ast_rtcp::normdev_rxjitter, ast_rtcp::normdev_rxlost, ast_rtp_instance_stats::normdevrtt, ast_rtcp::normdevrtt, ast_rtcp::received_prior, ast_rtp_instance_stats::remote_maxjitter, ast_rtp_instance_stats::remote_maxrxploss, ast_rtp_instance_stats::remote_minjitter, ast_rtp_instance_stats::remote_minrxploss, ast_rtp_instance_stats::remote_normdevjitter, ast_rtp_instance_stats::remote_normdevrxploss, ast_rtp_instance_stats::remote_ssrc, ast_rtp_instance_stats::remote_stdevjitter, 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_minjitter, ast_rtcp::reported_minlost, ast_rtcp::reported_normdev_jitter, ast_rtcp::reported_normdev_lost, ast_rtcp::reported_stdev_jitter, ast_rtcp::reported_stdev_lost, 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::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::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 7228 of file res_rtp_asterisk.c.

7231 {
7232  unsigned int *rtpheader = (unsigned int*)(read_area);
7233  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
7234  struct ast_rtp_instance *instance1;
7235  int res = length, hdrlen = 12, ssrc, seqno, payloadtype, padding, mark, ext, cc;
7236  unsigned int timestamp;
7237  RAII_VAR(struct ast_rtp_payload_type *, payload, NULL, ao2_cleanup);
7238  struct frame_list frames;
7239 
7240  /* If this payload is encrypted then decrypt it using the given SRTP instance */
7241  if ((*read_area & 0xC0) && res_srtp && srtp && res_srtp->unprotect(
7242  srtp, read_area, &res, 0 | (srtp_replay_protection << 1)) < 0) {
7243  return &ast_null_frame;
7244  }
7245 
7246  /* If we are currently sending DTMF to the remote party send a continuation packet */
7247  if (rtp->sending_digit) {
7248  ast_rtp_dtmf_continuation(instance);
7249  }
7250 
7251  /* Pull out the various other fields we will need */
7252  ssrc = ntohl(rtpheader[2]);
7253  seqno = ntohl(rtpheader[0]);
7254  payloadtype = (seqno & 0x7f0000) >> 16;
7255  padding = seqno & (1 << 29);
7256  mark = seqno & (1 << 23);
7257  ext = seqno & (1 << 28);
7258  cc = (seqno & 0xF000000) >> 24;
7259  seqno &= 0xffff;
7260  timestamp = ntohl(rtpheader[1]);
7261 
7263 
7264  /* Remove any padding bytes that may be present */
7265  if (padding) {
7266  res -= read_area[res - 1];
7267  }
7268 
7269  /* Skip over any CSRC fields */
7270  if (cc) {
7271  hdrlen += cc * 4;
7272  }
7273 
7274  /* Look for any RTP extensions, currently we do not support any */
7275  if (ext) {
7276  int extensions_size = (ntohl(rtpheader[hdrlen/4]) & 0xffff) << 2;
7277  unsigned int profile;
7278  profile = (ntohl(rtpheader[3]) & 0xffff0000) >> 16;
7279 
7280  if (profile == 0xbede) {
7281  /* We skip over the first 4 bytes as they are just for the one byte extension header */
7282  rtp_instance_parse_extmap_extensions(instance, rtp, read_area + hdrlen + 4, extensions_size);
7283  } else if (DEBUG_ATLEAST(1)) {
7284  if (profile == 0x505a) {
7285  ast_log(LOG_DEBUG, "Found Zfone extension in RTP stream - zrtp - not supported.\n");
7286  } else {
7287  /* SDP negotiated RTP extensions can not currently be output in logging */
7288  ast_log(LOG_DEBUG, "Found unknown RTP Extensions %x\n", profile);
7289  }
7290  }
7291 
7292  hdrlen += extensions_size;
7293  hdrlen += 4;
7294  }
7295 
7296  /* Make sure after we potentially mucked with the header length that it is once again valid */
7297  if (res < hdrlen) {
7298  ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d\n", res, hdrlen);
7300  }
7301 
7302  /* Only non-bundled instances can change/learn the remote's SSRC implicitly. */
7303  if (!bundled) {
7304  /* Force a marker bit and change SSRC if the SSRC changes */
7305  if (rtp->themssrc_valid && rtp->themssrc != ssrc) {
7306  struct ast_frame *f, srcupdate = {
7308  .subclass.integer = AST_CONTROL_SRCCHANGE,
7309  };
7310 
7311  if (!mark) {
7313  ast_debug(0, "(%p) RTP forcing Marker bit, because SSRC has changed\n", instance);
7314  }
7315  mark = 1;
7316  }
7317 
7318  f = ast_frisolate(&srcupdate);
7320 
7321  rtp->seedrxseqno = 0;
7322  rtp->rxcount = 0;
7323  rtp->rxoctetcount = 0;
7324  rtp->cycles = 0;
7325  prev_seqno = 0;
7326  rtp->last_seqno = 0;
7327  rtp->last_end_timestamp.ts = 0;
7328  rtp->last_end_timestamp.is_set = 0;
7329  if (rtp->rtcp) {
7330  rtp->rtcp->expected_prior = 0;
7331  rtp->rtcp->received_prior = 0;
7332  }
7333  }
7334 
7335  rtp->themssrc = ssrc; /* Record their SSRC to put in future RR */
7336  rtp->themssrc_valid = 1;
7337  }
7338 
7339  rtp->rxcount++;
7340  rtp->rxoctetcount += (res - hdrlen);
7341  if (rtp->rxcount == 1) {
7342  rtp->seedrxseqno = seqno;
7343  }
7344 
7345  /* Do not schedule RR if RTCP isn't run */
7346  if (rtp->rtcp && !ast_sockaddr_isnull(&rtp->rtcp->them) && rtp->rtcp->schedid < 0) {
7347  /* Schedule transmission of Receiver Report */
7348  ao2_ref(instance, +1);
7349  rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, instance);
7350  if (rtp->rtcp->schedid < 0) {
7351  ao2_ref(instance, -1);
7352  ast_log(LOG_WARNING, "scheduling RTCP transmission failed.\n");
7353  }
7354  }
7355  if ((int)prev_seqno - (int)seqno > 100) /* if so it would indicate that the sender cycled; allow for misordering */
7356  rtp->cycles += RTP_SEQ_MOD;
7357 
7358  /* If we are directly bridged to another instance send the audio directly out,
7359  * but only after updating core information about the received traffic so that
7360  * outgoing RTCP reflects it.
7361  */
7362  instance1 = ast_rtp_instance_get_bridged(instance);
7363  if (instance1
7364  && !bridge_p2p_rtp_write(instance, instance1, rtpheader, res, hdrlen)) {
7365  struct timeval rxtime;
7366  struct ast_frame *f;
7367 
7368  /* Update statistics for jitter so they are correct in RTCP */
7369  calc_rxstamp(&rxtime, rtp, timestamp, mark);
7370 
7371  /* When doing P2P we don't need to raise any frames about SSRC change to the core */
7372  while ((f = AST_LIST_REMOVE_HEAD(&frames, frame_list)) != NULL) {
7373  ast_frfree(f);
7374  }
7375 
7376  return &ast_null_frame;
7377  }
7378 
7379  payload = ast_rtp_codecs_get_payload(ast_rtp_instance_get_codecs(instance), payloadtype);
7380  if (!payload) {
7381  /* Unknown payload type. */
7383  }
7384 
7385  /* If the payload is not actually an Asterisk one but a special one pass it off to the respective handler */
7386  if (!payload->asterisk_format) {
7387  struct ast_frame *f = NULL;
7388  if (payload->rtp_code == AST_RTP_DTMF) {
7389  /* process_dtmf_rfc2833 may need to return multiple frames. We do this
7390  * by passing the pointer to the frame list to it so that the method
7391  * can append frames to the list as needed.
7392  */
7393  process_dtmf_rfc2833(instance, read_area + hdrlen, res - hdrlen, seqno, timestamp, payloadtype, mark, &frames);
7394  } else if (payload->rtp_code == AST_RTP_CISCO_DTMF) {
7395  f = process_dtmf_cisco(instance, read_area + hdrlen, res - hdrlen, seqno, timestamp, payloadtype, mark);
7396  } else if (payload->rtp_code == AST_RTP_CN) {
7397  f = process_cn_rfc3389(instance, read_area + hdrlen, res - hdrlen, seqno, timestamp, payloadtype, mark);
7398  } else {
7399  ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n",
7400  payloadtype,
7401  ast_sockaddr_stringify(remote_address));
7402  }
7403 
7404  if (f) {
7406  }
7407  /* Even if no frame was returned by one of the above methods,
7408  * we may have a frame to return in our frame list
7409  */
7411  }
7412 
7413  ao2_replace(rtp->lastrxformat, payload->format);
7414  ao2_replace(rtp->f.subclass.format, payload->format);
7415  switch (ast_format_get_type(rtp->f.subclass.format)) {
7416  case AST_MEDIA_TYPE_AUDIO:
7417  rtp->f.frametype = AST_FRAME_VOICE;
7418  break;
7419  case AST_MEDIA_TYPE_VIDEO:
7420  rtp->f.frametype = AST_FRAME_VIDEO;
7421  break;
7422  case AST_MEDIA_TYPE_TEXT:
7423  rtp->f.frametype = AST_FRAME_TEXT;
7424  break;
7425  case AST_MEDIA_TYPE_IMAGE:
7426  /* Fall through */
7427  default:
7428  ast_log(LOG_WARNING, "Unknown or unsupported media type: %s\n",
7430  return &ast_null_frame;
7431  }
7432 
7433  if (rtp->dtmf_timeout && rtp->dtmf_timeout < timestamp) {
7434  rtp->dtmf_timeout = 0;
7435 
7436  if (rtp->resp) {
7437  struct ast_frame *f;
7438  f = create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0);
7440  rtp->resp = 0;
7441  rtp->dtmf_timeout = rtp->dtmf_duration = 0;
7443  return AST_LIST_FIRST(&frames);
7444  }
7445  }
7446 
7447  rtp->f.src = "RTP";
7448  rtp->f.mallocd = 0;
7449  rtp->f.datalen = res - hdrlen;
7450  rtp->f.data.ptr = read_area + hdrlen;
7451  rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
7453  rtp->f.seqno = seqno;
7454  rtp->f.stream_num = rtp->stream_num;
7455 
7457  && ((int)seqno - (prev_seqno + 1) > 0)
7458  && ((int)seqno - (prev_seqno + 1) < 10)) {
7459  unsigned char *data = rtp->f.data.ptr;
7460 
7461  memmove(rtp->f.data.ptr+3, rtp->f.data.ptr, rtp->f.datalen);
7462  rtp->f.datalen +=3;
7463  *data++ = 0xEF;
7464  *data++ = 0xBF;
7465  *data = 0xBD;
7466  }
7467 
7469  unsigned char *data = rtp->f.data.ptr;
7470  unsigned char *header_end;
7471  int num_generations;
7472  int header_length;
7473  int len;
7474  int diff =(int)seqno - (prev_seqno+1); /* if diff = 0, no drop*/
7475  int x;
7476 
7478  header_end = memchr(data, ((*data) & 0x7f), rtp->f.datalen);
7479  if (header_end == NULL) {
7481  }
7482  header_end++;
7483 
7484  header_length = header_end - data;
7485  num_generations = header_length / 4;
7486  len = header_length;
7487 
7488  if (!diff) {
7489  for (x = 0; x < num_generations; x++)
7490  len += data[x * 4 + 3];
7491 
7492  if (!(rtp->f.datalen - len))
7494 
7495  rtp->f.data.ptr += len;
7496  rtp->f.datalen -= len;
7497  } else if (diff > num_generations && diff < 10) {
7498  len -= 3;
7499  rtp->f.data.ptr += len;
7500  rtp->f.datalen -= len;
7501 
7502  data = rtp->f.data.ptr;
7503  *data++ = 0xEF;
7504  *data++ = 0xBF;
7505  *data = 0xBD;
7506  } else {
7507  for ( x = 0; x < num_generations - diff; x++)
7508  len += data[x * 4 + 3];
7509 
7510  rtp->f.data.ptr += len;
7511  rtp->f.datalen -= len;
7512  }
7513  }
7514 
7516  rtp->f.samples = ast_codec_samples_count(&rtp->f);
7518  ast_frame_byteswap_be(&rtp->f);
7519  }
7520  calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
7521  /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
7523  rtp->f.ts = timestamp / (ast_rtp_get_rate(rtp->f.subclass.format) / 1000);
7524  rtp->f.len = rtp->f.samples / ((ast_format_get_sample_rate(rtp->f.subclass.format) / 1000));
7526  /* Video -- samples is # of samples vs. 90000 */
7527  if (!rtp->lastividtimestamp)
7528  rtp->lastividtimestamp = timestamp;
7529  calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
7531  rtp->f.ts = timestamp / (ast_rtp_get_rate(rtp->f.subclass.format) / 1000);
7532  rtp->f.samples = timestamp - rtp->lastividtimestamp;
7533  rtp->lastividtimestamp = timestamp;
7534  rtp->f.delivery.tv_sec = 0;
7535  rtp->f.delivery.tv_usec = 0;
7536  /* Pass the RTP marker bit as bit */
7537  rtp->f.subclass.frame_ending = mark ? 1 : 0;
7539  /* TEXT -- samples is # of samples vs. 1000 */
7540  if (!rtp->lastitexttimestamp)
7541  rtp->lastitexttimestamp = timestamp;
7542  rtp->f.samples = timestamp - rtp->lastitexttimestamp;
7543  rtp->lastitexttimestamp = timestamp;
7544  rtp->f.delivery.tv_sec = 0;
7545  rtp->f.delivery.tv_usec = 0;
7546  } else {
7547  ast_log(LOG_WARNING, "Unknown or unsupported media type: %s\n",
7549  return &ast_null_frame;
7550  }
7551 
7553  return AST_LIST_FIRST(&frames);
7554 }
#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:378
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:347
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
#define ast_frame_byteswap_be(fr)
@ AST_FRFLAG_HAS_SEQUENCE_NUMBER
@ AST_FRFLAG_HAS_TIMING_INFO
#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 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)
static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, struct ast_rtp_instance *instance1, unsigned int *rtpheader, int len, int hdrlen)
static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
static struct ast_frame * create_dtmf_frame(struct ast_rtp_instance *instance, enum ast_frame_type type, int compensate)
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 calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
static void rtp_instance_parse_extmap_extensions(struct ast_rtp_instance *instance, struct ast_rtp *rtp, unsigned char *extension, int len)
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 unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
#define RTP_SEQ_MOD
static int ast_rtcp_write(const void *data)
Write a RTCP packet to the far end.
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:2226
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:1471
#define AST_RTP_CN
Definition: rtp_engine.h:268
#define AST_RTP_CISCO_DTMF
Definition: rtp_engine.h:270
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:245
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:105

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(), 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 8671 of file res_rtp_asterisk.c.

8672 {
8673  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance0);
8674 
8675  ao2_lock(instance0);
8677  if (rtp->smoother) {
8679  rtp->smoother = NULL;
8680  }
8681 
8682  /* We must use a new SSRC when local bridge ends */
8683  if (!instance1) {
8684  rtp->ssrc = rtp->ssrc_orig;
8685  rtp->ssrc_orig = 0;
8686  rtp->ssrc_saved = 0;
8687  } else if (!rtp->ssrc_saved) {
8688  /* In case ast_rtp_local_bridge is called multiple times, only save the ssrc from before local bridge began */
8689  rtp->ssrc_orig = rtp->ssrc;
8690  rtp->ssrc_saved = 1;
8691  }
8692 
8693  ao2_unlock(instance0);
8694 
8695  return 0;
8696 }
#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 4017 of file res_rtp_asterisk.c.

4020 {
4021  struct ast_rtp *rtp = NULL;
4022 
4023  /* Create a new RTP structure to hold all of our data */
4024  if (!(rtp = ast_calloc(1, sizeof(*rtp)))) {
4025  return -1;
4026  }
4027 
4028  /* Set default parameters on the newly created RTP structure */
4029  rtp->ssrc = ast_random();
4030  ast_uuid_generate_str(rtp->cname, sizeof(rtp->cname));
4031  rtp->seqno = ast_random() & 0x7fff;
4032  rtp->expectedrxseqno = -1;
4033  rtp->expectedseqno = -1;
4034  rtp->sched = sched;
4035  ast_sockaddr_copy(&rtp->bind_address, addr);
4036 
4037  /* Transport creation operations can grab the RTP data from the instance, so set it */
4038  ast_rtp_instance_set_data(instance, rtp);
4039 
4040  if (rtp_allocate_transport(instance, rtp)) {
4041  return -1;
4042  }
4043 
4044  if (AST_VECTOR_INIT(&rtp->ssrc_mapping, 1)) {
4045  return -1;
4046  }
4047 
4049  return -1;
4050  }
4051  rtp->transport_wide_cc.schedid = -1;
4052 
4056  rtp->stream_num = -1;
4057 
4058  return 0;
4059 }
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:558
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, rtp_transport_wide_cc_statistics::packet_statistics, rtp_allocate_transport(), 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 8331 of file res_rtp_asterisk.c.

8332 {
8333  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8334 
8335  if (property == AST_RTP_PROPERTY_RTCP) {
8336  if (value) {
8337  struct ast_sockaddr local_addr;
8338 
8339  if (rtp->rtcp && rtp->rtcp->type == value) {
8340  ast_debug_rtcp(1, "(%p) RTCP ignoring duplicate property\n", instance);
8341  return;
8342  }
8343 
8344  if (!rtp->rtcp) {
8345  rtp->rtcp = ast_calloc(1, sizeof(*rtp->rtcp));
8346  if (!rtp->rtcp) {
8347  return;
8348  }
8349  rtp->rtcp->s = -1;
8350 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8351  rtp->rtcp->dtls.timeout_timer = -1;
8352 #endif
8353  rtp->rtcp->schedid = -1;
8354  }
8355 
8356  rtp->rtcp->type = value;
8357 
8358  /* Grab the IP address and port we are going to use */
8359  ast_rtp_instance_get_local_address(instance, &rtp->rtcp->us);
8361  ast_sockaddr_set_port(&rtp->rtcp->us,
8362  ast_sockaddr_port(&rtp->rtcp->us) + 1);
8363  }
8364 
8365  ast_sockaddr_copy(&local_addr, &rtp->rtcp->us);
8366  if (!ast_find_ourip(&local_addr, &rtp->rtcp->us, 0)) {
8367  ast_sockaddr_set_port(&local_addr, ast_sockaddr_port(&rtp->rtcp->us));
8368  } else {
8369  /* Failed to get local address reset to use default. */
8370  ast_sockaddr_copy(&local_addr, &rtp->rtcp->us);
8371  }
8372 
8373  ast_free(rtp->rtcp->local_addr_str);
8374  rtp->rtcp->local_addr_str = ast_strdup(ast_sockaddr_stringify(&local_addr));
8375  if (!rtp->rtcp->local_addr_str) {
8376  ast_free(rtp->rtcp);
8377  rtp->rtcp = NULL;
8378  return;
8379  }
8380 
8382  /* We're either setting up RTCP from scratch or
8383  * switching from MUX. Either way, we won't have
8384  * a socket set up, and we need to set it up
8385  */
8386  if ((rtp->rtcp->s =
8387  create_new_socket("RTCP",
8388  ast_sockaddr_is_ipv4(&rtp->rtcp->us) ?
8389  AF_INET :
8390  ast_sockaddr_is_ipv6(&rtp->rtcp->us) ?
8391  AF_INET6 : -1)) < 0) {
8392  ast_debug_rtcp(1, "(%p) RTCP failed to create a new socket\n", instance);
8393  ast_free(rtp->rtcp->local_addr_str);
8394  ast_free(rtp->rtcp);
8395  rtp->rtcp = NULL;
8396  return;
8397  }
8398 
8399  /* 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 */
8400  if (ast_bind(rtp->rtcp->s, &rtp->rtcp->us)) {
8401  ast_debug_rtcp(1, "(%p) RTCP failed to setup RTP instance\n", instance);
8402  close(rtp->rtcp->s);
8403  ast_free(rtp->rtcp->local_addr_str);
8404  ast_free(rtp->rtcp);
8405  rtp->rtcp = NULL;
8406  return;
8407  }
8408 #ifdef HAVE_PJPROJECT
8409  if (rtp->ice) {
8410  rtp_add_candidates_to_ice(instance, rtp, &rtp->rtcp->us, ast_sockaddr_port(&rtp->rtcp->us), AST_RTP_ICE_COMPONENT_RTCP, TRANSPORT_SOCKET_RTCP);
8411  }
8412 #endif
8413 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8414  dtls_setup_rtcp(instance);
8415 #endif
8416  } else {
8417  struct ast_sockaddr addr;
8418  /* RTCPMUX uses the same socket as RTP. If we were previously using standard RTCP
8419  * then close the socket we previously created.
8420  *
8421  * It may seem as though there is a possible race condition here where we might try
8422  * to close the RTCP socket while it is being used to send data. However, this is not
8423  * a problem in practice since setting and adjusting of RTCP properties happens prior
8424  * to activating RTP. It is not until RTP is activated that timers start for RTCP
8425  * transmission
8426  */
8427  if (rtp->rtcp->s > -1 && rtp->rtcp->s != rtp->s) {
8428  close(rtp->rtcp->s);
8429  }
8430  rtp->rtcp->s = rtp->s;
8431  ast_rtp_instance_get_remote_address(instance, &addr);
8432  ast_sockaddr_copy(&rtp->rtcp->them, &addr);
8433 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8434  if (rtp->rtcp->dtls.ssl && rtp->rtcp->dtls.ssl != rtp->dtls.ssl) {
8435  SSL_free(rtp->rtcp->dtls.ssl);
8436  }
8437  rtp->rtcp->dtls.ssl = rtp->dtls.ssl;
8438 #endif
8439  }
8440 
8441  ast_debug_rtcp(1, "(%p) RTCP setup on RTP instance\n", instance);
8442  } else {
8443  if (rtp->rtcp) {
8444  if (rtp->rtcp->schedid > -1) {
8445  ao2_unlock(instance);
8446  if (!ast_sched_del(rtp->sched, rtp->rtcp->schedid)) {
8447  /* Successfully cancelled scheduler entry. */
8448  ao2_ref(instance, -1);
8449  } else {
8450  /* Unable to cancel scheduler entry */
8451  ast_debug_rtcp(1, "(%p) RTCP failed to tear down RTCP\n", instance);
8452  ao2_lock(instance);
8453  return;
8454  }
8455  ao2_lock(instance);
8456  rtp->rtcp->schedid = -1;
8457  }
8458  if (rtp->transport_wide_cc.schedid > -1) {
8459  ao2_unlock(instance);
8460  if (!ast_sched_del(rtp->sched, rtp->transport_wide_cc.schedid)) {
8461  ao2_ref(instance, -1);
8462  } else {
8463  ast_debug_rtcp(1, "(%p) RTCP failed to tear down transport-cc feedback\n", instance);
8464  ao2_lock(instance);
8465  return;
8466  }
8467  ao2_lock(instance);
8468  rtp->transport_wide_cc.schedid = -1;
8469  }
8470  if (rtp->rtcp->s > -1 && rtp->rtcp->s != rtp->s) {
8471  close(rtp->rtcp->s);
8472  }
8473 #if defined(HAVE_OPENSSL) && (OPENSSL_VERSION_NUMBER >= 0x10001000L) && !defined(OPENSSL_NO_SRTP)
8474  ao2_unlock(instance);
8475  dtls_srtp_stop_timeout_timer(instance, rtp, 1);
8476  ao2_lock(instance);
8477 
8478  if (rtp->rtcp->dtls.ssl && rtp->rtcp->dtls.ssl != rtp->dtls.ssl) {
8479  SSL_free(rtp->rtcp->dtls.ssl);
8480  }
8481 #endif
8482  ast_free(rtp->rtcp->local_addr_str);
8483  ast_free(rtp->rtcp);
8484  rtp->rtcp = NULL;
8485  }
8486  }
8487  } else if (property == AST_RTP_PROPERTY_ASYMMETRIC_CODEC) {
8488  rtp->asymmetric_codec = value;
8489  } else if (property == AST_RTP_PROPERTY_RETRANS_SEND) {
8490  if (value) {
8491  if (!rtp->send_buffer) {
8493  }
8494  } else {
8495  if (rtp->send_buffer) {
8497  rtp->send_buffer = NULL;
8498  }
8499  }
8500  } else if (property == AST_RTP_PROPERTY_RETRANS_RECV) {
8501  if (value) {
8502  if (!rtp->recv_buffer) {
8504  AST_VECTOR_INIT(&rtp->missing_seqno, 0);
8505  }
8506  } else {
8507  if (rtp->recv_buffer) {
8509  rtp->recv_buffer = NULL;
8511  }
8512  }
8513  }
8514 }
int ast_find_ourip(struct ast_sockaddr *ourip, const struct ast_sockaddr *bindaddr, int family)
Find our IP address.
Definition: acl.c:1052
#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:259
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:643
@ 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_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 8832 of file res_rtp_asterisk.c.

8833 {
8834  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
8835 
8836  return ast_set_qos(rtp->s, tos, cos, desc);
8837 }
static const char desc[]
Definition: cdr_radius.c:84
unsigned int tos
Definition: chan_iax2.c:348
unsigned int cos
Definition: chan_iax2.c:349
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 ast_frame * ast_rtp_read ( struct ast_rtp_instance instance,
int  rtcp 
)
static
Precondition
instance is locked

Definition at line 7666 of file res_rtp_asterisk.c.

7667 {
7668  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
7669  struct ast_srtp *srtp;
7671  struct ast_sockaddr addr;
7672  int res, hdrlen = 12, version, payloadtype;
7673  unsigned char *read_area = rtp->rawdata + AST_FRIENDLY_OFFSET;
7674  size_t read_area_size = sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET;
7675  unsigned int *rtpheader = (unsigned int*)(read_area), seqno, ssrc, timestamp, prev_seqno;
7676  struct ast_sockaddr remote_address = { {0,} };
7677  struct frame_list frames;
7678  struct ast_frame *frame;
7679  unsigned int bundled;
7680 
7681  /* If this is actually RTCP let's hop on over and handle it */
7682  if (rtcp) {
7683  if (rtp->rtcp && rtp->rtcp->type == AST_RTP_INSTANCE_RTCP_STANDARD) {
7684  return ast_rtcp_read(instance);
7685  }
7686  return &ast_null_frame;
7687  }
7688 
7689  /* Actually read in the data from the socket */
7690  if ((res = rtp_recvfrom(instance, read_area, read_area_size, 0,
7691  &addr)) < 0) {
7692  if (res == RTP_DTLS_ESTABLISHED) {
7693  rtp->f.frametype = AST_FRAME_CONTROL;
7695  return &rtp->f;
7696  }
7697 
7698  ast_assert(errno != EBADF);
7699  if (errno != EAGAIN) {
7700  ast_log(LOG_WARNING, "RTP Read error: %s. Hanging up.\n",
7701  (errno) ? strerror(errno) : "Unspecified");
7702  return NULL;
7703  }
7704  return &ast_null_frame;
7705  }
7706 
7707