Wed Jan 8 2020 09:50:19

Asterisk developer's documentation


res_rtp_asterisk.c File Reference

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

#include "asterisk.h"
#include <sys/time.h>
#include <signal.h>
#include <fcntl.h>
#include "asterisk/stun.h"
#include "asterisk/pbx.h"
#include "asterisk/frame.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"

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  frame_list
 
struct  rtp_red
 

Macros

#define DEFAULT_DTMF_TIMEOUT   (150 * (8000 / 1000))
 
#define DEFAULT_LEARNING_MIN_SEQUENTIAL   4
 
#define DEFAULT_RTP_END   31000
 
#define DEFAULT_RTP_START   5000
 
#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 MAX_TIMESTAMP_SKEW   640
 
#define MAXIMUM_RTP_PORT   65535
 
#define MINIMUM_RTP_PORT   1024
 
#define RTCP_DEFAULT_INTERVALMS   5000
 
#define RTCP_MAX_INTERVALMS   60000
 
#define RTCP_MIN_INTERVALMS   500
 
#define RTCP_PT_APP   204
 
#define RTCP_PT_BYE   203
 
#define RTCP_PT_FUR   192
 
#define RTCP_PT_RR   201
 
#define RTCP_PT_SDES   202
 
#define RTCP_PT_SR   200
 
#define RTP_MTU   1200
 
#define RTP_SEQ_MOD   (1<<16)
 
#define SQUARE(x)   ((x) * (x))
 
#define ZFONE_PROFILE_ID   0x505a
 

Enumerations

enum  strict_rtp_state { STRICT_RTP_OPEN = 0, STRICT_RTP_LEARN, STRICT_RTP_CLOSED }
 

Functions

static void __reg_module (void)
 
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)
 
static void __unreg_module (void)
 
static unsigned int ast_rtcp_calc_interval (struct ast_rtp *rtp)
 
static struct ast_frameast_rtcp_read (struct ast_rtp_instance *instance)
 
static int ast_rtcp_write (const void *data)
 Write and RTCP packet to the far end. More...
 
static int ast_rtcp_write_rr (struct ast_rtp_instance *instance)
 Send RTCP recipient's report. More...
 
static int ast_rtcp_write_sr (struct ast_rtp_instance *instance)
 Send RTCP sender's report. More...
 
static void ast_rtp_alt_remote_address_set (struct ast_rtp_instance *instance, struct ast_sockaddr *addr)
 
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_fd (struct ast_rtp_instance *instance, int rtcp)
 
static int ast_rtp_get_stat (struct ast_rtp_instance *instance, struct ast_rtp_instance_stats *stats, enum ast_rtp_instance_stat stat)
 
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 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 int ast_rtp_raw_write (struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
 
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_sendcng (struct ast_rtp_instance *instance, int level)
 generate comfort noice (CNG) More...
 
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, unsigned int *rtpheader, int len, int hdrlen)
 
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 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 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 int load_module (void)
 
static double normdev_compute (double normdev, double sample, unsigned int sample_count)
 Calculate normal deviation. More...
 
static struct ast_frameprocess_cn_rfc3389 (struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, struct ast_sockaddr *addr, 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, struct ast_sockaddr *addr, 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, struct ast_sockaddr *addr, int payloadtype, int mark, struct frame_list *frames)
 
static struct ast_framered_t140_to_red (struct rtp_red *red)
 
static int red_write (const void *data)
 Write t140 redundacy 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_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)
 
static int rtp_debug_test_addr (struct ast_sockaddr *addr)
 
static char * rtp_do_debug_ip (struct ast_cli_args *a)
 
static int rtp_get_rate (format_t subclass)
 
static int rtp_learning_rtp_seq_update (struct ast_rtp *rtp, uint16_t seq)
 
static void rtp_learning_seq_init (struct ast_rtp *rtp, uint16_t seq)
 
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)
 
static int rtp_sendto (struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
 
static double stddev_compute (double stddev, double sample, double normdev, double normdev_curent, unsigned int sample_count)
 
static void timeval2ntp (struct timeval tv, unsigned int *msw, unsigned int *lsw)
 
static int unload_module (void)
 

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
 
static 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_sequential
 
struct ast_srtp_resres_srtp
 
static int rtcpdebug
 
static struct ast_sockaddr rtcpdebugaddr
 
static int rtcpdebugport
 
static int rtcpinterval = RTCP_DEFAULT_INTERVALMS
 
static int rtcpstats
 
static int rtpdebug
 
static struct ast_sockaddr rtpdebugaddr
 
static int rtpdebugport
 
static int rtpend = DEFAULT_RTP_END
 
static int rtpstart = DEFAULT_RTP_START
 
static int strictrtp
 

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

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

samples

Definition at line 80 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DEFAULT_LEARNING_MIN_SEQUENTIAL   4

Definition at line 84 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DEFAULT_RTP_END   31000

Default maximum port number to end allocating RTP ports at

Definition at line 65 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DEFAULT_RTP_START   5000

Default port number to start allocating RTP ports from

Definition at line 64 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define DTMF_SAMPLE_RATE_MS   8

DTMF samples per millisecond

Definition at line 78 of file res_rtp_asterisk.c.

Referenced by ast_rtp_dtmf_begin(), ast_rtp_dtmf_continuation(), and ast_rtp_dtmf_end_with_duration().

#define FLAG_3389_WARNING   (1 << 0)

Definition at line 111 of file res_rtp_asterisk.c.

Referenced by process_cn_rfc3389().

#define FLAG_DTMF_COMPENSATE   (1 << 4)

Definition at line 116 of file res_rtp_asterisk.c.

#define FLAG_NAT_ACTIVE   (3 << 1)

Definition at line 112 of file res_rtp_asterisk.c.

Referenced by ast_rtp_raw_write(), ast_rtp_read(), and bridge_p2p_rtp_write().

#define FLAG_NAT_INACTIVE   (0 << 1)

Definition at line 113 of file res_rtp_asterisk.c.

Referenced by ast_rtp_raw_write(), and bridge_p2p_rtp_write().

#define FLAG_NAT_INACTIVE_NOWARN   (1 << 1)

Definition at line 114 of file res_rtp_asterisk.c.

Referenced by ast_rtp_raw_write(), and bridge_p2p_rtp_write().

#define FLAG_NEED_MARKER_BIT   (1 << 3)
#define MAX_TIMESTAMP_SKEW   640

Definition at line 57 of file res_rtp_asterisk.c.

Referenced by ast_rtp_raw_write().

#define MAXIMUM_RTP_PORT   65535

Maximum port number to accept

Definition at line 68 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define MINIMUM_RTP_PORT   1024

Minimum port number to accept

Definition at line 67 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define RTCP_DEFAULT_INTERVALMS   5000

Default milli-seconds between RTCP reports we send

Definition at line 60 of file res_rtp_asterisk.c.

#define RTCP_MAX_INTERVALMS   60000

Max milli-seconds between RTCP reports we send

Definition at line 62 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define RTCP_MIN_INTERVALMS   500

Min milli-seconds between RTCP reports we send

Definition at line 61 of file res_rtp_asterisk.c.

Referenced by rtp_reload().

#define RTCP_PT_APP   204

Definition at line 75 of file res_rtp_asterisk.c.

#define RTCP_PT_BYE   203

Definition at line 74 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_read().

#define RTCP_PT_FUR   192

Definition at line 70 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_read().

#define RTCP_PT_RR   201

Definition at line 72 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_read(), and ast_rtcp_write_rr().

#define RTCP_PT_SDES   202

Definition at line 73 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_read(), ast_rtcp_write_rr(), and ast_rtcp_write_sr().

#define RTCP_PT_SR   200

Definition at line 71 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_read(), and ast_rtcp_write_sr().

#define RTP_MTU   1200

Definition at line 77 of file res_rtp_asterisk.c.

#define RTP_SEQ_MOD   (1<<16)

A sequence number can't be more than 16 bits

Definition at line 59 of file res_rtp_asterisk.c.

Referenced by ast_rtp_read().

#define SQUARE (   x)    ((x) * (x))

Referenced by stddev_compute().

#define ZFONE_PROFILE_ID   0x505a

Definition at line 82 of file res_rtp_asterisk.c.

Enumeration Type Documentation

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

105  {
106  STRICT_RTP_OPEN = 0, /*! No RTP packets should be dropped, all sources accepted */
107  STRICT_RTP_LEARN, /*! Accept next packet as source */
108  STRICT_RTP_CLOSED, /*! Drop all RTP packets not coming from source that was learned */
109 };

Function Documentation

static void __reg_module ( void  )
static

Definition at line 3101 of file res_rtp_asterisk.c.

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

Definition at line 359 of file res_rtp_asterisk.c.

References ast_recvfrom(), ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_srtp::buf, len(), ast_rtp::rtcp, ast_rtp::s, ast_rtcp::s, and ast_srtp_res::unprotect.

Referenced by rtcp_recvfrom(), and rtp_recvfrom().

360 {
361  int len;
362  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
363  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance);
364  char *in = buf;
365 
366  if ((len = ast_recvfrom(rtcp ? rtp->rtcp->s : rtp->s, buf, size, flags, sa)) < 0) {
367  return len;
368  }
369 
370  if ((*in & 0xC0) && res_srtp && srtp && res_srtp->unprotect(srtp, buf, &len, rtcp) < 0) {
371  return -1;
372  }
373 
374  return len;
375 }
RTP session description.
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:1849
int(* unprotect)(struct ast_srtp *srtp, void *buf, int *size, int rtcp)
Definition: res_srtp.h:46
struct ast_rtcp * rtcp
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
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:478
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct ast_srtp_res * res_srtp
Definition: rtp_engine.c:48
unsigned char buf[8192+AST_FRIENDLY_OFFSET]
Definition: res_srtp.c:59
static int __rtp_sendto ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa,
int  rtcp 
)
static

Definition at line 387 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_sendto(), ast_srtp::buf, len(), ast_srtp_res::protect, ast_rtp::rtcp, ast_rtp::s, and ast_rtcp::s.

Referenced by rtcp_sendto(), and rtp_sendto().

388 {
389  int len = size;
390  void *temp = buf;
391  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
392  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance);
393 
394  if (res_srtp && srtp && res_srtp->protect(srtp, &temp, &len, rtcp) < 0) {
395  return -1;
396  }
397 
398  return ast_sendto(rtcp ? rtp->rtcp->s : rtp->s, temp, len, flags, sa);
399 }
RTP session description.
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:486
int(* protect)(struct ast_srtp *srtp, void **buf, int *size, int rtcp)
Definition: res_srtp.h:48
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:1849
struct ast_rtcp * rtcp
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct ast_srtp_res * res_srtp
Definition: rtp_engine.c:48
unsigned char buf[8192+AST_FRIENDLY_OFFSET]
Definition: res_srtp.c:59
static void __unreg_module ( void  )
static

Definition at line 3101 of file res_rtp_asterisk.c.

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

References rtcpinterval.

Referenced by ast_rtp_raw_write(), and ast_rtp_read().

417 {
418  unsigned int interval;
419  /*! \todo XXX Do a more reasonable calculation on this one
420  * Look in RFC 3550 Section A.7 for an example*/
421  interval = rtcpinterval;
422  return interval;
423 }
static int rtcpinterval
static struct ast_frame* ast_rtcp_read ( struct ast_rtp_instance instance)
static

Definition at line 1790 of file res_rtp_asterisk.c.

References ast_rtcp::accumulated_transit, ast_assert, AST_CONTROL_VIDUPDATE, ast_debug, AST_FRAME_CONTROL, AST_FRIENDLY_OFFSET, ast_log(), ast_null_frame, ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), AST_RTP_PROPERTY_NAT, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_stringify(), ast_verbose(), ast_frame::datalen, errno, EVENT_FLAG_REPORTING, ast_rtp::f, f, ast_frame::frametype, if(), ast_frame_subclass::integer, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, manager_event, ast_rtcp::maxrtt, ast_rtcp::minrtt, normdev_compute(), ast_rtcp::normdevrtt, option_debug, ast_rtcp::reported_jitter, ast_rtcp::reported_jitter_count, 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, rtcp_debug_test_addr(), ast_rtcp::rtcp_info, RTCP_PT_BYE, RTCP_PT_FUR, RTCP_PT_RR, RTCP_PT_SDES, RTCP_PT_SR, rtcp_recvfrom(), ast_rtcp::rtt, ast_rtcp::rtt_count, ast_rtcp::rxlsr, ast_frame::samples, ast_rtcp::soc, ast_rtcp::spc, ast_frame::src, stddev_compute(), ast_rtcp::stdevrtt, ast_frame::subclass, ast_rtcp::them, ast_rtcp::themrxlsr, and timeval2ntp().

Referenced by ast_rtp_read().

1791 {
1792  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1793  struct ast_sockaddr addr;
1794  unsigned int rtcpdata[8192 + AST_FRIENDLY_OFFSET];
1795  unsigned int *rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET);
1796  int res, packetwords, position = 0;
1797  struct ast_frame *f = &ast_null_frame;
1798 
1799  /* Read in RTCP data from the socket */
1800  if ((res = rtcp_recvfrom(instance, rtcpdata + AST_FRIENDLY_OFFSET,
1801  sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET,
1802  0, &addr)) < 0) {
1803  ast_assert(errno != EBADF);
1804  if (errno != EAGAIN) {
1805  ast_log(LOG_WARNING, "RTCP Read error: %s. Hanging up.\n", strerror(errno));
1806  return NULL;
1807  }
1808  return &ast_null_frame;
1809  }
1810 
1811  packetwords = res / 4;
1812 
1814  /* Send to whoever sent to us */
1815  if (ast_sockaddr_cmp(&rtp->rtcp->them, &addr)) {
1816  ast_sockaddr_copy(&rtp->rtcp->them, &addr);
1817  if (option_debug || rtpdebug)
1818  ast_debug(0, "RTCP NAT: Got RTCP from other end. Now sending to address %s\n",
1819  ast_sockaddr_stringify(&rtp->rtcp->them));
1820  }
1821  }
1822 
1823  ast_debug(1, "Got RTCP report of %d bytes\n", res);
1824 
1825  while (position < packetwords) {
1826  int i, pt, rc;
1827  unsigned int length, dlsr, lsr, msw, lsw, comp;
1828  struct timeval now;
1829  double rttsec, reported_jitter, reported_normdev_jitter_current, normdevrtt_current, reported_lost, reported_normdev_lost_current;
1830  uint64_t rtt = 0;
1831 
1832  i = position;
1833  length = ntohl(rtcpheader[i]);
1834  pt = (length & 0xff0000) >> 16;
1835  rc = (length & 0x1f000000) >> 24;
1836  length &= 0xffff;
1837 
1838  if ((i + length) > packetwords) {
1839  if (option_debug || rtpdebug)
1840  ast_log(LOG_DEBUG, "RTCP Read too short\n");
1841  return &ast_null_frame;
1842  }
1843 
1844  if (rtcp_debug_test_addr(&addr)) {
1845  ast_verbose("\n\nGot RTCP from %s\n",
1846  ast_sockaddr_stringify(&addr));
1847  ast_verbose("PT: %d(%s)\n", pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Unknown");
1848  ast_verbose("Reception reports: %d\n", rc);
1849  ast_verbose("SSRC of sender: %u\n", rtcpheader[i + 1]);
1850  }
1851 
1852  i += 2; /* Advance past header and ssrc */
1853  if (rc == 0 && pt == RTCP_PT_RR) { /* We're receiving a receiver report with no reports, which is ok */
1854  position += (length + 1);
1855  continue;
1856  }
1857 
1858  switch (pt) {
1859  case RTCP_PT_SR:
1860  gettimeofday(&rtp->rtcp->rxlsr,NULL); /* To be able to populate the dlsr */
1861  rtp->rtcp->spc = ntohl(rtcpheader[i+3]);
1862  rtp->rtcp->soc = ntohl(rtcpheader[i + 4]);
1863  rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16); /* Going to LSR in RR*/
1864 
1865  if (rtcp_debug_test_addr(&addr)) {
1866  ast_verbose("NTP timestamp: %lu.%010lu\n", (unsigned long) ntohl(rtcpheader[i]), (unsigned long) ntohl(rtcpheader[i + 1]) * 4096);
1867  ast_verbose("RTP timestamp: %lu\n", (unsigned long) ntohl(rtcpheader[i + 2]));
1868  ast_verbose("SPC: %lu\tSOC: %lu\n", (unsigned long) ntohl(rtcpheader[i + 3]), (unsigned long) ntohl(rtcpheader[i + 4]));
1869  }
1870  i += 5;
1871  if (rc < 1)
1872  break;
1873  /* Intentional fall through */
1874  case RTCP_PT_RR:
1875  /* Don't handle multiple reception reports (rc > 1) yet */
1876  /* Calculate RTT per RFC */
1877  gettimeofday(&now, NULL);
1878  timeval2ntp(now, &msw, &lsw);
1879  if (ntohl(rtcpheader[i + 4]) && ntohl(rtcpheader[i + 5])) { /* We must have the LSR && DLSR */
1880  comp = ((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16);
1881  lsr = ntohl(rtcpheader[i + 4]);
1882  dlsr = ntohl(rtcpheader[i + 5]);
1883  rtt = comp - lsr - dlsr;
1884 
1885  /* Convert end to end delay to usec (keeping the calculation in 64bit space)
1886  sess->ee_delay = (eedelay * 1000) / 65536; */
1887  if (rtt < 4294) {
1888  rtt = (rtt * 1000000) >> 16;
1889  } else {
1890  rtt = (rtt * 1000) >> 16;
1891  rtt *= 1000;
1892  }
1893  rtt = rtt / 1000.;
1894  rttsec = rtt / 1000.;
1895  rtp->rtcp->rtt = rttsec;
1896 
1897  if (comp - dlsr >= lsr) {
1898  rtp->rtcp->accumulated_transit += rttsec;
1899 
1900  if (rtp->rtcp->rtt_count == 0)
1901  rtp->rtcp->minrtt = rttsec;
1902 
1903  if (rtp->rtcp->maxrtt<rttsec)
1904  rtp->rtcp->maxrtt = rttsec;
1905  if (rtp->rtcp->minrtt>rttsec)
1906  rtp->rtcp->minrtt = rttsec;
1907 
1908  normdevrtt_current = normdev_compute(rtp->rtcp->normdevrtt, rttsec, rtp->rtcp->rtt_count);
1909 
1910  rtp->rtcp->stdevrtt = stddev_compute(rtp->rtcp->stdevrtt, rttsec, rtp->rtcp->normdevrtt, normdevrtt_current, rtp->rtcp->rtt_count);
1911 
1912  rtp->rtcp->normdevrtt = normdevrtt_current;
1913 
1914  rtp->rtcp->rtt_count++;
1915  } else if (rtcp_debug_test_addr(&addr)) {
1916  ast_verbose("Internal RTCP NTP clock skew detected: "
1917  "lsr=%u, now=%u, dlsr=%u (%u:%03ums), "
1918  "diff=%u\n",
1919  lsr, comp, dlsr, dlsr / 65536,
1920  (dlsr % 65536) * 1000 / 65536,
1921  dlsr - (comp - lsr));
1922  }
1923  }
1924 
1925  rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]);
1926  reported_jitter = (double) rtp->rtcp->reported_jitter;
1927 
1928  if (rtp->rtcp->reported_jitter_count == 0)
1929  rtp->rtcp->reported_minjitter = reported_jitter;
1930 
1931  if (reported_jitter < rtp->rtcp->reported_minjitter)
1932  rtp->rtcp->reported_minjitter = reported_jitter;
1933 
1934  if (reported_jitter > rtp->rtcp->reported_maxjitter)
1935  rtp->rtcp->reported_maxjitter = reported_jitter;
1936 
1937  reported_normdev_jitter_current = normdev_compute(rtp->rtcp->reported_normdev_jitter, reported_jitter, rtp->rtcp->reported_jitter_count);
1938 
1939  rtp->rtcp->reported_stdev_jitter = stddev_compute(rtp->rtcp->reported_stdev_jitter, reported_jitter, rtp->rtcp->reported_normdev_jitter, reported_normdev_jitter_current, rtp->rtcp->reported_jitter_count);
1940 
1941  rtp->rtcp->reported_normdev_jitter = reported_normdev_jitter_current;
1942 
1943  rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff;
1944 
1945  reported_lost = (double) rtp->rtcp->reported_lost;
1946 
1947  /* using same counter as for jitter */
1948  if (rtp->rtcp->reported_jitter_count == 0)
1949  rtp->rtcp->reported_minlost = reported_lost;
1950 
1951  if (reported_lost < rtp->rtcp->reported_minlost)
1952  rtp->rtcp->reported_minlost = reported_lost;
1953 
1954  if (reported_lost > rtp->rtcp->reported_maxlost)
1955  rtp->rtcp->reported_maxlost = reported_lost;
1956  reported_normdev_lost_current = normdev_compute(rtp->rtcp->reported_normdev_lost, reported_lost, rtp->rtcp->reported_jitter_count);
1957 
1958  rtp->rtcp->reported_stdev_lost = stddev_compute(rtp->rtcp->reported_stdev_lost, reported_lost, rtp->rtcp->reported_normdev_lost, reported_normdev_lost_current, rtp->rtcp->reported_jitter_count);
1959 
1960  rtp->rtcp->reported_normdev_lost = reported_normdev_lost_current;
1961 
1962  rtp->rtcp->reported_jitter_count++;
1963 
1964  if (rtcp_debug_test_addr(&addr)) {
1965  ast_verbose(" Fraction lost: %ld\n", (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24));
1966  ast_verbose(" Packets lost so far: %u\n", rtp->rtcp->reported_lost);
1967  ast_verbose(" Highest sequence number: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff));
1968  ast_verbose(" Sequence number cycles: %ld\n", (long) (ntohl(rtcpheader[i + 2])) >> 16);
1969  ast_verbose(" Interarrival jitter: %u\n", rtp->rtcp->reported_jitter);
1970  ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096);
1971  ast_verbose(" DLSR: %4.4f (sec)\n",ntohl(rtcpheader[i + 5])/65536.0);
1972  if (rtt)
1973  ast_verbose(" RTT: %lu(sec)\n", (unsigned long) rtt);
1974  }
1975  if (rtt) {
1976  manager_event(EVENT_FLAG_REPORTING, "RTCPReceived", "From: %s\r\n"
1977  "PT: %d(%s)\r\n"
1978  "ReceptionReports: %d\r\n"
1979  "SenderSSRC: %u\r\n"
1980  "FractionLost: %ld\r\n"
1981  "PacketsLost: %u\r\n"
1982  "HighestSequence: %ld\r\n"
1983  "SequenceNumberCycles: %ld\r\n"
1984  "IAJitter: %u\r\n"
1985  "LastSR: %lu.%010lu\r\n"
1986  "DLSR: %4.4f(sec)\r\n"
1987  "RTT: %llu(sec)\r\n",
1988  ast_sockaddr_stringify(&addr),
1989  pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Unknown",
1990  rc,
1991  rtcpheader[i + 1],
1992  (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24),
1993  rtp->rtcp->reported_lost,
1994  (long) (ntohl(rtcpheader[i + 2]) & 0xffff),
1995  (long) (ntohl(rtcpheader[i + 2])) >> 16,
1996  rtp->rtcp->reported_jitter,
1997  (unsigned long) ntohl(rtcpheader[i + 4]) >> 16, ((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096,
1998  ntohl(rtcpheader[i + 5])/65536.0,
1999  (unsigned long long)rtt);
2000  } else {
2001  manager_event(EVENT_FLAG_REPORTING, "RTCPReceived", "From: %s\r\n"
2002  "PT: %d(%s)\r\n"
2003  "ReceptionReports: %d\r\n"
2004  "SenderSSRC: %u\r\n"
2005  "FractionLost: %ld\r\n"
2006  "PacketsLost: %u\r\n"
2007  "HighestSequence: %ld\r\n"
2008  "SequenceNumberCycles: %ld\r\n"
2009  "IAJitter: %u\r\n"
2010  "LastSR: %lu.%010lu\r\n"
2011  "DLSR: %4.4f(sec)\r\n",
2012  ast_sockaddr_stringify(&addr),
2013  pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Unknown",
2014  rc,
2015  rtcpheader[i + 1],
2016  (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24),
2017  rtp->rtcp->reported_lost,
2018  (long) (ntohl(rtcpheader[i + 2]) & 0xffff),
2019  (long) (ntohl(rtcpheader[i + 2])) >> 16,
2020  rtp->rtcp->reported_jitter,
2021  (unsigned long) ntohl(rtcpheader[i + 4]) >> 16,
2022  ((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096,
2023  ntohl(rtcpheader[i + 5])/65536.0);
2024  }
2025  break;
2026  case RTCP_PT_FUR:
2027  if (rtcp_debug_test_addr(&addr))
2028  ast_verbose("Received an RTCP Fast Update Request\n");
2029  rtp->f.frametype = AST_FRAME_CONTROL;
2031  rtp->f.datalen = 0;
2032  rtp->f.samples = 0;
2033  rtp->f.mallocd = 0;
2034  rtp->f.src = "RTP";
2035  f = &rtp->f;
2036  break;
2037  case RTCP_PT_SDES:
2038  if (rtcp_debug_test_addr(&addr))
2039  ast_verbose("Received an SDES from %s\n",
2040  ast_sockaddr_stringify(&rtp->rtcp->them));
2041  break;
2042  case RTCP_PT_BYE:
2043  if (rtcp_debug_test_addr(&addr))
2044  ast_verbose("Received a BYE from %s\n",
2045  ast_sockaddr_stringify(&rtp->rtcp->them));
2046  break;
2047  default:
2048  ast_debug(1, "Unknown RTCP packet (pt=%d) received from %s\n",
2049  pt, ast_sockaddr_stringify(&rtp->rtcp->them));
2050  break;
2051  }
2052  position += (length + 1);
2053  }
2054 
2055  rtp->rtcp->rtcp_info = 1;
2056 
2057  return f;
2058 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
#define RTCP_PT_SR
double reported_stdev_jitter
double reported_stdev_lost
static int rtpdebug
struct ast_frame ast_null_frame
Definition: frame.c:131
int option_debug
Definition: asterisk.c:182
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:121
#define LOG_WARNING
Definition: logger.h:144
double reported_minlost
double reported_minjitter
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
struct ast_sockaddr them
static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
unsigned int reported_jitter
#define ast_assert(a)
Definition: utils.h:738
unsigned int soc
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
double reported_maxlost
#define LOG_DEBUG
Definition: logger.h:122
Socket address structure.
Definition: netsock2.h:63
static int rtcp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct timeval rxlsr
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
double accumulated_transit
const char * src
Definition: frame.h:158
double reported_normdev_lost
int datalen
Definition: frame.h:148
unsigned int spc
struct ast_rtcp * rtcp
#define RTCP_PT_RR
static double stddev_compute(double stddev, double sample, double normdev, double normdev_curent, unsigned int sample_count)
static int rtcp_debug_test_addr(struct ast_sockaddr *addr)
static double normdev_compute(double normdev, double sample, unsigned int sample_count)
Calculate normal deviation.
unsigned int reported_lost
double stdevrtt
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
unsigned int themrxlsr
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
double reported_maxjitter
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
#define RTCP_PT_FUR
static struct ast_format f[]
Definition: format_g726.c:181
struct ast_frame f
if(yyss+yystacksize-1<=yyssp)
Definition: ast_expr2.c:1874
int mallocd
Definition: frame.h:152
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
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:478
Data structure associated with a single frame of data.
Definition: frame.h:142
unsigned int rtt_count
#define RTCP_PT_SDES
unsigned int reported_jitter_count
enum ast_frame_type frametype
Definition: frame.h:144
double normdevrtt
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
#define RTCP_PT_BYE
int samples
Definition: frame.h:150
double reported_normdev_jitter
static int ast_rtcp_write ( const void *  data)
static

Write and 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

Definition at line 1140 of file res_rtp_asterisk.c.

References ao2_ref, ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_instance_get_data(), ast_rtcp::lastsrtxcount, ast_rtp::rtcp, ast_rtcp::schedid, and ast_rtp::txcount.

Referenced by ast_rtp_raw_write(), and ast_rtp_read().

1141 {
1142  struct ast_rtp_instance *instance = (struct ast_rtp_instance *) data;
1143  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1144  int res;
1145 
1146  if (!rtp || !rtp->rtcp || rtp->rtcp->schedid == -1) {
1147  ao2_ref(instance, -1);
1148  return 0;
1149  }
1150 
1151  if (rtp->txcount > rtp->rtcp->lastsrtxcount) {
1152  res = ast_rtcp_write_sr(instance);
1153  } else {
1154  res = ast_rtcp_write_rr(instance);
1155  }
1156 
1157  if (!res) {
1158  /*
1159  * Not being rescheduled.
1160  */
1161  ao2_ref(instance, -1);
1162  rtp->rtcp->schedid = -1;
1163  }
1164 
1165  return res;
1166 }
RTP session description.
unsigned int txcount
static int ast_rtcp_write_rr(struct ast_rtp_instance *instance)
Send RTCP recipient&#39;s report.
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct ast_rtcp * rtcp
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
unsigned int lastsrtxcount
static int ast_rtcp_write_sr(struct ast_rtp_instance *instance)
Send RTCP sender&#39;s report.
static int ast_rtcp_write_rr ( struct ast_rtp_instance instance)
static

Send RTCP recipient's report.

Note
Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos it can change mid call, and SDES can't)

Definition at line 908 of file res_rtp_asterisk.c.

References ast_log(), ast_rtp_instance_get_data(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verbose(), ast_frame_subclass::codec, ast_rtp::cycles, errno, ast_rtcp::expected_prior, ast_rtp::f, ast_rtp::lastrxseqno, len(), LOG_ERROR, ast_rtcp::maxrxlost, ast_rtcp::minrxlost, normdev_compute(), ast_rtcp::normdev_rxlost, ast_rtcp::received_prior, ast_rtcp::rr_count, ast_rtp::rtcp, rtcp_debug_test_addr(), RTCP_PT_RR, RTCP_PT_SDES, rtcp_sendto(), rtp_get_rate(), ast_rtp::rxcount, ast_rtp::rxjitter, ast_rtcp::rxlost, ast_rtcp::rxlost_count, ast_rtcp::rxlsr, ast_rtp::seedrxseqno, ast_rtp::ssrc, stddev_compute(), ast_rtcp::stdev_rxlost, ast_frame::subclass, ast_rtcp::them, ast_rtcp::themrxlsr, ast_rtp::themssrc, and timersub().

Referenced by ast_rtcp_write().

909 {
910  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
911  int res;
912  int len = 32;
913  unsigned int lost;
914  unsigned int extended;
915  unsigned int expected;
916  unsigned int expected_interval;
917  unsigned int received_interval;
918  int lost_interval;
919  struct timeval now;
920  unsigned int *rtcpheader;
921  char bdata[1024];
922  struct timeval dlsr;
923  int fraction;
924  int rate = rtp_get_rate(rtp->f.subclass.codec);
925 
926  double rxlost_current;
927 
928  if (!rtp || !rtp->rtcp)
929  return 0;
930 
931  if (ast_sockaddr_isnull(&rtp->rtcp->them)) {
932  /*
933  * RTCP was stopped.
934  */
935  return 0;
936  }
937 
938  extended = rtp->cycles + rtp->lastrxseqno;
939  expected = extended - rtp->seedrxseqno + 1;
940  lost = expected - rtp->rxcount;
941  expected_interval = expected - rtp->rtcp->expected_prior;
942  rtp->rtcp->expected_prior = expected;
943  received_interval = rtp->rxcount - rtp->rtcp->received_prior;
944  rtp->rtcp->received_prior = rtp->rxcount;
945  lost_interval = expected_interval - received_interval;
946 
947  if (lost_interval <= 0)
948  rtp->rtcp->rxlost = 0;
949  else rtp->rtcp->rxlost = rtp->rtcp->rxlost;
950  if (rtp->rtcp->rxlost_count == 0)
951  rtp->rtcp->minrxlost = rtp->rtcp->rxlost;
952  if (lost_interval < rtp->rtcp->minrxlost)
953  rtp->rtcp->minrxlost = rtp->rtcp->rxlost;
954  if (lost_interval > rtp->rtcp->maxrxlost)
955  rtp->rtcp->maxrxlost = rtp->rtcp->rxlost;
956 
957  rxlost_current = normdev_compute(rtp->rtcp->normdev_rxlost, rtp->rtcp->rxlost, rtp->rtcp->rxlost_count);
958  rtp->rtcp->stdev_rxlost = stddev_compute(rtp->rtcp->stdev_rxlost, rtp->rtcp->rxlost, rtp->rtcp->normdev_rxlost, rxlost_current, rtp->rtcp->rxlost_count);
959  rtp->rtcp->normdev_rxlost = rxlost_current;
960  rtp->rtcp->rxlost_count++;
961 
962  if (expected_interval == 0 || lost_interval <= 0)
963  fraction = 0;
964  else
965  fraction = (lost_interval << 8) / expected_interval;
966  gettimeofday(&now, NULL);
967  timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
968  rtcpheader = (unsigned int *)bdata;
969  rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_RR << 16) | ((len/4)-1));
970  rtcpheader[1] = htonl(rtp->ssrc);
971  rtcpheader[2] = htonl(rtp->themssrc);
972  rtcpheader[3] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff));
973  rtcpheader[4] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff)));
974  rtcpheader[5] = htonl((unsigned int)(rtp->rxjitter * rate));
975  rtcpheader[6] = htonl(rtp->rtcp->themrxlsr);
976  rtcpheader[7] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000);
977 
978  /*! \note Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos
979  it can change mid call, and SDES can't) */
980  rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2);
981  rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */
982  rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */
983  len += 12;
984 
985  res = rtcp_sendto(instance, (unsigned int *)rtcpheader, len, 0, &rtp->rtcp->them);
986 
987  if (res < 0) {
988  ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted: %s\n",strerror(errno));
989  return 0;
990  }
991 
992  rtp->rtcp->rr_count++;
993  if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
994  ast_verbose("\n* Sending RTCP RR to %s\n"
995  " Our SSRC: %u\nTheir SSRC: %u\niFraction lost: %d\nCumulative loss: %u\n"
996  " IA jitter: %.4f\n"
997  " Their last SR: %u\n"
998  " DLSR: %4.4f (sec)\n\n",
1000  rtp->ssrc, rtp->themssrc, fraction, lost,
1001  rtp->rxjitter,
1002  rtp->rtcp->themrxlsr,
1003  (double)(ntohl(rtcpheader[7])/65536.0));
1004  }
1005 
1006  return res;
1007 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
double rxjitter
unsigned int rxlost_count
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
struct ast_sockaddr them
unsigned int rxcount
format_t codec
Definition: frame.h:137
unsigned int expected_prior
double stdev_rxlost
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
unsigned int ssrc
struct timeval rxlsr
double normdev_rxlost
struct ast_rtcp * rtcp
unsigned int cycles
#define RTCP_PT_RR
static double stddev_compute(double stddev, double sample, double normdev, double normdev_curent, unsigned int sample_count)
static int rtcp_debug_test_addr(struct ast_sockaddr *addr)
unsigned int themssrc
void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff)
#define LOG_ERROR
Definition: logger.h:155
static double normdev_compute(double normdev, double sample, unsigned int sample_count)
Calculate normal deviation.
unsigned int received_prior
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
unsigned int themrxlsr
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
unsigned int rr_count
struct ast_frame f
static int rtp_get_rate(format_t subclass)
#define RTCP_PT_SDES
static int rtcp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
double minrxlost
unsigned short seedrxseqno
double maxrxlost
static int ast_rtcp_write_sr ( struct ast_rtp_instance instance)
static

Send RTCP sender's report.

Definition at line 1010 of file res_rtp_asterisk.c.

References ast_log(), ast_rtp_instance_get_data(), ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_verbose(), ast_frame_subclass::codec, ast_rtp::cycles, errno, EVENT_FLAG_REPORTING, ast_rtcp::expected_prior, ast_rtp::f, ast_rtp::lastrxseqno, ast_rtcp::lastsrtxcount, ast_rtp::lastts, len(), LOG_ERROR, manager_event, ast_rtcp::received_prior, ast_rtp::rtcp, rtcp_debug_test_addr(), RTCP_PT_SDES, RTCP_PT_SR, rtcp_sendto(), rtp_get_rate(), ast_rtp::rxcount, ast_rtp::rxjitter, ast_rtcp::rxlsr, ast_rtp::seedrxseqno, ast_rtcp::sr_count, ast_rtp::ssrc, ast_frame::subclass, ast_rtcp::them, ast_rtcp::themrxlsr, ast_rtp::themssrc, timersub(), timeval2ntp(), ast_rtp::txcount, ast_rtcp::txlsr, and ast_rtp::txoctetcount.

Referenced by ast_rtcp_write().

1011 {
1012  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1013  int res;
1014  int len = 0;
1015  struct timeval now;
1016  unsigned int now_lsw;
1017  unsigned int now_msw;
1018  unsigned int *rtcpheader;
1019  unsigned int lost;
1020  unsigned int extended;
1021  unsigned int expected;
1022  unsigned int expected_interval;
1023  unsigned int received_interval;
1024  int lost_interval;
1025  int fraction;
1026  struct timeval dlsr;
1027  char bdata[512];
1028  int rate = rtp_get_rate(rtp->f.subclass.codec);
1029 
1030  if (!rtp || !rtp->rtcp)
1031  return 0;
1032 
1033  if (ast_sockaddr_isnull(&rtp->rtcp->them)) { /* This'll stop rtcp for this rtp session */
1034  /*
1035  * RTCP was stopped.
1036  */
1037  return 0;
1038  }
1039 
1040  gettimeofday(&now, NULL);
1041  timeval2ntp(now, &now_msw, &now_lsw); /* fill thses ones in from utils.c*/
1042  rtcpheader = (unsigned int *)bdata;
1043  rtcpheader[1] = htonl(rtp->ssrc); /* Our SSRC */
1044  rtcpheader[2] = htonl(now_msw); /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970*/
1045  rtcpheader[3] = htonl(now_lsw); /* now, LSW */
1046  rtcpheader[4] = htonl(rtp->lastts); /* FIXME shouldn't be that, it should be now */
1047  rtcpheader[5] = htonl(rtp->txcount); /* No. packets sent */
1048  rtcpheader[6] = htonl(rtp->txoctetcount); /* No. bytes sent */
1049  len += 28;
1050 
1051  extended = rtp->cycles + rtp->lastrxseqno;
1052  expected = extended - rtp->seedrxseqno + 1;
1053  if (rtp->rxcount > expected)
1054  expected += rtp->rxcount - expected;
1055  lost = expected - rtp->rxcount;
1056  expected_interval = expected - rtp->rtcp->expected_prior;
1057  rtp->rtcp->expected_prior = expected;
1058  received_interval = rtp->rxcount - rtp->rtcp->received_prior;
1059  rtp->rtcp->received_prior = rtp->rxcount;
1060  lost_interval = expected_interval - received_interval;
1061  if (expected_interval == 0 || lost_interval <= 0)
1062  fraction = 0;
1063  else
1064  fraction = (lost_interval << 8) / expected_interval;
1065  timersub(&now, &rtp->rtcp->rxlsr, &dlsr);
1066  rtcpheader[7] = htonl(rtp->themssrc);
1067  rtcpheader[8] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff));
1068  rtcpheader[9] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff)));
1069  rtcpheader[10] = htonl((unsigned int)(rtp->rxjitter * rate));
1070  rtcpheader[11] = htonl(rtp->rtcp->themrxlsr);
1071  rtcpheader[12] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000);
1072  len += 24;
1073 
1074  rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SR << 16) | ((len/4)-1));
1075 
1076  /* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */
1077  /* it can change mid call, and SDES can't) */
1078  rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2);
1079  rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */
1080  rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */
1081  len += 12;
1082 
1083  res = rtcp_sendto(instance, (unsigned int *)rtcpheader, len, 0, &rtp->rtcp->them);
1084  if (res < 0) {
1085  ast_log(LOG_ERROR, "RTCP SR transmission error to %s, rtcp halted %s\n",
1087  strerror(errno));
1088  return 0;
1089  }
1090 
1091  /* FIXME Don't need to get a new one */
1092  gettimeofday(&rtp->rtcp->txlsr, NULL);
1093  rtp->rtcp->sr_count++;
1094 
1095  rtp->rtcp->lastsrtxcount = rtp->txcount;
1096 
1097  if (rtcp_debug_test_addr(&rtp->rtcp->them)) {
1098  ast_verbose("* Sent RTCP SR to %s\n", ast_sockaddr_stringify(&rtp->rtcp->them));
1099  ast_verbose(" Our SSRC: %u\n", rtp->ssrc);
1100  ast_verbose(" Sent(NTP): %u.%010u\n", (unsigned int)now.tv_sec, (unsigned int)now.tv_usec*4096);
1101  ast_verbose(" Sent(RTP): %u\n", rtp->lastts);
1102  ast_verbose(" Sent packets: %u\n", rtp->txcount);
1103  ast_verbose(" Sent octets: %u\n", rtp->txoctetcount);
1104  ast_verbose(" Report block:\n");
1105  ast_verbose(" Fraction lost: %d\n", fraction);
1106  ast_verbose(" Cumulative loss: %u\n", lost);
1107  ast_verbose(" IA jitter: %.4f\n", rtp->rxjitter);
1108  ast_verbose(" Their last SR: %u\n", rtp->rtcp->themrxlsr);
1109  ast_verbose(" DLSR: %4.4f (sec)\n\n", (double)(ntohl(rtcpheader[12])/65536.0));
1110  }
1111  manager_event(EVENT_FLAG_REPORTING, "RTCPSent", "To: %s\r\n"
1112  "OurSSRC: %u\r\n"
1113  "SentNTP: %u.%010u\r\n"
1114  "SentRTP: %u\r\n"
1115  "SentPackets: %u\r\n"
1116  "SentOctets: %u\r\n"
1117  "ReportBlock:\r\n"
1118  "FractionLost: %d\r\n"
1119  "CumulativeLoss: %u\r\n"
1120  "IAJitter: %.4f\r\n"
1121  "TheirLastSR: %u\r\n"
1122  "DLSR: %4.4f (sec)\r\n",
1124  rtp->ssrc,
1125  (unsigned int)now.tv_sec, (unsigned int)now.tv_usec*4096,
1126  rtp->lastts,
1127  rtp->txcount,
1128  rtp->txoctetcount,
1129  fraction,
1130  lost,
1131  rtp->rxjitter,
1132  rtp->rtcp->themrxlsr,
1133  (double)(ntohl(rtcpheader[12])/65536.0));
1134  return res;
1135 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
#define RTCP_PT_SR
double rxjitter
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
unsigned int txcount
struct ast_sockaddr them
unsigned int rxcount
static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
format_t codec
Definition: frame.h:137
unsigned int expected_prior
unsigned int sr_count
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
unsigned int ssrc
struct timeval rxlsr
struct timeval txlsr
struct ast_rtcp * rtcp
unsigned int cycles
static int rtcp_debug_test_addr(struct ast_sockaddr *addr)
unsigned int themssrc
void timersub(struct timeval *tvend, struct timeval *tvstart, struct timeval *tvdiff)
#define LOG_ERROR
Definition: logger.h:155
unsigned int received_prior
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
unsigned int themrxlsr
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct ast_frame f
static int rtp_get_rate(format_t subclass)
unsigned int lastsrtxcount
#define EVENT_FLAG_REPORTING
Definition: manager.h:80
unsigned int lastts
unsigned int txoctetcount
#define RTCP_PT_SDES
static int rtcp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
#define manager_event(category, event, contents,...)
External routines may send asterisk manager events this way.
Definition: manager.h:219
unsigned short seedrxseqno
static void ast_rtp_alt_remote_address_set ( struct ast_rtp_instance instance,
struct ast_sockaddr addr 
)
static

Definition at line 2622 of file res_rtp_asterisk.c.

References ast_rtp::alt_rtp_address, ast_rtp_instance_get_data(), and ast_sockaddr_copy().

2623 {
2624  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2625 
2626  /* No need to futz with rtp->rtcp here because ast_rtcp_read is already able to adjust if receiving
2627  * RTCP from an "unexpected" source
2628  */
2629  ast_sockaddr_copy(&rtp->alt_rtp_address, addr);
2630 
2631  return;
2632 }
RTP session description.
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:121
struct ast_sockaddr alt_rtp_address
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
static void ast_rtp_change_source ( struct ast_rtp_instance instance)
static

Definition at line 871 of file res_rtp_asterisk.c.

References ast_debug, ast_random(), ast_rtp_instance_get_data(), ast_rtp_instance_get_srtp(), ast_set_flag, ast_srtp_res::change_source, FLAG_NEED_MARKER_BIT, ast_rtp::lastts, and ast_rtp::ssrc.

872 {
873  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
874  struct ast_srtp *srtp = ast_rtp_instance_get_srtp(instance);
875  unsigned int ssrc = ast_random();
876 
877  if (!rtp->lastts) {
878  ast_debug(3, "Not changing SSRC since we haven't sent any RTP yet\n");
879  return;
880  }
881 
882  /* We simply set this bit so that the next packet sent will have the marker bit turned on */
884 
885  ast_debug(3, "Changing ssrc from %u to %u due to a source change\n", rtp->ssrc, ssrc);
886 
887  if (srtp) {
888  ast_debug(3, "Changing ssrc for SRTP from %u to %u\n", rtp->ssrc, ssrc);
889  res_srtp->change_source(srtp, rtp->ssrc, ssrc);
890  }
891 
892  rtp->ssrc = ssrc;
893 
894  return;
895 }
RTP session description.
#define ast_set_flag(p, flag)
Definition: utils.h:70
int(* change_source)(struct ast_srtp *srtp, unsigned int from_ssrc, unsigned int to_ssrc)
Definition: res_srtp.h:42
struct ast_srtp * ast_rtp_instance_get_srtp(struct ast_rtp_instance *instance)
Obtain the SRTP instance associated with an RTP instance.
Definition: rtp_engine.c:1849
unsigned int ssrc
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
long int ast_random(void)
Definition: utils.c:1640
#define FLAG_NEED_MARKER_BIT
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct ast_srtp_res * res_srtp
Definition: rtp_engine.c:48
unsigned int lastts
static int ast_rtp_destroy ( struct ast_rtp_instance instance)
static

Definition at line 616 of file res_rtp_asterisk.c.

References ast_free, ast_rtp_instance_get_data(), AST_SCHED_DEL, ast_smoother_free(), ast_rtp::red, ast_rtp::rtcp, ast_rtp::s, ast_rtcp::s, ast_rtp::sched, rtp_red::schedid, and ast_rtp::smoother.

617 {
618  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
619 
620  /* Destroy the smoother that was smoothing out audio if present */
621  if (rtp->smoother) {
623  }
624 
625  /* Close our own socket so we no longer get packets */
626  if (rtp->s > -1) {
627  close(rtp->s);
628  }
629 
630  /* Destroy RTCP if it was being used */
631  if (rtp->rtcp) {
632  /*
633  * It is not possible for there to be an active RTCP scheduler
634  * entry at this point since it holds a reference to the
635  * RTP instance while it's active.
636  */
637  close(rtp->rtcp->s);
638  ast_free(rtp->rtcp);
639  }
640 
641  /* Destroy RED if it was being used */
642  if (rtp->red) {
643  AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
644  ast_free(rtp->red);
645  }
646 
647  /* Finally destroy ourselves */
648  ast_free(rtp);
649 
650  return 0;
651 }
RTP session description.
void ast_smoother_free(struct ast_smoother *s)
Definition: frame.c:294
struct sched_context * sched
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
struct ast_rtcp * rtcp
#define ast_free(a)
Definition: astmm.h:97
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct ast_smoother * smoother
struct rtp_red * red
static int ast_rtp_dtmf_begin ( struct ast_rtp_instance instance,
char  digit 
)
static

Definition at line 666 of file res_rtp_asterisk.c.

References ast_log(), ast_rtp_codecs_payload_code(), 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(), DTMF_SAMPLE_RATE_MS, ast_rtp::dtmfmute, errno, ast_rtp::lastdigitts, ast_rtp::lastts, LOG_ERROR, LOG_WARNING, 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.

667 {
668  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
669  struct ast_sockaddr remote_address = { {0,} };
670  int hdrlen = 12, res = 0, i = 0, payload = 101;
671  char data[256];
672  unsigned int *rtpheader = (unsigned int*)data;
673 
674  ast_rtp_instance_get_remote_address(instance, &remote_address);
675 
676  /* If we have no remote address information bail out now */
677  if (ast_sockaddr_isnull(&remote_address)) {
678  return -1;
679  }
680 
681  /* Convert given digit into what we want to transmit */
682  if ((digit <= '9') && (digit >= '0')) {
683  digit -= '0';
684  } else if (digit == '*') {
685  digit = 10;
686  } else if (digit == '#') {
687  digit = 11;
688  } else if ((digit >= 'A') && (digit <= 'D')) {
689  digit = digit - 'A' + 12;
690  } else if ((digit >= 'a') && (digit <= 'd')) {
691  digit = digit - 'a' + 12;
692  } else {
693  ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
694  return -1;
695  }
696 
697  /* Grab the payload that they expect the RFC2833 packet to be received in */
699 
700  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
701  rtp->send_duration = 160;
702  rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
703  rtp->lastdigitts = rtp->lastts + rtp->send_duration;
704 
705  /* Create the actual packet that we will be sending */
706  rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno));
707  rtpheader[1] = htonl(rtp->lastdigitts);
708  rtpheader[2] = htonl(rtp->ssrc);
709 
710  /* Actually send the packet */
711  for (i = 0; i < 2; i++) {
712  rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
713  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address);
714  if (res < 0) {
715  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
716  ast_sockaddr_stringify(&remote_address),
717  strerror(errno));
718  }
719  if (rtp_debug_test_addr(&remote_address)) {
720  ast_verbose("Sent RTP DTMF packet to %s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
721  ast_sockaddr_stringify(&remote_address),
722  payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
723  }
724  rtp->seqno++;
725  rtp->send_duration += 160;
726  rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
727  }
728 
729  /* Record that we are in the process of sending a digit and information needed to continue doing so */
730  rtp->sending_digit = 1;
731  rtp->send_digit = digit;
732  rtp->send_payload = payload;
733 
734  return 0;
735 }
RTP session description.
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
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:483
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
Socket address structure.
Definition: netsock2.h:63
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
unsigned int ssrc
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define LOG_ERROR
Definition: logger.h:155
unsigned int lastdigitts
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
#define DTMF_SAMPLE_RATE_MS
unsigned int lastts
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
struct timeval dtmfmute
unsigned short seqno
#define AST_RTP_DTMF
Definition: rtp_engine.h:218
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code)
Retrieve a payload based on whether it is an Asterisk format and the code.
Definition: rtp_engine.c:654
char sending_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

Definition at line 2753 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_prop(), AST_RTP_PROPERTY_DTMF, ast_channel_tech::send_digit_begin, and ast_channel::tech.

2754 {
2755  /* If both sides are not using the same method of DTMF transmission
2756  * (ie: one is RFC2833, other is INFO... then we can not do direct media.
2757  * --------------------------------------------------
2758  * | DTMF Mode | HAS_DTMF | Accepts Begin Frames |
2759  * |-----------|------------|-----------------------|
2760  * | Inband | False | True |
2761  * | RFC2833 | True | True |
2762  * | SIP INFO | False | False |
2763  * --------------------------------------------------
2764  */
2766  (!chan0->tech->send_digit_begin != !chan1->tech->send_digit_begin)) ? 0 : 1);
2767 }
int(*const send_digit_begin)(struct ast_channel *chan, char digit)
Start sending a literal DTMF digit.
Definition: channel.h:528
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:478
struct ast_channel_tech * tech
Definition: channel.h:743
static int ast_rtp_dtmf_continuation ( struct ast_rtp_instance instance)
static

Definition at line 737 of file res_rtp_asterisk.c.

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, 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_read().

738 {
739  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
740  struct ast_sockaddr remote_address = { {0,} };
741  int hdrlen = 12, res = 0;
742  char data[256];
743  unsigned int *rtpheader = (unsigned int*)data;
744 
745  ast_rtp_instance_get_remote_address(instance, &remote_address);
746 
747  /* Make sure we know where the other side is so we can send them the packet */
748  if (ast_sockaddr_isnull(&remote_address)) {
749  return -1;
750  }
751 
752  /* Actually create the packet we will be sending */
753  rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
754  rtpheader[1] = htonl(rtp->lastdigitts);
755  rtpheader[2] = htonl(rtp->ssrc);
756  rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration));
757 
758  /* Boom, send it on out */
759  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address);
760  if (res < 0) {
761  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
762  ast_sockaddr_stringify(&remote_address),
763  strerror(errno));
764  }
765 
766  if (rtp_debug_test_addr(&remote_address)) {
767  ast_verbose("Sent RTP DTMF packet to %s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
768  ast_sockaddr_stringify(&remote_address),
769  rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
770  }
771 
772  /* And now we increment some values for the next time we swing by */
773  rtp->seqno++;
774  rtp->send_duration += 160;
775  rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
776 
777  return 0;
778 }
RTP session description.
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
Socket address structure.
Definition: netsock2.h:63
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
unsigned int ssrc
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define LOG_ERROR
Definition: logger.h:155
unsigned int lastdigitts
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
#define DTMF_SAMPLE_RATE_MS
unsigned int lastts
unsigned short seqno
static int ast_rtp_dtmf_end ( struct ast_rtp_instance instance,
char  digit 
)
static

Definition at line 855 of file res_rtp_asterisk.c.

References ast_rtp_dtmf_end_with_duration().

856 {
857  return ast_rtp_dtmf_end_with_duration(instance, digit, 0);
858 }
static int ast_rtp_dtmf_end_with_duration(struct ast_rtp_instance *instance, char digit, unsigned int duration)
static int ast_rtp_dtmf_end_with_duration ( struct ast_rtp_instance instance,
char  digit,
unsigned int  duration 
)
static

Definition at line 780 of file res_rtp_asterisk.c.

References ast_debug, ast_log(), 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(), cleanup(), ast_frame_subclass::codec, DTMF_SAMPLE_RATE_MS, ast_rtp::dtmfmute, errno, ast_rtp::f, ast_rtp::lastdigitts, ast_rtp::lastts, LOG_ERROR, LOG_WARNING, rtp_debug_test_addr(), rtp_get_rate(), rtp_sendto(), ast_rtp::send_digit, ast_rtp::send_duration, ast_rtp::send_payload, ast_rtp::sending_digit, ast_rtp::seqno, ast_rtp::ssrc, and ast_frame::subclass.

Referenced by ast_rtp_dtmf_end().

781 {
782  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
783  struct ast_sockaddr remote_address = { {0,} };
784  int hdrlen = 12, res = -1, i = 0;
785  char data[256];
786  unsigned int *rtpheader = (unsigned int*)data;
787  unsigned int measured_samples;
788 
789  ast_rtp_instance_get_remote_address(instance, &remote_address);
790 
791  /* Make sure we know where the remote side is so we can send them the packet we construct */
792  if (ast_sockaddr_isnull(&remote_address)) {
793  goto cleanup;
794  }
795 
796  /* Convert the given digit to the one we are going to send */
797  if ((digit <= '9') && (digit >= '0')) {
798  digit -= '0';
799  } else if (digit == '*') {
800  digit = 10;
801  } else if (digit == '#') {
802  digit = 11;
803  } else if ((digit >= 'A') && (digit <= 'D')) {
804  digit = digit - 'A' + 12;
805  } else if ((digit >= 'a') && (digit <= 'd')) {
806  digit = digit - 'a' + 12;
807  } else {
808  ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
809  goto cleanup;
810  }
811 
812  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
813 
814  if (duration > 0 && (measured_samples = duration * rtp_get_rate(rtp->f.subclass.codec) / 1000) > rtp->send_duration) {
815  ast_debug(2, "Adjusting final end duration from %d to %u\n", rtp->send_duration, measured_samples);
816  rtp->send_duration = measured_samples;
817  }
818 
819  /* Construct the packet we are going to send */
820  rtpheader[1] = htonl(rtp->lastdigitts);
821  rtpheader[2] = htonl(rtp->ssrc);
822  rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration));
823  rtpheader[3] |= htonl((1 << 23));
824 
825  /* Send it 3 times, that's the magical number */
826  for (i = 0; i < 3; i++) {
827 
828  rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno));
829 
830  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 4, 0, &remote_address);
831  if (res < 0) {
832  ast_log(LOG_ERROR, "RTP Transmission error to %s: %s\n",
833  ast_sockaddr_stringify(&remote_address),
834  strerror(errno));
835  }
836  if (rtp_debug_test_addr(&remote_address)) {
837  ast_verbose("Sent RTP DTMF packet to %s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
838  ast_sockaddr_stringify(&remote_address),
839  rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen);
840  }
841 
842  rtp->seqno++;
843  }
844  res = 0;
845 
846  /* Oh and we can't forget to turn off the stuff that says we are sending DTMF */
847  rtp->lastts += calc_txstamp(rtp, NULL) * DTMF_SAMPLE_RATE_MS;
848 cleanup:
849  rtp->sending_digit = 0;
850  rtp->send_digit = 0;
851 
852  return res;
853 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
format_t codec
Definition: frame.h:137
Socket address structure.
Definition: netsock2.h:63
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
unsigned int ssrc
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define LOG_ERROR
Definition: logger.h:155
unsigned int lastdigitts
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
#define DTMF_SAMPLE_RATE_MS
struct ast_frame f
static void * cleanup(void *unused)
Definition: pbx_realtime.c:125
static int rtp_get_rate(format_t subclass)
unsigned int lastts
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
struct timeval dtmfmute
unsigned short seqno
char sending_digit
static enum ast_rtp_dtmf_mode ast_rtp_dtmf_mode_get ( struct ast_rtp_instance instance)
static

Definition at line 660 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::dtmfmode.

661 {
662  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
663  return rtp->dtmfmode;
664 }
RTP session description.
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
enum ast_rtp_dtmf_mode dtmfmode
static int ast_rtp_dtmf_mode_set ( struct ast_rtp_instance instance,
enum ast_rtp_dtmf_mode  dtmf_mode 
)
static

Definition at line 653 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), and ast_rtp::dtmfmode.

654 {
655  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
656  rtp->dtmfmode = dtmf_mode;
657  return 0;
658 }
RTP session description.
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
enum ast_rtp_dtmf_mode dtmfmode
static int ast_rtp_fd ( struct ast_rtp_instance instance,
int  rtcp 
)
static

Definition at line 2592 of file res_rtp_asterisk.c.

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

2593 {
2594  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2595 
2596  return rtcp ? (rtp->rtcp ? rtp->rtcp->s : -1) : rtp->s;
2597 }
RTP session description.
struct ast_rtcp * rtcp
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
static int ast_rtp_get_stat ( struct ast_rtp_instance instance,
struct ast_rtp_instance_stats stats,
enum ast_rtp_instance_stat  stat 
)
static

Definition at line 2705 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), 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_RXPLOSS, AST_RTP_INSTANCE_STAT_STDEVRTT, AST_RTP_INSTANCE_STAT_TXCOUNT, AST_RTP_INSTANCE_STAT_TXJITTER, AST_RTP_INSTANCE_STAT_TXPLOSS, AST_RTP_STAT_SET, AST_RTP_STAT_TERMINATOR, 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_rtcp::maxrtt, ast_rtp_instance_stats::maxrtt, ast_rtcp::maxrxjitter, ast_rtcp::maxrxlost, ast_rtcp::minrtt, ast_rtp_instance_stats::minrtt, ast_rtcp::minrxjitter, ast_rtcp::minrxlost, ast_rtcp::normdev_rxjitter, ast_rtcp::normdev_rxlost, ast_rtcp::normdevrtt, ast_rtp_instance_stats::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_rtcp::rtt, ast_rtp_instance_stats::rtt, ast_rtp::rxcount, ast_rtp_instance_stats::rxcount, ast_rtp::rxjitter, ast_rtp_instance_stats::rxjitter, ast_rtp_instance_stats::rxploss, ast_rtp::ssrc, ast_rtcp::stdev_rxjitter, ast_rtcp::stdev_rxlost, ast_rtcp::stdevrtt, ast_rtp_instance_stats::stdevrtt, ast_rtp::themssrc, ast_rtp::txcount, ast_rtp_instance_stats::txcount, ast_rtp_instance_stats::txjitter, and ast_rtp_instance_stats::txploss.

2706 {
2707  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2708 
2709  if (!rtp->rtcp) {
2710  return -1;
2711  }
2712 
2715 
2727 
2739 
2746 
2749 
2750  return 0;
2751 }
RTP session description.
double reported_stdev_jitter
double reported_stdev_lost
double rxjitter
double reported_minlost
double reported_minjitter
unsigned int txcount
unsigned int txcount
Definition: rtp_engine.h:237
unsigned int rxcount
unsigned int rxploss
Definition: rtp_engine.h:263
unsigned int reported_jitter
double stdev_rxjitter
double reported_maxlost
unsigned int expected_prior
double minrxjitter
double stdev_rxlost
unsigned int ssrc
double reported_normdev_lost
double normdev_rxlost
double maxrxjitter
struct ast_rtcp * rtcp
unsigned int rxcount
Definition: rtp_engine.h:239
unsigned int themssrc
unsigned int reported_lost
double stdevrtt
unsigned int received_prior
unsigned int local_ssrc
Definition: rtp_engine.h:291
double reported_maxjitter
unsigned int txploss
Definition: rtp_engine.h:261
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
#define AST_RTP_STAT_SET(current_stat, combined, placement, value)
Definition: rtp_engine.h:296
#define AST_RTP_STAT_TERMINATOR(combined)
Definition: rtp_engine.h:304
double normdevrtt
double minrxlost
double normdev_rxjitter
double maxrxlost
unsigned int remote_ssrc
Definition: rtp_engine.h:293
double reported_normdev_jitter
static int ast_rtp_local_bridge ( struct ast_rtp_instance instance0,
struct ast_rtp_instance instance1 
)
static

Definition at line 2696 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_set_flag, and FLAG_NEED_MARKER_BIT.

2697 {
2698  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance0);
2699 
2701 
2702  return 0;
2703 }
RTP session description.
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define FLAG_NEED_MARKER_BIT
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
static int ast_rtp_new ( struct ast_rtp_instance instance,
struct sched_context sched,
struct ast_sockaddr addr,
void *  data 
)
static

Definition at line 549 of file res_rtp_asterisk.c.

References ast_bind(), ast_calloc, ast_debug, ast_free, ast_log(), ast_random(), ast_rtp_instance_set_data(), ast_rtp_instance_set_local_address(), ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv6(), ast_sockaddr_set_port, create_new_socket(), errno, LOG_ERROR, rtp_learning_seq_init(), rtpstart, ast_rtp::s, ast_rtp::sched, sched, ast_rtp::seqno, ast_rtp::ssrc, STRICT_RTP_LEARN, STRICT_RTP_OPEN, and ast_rtp::strict_rtp_state.

552 {
553  struct ast_rtp *rtp = NULL;
554  int x, startplace;
555 
556  /* Create a new RTP structure to hold all of our data */
557  if (!(rtp = ast_calloc(1, sizeof(*rtp)))) {
558  return -1;
559  }
560 
561  /* Set default parameters on the newly created RTP structure */
562  rtp->ssrc = ast_random();
563  rtp->seqno = ast_random() & 0xffff;
565  if (strictrtp) {
566  rtp_learning_seq_init(rtp, (uint16_t)rtp->seqno);
567  }
568 
569  /* Create a new socket for us to listen on and use */
570  if ((rtp->s =
571  create_new_socket("RTP",
572  ast_sockaddr_is_ipv4(addr) ? AF_INET :
573  ast_sockaddr_is_ipv6(addr) ? AF_INET6 : -1)) < 0) {
574  ast_debug(1, "Failed to create a new socket for RTP instance '%p'\n", instance);
575  ast_free(rtp);
576  return -1;
577  }
578 
579  /* Now actually find a free RTP port to use */
580  x = (rtpend == rtpstart) ? rtpstart : (ast_random() % (rtpend - rtpstart)) + rtpstart;
581  x = x & ~1;
582  startplace = x;
583 
584  for (;;) {
585  ast_sockaddr_set_port(addr, x);
586  /* Try to bind, this will tell us whether the port is available or not */
587  if (!ast_bind(rtp->s, addr)) {
588  ast_debug(1, "Allocated port %d for RTP instance '%p'\n", x, instance);
589  ast_rtp_instance_set_local_address(instance, addr);
590  break;
591  }
592 
593  x += 2;
594  if (x > rtpend) {
595  x = (rtpstart + 1) & ~1;
596  }
597 
598  /* See if we ran out of ports or if the bind actually failed because of something other than the address being in use */
599  if (x == startplace || (errno != EADDRINUSE && errno != EACCES)) {
600  ast_log(LOG_ERROR, "Oh dear... we couldn't allocate a port for RTP instance '%p'\n", instance);
601  close(rtp->s);
602  ast_free(rtp);
603  return -1;
604  }
605  }
606 
607  /* Record any information we may need */
608  rtp->sched = sched;
609 
610  /* Associate the RTP structure with the RTP instance and be done */
611  ast_rtp_instance_set_data(instance, rtp);
612 
613  return 0;
614 }
RTP session description.
enum strict_rtp_state strict_rtp_state
struct sched_context * sched
static int rtpstart
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:462
struct sched_context * sched
Definition: chan_sip.c:782
unsigned int ssrc
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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:364
long int ast_random(void)
Definition: utils.c:1640
int ast_rtp_instance_set_local_address(struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
Set the address that we are expecting to receive RTP on.
Definition: rtp_engine.c:384
#define LOG_ERROR
Definition: logger.h:155
static int strictrtp
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
#define ast_free(a)
Definition: astmm.h:97
#define ast_calloc(a, b)
Definition: astmm.h:82
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:400
static int create_new_socket(const char *type, int af)
static void rtp_learning_seq_init(struct ast_rtp *rtp, uint16_t seq)
unsigned short seqno
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
static int rtpend
static void ast_rtp_prop_set ( struct ast_rtp_instance instance,
enum ast_rtp_property  property,
int  value 
)
static

Definition at line 2523 of file res_rtp_asterisk.c.

References ao2_ref, ast_bind(), ast_calloc, ast_debug, ast_free, ast_rtp_instance_get_data(), ast_rtp_instance_get_local_address(), AST_RTP_PROPERTY_RTCP, ast_sched_del(), ast_sockaddr_is_ipv4(), ast_sockaddr_is_ipv6(), ast_sockaddr_port, ast_sockaddr_set_port, create_new_socket(), ast_rtp::rtcp, ast_rtcp::s, ast_rtp::sched, ast_rtcp::schedid, and ast_rtcp::us.

2524 {
2525  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2526 
2527  if (property == AST_RTP_PROPERTY_RTCP) {
2528  if (value) {
2529  if (rtp->rtcp) {
2530  ast_debug(1, "Ignoring duplicate RTCP property on RTP instance '%p'\n", instance);
2531  return;
2532  }
2533  /* Setup RTCP to be activated on the next RTP write */
2534  if (!(rtp->rtcp = ast_calloc(1, sizeof(*rtp->rtcp)))) {
2535  return;
2536  }
2537 
2538  /* Grab the IP address and port we are going to use */
2539  ast_rtp_instance_get_local_address(instance, &rtp->rtcp->us);
2540  ast_sockaddr_set_port(&rtp->rtcp->us,
2541  ast_sockaddr_port(&rtp->rtcp->us) + 1);
2542 
2543  if ((rtp->rtcp->s =
2544  create_new_socket("RTCP",
2545  ast_sockaddr_is_ipv4(&rtp->rtcp->us) ?
2546  AF_INET :
2547  ast_sockaddr_is_ipv6(&rtp->rtcp->us) ?
2548  AF_INET6 : -1)) < 0) {
2549  ast_debug(1, "Failed to create a new socket for RTCP on instance '%p'\n", instance);
2550  ast_free(rtp->rtcp);
2551  rtp->rtcp = NULL;
2552  return;
2553  }
2554 
2555  /* 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 */
2556  if (ast_bind(rtp->rtcp->s, &rtp->rtcp->us)) {
2557  ast_debug(1, "Failed to setup RTCP on RTP instance '%p'\n", instance);
2558  close(rtp->rtcp->s);
2559  ast_free(rtp->rtcp);
2560  rtp->rtcp = NULL;
2561  return;
2562  }
2563 
2564  ast_debug(1, "Setup RTCP on RTP instance '%p'\n", instance);
2565  rtp->rtcp->schedid = -1;
2566 
2567  return;
2568  } else {
2569  if (rtp->rtcp) {
2570  if (rtp->rtcp->schedid > 0) {
2571  if (!ast_sched_del(rtp->sched, rtp->rtcp->schedid)) {
2572  /* Successfully cancelled scheduler entry. */
2573  ao2_ref(instance, -1);
2574  } else {
2575  /* Unable to cancel scheduler entry */
2576  ast_debug(1, "Failed to tear down RTCP on RTP instance '%p'\n", instance);
2577  return;
2578  }
2579  rtp->rtcp->schedid = -1;
2580  }
2581  close(rtp->rtcp->s);
2582  ast_free(rtp->rtcp);
2583  rtp->rtcp = NULL;
2584  }
2585  return;
2586  }
2587  }
2588 
2589  return;
2590 }
RTP session description.
int ast_sched_del(struct sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event Remove this event from being run. A procedure should not remove its own eve...
Definition: sched.c:468
struct sched_context * sched
int value
Definition: syslog.c:39
int ast_bind(int sockfd, const struct ast_sockaddr *addr)
Wrapper around bind(2) that uses struct ast_sockaddr.
Definition: netsock2.c:462
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:406
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define ao2_ref(o, delta)
Definition: astobj2.h:472
struct ast_rtcp * rtcp
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
#define ast_free(a)
Definition: astmm.h:97
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
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:430
struct ast_sockaddr us
#define ast_calloc(a, b)
Definition: astmm.h:82
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:400
static int create_new_socket(const char *type, int af)
int ast_sockaddr_is_ipv6(const struct ast_sockaddr *addr)
Determine if this is an IPv6 address.
Definition: netsock2.c:418
static int ast_rtp_qos_set ( struct ast_rtp_instance instance,
int  tos,
int  cos,
const char *  desc 
)
static

Definition at line 2806 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_set_qos(), and ast_rtp::s.

2807 {
2808  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2809 
2810  return ast_set_qos(rtp->s, tos, cos, desc);
2811 }
RTP session description.
static unsigned int tos
Definition: chan_h323.c:146
static const char desc[]
Definition: cdr_radius.c:85
int ast_set_qos(int sockfd, int tos, int cos, const char *desc)
Set type of service.
Definition: netsock2.c:493
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
static unsigned int cos
Definition: chan_h323.c:147
static int ast_rtp_raw_write ( struct ast_rtp_instance instance,
struct ast_frame frame,
int  codec 
)
static

Definition at line 1168 of file res_rtp_asterisk.c.

References ao2_ref, ast_clear_flag, ast_debug, AST_FORMAT_G722, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_FRFLAG_HAS_TIMING_INFO, ast_log(), ast_rtcp_calc_interval(), ast_rtcp_write(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), ast_rtp_instance_get_remote_address(), AST_RTP_PROPERTY_NAT, ast_sched_add(), ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_test_flag, ast_tvzero(), ast_verbose(), calc_txstamp(), ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, FLAG_NAT_ACTIVE, FLAG_NAT_INACTIVE, FLAG_NAT_INACTIVE_NOWARN, FLAG_NEED_MARKER_BIT, ast_frame::frametype, ast_rtp::lastdigitts, ast_rtp::lastotexttimestamp, ast_rtp::lastovidtimestamp, ast_rtp::lastts, LOG_WARNING, MAX_TIMESTAMP_SKEW, option_debug, ast_frame::ptr, put_unaligned_uint32(), ast_rtp::rtcp, rtp_debug_test_addr(), rtp_get_rate(), rtp_sendto(), ast_frame::samples, ast_rtp::sched, ast_rtcp::schedid, ast_rtp::sending_digit, ast_rtp::seqno, ast_rtp::ssrc, ast_frame::subclass, ast_frame::ts, ast_rtp::txcount, and ast_rtp::txoctetcount.

Referenced by ast_rtp_write().

1169 {
1170  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1171  int pred, mark = 0;
1172  unsigned int ms = calc_txstamp(rtp, &frame->delivery);
1173  struct ast_sockaddr remote_address = { {0,} };
1174  int rate = rtp_get_rate(frame->subclass.codec) / 1000;
1175 
1176  if (frame->subclass.codec == AST_FORMAT_G722) {
1177  frame->samples /= 2;
1178  }
1179 
1180  if (rtp->sending_digit) {
1181  return 0;
1182  }
1183 
1184  if (frame->frametype == AST_FRAME_VOICE) {
1185  pred = rtp->lastts + frame->samples;
1186 
1187  /* Re-calculate last TS */
1188  rtp->lastts = rtp->lastts + ms * rate;
1189  if (ast_tvzero(frame->delivery)) {
1190  /* If this isn't an absolute delivery time, Check if it is close to our prediction,
1191  and if so, go with our prediction */
1192  if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW) {
1193  rtp->lastts = pred;
1194  } else {
1195  ast_debug(3, "Difference is %d, ms is %u\n", abs(rtp->lastts - pred), ms);
1196  mark = 1;
1197  }
1198  }
1199  } else if (frame->frametype == AST_FRAME_VIDEO) {
1200  mark = frame->subclass.codec & 0x1;
1201  pred = rtp->lastovidtimestamp + frame->samples;
1202  /* Re-calculate last TS */
1203  rtp->lastts = rtp->lastts + ms * 90;
1204  /* If it's close to our prediction, go for it */
1205  if (ast_tvzero(frame->delivery)) {
1206  if (abs(rtp->lastts - pred) < 7200) {
1207  rtp->lastts = pred;
1208  rtp->lastovidtimestamp += frame->samples;
1209  } else {
1210  ast_debug(3, "Difference is %d, ms is %u (%u), pred/ts/samples %u/%d/%d\n", abs(rtp->lastts - pred), ms, ms * 90, rtp->lastts, pred, frame->samples);
1211  rtp->lastovidtimestamp = rtp->lastts;
1212  }
1213  }
1214  } else {
1215  pred = rtp->lastotexttimestamp + frame->samples;
1216  /* Re-calculate last TS */
1217  rtp->lastts = rtp->lastts + ms;
1218  /* If it's close to our prediction, go for it */
1219  if (ast_tvzero(frame->delivery)) {
1220  if (abs(rtp->lastts - pred) < 7200) {
1221  rtp->lastts = pred;
1222  rtp->lastotexttimestamp += frame->samples;
1223  } else {
1224  ast_debug(3, "Difference is %d, ms is %u, pred/ts/samples %u/%d/%d\n", abs(rtp->lastts - pred), ms, rtp->lastts, pred, frame->samples);
1225  rtp->lastotexttimestamp = rtp->lastts;
1226  }
1227  }
1228  }
1229 
1230  /* If we have been explicitly told to set the marker bit then do so */
1231  if (ast_test_flag(rtp, FLAG_NEED_MARKER_BIT)) {
1232  mark = 1;
1234  }
1235 
1236  /* If the timestamp for non-digt packets has moved beyond the timestamp for digits, update the digit timestamp */
1237  if (rtp->lastts > rtp->lastdigitts) {
1238  rtp->lastdigitts = rtp->lastts;
1239  }
1240 
1242  rtp->lastts = frame->ts * rate;
1243  }
1244 
1245  ast_rtp_instance_get_remote_address(instance, &remote_address);
1246 
1247  /* If we know the remote address construct a packet and send it out */
1248  if (!ast_sockaddr_isnull(&remote_address)) {
1249  int hdrlen = 12, res;
1250  unsigned char *rtpheader = (unsigned char *)(frame->data.ptr - hdrlen);
1251 
1252  put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23)));
1253  put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts));
1254  put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc));
1255 
1256  if ((res = rtp_sendto(instance, (void *)rtpheader, frame->datalen + hdrlen, 0, &remote_address)) < 0) {
1258  ast_debug(1, "RTP Transmission error of packet %d to %s: %s\n",
1259  rtp->seqno,
1260  ast_sockaddr_stringify(&remote_address),
1261  strerror(errno));
1263  /* Only give this error message once if we are not RTP debugging */
1264  if (option_debug || rtpdebug)
1265  ast_debug(0, "RTP NAT: Can't write RTP to private address %s, waiting for other end to send audio...\n",
1266  ast_sockaddr_stringify(&remote_address));
1268  }
1269  } else {
1270  rtp->txcount++;
1271  rtp->txoctetcount += (res - hdrlen);
1272 
1273  if (rtp->rtcp && rtp->rtcp->schedid < 1) {
1274  ast_debug(1, "Starting RTCP transmission on RTP instance '%p'\n", instance);
1275  ao2_ref(instance, +1);
1276  rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, instance);
1277  if (rtp->rtcp->schedid < 0) {
1278  ao2_ref(instance, -1);
1279  ast_log(LOG_WARNING, "scheduling RTCP transmission failed.\n");
1280  }
1281  }
1282  }
1283 
1284  if (rtp_debug_test_addr(&remote_address)) {
1285  ast_verbose("Sent RTP packet to %s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
1286  ast_sockaddr_stringify(&remote_address),
1287  codec, rtp->seqno, rtp->lastts, res - hdrlen);
1288  }
1289  }
1290 
1291  rtp->seqno++;
1292 
1293  return 0;
1294 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
static int rtpdebug
unsigned int lastovidtimestamp
unsigned int lastotexttimestamp
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
struct sched_context * sched
#define ast_test_flag(p, flag)
Definition: utils.h:63
int option_debug
Definition: asterisk.c:182
static int ast_rtcp_write(const void *data)
Write and RTCP packet to the far end.
void * ptr
Definition: frame.h:160
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
unsigned int txcount
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
static void put_unaligned_uint32(void *p, unsigned int datum)
Definition: unaligned.h:58
long ts
Definition: frame.h:168
format_t codec
Definition: frame.h:137
Socket address structure.
Definition: netsock2.h:63
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
unsigned int ssrc
#define FLAG_NAT_ACTIVE
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define FLAG_NAT_INACTIVE_NOWARN
int datalen
Definition: frame.h:148
#define ao2_ref(o, delta)
Definition: astobj2.h:472
#define FLAG_NEED_MARKER_BIT
struct ast_rtcp * rtcp
unsigned int lastdigitts
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
static int rtp_get_rate(format_t subclass)
#define ast_clear_flag(p, flag)
Definition: utils.h:77
struct timeval delivery
Definition: frame.h:162
unsigned int lastts
unsigned int txoctetcount
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:478
static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
#define AST_FORMAT_G722
Definition: frame.h:266
enum ast_frame_type frametype
Definition: frame.h:144
unsigned short seqno
#define MAX_TIMESTAMP_SKEW
union ast_frame::@172 data
#define FLAG_NAT_INACTIVE
char sending_digit
int samples
Definition: frame.h:150
static struct ast_frame * ast_rtp_read ( struct ast_rtp_instance instance,
int  rtcp 
)
static

Definition at line 2135 of file res_rtp_asterisk.c.

References ast_rtp::alt_rtp_address, ao2_ref, ast_assert, ast_codec_get_samples(), AST_CONTROL_SRCCHANGE, ast_debug, AST_FORMAT_AUDIO_MASK, ast_format_rate(), AST_FORMAT_SLINEAR, AST_FORMAT_SLINEAR16, AST_FORMAT_T140, AST_FORMAT_T140RED, AST_FORMAT_VIDEO_MASK, ast_frame_byteswap_be, AST_FRAME_CONTROL, AST_FRAME_DTMF_END, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_FRFLAG_HAS_TIMING_INFO, AST_FRIENDLY_OFFSET, ast_frisolate(), AST_LIST_EMPTY, AST_LIST_FIRST, AST_LIST_HEAD_INIT_NOLOCK, AST_LIST_INSERT_TAIL, ast_log(), ast_null_frame, ast_rtcp_calc_interval(), ast_rtcp_read(), ast_rtcp_write(), AST_RTP_CISCO_DTMF, AST_RTP_CN, ast_rtp_codecs_payload_lookup(), AST_RTP_DTMF, ast_rtp_dtmf_continuation(), ast_rtp_instance_get_bridged(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), ast_rtp_instance_get_remote_address(), ast_rtp_instance_set_remote_address(), AST_RTP_PROPERTY_NAT, ast_samp2tv(), ast_sched_add(), ast_set_flag, ast_sockaddr_cmp(), ast_sockaddr_copy(), ast_sockaddr_from_sin, ast_sockaddr_ipv4_mapped(), ast_sockaddr_is_ipv4(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_sockaddr_stringify(), ast_sockaddr_to_sin, ast_strdupa, AST_STUN_ACCEPT, ast_stun_handle_packet(), ast_tv(), ast_tvdiff_ms(), ast_verbose(), ast_rtp_payload_type::asterisk_format, bridge_p2p_rtp_write(), calc_rxstamp(), ast_rtp_payload_type::code, ast_frame_subclass::codec, create_dtmf_frame(), ast_rtp::cycles, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_rtp::dtmf_duration, ast_rtp::dtmf_timeout, errno, ast_rtcp::expected_prior, ext, ast_rtp::f, f, FLAG_NAT_ACTIVE, ast_frame::frametype, ast_rtp::last_end_timestamp, ast_rtp::last_seqno, ast_rtp::lastitexttimestamp, ast_rtp::lastividtimestamp, ast_rtp::lastrxformat, ast_rtp::lastrxseqno, ast_rtp::lastrxts, ast_frame::len, len(), LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, ast_frame::offset, option_debug, process_cn_rfc3389(), process_dtmf_cisco(), process_dtmf_rfc2833(), ast_frame::ptr, ast_rtp::rawdata, ast_rtcp::received_prior, ast_rtp::resp, ast_rtp::rtcp, rtp_debug_test_addr(), rtp_get_rate(), rtp_learning_rtp_seq_update(), rtp_recvfrom(), RTP_SEQ_MOD, ast_rtp::rxcount, ast_rtp::rxseqno, ast_rtp::rxssrc, ast_rtp::s, ast_frame::samples, ast_rtp::sched, ast_rtcp::schedid, ast_rtp::seedrxseqno, ast_rtp::sending_digit, ast_frame::seqno, ast_frame::src, ast_rtp::strict_rtp_address, STRICT_RTP_CLOSED, STRICT_RTP_LEARN, ast_rtp::strict_rtp_state, ast_frame::subclass, ast_rtcp::them, ast_rtp::themssrc, ast_frame::ts, and version.

2136 {
2137  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2138  struct ast_sockaddr addr;
2139  int res, hdrlen = 12, version, payloadtype, padding, mark, ext, cc, prev_seqno;
2140  unsigned int *rtpheader = (unsigned int*)(rtp->rawdata + AST_FRIENDLY_OFFSET), seqno, ssrc, timestamp;
2141  struct ast_rtp_payload_type payload;
2142  struct ast_sockaddr remote_address = { {0,} };
2143  struct frame_list frames;
2144 
2145  /* If this is actually RTCP let's hop on over and handle it */
2146  if (rtcp) {
2147  if (rtp->rtcp) {
2148  return ast_rtcp_read(instance);
2149  }
2150  return &ast_null_frame;
2151  }
2152 
2153  /* If we are currently sending DTMF to the remote party send a continuation packet */
2154  if (rtp->sending_digit) {
2155  ast_rtp_dtmf_continuation(instance);
2156  }
2157 
2158  /* Actually read in the data from the socket */
2159  if ((res = rtp_recvfrom(instance, rtp->rawdata + AST_FRIENDLY_OFFSET,
2160  sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 0,
2161  &addr)) < 0) {
2162  ast_assert(errno != EBADF);
2163  if (errno != EAGAIN) {
2164  ast_log(LOG_WARNING, "RTP Read error: %s. Hanging up.\n", strerror(errno));
2165  return NULL;
2166  }
2167  return &ast_null_frame;
2168  }
2169 
2170  /* Make sure the data that was read in is actually enough to make up an RTP packet */
2171  if (res < hdrlen) {
2172  ast_log(LOG_WARNING, "RTP Read too short\n");
2173  return &ast_null_frame;
2174  }
2175 
2176  /* Get fields and verify this is an RTP packet */
2177  seqno = ntohl(rtpheader[0]);
2178 
2179  ast_rtp_instance_get_remote_address(instance, &remote_address);
2180 
2181  if (!(version = (seqno & 0xC0000000) >> 30)) {
2182  struct sockaddr_in addr_tmp;
2183  struct ast_sockaddr addr_v4;
2184  if (ast_sockaddr_is_ipv4(&addr)) {
2185  ast_sockaddr_to_sin(&addr, &addr_tmp);
2186  } else if (ast_sockaddr_ipv4_mapped(&addr, &addr_v4)) {
2187  ast_debug(1, "Using IPv6 mapped address %s for STUN\n",
2188  ast_sockaddr_stringify(&addr));
2189  ast_sockaddr_to_sin(&addr_v4, &addr_tmp);
2190  } else {
2191  ast_debug(1, "Cannot do STUN for non IPv4 address %s\n",
2192  ast_sockaddr_stringify(&addr));
2193  return &ast_null_frame;
2194  }
2195  if ((ast_stun_handle_packet(rtp->s, &addr_tmp, rtp->rawdata + AST_FRIENDLY_OFFSET, res, NULL, NULL) == AST_STUN_ACCEPT) &&
2196  ast_sockaddr_isnull(&remote_address)) {
2197  ast_sockaddr_from_sin(&addr, &addr_tmp);
2198  ast_rtp_instance_set_remote_address(instance, &addr);
2199  }
2200  return &ast_null_frame;
2201  }
2202 
2203  /* If strict RTP protection is enabled see if we need to learn the remote address or if we need to drop the packet */
2204  if (rtp->strict_rtp_state == STRICT_RTP_LEARN) {
2205  ast_debug(1, "%p -- start learning mode pass with addr = %s\n", rtp, ast_sockaddr_stringify(&addr));
2206  /* For now, we always copy the address. */
2207  ast_sockaddr_copy(&rtp->strict_rtp_address, &addr);
2208 
2209  /* Send the rtp and the seqno from header to rtp_learning_rtp_seq_update to see whether we can exit or not*/
2210  if (rtp_learning_rtp_seq_update(rtp, ntohl(rtpheader[0]))) {
2211  ast_debug(1, "%p -- Condition for learning hasn't exited, so reject the frame.\n", rtp);
2212  return &ast_null_frame;
2213  }
2214 
2215  ast_debug(1, "%p -- Probation Ended. Set strict_rtp_state to STRICT_RTP_CLOSED with address %s\n", rtp, ast_sockaddr_stringify(&addr));
2217  } else if (rtp->strict_rtp_state == STRICT_RTP_CLOSED) {
2218  if (ast_sockaddr_cmp(&rtp->strict_rtp_address, &addr)) {
2219  /* Hmm, not the strict addres. Perhaps we're getting audio from the alternate? */
2220  if (!ast_sockaddr_cmp(&rtp->alt_rtp_address, &addr)) {
2221  /* ooh, we did! You're now the new expected address, son! */
2223  &addr);
2224  } else {
2225  const char *real_addr = ast_strdupa(ast_sockaddr_stringify(&addr));
2226  const char *expected_addr = ast_strdupa(ast_sockaddr_stringify(&rtp->strict_rtp_address));
2227 
2228  ast_debug(1, "Received RTP packet from %s, dropping due to strict RTP protection. Expected it to be from %s\n",
2229  real_addr, expected_addr);
2230 
2231  return &ast_null_frame;
2232  }
2233  }
2234  }
2235 
2236  /* If symmetric RTP is enabled see if the remote side is not what we expected and change where we are sending audio */
2238  if (ast_sockaddr_cmp(&remote_address, &addr)) {
2239  ast_rtp_instance_set_remote_address(instance, &addr);
2240  ast_sockaddr_copy(&remote_address, &addr);
2241  if (rtp->rtcp) {
2242  ast_sockaddr_copy(&rtp->rtcp->them, &addr);
2243  ast_sockaddr_set_port(&rtp->rtcp->them, ast_sockaddr_port(&addr) + 1);
2244  }
2245  rtp->rxseqno = 0;
2247  if (option_debug || rtpdebug)
2248  ast_debug(0, "RTP NAT: Got audio from other end. Now sending to address %s\n",
2249  ast_sockaddr_stringify(&remote_address));
2250  }
2251  }
2252 
2253  /* If we are directly bridged to another instance send the audio directly out */
2254  if (ast_rtp_instance_get_bridged(instance) && !bridge_p2p_rtp_write(instance, rtpheader, res, hdrlen)) {
2255  return &ast_null_frame;
2256  }
2257 
2258  /* If the version is not what we expected by this point then just drop the packet */
2259  if (version != 2) {
2260  return &ast_null_frame;
2261  }
2262 
2263  /* Pull out the various other fields we will need */
2264  payloadtype = (seqno & 0x7f0000) >> 16;
2265  padding = seqno & (1 << 29);
2266  mark = seqno & (1 << 23);
2267  ext = seqno & (1 << 28);
2268  cc = (seqno & 0xF000000) >> 24;
2269  seqno &= 0xffff;
2270  timestamp = ntohl(rtpheader[1]);
2271  ssrc = ntohl(rtpheader[2]);
2272 
2274  /* Force a marker bit and change SSRC if the SSRC changes */
2275  if (rtp->rxssrc && rtp->rxssrc != ssrc) {
2276  struct ast_frame *f, srcupdate = {
2278  .subclass.integer = AST_CONTROL_SRCCHANGE,
2279  };
2280 
2281  if (!mark) {
2282  if (option_debug || rtpdebug) {
2283  ast_debug(1, "Forcing Marker bit, because SSRC has changed\n");
2284  }
2285  mark = 1;
2286  }
2287 
2288  f = ast_frisolate(&srcupdate);
2290 
2291  rtp->seedrxseqno = 0;
2292  rtp->rxcount = 0;
2293  rtp->cycles = 0;
2294  rtp->lastrxseqno = 0;
2295  rtp->last_seqno = 0;
2296  rtp->last_end_timestamp = 0;
2297  if (rtp->rtcp) {
2298  rtp->rtcp->expected_prior = 0;
2299  rtp->rtcp->received_prior = 0;
2300  }
2301  }
2302 
2303  rtp->rxssrc = ssrc;
2304 
2305  /* Remove any padding bytes that may be present */
2306  if (padding) {
2307  res -= rtp->rawdata[AST_FRIENDLY_OFFSET + res - 1];
2308  }
2309 
2310  /* Skip over any CSRC fields */
2311  if (cc) {
2312  hdrlen += cc * 4;
2313  }
2314 
2315  /* Look for any RTP extensions, currently we do not support any */
2316  if (ext) {
2317  hdrlen += (ntohl(rtpheader[hdrlen/4]) & 0xffff) << 2;
2318  hdrlen += 4;
2319  if (option_debug) {
2320  unsigned int profile;
2321  profile = (ntohl(rtpheader[3]) & 0xffff0000) >> 16;
2322  if (profile == 0x505a)
2323  ast_debug(1, "Found Zfone extension in RTP stream - zrtp - not supported.\n");
2324  else
2325  ast_debug(1, "Found unknown RTP Extensions %x\n", profile);
2326  }
2327  }
2328 
2329  /* Make sure after we potentially mucked with the header length that it is once again valid */
2330  if (res < hdrlen) {
2331  ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d\n", res, hdrlen);
2333  }
2334 
2335  rtp->rxcount++;
2336  if (rtp->rxcount == 1) {
2337  rtp->seedrxseqno = seqno;
2338  }
2339 
2340  /* Do not schedule RR if RTCP isn't run */
2341  if (rtp->rtcp && !ast_sockaddr_isnull(&rtp->rtcp->them) && rtp->rtcp->schedid < 1) {
2342  /* Schedule transmission of Receiver Report */
2343  ao2_ref(instance, +1);
2344  rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, instance);
2345  if (rtp->rtcp->schedid < 0) {
2346  ao2_ref(instance, -1);
2347  ast_log(LOG_WARNING, "scheduling RTCP transmission failed.\n");
2348  }
2349  }
2350  if ((int)rtp->lastrxseqno - (int)seqno > 100) /* if so it would indicate that the sender cycled; allow for misordering */
2351  rtp->cycles += RTP_SEQ_MOD;
2352 
2353  prev_seqno = rtp->lastrxseqno;
2354  rtp->lastrxseqno = seqno;
2355 
2356  if (!rtp->themssrc) {
2357  rtp->themssrc = ntohl(rtpheader[2]); /* Record their SSRC to put in future RR */
2358  }
2359 
2360  if (rtp_debug_test_addr(&addr)) {
2361  ast_verbose("Got RTP packet from %s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6d)\n",
2362  ast_sockaddr_stringify(&addr),
2363  payloadtype, seqno, timestamp,res - hdrlen);
2364  }
2365 
2366  payload = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(instance), payloadtype);
2367 
2368  /* If the payload is not actually an Asterisk one but a special one pass it off to the respective handler */
2369  if (!payload.asterisk_format) {
2370  struct ast_frame *f = NULL;
2371  if (payload.code == AST_RTP_DTMF) {
2372  /* process_dtmf_rfc2833 may need to return multiple frames. We do this
2373  * by passing the pointer to the frame list to it so that the method
2374  * can append frames to the list as needed.
2375  */
2376  process_dtmf_rfc2833(instance, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp, &addr, payloadtype, mark, &frames);
2377  } else if (payload.code == AST_RTP_CISCO_DTMF) {
2378  f = process_dtmf_cisco(instance, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp, &addr, payloadtype, mark);
2379  } else if (payload.code == AST_RTP_CN) {
2380  f = process_cn_rfc3389(instance, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp, &addr, payloadtype, mark);
2381  } else {
2382  ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n",
2383  payloadtype,
2384  ast_sockaddr_stringify(&remote_address));
2385  }
2386 
2387  if (f) {
2389  }
2390  /* Even if no frame was returned by one of the above methods,
2391  * we may have a frame to return in our frame list
2392  */
2393  if (!AST_LIST_EMPTY(&frames)) {
2394  return AST_LIST_FIRST(&frames);
2395  }
2396  return &ast_null_frame;
2397  }
2398 
2399  rtp->lastrxformat = rtp->f.subclass.codec = payload.code;
2401 
2402  rtp->rxseqno = seqno;
2403 
2404  if (rtp->dtmf_timeout && rtp->dtmf_timeout < timestamp) {
2405  rtp->dtmf_timeout = 0;
2406 
2407  if (rtp->resp) {
2408  struct ast_frame *f;
2409  f = create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0);
2411  rtp->resp = 0;
2412  rtp->dtmf_timeout = rtp->dtmf_duration = 0;
2414  return AST_LIST_FIRST(&frames);
2415  }
2416  }
2417 
2418  rtp->lastrxts = timestamp;
2419 
2420  rtp->f.src = "RTP";
2421  rtp->f.mallocd = 0;
2422  rtp->f.datalen = res - hdrlen;
2423  rtp->f.data.ptr = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
2424  rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
2425  rtp->f.seqno = seqno;
2426 
2427  if (rtp->f.subclass.codec == AST_FORMAT_T140 && (int)seqno - (prev_seqno+1) > 0 && (int)seqno - (prev_seqno+1) < 10) {
2428  unsigned char *data = rtp->f.data.ptr;
2429 
2430  memmove(rtp->f.data.ptr+3, rtp->f.data.ptr, rtp->f.datalen);
2431  rtp->f.datalen +=3;
2432  *data++ = 0xEF;
2433  *data++ = 0xBF;
2434  *data = 0xBD;
2435  }
2436 
2437  if (rtp->f.subclass.codec == AST_FORMAT_T140RED) {
2438  unsigned char *data = rtp->f.data.ptr;
2439  unsigned char *header_end;
2440  int num_generations;
2441  int header_length;
2442  int len;
2443  int diff =(int)seqno - (prev_seqno+1); /* if diff = 0, no drop*/
2444  int x;
2445 
2447  header_end = memchr(data, ((*data) & 0x7f), rtp->f.datalen);
2448  if (header_end == NULL) {
2450  }
2451  header_end++;
2452 
2453  header_length = header_end - data;
2454  num_generations = header_length / 4;
2455  len = header_length;
2456 
2457  if (!diff) {
2458  for (x = 0; x < num_generations; x++)
2459  len += data[x * 4 + 3];
2460 
2461  if (!(rtp->f.datalen - len))
2463 
2464  rtp->f.data.ptr += len;
2465  rtp->f.datalen -= len;
2466  } else if (diff > num_generations && diff < 10) {
2467  len -= 3;
2468  rtp->f.data.ptr += len;
2469  rtp->f.datalen -= len;
2470 
2471  data = rtp->f.data.ptr;
2472  *data++ = 0xEF;
2473  *data++ = 0xBF;
2474  *data = 0xBD;
2475  } else {
2476  for ( x = 0; x < num_generations - diff; x++)
2477  len += data[x * 4 + 3];
2478 
2479  rtp->f.data.ptr += len;
2480  rtp->f.datalen -= len;
2481  }
2482  }
2483 
2484  if (rtp->f.subclass.codec & AST_FORMAT_AUDIO_MASK) {
2485  rtp->f.samples = ast_codec_get_samples(&rtp->f);
2486  if ((rtp->f.subclass.codec == AST_FORMAT_SLINEAR) || (rtp->f.subclass.codec == AST_FORMAT_SLINEAR16)) {
2487  ast_frame_byteswap_be(&rtp->f);
2488  }
2489  calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
2490  /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */
2492  rtp->f.ts = timestamp / (rtp_get_rate(rtp->f.subclass.codec) / 1000);
2493  rtp->f.len = rtp->f.samples / ((ast_format_rate(rtp->f.subclass.codec) / 1000));
2494  } else if (rtp->f.subclass.codec & AST_FORMAT_VIDEO_MASK) {
2495  /* Video -- samples is # of samples vs. 90000 */
2496  if (!rtp->lastividtimestamp)
2497  rtp->lastividtimestamp = timestamp;
2498  rtp->f.samples = timestamp - rtp->lastividtimestamp;
2499  rtp->lastividtimestamp = timestamp;
2500  rtp->f.delivery.tv_sec = 0;
2501  rtp->f.delivery.tv_usec = 0;
2502  /* Pass the RTP marker bit as bit 0 in the subclass field.
2503  * This is ok because subclass is actually a bitmask, and
2504  * the low bits represent audio formats, that are not
2505  * involved here since we deal with video.
2506  */
2507  if (mark)
2508  rtp->f.subclass.codec |= 0x1;
2509  } else {
2510  /* TEXT -- samples is # of samples vs. 1000 */
2511  if (!rtp->lastitexttimestamp)
2512  rtp->lastitexttimestamp = timestamp;
2513  rtp->f.samples = timestamp - rtp->lastitexttimestamp;
2514  rtp->lastitexttimestamp = timestamp;
2515  rtp->f.delivery.tv_sec = 0;
2516  rtp->f.delivery.tv_usec = 0;
2517  }
2518 
2520  return AST_LIST_FIRST(&frames);
2521 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
uint32_t version
#define AST_LIST_FIRST(head)
Returns the first entry contained in a list.
Definition: linkedlists.h:420
static int rtpdebug
enum strict_rtp_state strict_rtp_state
int offset
Definition: frame.h:156
struct ast_frame ast_null_frame
Definition: frame.c:131
int seqno
Definition: frame.h:172
struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload)
Retrieve payload information by payload.
Definition: rtp_engine.c:618
struct sched_context * sched
int option_debug
Definition: asterisk.c:182
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:121
static int ast_rtcp_write(const void *data)
Write and RTCP packet to the far end.
void * ptr
Definition: frame.h:160
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
#define ast_set_flag(p, flag)
Definition: utils.h:70
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:483
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
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:39
struct ast_sockaddr them
unsigned int rxcount
long ts
Definition: frame.h:168
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
static struct ast_frame * create_dtmf_frame(struct ast_rtp_instance *instance, enum ast_frame_type type, int compensate)
#define ast_frame_byteswap_be(fr)
Definition: frame.h:616
#define AST_LIST_EMPTY(head)
Checks whether the specified list contains any entries.
Definition: linkedlists.h:449
#define ast_assert(a)
Definition: utils.h:738
format_t lastrxformat
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
struct ast_frame * ast_frisolate(struct ast_frame *fr)
Makes a frame independent of any static storage.
Definition: frame.c:391
format_t codec
Definition: frame.h:137
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
const char * ext
Definition: http.c:112
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:264
Socket address structure.
Definition: netsock2.h:63
unsigned int expected_prior
static int frames
Definition: iax2-parser.c:49
unsigned short rxseqno
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:406
unsigned char rawdata[8192+AST_FRIENDLY_OFFSET]
#define RTP_SEQ_MOD
#define FLAG_NAT_ACTIVE
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
const char * src
Definition: frame.h:158
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
#define AST_FORMAT_T140RED
Definition: frame.h:292
int datalen
Definition: frame.h:148
struct ast_sockaddr alt_rtp_address
#define ao2_ref(o, delta)
Definition: astobj2.h:472
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:191
int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:391
static void process_dtmf_rfc2833(struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, struct ast_sockaddr *addr, int payloadtype, int mark, struct frame_list *frames)
static int ast_rtp_dtmf_continuation(struct ast_rtp_instance *instance)
static struct ast_frame * process_cn_rfc3389(struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, struct ast_sockaddr *addr, int payloadtype, int mark)
#define AST_FORMAT_SLINEAR16
Definition: frame.h:272
unsigned int lastrxts
struct ast_rtcp * rtcp
unsigned int cycles
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static int rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
unsigned int themssrc
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
unsigned int received_prior
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
unsigned int rxssrc
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static struct ast_frame * ast_rtcp_read(struct ast_rtp_instance *instance)
unsigned int dtmf_timeout
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
#define AST_FORMAT_VIDEO_MASK
Definition: frame.h:290
#define AST_RTP_CISCO_DTMF
Definition: rtp_engine.h:222
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
#define AST_FORMAT_AUDIO_MASK
Definition: frame.h:274
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
struct ast_sockaddr strict_rtp_address
static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
static struct ast_format f[]
Definition: format_g726.c:181
struct ast_frame f
static int rtp_learning_rtp_seq_update(struct ast_rtp *rtp, uint16_t seq)
unsigned int dtmf_duration
static int rtp_get_rate(format_t subclass)
struct timeval delivery
Definition: frame.h:162
int mallocd
Definition: frame.h:152
unsigned int lastividtimestamp
#define AST_LIST_HEAD_INIT_NOLOCK(head)
Initializes a list head structure.
Definition: linkedlists.h:666
#define AST_FORMAT_T140
Definition: frame.h:294
#define AST_FORMAT_SLINEAR
Definition: frame.h:254
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
int ast_codec_get_samples(struct ast_frame *f)
Returns the number of samples contained in the frame.
Definition: frame.c:1470
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:1418
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:478
static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
int ast_sockaddr_is_ipv4(const struct ast_sockaddr *addr)
Determine if the address is an IPv4 address.
Definition: netsock2.c:400
Data structure associated with a single frame of data.
Definition: frame.h:142
static int bridge_p2p_rtp_write(struct ast_rtp_instance *instance, unsigned int *rtpheader, int len, int hdrlen)
static struct ast_frame * process_dtmf_cisco(struct ast_rtp_instance *instance, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp, struct ast_sockaddr *addr, int payloadtype, int mark)
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
enum ast_frame_type frametype
Definition: frame.h:144
unsigned int last_seqno
#define AST_RTP_CN
Definition: rtp_engine.h:220
#define AST_RTP_DTMF
Definition: rtp_engine.h:218
union ast_frame::@172 data
unsigned int lastitexttimestamp
unsigned short seedrxseqno
long len
Definition: frame.h:170
unsigned int last_end_timestamp
char sending_digit
int samples
Definition: frame.h:150
static void ast_rtp_remote_address_set ( struct ast_rtp_instance instance,
struct ast_sockaddr addr 
)
static

Definition at line 2599 of file res_rtp_asterisk.c.

References ast_debug, ast_rtp_instance_get_data(), ast_sockaddr_copy(), ast_sockaddr_isnull(), ast_sockaddr_port, ast_sockaddr_set_port, ast_rtp::rtcp, rtp_learning_seq_init(), ast_rtp::rxseqno, ast_rtp::seqno, STRICT_RTP_LEARN, ast_rtp::strict_rtp_state, and ast_rtcp::them.

2600 {
2601  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2602 
2603  if (rtp->rtcp) {
2604  ast_debug(1, "Setting RTCP address on RTP instance '%p'\n", instance);
2605  ast_sockaddr_copy(&rtp->rtcp->them, addr);
2606  if (!ast_sockaddr_isnull(addr)) {
2608  ast_sockaddr_port(addr) + 1);
2609  }
2610  }
2611 
2612  rtp->rxseqno = 0;
2613 
2614  if (strictrtp) {
2616  rtp_learning_seq_init(rtp, rtp->seqno);
2617  }
2618 
2619  return;
2620 }
RTP session description.
enum strict_rtp_state strict_rtp_state
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:121
struct ast_sockaddr them
unsigned short rxseqno
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
#define ast_sockaddr_port(addr)
Get the port number of a socket address.
Definition: netsock2.h:406
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
struct ast_rtcp * rtcp
static int strictrtp
#define ast_sockaddr_set_port(addr, port)
Sets the port number of a socket address.
Definition: netsock2.h:422
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
static void rtp_learning_seq_init(struct ast_rtp *rtp, uint16_t seq)
unsigned short seqno
static int ast_rtp_sendcng ( struct ast_rtp_instance instance,
int  level 
)
static

generate comfort noice (CNG)

Definition at line 2814 of file res_rtp_asterisk.c.

References ast_log(), AST_RTP_CN, ast_rtp_codecs_payload_code(), 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(), ast_rtp::data, ast_rtp::dtmfmute, errno, ast_rtp::lastdigitts, ast_rtp::lastts, LOG_ERROR, rtp_debug_test_addr(), rtp_sendto(), ast_rtp::seqno, and ast_rtp::ssrc.

2815 {
2816  unsigned int *rtpheader;
2817  int hdrlen = 12;
2818  int res, payload = 0;
2819  char data[256];
2820  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2821  struct ast_sockaddr remote_address = { {0,} };
2822 
2823  ast_rtp_instance_get_remote_address(instance, &remote_address);
2824 
2825  if (ast_sockaddr_isnull(&remote_address)) {
2826  return -1;
2827  }
2828 
2830 
2831  level = 127 - (level & 0x7f);
2832 
2833  rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000));
2834 
2835  /* Get a pointer to the header */
2836  rtpheader = (unsigned int *)data;
2837  rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno));
2838  rtpheader[1] = htonl(rtp->lastts);
2839  rtpheader[2] = htonl(rtp->ssrc);
2840  data[12] = level;
2841 
2842  res = rtp_sendto(instance, (void *) rtpheader, hdrlen + 1, 0, &remote_address);
2843 
2844  if (res < 0) {
2845  ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s: %s\n", ast_sockaddr_stringify(&remote_address), strerror(errno));
2846  } else if (rtp_debug_test_addr(&remote_address)) {
2847  ast_verbose("Sent Comfort Noise RTP packet to %s (type %-2.2d, seq %-6.6d, ts %-6.6u, len %-6.6d)\n",
2848  ast_sockaddr_stringify(&remote_address),
2849  AST_RTP_CN, rtp->seqno, rtp->lastdigitts, res - hdrlen);
2850  }
2851 
2852  rtp->seqno++;
2853 
2854  return res;
2855 }
RTP session description.
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
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:483
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
Socket address structure.
Definition: netsock2.h:63
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
unsigned int ssrc
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define LOG_ERROR
Definition: logger.h:155
unsigned int lastdigitts
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
unsigned int lastts
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
struct timeval dtmfmute
unsigned short seqno
#define AST_RTP_CN
Definition: rtp_engine.h:220
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code)
Retrieve a payload based on whether it is an Asterisk format and the code.
Definition: rtp_engine.c:654
static void ast_rtp_stop ( struct ast_rtp_instance instance)
static

Definition at line 2779 of file res_rtp_asterisk.c.

References ao2_ref, ast_rtp_instance_get_data(), ast_rtp_instance_set_remote_address(), AST_SCHED_DEL, ast_sched_del(), ast_set_flag, ast_sockaddr_setnull(), FLAG_NEED_MARKER_BIT, free, ast_rtp::red, ast_rtp::rtcp, ast_rtp::sched, ast_rtcp::schedid, rtp_red::schedid, and ast_rtcp::them.

2780 {
2781  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2782  struct ast_sockaddr addr = { {0,} };
2783 
2784  if (rtp->rtcp && rtp->rtcp->schedid > 0) {
2785  if (!ast_sched_del(rtp->sched, rtp->rtcp->schedid)) {
2786  /* successfully cancelled scheduler entry. */
2787  ao2_ref(instance, -1);
2788  }
2789  rtp->rtcp->schedid = -1;
2790  }
2791 
2792  if (rtp->red) {
2793  AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
2794  free(rtp->red);
2795  rtp->red = NULL;
2796  }
2797 
2798  ast_rtp_instance_set_remote_address(instance, &addr);
2799  if (rtp->rtcp) {
2800  ast_sockaddr_setnull(&rtp->rtcp->them);
2801  }
2802 
2804 }
RTP session description.
int ast_sched_del(struct sched_context *con, int id) attribute_warn_unused_result
Deletes a scheduled event Remove this event from being run. A procedure should not remove its own eve...
Definition: sched.c:468
struct sched_context * sched
#define ast_set_flag(p, flag)
Definition: utils.h:70
struct ast_sockaddr them
Socket address structure.
Definition: netsock2.h:63
static void ast_sockaddr_setnull(struct ast_sockaddr *addr)
Sets address addr to null.
Definition: netsock2.h:106
#define AST_SCHED_DEL(sched, id)
a loop construct to ensure that the scheduled task get deleted. The idea is that if we loop attemptin...
Definition: sched.h:51
#define ao2_ref(o, delta)
Definition: astobj2.h:472
int ast_rtp_instance_set_remote_address(struct ast_rtp_instance *instance, const struct ast_sockaddr *address)
Set the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:391
#define FLAG_NEED_MARKER_BIT
struct ast_rtcp * rtcp
#define free(a)
Definition: astmm.h:94
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct rtp_red * red
static void ast_rtp_stun_request ( struct ast_rtp_instance instance,
struct ast_sockaddr suggestion,
const char *  username 
)
static

Definition at line 2769 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_sockaddr_from_sin, ast_sockaddr_to_sin, ast_stun_request(), and ast_rtp::s.

2770 {
2771  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2772  struct sockaddr_in suggestion_tmp;
2773 
2774  ast_sockaddr_to_sin(suggestion, &suggestion_tmp);
2775  ast_stun_request(rtp->s, &suggestion_tmp, username, NULL);
2776  ast_sockaddr_from_sin(suggestion, &suggestion_tmp);
2777 }
RTP session description.
#define ast_sockaddr_from_sin(addr, sin)
Converts a struct sockaddr_in to a struct ast_sockaddr.
Definition: netsock2.h:642
int ast_stun_request(int s, struct sockaddr_in *dst, const char *username, struct sockaddr_in *answer)
Generic STUN request.
Definition: stun.c:373
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
#define ast_sockaddr_to_sin(addr, sin)
Converts a struct ast_sockaddr to a struct sockaddr_in.
Definition: netsock2.h:629
static void ast_rtp_update_source ( struct ast_rtp_instance instance)
static

Definition at line 860 of file res_rtp_asterisk.c.

References ast_debug, ast_rtp_instance_get_data(), ast_set_flag, and FLAG_NEED_MARKER_BIT.

861 {
862  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
863 
864  /* We simply set this bit so that the next packet sent will have the marker bit turned on */
866  ast_debug(3, "Setting the marker bit due to a source update\n");
867 
868  return;
869 }
RTP session description.
#define ast_set_flag(p, flag)
Definition: utils.h:70
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define FLAG_NEED_MARKER_BIT
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
static int ast_rtp_write ( struct ast_rtp_instance instance,
struct ast_frame frame 
)
static

Definition at line 1333 of file res_rtp_asterisk.c.

References ast_codec_pref_getsize(), ast_debug, AST_FORMAT_G719, AST_FORMAT_G723_1, AST_FORMAT_SIREN14, AST_FORMAT_SIREN7, AST_FORMAT_SPEEX, AST_FORMAT_SPEEX16, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_getformatname(), ast_log(), ast_rtp_codecs_payload_code(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address(), ast_rtp_raw_write(), ast_smoother_feed, ast_smoother_feed_be, AST_SMOOTHER_FLAG_BE, ast_smoother_free(), ast_smoother_new(), ast_smoother_read(), ast_smoother_set_flags(), ast_smoother_test_flag(), ast_sockaddr_isnull(), ast_frame_subclass::codec, ast_format_list::cur_ms, ast_frame::data, ast_frame::datalen, f, ast_format_list::flags, ast_format_list::fr_len, ast_frame::frametype, ast_format_list::inc_ms, ast_rtp::lasttxformat, LOG_WARNING, ast_frame::offset, ast_frame::ptr, ast_rtp::red, red_t140_to_red(), ast_rtp::smoother, and ast_frame::subclass.

Referenced by red_write().

1334 {
1335  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1336  struct ast_sockaddr remote_address = { {0,} };
1337  format_t codec, subclass;
1338 
1339  ast_rtp_instance_get_remote_address(instance, &remote_address);
1340 
1341  /* If we don't actually know the remote address don't even bother doing anything */
1342  if (ast_sockaddr_isnull(&remote_address)) {
1343  ast_debug(1, "No remote address on RTP instance '%p' so dropping frame\n", instance);
1344  return 0;
1345  }
1346 
1347  /* If there is no data length we can't very well send the packet */
1348  if (!frame->datalen) {
1349  ast_debug(1, "Received frame with no data for RTP instance '%p' so dropping frame\n", instance);
1350  return 0;
1351  }
1352 
1353  /* If the packet is not one our RTP stack supports bail out */
1354  if (frame->frametype != AST_FRAME_VOICE && frame->frametype != AST_FRAME_VIDEO && frame->frametype != AST_FRAME_TEXT) {
1355  ast_log(LOG_WARNING, "RTP can only send voice, video, and text\n");
1356  return -1;
1357  }
1358 
1359  if (rtp->red) {
1360  /* return 0; */
1361  /* no primary data or generations to send */
1362  if ((frame = red_t140_to_red(rtp->red)) == NULL)
1363  return 0;
1364  }
1365 
1366  /* Grab the subclass and look up the payload we are going to use */
1367  subclass = frame->subclass.codec;
1368  if (frame->frametype == AST_FRAME_VIDEO) {
1369  subclass &= ~0x1LL;
1370  }
1371  if ((codec = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance), 1, subclass)) < 0) {
1372  ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(frame->subclass.codec));
1373  return -1;
1374  }
1375 
1376  /* Oh dear, if the format changed we will have to set up a new smoother */
1377  if (rtp->lasttxformat != subclass) {
1378  ast_debug(1, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
1379  rtp->lasttxformat = subclass;
1380  if (rtp->smoother) {
1382  rtp->smoother = NULL;
1383  }
1384  }
1385 
1386  /* If no smoother is present see if we have to set one up */
1387  if (!rtp->smoother) {
1388  struct ast_format_list fmt = ast_codec_pref_getsize(&ast_rtp_instance_get_codecs(instance)->pref, subclass);
1389 
1390  switch (subclass) {
1391  case AST_FORMAT_SPEEX:
1392  case AST_FORMAT_SPEEX16:
1393  case AST_FORMAT_G723_1:
1394  case AST_FORMAT_SIREN7:
1395  case AST_FORMAT_SIREN14:
1396  case AST_FORMAT_G719:
1397  /* these are all frame-based codecs and cannot be safely run through
1398  a smoother */
1399  break;
1400  default:
1401  if (fmt.inc_ms) {
1402  if (!(rtp->smoother = ast_smoother_new((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms))) {
1403  ast_log(LOG_WARNING, "Unable to create smoother: format %s ms: %d len: %d\n", ast_getformatname(subclass), fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
1404  return -1;
1405  }
1406  if (fmt.flags) {
1408  }
1409  ast_debug(1, "Created smoother: format: %s ms: %d len: %d\n", ast_getformatname(subclass), fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms));
1410  }
1411  }
1412  }
1413 
1414  /* Feed audio frames into the actual function that will create a frame and send it */
1415  if (rtp->smoother) {
1416  struct ast_frame *f;
1417 
1419  ast_smoother_feed_be(rtp->smoother, frame);
1420  } else {
1421  ast_smoother_feed(rtp->smoother, frame);
1422  }
1423 
1424  while ((f = ast_smoother_read(rtp->smoother)) && (f->data.ptr)) {
1425  ast_rtp_raw_write(instance, f, codec);
1426  }
1427  } else {
1428  int hdrlen = 12;
1429  struct ast_frame *f = NULL;
1430 
1431  if (frame->offset < hdrlen) {
1432  f = ast_frdup(frame);
1433  } else {
1434  f = frame;
1435  }
1436  if (f->data.ptr) {
1437  ast_rtp_raw_write(instance, f, codec);
1438  }
1439  if (f != frame) {
1440  ast_frfree(f);
1441  }
1442 
1443  }
1444 
1445  return 0;
1446 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
struct ast_smoother * ast_smoother_new(int bytes)
Definition: frame.c:183
void ast_smoother_free(struct ast_smoother *s)
Definition: frame.c:294
int offset
Definition: frame.h:156
unsigned int flags
Definition: frame.h:560
struct ast_frame * ast_smoother_read(struct ast_smoother *s)
Definition: frame.c:244
#define AST_FORMAT_G723_1
Definition: frame.h:242
void * ptr
Definition: frame.h:160
format_t lasttxformat
void ast_smoother_set_flags(struct ast_smoother *smoother, int flags)
Definition: frame.c:198
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:483
#define LOG_WARNING
Definition: logger.h:144
format_t codec
Definition: frame.h:137
Socket address structure.
Definition: netsock2.h:63
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
Definition of supported media formats (codecs)
Definition: frame.h:550
struct ast_format_list ast_codec_pref_getsize(struct ast_codec_pref *pref, format_t format)
Get packet size for codec.
Definition: frame.c:1205
static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame *frame, int codec)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_SMOOTHER_FLAG_BE
Definition: frame.h:428
#define AST_FORMAT_SPEEX
Definition: frame.h:260
int datalen
Definition: frame.h:148
char * ast_getformatname(format_t format)
Get the name of a format.
Definition: frame.c:578
#define AST_FORMAT_SIREN7
Definition: frame.h:268
int64_t format_t
Definition: frame_defs.h:32
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
#define AST_FORMAT_SIREN14
Definition: frame.h:270
static struct ast_format f[]
Definition: format_g726.c:181
int ast_smoother_test_flag(struct ast_smoother *s, int flag)
Definition: frame.c:203
struct ast_smoother * smoother
struct rtp_red * red
#define AST_FORMAT_G719
Definition: frame.h:299
Data structure associated with a single frame of data.
Definition: frame.h:142
enum ast_frame_type frametype
Definition: frame.h:144
#define ast_frfree(fr)
Definition: frame.h:583
static struct ast_frame * red_t140_to_red(struct rtp_red *red)
union ast_frame::@172 data
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code)
Retrieve a payload based on whether it is an Asterisk format and the code.
Definition: rtp_engine.c:654
#define ast_smoother_feed_be(s, f)
Definition: frame.h:691
struct ast_frame * ast_frdup(const struct ast_frame *fr)
Copies a frame.
Definition: frame.c:474
#define ast_smoother_feed(s, f)
Definition: frame.h:686
#define AST_FORMAT_SPEEX16
Definition: frame.h:301
static int bridge_p2p_rtp_write ( struct ast_rtp_instance instance,
unsigned int *  rtpheader,
int  len,
int  hdrlen 
)
static

Definition at line 2060 of file res_rtp_asterisk.c.

References ast_clear_flag, ast_debug, ast_log(), ast_rtp_codecs_payload_code(), ast_rtp_codecs_payload_lookup(), ast_rtp_instance_get_bridged(), ast_rtp_instance_get_codecs(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), ast_rtp_instance_get_remote_address(), AST_RTP_PROPERTY_NAT, ast_set_flag, ast_sockaddr_isnull(), ast_sockaddr_stringify(), ast_test_flag, ast_verbose(), ast_rtp_payload_type::asterisk_format, ast_rtp::bridged, ast_rtp_payload_type::code, errno, FLAG_NAT_ACTIVE, FLAG_NAT_INACTIVE, FLAG_NAT_INACTIVE_NOWARN, FLAG_NEED_MARKER_BIT, LOG_WARNING, option_debug, reconstruct(), rtp_debug_test_addr(), and rtp_sendto().

Referenced by ast_rtp_read().

2061 {
2062  struct ast_rtp_instance *instance1 = ast_rtp_instance_get_bridged(instance);
2063  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance), *bridged = ast_rtp_instance_get_data(instance1);
2064  int res = 0, payload = 0, bridged_payload = 0, mark;
2065  struct ast_rtp_payload_type payload_type;
2066  int reconstruct = ntohl(rtpheader[0]);
2067  struct ast_sockaddr remote_address = { {0,} };
2068 
2069  /* Get fields from packet */
2070  payload = (reconstruct & 0x7f0000) >> 16;
2071  mark = (((reconstruct & 0x800000) >> 23) != 0);
2072 
2073  /* Check what the payload value should be */
2074  payload_type = ast_rtp_codecs_payload_lookup(ast_rtp_instance_get_codecs(instance), payload);
2075 
2076  /* Otherwise adjust bridged payload to match */
2077  bridged_payload = ast_rtp_codecs_payload_code(ast_rtp_instance_get_codecs(instance1), payload_type.asterisk_format, payload_type.code);
2078 
2079  /* If no codec could be matched between instance and instance1, then somehow things were made incompatible while we were still bridged. Bail. */
2080  if (bridged_payload < 0) {
2081  return -1;
2082  }
2083 
2084  /* If the payload coming in is not one of the negotiated ones then send it to the core, this will cause formats to change and the bridge to break */
2085  if (!(ast_rtp_instance_get_codecs(instance1)->payloads[bridged_payload].code)) {
2086  return -1;
2087  }
2088 
2089  /* If the marker bit has been explicitly set turn it on */
2090  if (ast_test_flag(rtp, FLAG_NEED_MARKER_BIT)) {
2091  mark = 1;
2093  }
2094 
2095  /* Reconstruct part of the packet */
2096  reconstruct &= 0xFF80FFFF;
2097  reconstruct |= (bridged_payload << 16);
2098  reconstruct |= (mark << 23);
2099  rtpheader[0] = htonl(reconstruct);
2100 
2101  ast_rtp_instance_get_remote_address(instance1, &remote_address);
2102 
2103  if (ast_sockaddr_isnull(&remote_address)) {
2104  ast_debug(1, "Remote address is null, most likely RTP has been stopped\n");
2105  return 0;
2106  }
2107 
2108  /* Send the packet back out */
2109  res = rtp_sendto(instance1, (void *)rtpheader, len, 0, &remote_address);
2110  if (res < 0) {
2113  "RTP Transmission error of packet to %s: %s\n",
2114  ast_sockaddr_stringify(&remote_address),
2115  strerror(errno));
2116  } else if (((ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(bridged, FLAG_NAT_INACTIVE_NOWARN)) {
2117  if (option_debug || rtpdebug)
2119  "RTP NAT: Can't write RTP to private "
2120  "address %s, waiting for other end to "
2121  "send audio...\n",
2122  ast_sockaddr_stringify(&remote_address));
2124  }
2125  return 0;
2126  } else if (rtp_debug_test_addr(&remote_address)) {
2127  ast_verbose("Sent RTP P2P packet to %s (type %-2.2d, len %-6.6d)\n",
2128  ast_sockaddr_stringify(&remote_address),
2129  bridged_payload, len - hdrlen);
2130  }
2131 
2132  return 0;
2133 }
RTP session description.
static int rtpdebug
struct ast_rtp_payload_type ast_rtp_codecs_payload_lookup(struct ast_rtp_codecs *codecs, int payload)
Retrieve payload information by payload.
Definition: rtp_engine.c:618
static int rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa)
#define ast_test_flag(p, flag)
Definition: utils.h:63
int option_debug
Definition: asterisk.c:182
#define ast_set_flag(p, flag)
Definition: utils.h:70
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:483
#define LOG_WARNING
Definition: logger.h:144
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
Socket address structure.
Definition: netsock2.h:63
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
#define FLAG_NAT_ACTIVE
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define FLAG_NAT_INACTIVE_NOWARN
#define FLAG_NEED_MARKER_BIT
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
#define ast_clear_flag(p, flag)
Definition: utils.h:77
static int reconstruct(int sign, int dqln, int y)
Definition: codec_g726.c:331
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:1418
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:478
int ast_rtp_codecs_payload_code(struct ast_rtp_codecs *codecs, const int asterisk_format, const format_t code)
Retrieve a payload based on whether it is an Asterisk format and the code.
Definition: rtp_engine.c:654
struct ast_rtp * bridged
#define FLAG_NAT_INACTIVE
static void calc_rxstamp ( struct timeval *  tv,
struct ast_rtp rtp,
unsigned int  timestamp,
int  mark 
)
static

Definition at line 1448 of file res_rtp_asterisk.c.

References ast_samp2tv(), ast_tvadd(), ast_tvsub(), ast_frame_subclass::codec, ast_rtp::drxcore, ast_rtp::f, ast_rtcp::maxrxjitter, ast_rtcp::minrxjitter, normdev_compute(), ast_rtcp::normdev_rxjitter, ast_rtp::rtcp, rtp_get_rate(), ast_rtp::rxcore, ast_rtp::rxjitter, ast_rtcp::rxjitter_count, ast_rtp::rxtransit, ast_rtp::seedrxts, stddev_compute(), ast_rtcp::stdev_rxjitter, and ast_frame::subclass.

Referenced by ast_rtp_read().

1449 {
1450  struct timeval now;
1451  struct timeval tmp;
1452  double transit;
1453  double current_time;
1454  double d;
1455  double dtv;
1456  double prog;
1457  int rate = rtp_get_rate(rtp->f.subclass.codec);
1458 
1459  double normdev_rxjitter_current;
1460  if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
1461  gettimeofday(&rtp->rxcore, NULL);
1462  rtp->drxcore = (double) rtp->rxcore.tv_sec + (double) rtp->rxcore.tv_usec / 1000000;
1463  /* map timestamp to a real time */
1464  rtp->seedrxts = timestamp; /* Their RTP timestamp started with this */
1465  tmp = ast_samp2tv(timestamp, rate);
1466  rtp->rxcore = ast_tvsub(rtp->rxcore, tmp);
1467  /* Round to 0.1ms for nice, pretty timestamps */
1468  rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 100;
1469  }
1470 
1471  gettimeofday(&now,NULL);
1472  /* rxcore is the mapping between the RTP timestamp and _our_ real time from gettimeofday() */
1473  tmp = ast_samp2tv(timestamp, rate);
1474  *tv = ast_tvadd(rtp->rxcore, tmp);
1475 
1476  prog = (double)((timestamp-rtp->seedrxts)/(float)(rate));
1477  dtv = (double)rtp->drxcore + (double)(prog);
1478  current_time = (double)now.tv_sec + (double)now.tv_usec/1000000;
1479  transit = current_time - dtv;
1480  d = transit - rtp->rxtransit;
1481  rtp->rxtransit = transit;
1482  if (d<0)
1483  d=-d;
1484  rtp->rxjitter += (1./16.) * (d - rtp->rxjitter);
1485 
1486  if (rtp->rtcp) {
1487  if (rtp->rxjitter > rtp->rtcp->maxrxjitter)
1488  rtp->rtcp->maxrxjitter = rtp->rxjitter;
1489  if (rtp->rtcp->rxjitter_count == 1)
1490  rtp->rtcp->minrxjitter = rtp->rxjitter;
1491  if (rtp->rtcp && rtp->rxjitter < rtp->rtcp->minrxjitter)
1492  rtp->rtcp->minrxjitter = rtp->rxjitter;
1493 
1494  normdev_rxjitter_current = normdev_compute(rtp->rtcp->normdev_rxjitter,rtp->rxjitter,rtp->rtcp->rxjitter_count);
1495  rtp->rtcp->stdev_rxjitter = stddev_compute(rtp->rtcp->stdev_rxjitter,rtp->rxjitter,rtp->rtcp->normdev_rxjitter,normdev_rxjitter_current,rtp->rtcp->rxjitter_count);
1496 
1497  rtp->rtcp->normdev_rxjitter = normdev_rxjitter_current;
1498  rtp->rtcp->rxjitter_count++;
1499  }
1500 }
double drxcore
union ast_frame_subclass subclass
Definition: frame.h:146
unsigned int rxjitter_count
double rxjitter
double stdev_rxjitter
format_t codec
Definition: frame.h:137
double minrxjitter
struct timeval rxcore
unsigned int seedrxts
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:191
double maxrxjitter
struct ast_rtcp * rtcp
double rxtransit
static double stddev_compute(double stddev, double sample, double normdev, double normdev_curent, unsigned int sample_count)
static double normdev_compute(double normdev, double sample, unsigned int sample_count)
Calculate normal deviation.
struct timeval ast_tvadd(struct timeval a, struct timeval b)
Returns the sum of two timevals a + b.
Definition: utils.c:1587
struct ast_frame f
static int rtp_get_rate(format_t subclass)
struct timeval tv
struct timeval ast_tvsub(struct timeval a, struct timeval b)
Returns the difference of two timevals a - b.
Definition: utils.c:1601
double normdev_rxjitter
static unsigned int calc_txstamp ( struct ast_rtp rtp,
struct timeval *  delivery 
)
static

Definition at line 530 of file res_rtp_asterisk.c.

References ast_tvdiff_ms(), ast_tvnow(), ast_tvzero(), and ast_rtp::txcore.

Referenced by ast_rtp_dtmf_begin(), ast_rtp_dtmf_continuation(), ast_rtp_dtmf_end_with_duration(), and ast_rtp_raw_write().

531 {
532  struct timeval t;
533  long ms;
534 
535  if (ast_tvzero(rtp->txcore)) {
536  rtp->txcore = ast_tvnow();
537  rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
538  }
539 
540  t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow();
541  if ((ms = ast_tvdiff_ms(t, rtp->txcore)) < 0) {
542  ms = 0;
543  }
544  rtp->txcore = t;
545 
546  return (unsigned int) ms;
547 }
int ast_tvzero(const struct timeval t)
Returns true if the argument is 0,0.
Definition: time.h:100
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
struct timeval txcore
static struct ast_frame* create_dtmf_frame ( struct ast_rtp_instance instance,
enum ast_frame_type  type,
int  compensate 
)
static

Definition at line 1502 of file res_rtp_asterisk.c.

References AST_CONTROL_FLASH, ast_debug, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_LIST_NEXT, ast_null_frame, ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address(), ast_sockaddr_stringify(), ast_tvcmp(), ast_tvnow(), ast_frame::datalen, ast_rtp::dtmfmute, ast_rtp::dtmfsamples, ast_rtp::f, ast_frame::frametype, ast_frame_subclass::integer, ast_frame::mallocd, ast_rtp::resp, ast_frame::samples, ast_frame::src, ast_frame::subclass, and type.

Referenced by ast_rtp_read(), process_dtmf_cisco(), and process_dtmf_rfc2833().

1503 {
1504  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1505  struct ast_sockaddr remote_address = { {0,} };
1506 
1507  ast_rtp_instance_get_remote_address(instance, &remote_address);
1508 
1509  if (((compensate && type == AST_FRAME_DTMF_END) || (type == AST_FRAME_DTMF_BEGIN)) && ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) {
1510  ast_debug(1, "Ignore potential DTMF echo from '%s'\n",
1511  ast_sockaddr_stringify(&remote_address));
1512  rtp->resp = 0;
1513  rtp->dtmfsamples = 0;
1514  return &ast_null_frame;
1515  }
1516  ast_debug(1, "Creating %s DTMF Frame: %d (%c), at %s\n",
1517  type == AST_FRAME_DTMF_END ? "END" : "BEGIN",
1518  rtp->resp, rtp->resp,
1519  ast_sockaddr_stringify(&remote_address));
1520  if (rtp->resp == 'X') {
1521  rtp->f.frametype = AST_FRAME_CONTROL;
1523  } else {
1524  rtp->f.frametype = type;
1525  rtp->f.subclass.integer = rtp->resp;
1526  }
1527  rtp->f.datalen = 0;
1528  rtp->f.samples = 0;
1529  rtp->f.mallocd = 0;
1530  rtp->f.src = "RTP";
1531  AST_LIST_NEXT(&rtp->f, frame_list) = NULL;
1532 
1533  return &rtp->f;
1534 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
struct ast_frame ast_null_frame
Definition: frame.c:131
#define AST_LIST_NEXT(elm, field)
Returns the next entry in the list after the given entry.
Definition: linkedlists.h:438
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition: time.h:142
Socket address structure.
Definition: netsock2.h:63
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
const char * src
Definition: frame.h:158
int datalen
Definition: frame.h:148
int ast_tvcmp(struct timeval _a, struct timeval _b)
Compres two struct timeval instances returning -1, 0, 1 if the first arg is smaller, equal or greater to the second.
Definition: time.h:120
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
struct ast_frame f
static const char type[]
Definition: chan_nbs.c:57
int mallocd
Definition: frame.h:152
struct timeval dtmfmute
enum ast_frame_type frametype
Definition: frame.h:144
unsigned int dtmfsamples
int samples
Definition: frame.h:150
static int create_new_socket ( const char *  type,
int  af 
)
static

Definition at line 454 of file res_rtp_asterisk.c.

References ast_log(), errno, and LOG_WARNING.

Referenced by ast_rtp_new(), and ast_rtp_prop_set().

455 {
456  int sock = socket(af, SOCK_DGRAM, 0);
457 
458  if (sock < 0) {
459  if (!type) {
460  type = "RTP/RTCP";
461  }
462  ast_log(LOG_WARNING, "Unable to allocate %s socket: %s\n", type, strerror(errno));
463  } else {
464  long flags = fcntl(sock, F_GETFL);
465  fcntl(sock, F_SETFL, flags | O_NONBLOCK);
466 #ifdef SO_NO_CHECK
467  if (nochecksums) {
468  setsockopt(sock, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums));
469  }
470 #endif
471  }
472 
473  return sock;
474 }
#define LOG_WARNING
Definition: logger.h:144
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
int errno
static const char type[]
Definition: chan_nbs.c:57
static char* handle_cli_rtcp_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2924 of file res_rtp_asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, rtcp_do_debug_ip(), rtcpdebugaddr, and ast_cli_entry::usage.

2925 {
2926  switch (cmd) {
2927  case CLI_INIT:
2928  e->command = "rtcp set debug {on|off|ip}";
2929  e->usage =
2930  "Usage: rtcp set debug {on|off|ip host[:port]}\n"
2931  " Enable/Disable dumping of all RTCP packets. If 'ip' is\n"
2932  " specified, limit the dumped packets to those to and from\n"
2933  " the specified 'host' with optional port.\n";
2934  return NULL;
2935  case CLI_GENERATE:
2936  return NULL;
2937  }
2938 
2939  if (a->argc == e->args) { /* set on or off */
2940  if (!strncasecmp(a->argv[e->args-1], "on", 2)) {
2941  rtcpdebug = 1;
2942  memset(&rtcpdebugaddr, 0, sizeof(rtcpdebugaddr));
2943  ast_cli(a->fd, "RTCP Debugging Enabled\n");
2944  return CLI_SUCCESS;
2945  } else if (!strncasecmp(a->argv[e->args-1], "off", 3)) {
2946  rtcpdebug = 0;
2947  ast_cli(a->fd, "RTCP Debugging Disabled\n");
2948  return CLI_SUCCESS;
2949  }
2950  } else if (a->argc == e->args +1) { /* ip */
2951  return rtcp_do_debug_ip(a);
2952  }
2953 
2954  return CLI_SHOWUSAGE; /* default, failure */
2955 }
const int argc
Definition: cli.h:154
Definition: cli.h:146
static char * rtcp_do_debug_ip(struct ast_cli_args *a)
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
static int rtcpdebug
const int fd
Definition: cli.h:153
static struct ast_sockaddr rtcpdebugaddr
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_rtcp_set_stats ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2957 of file res_rtp_asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, and ast_cli_entry::usage.

2958 {
2959  switch (cmd) {
2960  case CLI_INIT:
2961  e->command = "rtcp set stats {on|off}";
2962  e->usage =
2963  "Usage: rtcp set stats {on|off}\n"
2964  " Enable/Disable dumping of RTCP stats.\n";
2965  return NULL;
2966  case CLI_GENERATE:
2967  return NULL;
2968  }
2969 
2970  if (a->argc != e->args)
2971  return CLI_SHOWUSAGE;
2972 
2973  if (!strncasecmp(a->argv[e->args-1], "on", 2))
2974  rtcpstats = 1;
2975  else if (!strncasecmp(a->argv[e->args-1], "off", 3))
2976  rtcpstats = 0;
2977  else
2978  return CLI_SHOWUSAGE;
2979 
2980  ast_cli(a->fd, "RTCP Stats %s\n", rtcpstats ? "Enabled" : "Disabled");
2981  return CLI_SUCCESS;
2982 }
static int rtcpstats
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static char* handle_cli_rtp_set_debug ( struct ast_cli_entry e,
int  cmd,
struct ast_cli_args a 
)
static

Definition at line 2891 of file res_rtp_asterisk.c.

References ast_cli_args::argc, ast_cli_entry::args, ast_cli_args::argv, ast_cli(), CLI_GENERATE, CLI_INIT, CLI_SHOWUSAGE, CLI_SUCCESS, ast_cli_entry::command, ast_cli_args::fd, rtp_do_debug_ip(), rtpdebugaddr, and ast_cli_entry::usage.

2892 {
2893  switch (cmd) {
2894  case CLI_INIT:
2895  e->command = "rtp set debug {on|off|ip}";
2896  e->usage =
2897  "Usage: rtp set debug {on|off|ip host[:port]}\n"
2898  " Enable/Disable dumping of all RTP packets. If 'ip' is\n"
2899  " specified, limit the dumped packets to those to and from\n"
2900  " the specified 'host' with optional port.\n";
2901  return NULL;
2902  case CLI_GENERATE:
2903  return NULL;
2904  }
2905 
2906  if (a->argc == e->args) { /* set on or off */
2907  if (!strncasecmp(a->argv[e->args-1], "on", 2)) {
2908  rtpdebug = 1;
2909  memset(&rtpdebugaddr, 0, sizeof(rtpdebugaddr));
2910  ast_cli(a->fd, "RTP Debugging Enabled\n");
2911  return CLI_SUCCESS;
2912  } else if (!strncasecmp(a->argv[e->args-1], "off", 3)) {
2913  rtpdebug = 0;
2914  ast_cli(a->fd, "RTP Debugging Disabled\n");
2915  return CLI_SUCCESS;
2916  }
2917  } else if (a->argc == e->args +1) { /* ip */
2918  return rtp_do_debug_ip(a);
2919  }
2920 
2921  return CLI_SHOWUSAGE; /* default, failure */
2922 }
static int rtpdebug
const int argc
Definition: cli.h:154
Definition: cli.h:146
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int args
This gets set in ast_cli_register()
Definition: cli.h:179
const int fd
Definition: cli.h:153
static struct ast_sockaddr rtpdebugaddr
const char *const * argv
Definition: cli.h:155
#define CLI_SHOWUSAGE
Definition: cli.h:44
char * command
Definition: cli.h:180
static char * rtp_do_debug_ip(struct ast_cli_args *a)
const char * usage
Definition: cli.h:171
#define CLI_SUCCESS
Definition: cli.h:43
static int load_module ( void  )
static

Definition at line 3072 of file res_rtp_asterisk.c.

References ARRAY_LEN, ast_cli_register_multiple(), AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, ast_rtp_engine_register, ast_rtp_engine_unregister(), and rtp_reload().

3073 {
3075  return AST_MODULE_LOAD_DECLINE;
3076  }
3077 
3080  return AST_MODULE_LOAD_DECLINE;
3081  }
3082 
3083  rtp_reload(0);
3084 
3085  return AST_MODULE_LOAD_SUCCESS;
3086 }
#define ast_rtp_engine_register(engine)
Definition: rtp_engine.h:423
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
Unregister an RTP engine.
Definition: rtp_engine.c:222
static int rtp_reload(int reload)
static struct ast_cli_entry cli_rtp[]
static struct ast_rtp_engine asterisk_rtp_engine
int ast_cli_register_multiple(struct ast_cli_entry *e, int len)
Register multiple commands.
Definition: cli.c:2167
static double normdev_compute ( double  normdev,
double  sample,
unsigned int  sample_count 
)
static

Calculate normal deviation.

Definition at line 426 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_read(), ast_rtcp_write_rr(), and calc_rxstamp().

427 {
428  normdev = normdev * sample_count + sample;
429  sample_count++;
430 
431  return normdev / sample_count;
432 }
static struct ast_frame* process_cn_rfc3389 ( struct ast_rtp_instance instance,
unsigned char *  data,
int  len,
unsigned int  seqno,
unsigned int  timestamp,
struct ast_sockaddr addr,
int  payloadtype,
int  mark 
)
static

Definition at line 1749 of file res_rtp_asterisk.c.

References ast_debug, AST_FRAME_CNG, AST_FRIENDLY_OFFSET, ast_log(), ast_rtp_instance_get_data(), ast_rtp_instance_get_remote_address(), ast_set_flag, ast_sockaddr_stringify(), ast_test_flag, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_rtp::f, FLAG_3389_WARNING, ast_frame::frametype, ast_frame_subclass::integer, ast_rtp::lastrxformat, LOG_NOTICE, ast_frame::offset, ast_frame::ptr, ast_rtp::rawdata, ast_frame::samples, and ast_frame::subclass.

Referenced by ast_rtp_read().

1750 {
1751  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1752 
1753  /* Convert comfort noise into audio with various codecs. Unfortunately this doesn't
1754  totally help us out becuase we don't have an engine to keep it going and we are not
1755  guaranteed to have it every 20ms or anything */
1756  if (rtpdebug)
1757  ast_debug(0, "- RTP 3389 Comfort noise event: Level %" PRId64 " (len = %d)\n", rtp->lastrxformat, len);
1758 
1759  if (ast_test_flag(rtp, FLAG_3389_WARNING)) {
1760  struct ast_sockaddr remote_address = { {0,} };
1761 
1762  ast_rtp_instance_get_remote_address(instance, &remote_address);
1763 
1764  ast_log(LOG_NOTICE, "Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client address: %s\n",
1765  ast_sockaddr_stringify(&remote_address));
1767  }
1768 
1769  /* Must have at least one byte */
1770  if (!len)
1771  return NULL;
1772  if (len < 24) {
1773  rtp->f.data.ptr = rtp->rawdata + AST_FRIENDLY_OFFSET;
1774  rtp->f.datalen = len - 1;
1775  rtp->f.offset = AST_FRIENDLY_OFFSET;
1776  memcpy(rtp->f.data.ptr, data + 1, len - 1);
1777  } else {
1778  rtp->f.data.ptr = NULL;
1779  rtp->f.offset = 0;
1780  rtp->f.datalen = 0;
1781  }
1782  rtp->f.frametype = AST_FRAME_CNG;
1783  rtp->f.subclass.integer = data[0] & 0x7f;
1784  rtp->f.samples = 0;
1785  rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
1786 
1787  return &rtp->f;
1788 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
#define FLAG_3389_WARNING
static int rtpdebug
int offset
Definition: frame.h:156
#define ast_test_flag(p, flag)
Definition: utils.h:63
void * ptr
Definition: frame.h:160
#define ast_set_flag(p, flag)
Definition: utils.h:70
format_t lastrxformat
Socket address structure.
Definition: netsock2.h:63
unsigned char rawdata[8192+AST_FRIENDLY_OFFSET]
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
#define AST_FRIENDLY_OFFSET
Offset into a frame&#39;s data buffer.
Definition: frame.h:204
int datalen
Definition: frame.h:148
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
#define LOG_NOTICE
Definition: logger.h:133
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
struct ast_frame f
struct timeval delivery
Definition: frame.h:162
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
int samples
Definition: frame.h:150
static struct ast_frame* process_dtmf_cisco ( struct ast_rtp_instance instance,
unsigned char *  data,
int  len,
unsigned int  seqno,
unsigned int  timestamp,
struct ast_sockaddr addr,
int  payloadtype,
int  mark 
)
static

Definition at line 1670 of file res_rtp_asterisk.c.

References ast_debug, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), AST_RTP_PROPERTY_DTMF_COMPENSATE, create_dtmf_frame(), ast_rtp::dtmf_timeout, ast_rtp::dtmfsamples, f, ast_rtp::flags, ast_rtp::lastrxformat, option_debug, ast_rtp::resp, rtp_get_rate(), ast_frame::samples, and seq.

Referenced by ast_rtp_read().

1671 {
1672  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1673  unsigned int event, flags, power;
1674  char resp = 0;
1675  unsigned char seq;
1676  struct ast_frame *f = NULL;
1677 
1678  if (len < 4) {
1679  return NULL;
1680  }
1681 
1682  /* The format of Cisco RTP DTMF packet looks like next:
1683  +0 - sequence number of DTMF RTP packet (begins from 1,
1684  wrapped to 0)
1685  +1 - set of flags
1686  +1 (bit 0) - flaps by different DTMF digits delimited by audio
1687  or repeated digit without audio???
1688  +2 (+4,+6,...) - power level? (rises from 0 to 32 at begin of tone
1689  then falls to 0 at its end)
1690  +3 (+5,+7,...) - detected DTMF digit (0..9,*,#,A-D,...)
1691  Repeated DTMF information (bytes 4/5, 6/7) is history shifted right
1692  by each new packet and thus provides some redudancy.
1693 
1694  Sample of Cisco RTP DTMF packet is (all data in hex):
1695  19 07 00 02 12 02 20 02
1696  showing end of DTMF digit '2'.
1697 
1698  The packets
1699  27 07 00 02 0A 02 20 02
1700  28 06 20 02 00 02 0A 02
1701  shows begin of new digit '2' with very short pause (20 ms) after
1702  previous digit '2'. Bit +1.0 flips at begin of new digit.
1703 
1704  Cisco RTP DTMF packets comes as replacement of audio RTP packets
1705  so its uses the same sequencing and timestamping rules as replaced
1706  audio packets. Repeat interval of DTMF packets is 20 ms and not rely
1707  on audio framing parameters. Marker bit isn't used within stream of
1708  DTMFs nor audio stream coming immediately after DTMF stream. Timestamps
1709  are not sequential at borders between DTMF and audio streams,
1710  */
1711 
1712  seq = data[0];
1713  flags = data[1];
1714  power = data[2];
1715  event = data[3] & 0x1f;
1716 
1717  if (option_debug > 2 || rtpdebug)
1718  ast_debug(0, "Cisco DTMF Digit: %02x (len=%d, seq=%d, flags=%02x, power=%u, history count=%d)\n", event, len, seq, flags, power, (len - 4) / 2);
1719  if (event < 10) {
1720  resp = '0' + event;
1721  } else if (event < 11) {
1722  resp = '*';
1723  } else if (event < 12) {
1724  resp = '#';
1725  } else if (event < 16) {
1726  resp = 'A' + (event - 12);
1727  } else if (event < 17) {
1728  resp = 'X';
1729  }
1730  if ((!rtp->resp && power) || (rtp->resp && (rtp->resp != resp))) {
1731  rtp->resp = resp;
1732  /* Why we should care on DTMF compensation at reception? */
1734  f = create_dtmf_frame(instance, AST_FRAME_DTMF_BEGIN, 0);
1735  rtp->dtmfsamples = 0;
1736  }
1737  } else if ((rtp->resp == resp) && !power) {
1739  f->samples = rtp->dtmfsamples * (rtp->lastrxformat ? (rtp_get_rate(rtp->lastrxformat) / 1000) : 8);
1740  rtp->resp = 0;
1741  } else if (rtp->resp == resp)
1742  rtp->dtmfsamples += 20 * (rtp->lastrxformat ? (rtp_get_rate(rtp->lastrxformat) / 1000) : 8);
1743 
1744  rtp->dtmf_timeout = 0;
1745 
1746  return f;
1747 }
RTP session description.
static int rtpdebug
int option_debug
Definition: asterisk.c:182
static struct ast_frame * create_dtmf_frame(struct ast_rtp_instance *instance, enum ast_frame_type type, int compensate)
format_t lastrxformat
unsigned int flags
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
unsigned int dtmf_timeout
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
static struct ast_format f[]
Definition: format_g726.c:181
static int rtp_get_rate(format_t subclass)
static volatile unsigned int seq
Definition: app_sms.c:118
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:478
Data structure associated with a single frame of data.
Definition: frame.h:142
unsigned int dtmfsamples
union ast_frame::@172 data
int samples
Definition: frame.h:150
static void process_dtmf_rfc2833 ( struct ast_rtp_instance instance,
unsigned char *  data,
int  len,
unsigned int  seqno,
unsigned int  timestamp,
struct ast_sockaddr addr,
int  payloadtype,
int  mark,
struct frame_list frames 
)
static

Definition at line 1536 of file res_rtp_asterisk.c.

References ast_debug, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_frdup(), AST_LIST_INSERT_TAIL, ast_log(), ast_rtp_instance_get_data(), ast_rtp_instance_get_prop(), ast_rtp_instance_get_remote_address(), AST_RTP_PROPERTY_DTMF_COMPENSATE, ast_samp2tv(), ast_sockaddr_stringify(), ast_tv(), ast_tvdiff_ms(), ast_verbose(), ast_frame_subclass::codec, create_dtmf_frame(), ast_rtp::dtmf_duration, ast_rtp::dtmf_timeout, ast_rtp::dtmfsamples, dtmftimeout, f, ast_rtp::last_end_timestamp, ast_rtp::last_seqno, ast_frame::len, LOG_DEBUG, option_debug, ast_rtp::resp, rtp_debug_test_addr(), rtp_get_rate(), ast_frame::samples, ast_frame::seqno, and ast_frame::subclass.

Referenced by ast_rtp_read().

1537 {
1538  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
1539  struct ast_sockaddr remote_address = { {0,} };
1540  unsigned int event, event_end, samples;
1541  char resp = 0;
1542  struct ast_frame *f = NULL;
1543 
1544  ast_rtp_instance_get_remote_address(instance, &remote_address);
1545 
1546  /* Figure out event, event end, and samples */
1547  event = ntohl(*((unsigned int *)(data)));
1548  event >>= 24;
1549  event_end = ntohl(*((unsigned int *)(data)));
1550  event_end <<= 8;
1551  event_end >>= 24;
1552  samples = ntohl(*((unsigned int *)(data)));
1553  samples &= 0xFFFF;
1554 
1555  if (rtp_debug_test_addr(&remote_address)) {
1556  ast_verbose("Got RTP RFC2833 from %s (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6d, mark %d, event %08x, end %d, duration %-5.5u) \n",
1557  ast_sockaddr_stringify(&remote_address),
1558  payloadtype, seqno, timestamp, len, (mark?1:0), event, ((event_end & 0x80)?1:0), samples);
1559  }
1560 
1561  /* Print out debug if turned on */
1562  if (rtpdebug || option_debug > 2)
1563  ast_debug(0, "- RTP 2833 Event: %08x (len = %d)\n", event, len);
1564 
1565  /* Figure out what digit was pressed */
1566  if (event < 10) {
1567  resp = '0' + event;
1568  } else if (event < 11) {
1569  resp = '*';
1570  } else if (event < 12) {
1571  resp = '#';
1572  } else if (event < 16) {
1573  resp = 'A' + (event - 12);
1574  } else if (event < 17) { /* Event 16: Hook flash */
1575  resp = 'X';
1576  } else {
1577  /* Not a supported event */
1578  ast_log(LOG_DEBUG, "Ignoring RTP 2833 Event: %08x. Not a DTMF Digit.\n", event);
1579  return;
1580  }
1581 
1583  if ((rtp->last_end_timestamp != timestamp) || (rtp->resp && rtp->resp != resp)) {
1584  rtp->resp = resp;
1585  rtp->dtmf_timeout = 0;
1587  f->len = 0;
1588  rtp->last_end_timestamp = timestamp;
1589  AST_LIST_INSERT_TAIL(frames, f, frame_list);
1590  }
1591  } else {
1592  /* The duration parameter measures the complete
1593  duration of the event (from the beginning) - RFC2833.
1594  Account for the fact that duration is only 16 bits long
1595  (about 8 seconds at 8000 Hz) and can wrap is digit
1596  is hold for too long. */
1597  unsigned int new_duration = rtp->dtmf_duration;
1598  unsigned int last_duration = new_duration & 0xFFFF;
1599 
1600  if (last_duration > 64000 && samples < last_duration) {
1601  new_duration += 0xFFFF + 1;
1602  }
1603  new_duration = (new_duration & ~0xFFFF) | samples;
1604 
1605  if (event_end & 0x80) {
1606  if ((seqno != rtp->last_seqno) && (timestamp > rtp->last_end_timestamp)) {
1607  rtp->last_end_timestamp = timestamp;
1608  rtp->dtmf_duration = new_duration;
1609  rtp->resp = resp;
1610  f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
1612  rtp->resp = 0;
1613  rtp->dtmf_duration = rtp->dtmf_timeout = 0;
1614  AST_LIST_INSERT_TAIL(frames, f, frame_list);
1615  } else if (rtpdebug) {
1616  ast_debug(1, "Dropping re-transmitted, duplicate, or out of order DTMF END frame (seqno: %u, ts %u, digit %c)\n",
1617  seqno, timestamp, resp);
1618  }
1619  } else {
1620  /* Begin/continuation */
1621 
1622  /* The second portion of the seqno check is to not mistakenly
1623  * stop accepting DTMF if the seqno rolls over beyond
1624  * 65535.
1625  */
1626  if ((rtp->last_seqno > seqno && rtp->last_seqno - seqno < 50)
1627  || timestamp <= rtp->last_end_timestamp) {
1628  /* Out of order frame. Processing this can cause us to
1629  * improperly duplicate incoming DTMF, so just drop
1630  * this.
1631  */
1632  if (rtpdebug) {
1633  ast_debug(1, "Dropping out of order DTMF frame (seqno %u, ts %u, digit %c)\n",
1634  seqno, timestamp, resp);
1635  }
1636  return;
1637  }
1638 
1639  if (rtp->resp && rtp->resp != resp) {
1640  /* Another digit already began. End it */
1641  f = ast_frdup(create_dtmf_frame(instance, AST_FRAME_DTMF_END, 0));
1643  rtp->resp = 0;
1644  rtp->dtmf_duration = rtp->dtmf_timeout = 0;
1645  AST_LIST_INSERT_TAIL(frames, f, frame_list);
1646  }
1647 
1648  if (rtp->resp) {
1649  /* Digit continues */
1650  rtp->dtmf_duration = new_duration;
1651  } else {
1652  /* New digit began */
1653  rtp->resp = resp;
1655  rtp->dtmf_duration = samples;
1656  AST_LIST_INSERT_TAIL(frames, f, frame_list);
1657  }
1658 
1659  rtp->dtmf_timeout = timestamp + rtp->dtmf_duration + dtmftimeout;
1660  }
1661 
1662  rtp->last_seqno = seqno;
1663  }
1664 
1665  rtp->dtmfsamples = samples;
1666 
1667  return;
1668 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
static int rtpdebug
int seqno
Definition: frame.h:172
int option_debug
Definition: asterisk.c:182
void ast_verbose(const char *fmt,...)
Definition: logger.c:1568
static struct ast_frame * create_dtmf_frame(struct ast_rtp_instance *instance, enum ast_frame_type type, int compensate)
int64_t ast_tvdiff_ms(struct timeval end, struct timeval start)
Computes the difference (in milliseconds) between two struct timeval instances.
Definition: time.h:90
format_t codec
Definition: frame.h:137
static int dtmftimeout
#define LOG_DEBUG
Definition: logger.h:122
Socket address structure.
Definition: netsock2.h:63
static int rtp_debug_test_addr(struct ast_sockaddr *addr)
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
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:191
#define AST_LIST_INSERT_TAIL(head, elm, field)
Appends a list entry to the tail of a list.
Definition: linkedlists.h:716
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
unsigned int dtmf_timeout
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
void ast_rtp_instance_get_remote_address(struct ast_rtp_instance *instance, struct ast_sockaddr *address)
Get the address of the remote endpoint that we are sending RTP to.
Definition: rtp_engine.c:447
static struct ast_format f[]
Definition: format_g726.c:181
unsigned int dtmf_duration
static int rtp_get_rate(format_t subclass)
struct timeval ast_tv(ast_time_t sec, ast_suseconds_t usec)
Returns a timeval from sec, usec.
Definition: time.h:179
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:478
Data structure associated with a single frame of data.
Definition: frame.h:142
unsigned int last_seqno
unsigned int dtmfsamples
union ast_frame::@172 data
long len
Definition: frame.h:170
unsigned int last_end_timestamp
struct ast_frame * ast_frdup(const struct ast_frame *fr)
Copies a frame.
Definition: frame.c:474
int samples
Definition: frame.h:150
static struct ast_frame* red_t140_to_red ( struct rtp_red red)
static

Definition at line 1296 of file res_rtp_asterisk.c.

References ast_frame::data, ast_frame::datalen, for(), rtp_red::hdrlen, rtp_red::len, len(), rtp_red::num_gen, ast_frame::ptr, rtp_red::t140, and rtp_red::t140red.

Referenced by ast_rtp_write().

1296  {
1297  unsigned char *data = red->t140red.data.ptr;
1298  int len = 0;
1299  int i;
1300 
1301  /* replace most aged generation */
1302  if (red->len[0]) {
1303  for (i = 1; i < red->num_gen+1; i++)
1304  len += red->len[i];
1305 
1306  memmove(&data[red->hdrlen], &data[red->hdrlen+red->len[0]], len);
1307  }
1308 
1309  /* Store length of each generation and primary data length*/
1310  for (i = 0; i < red->num_gen; i++)
1311  red->len[i] = red->len[i+1];
1312  red->len[i] = red->t140.datalen;
1313 
1314  /* write each generation length in red header */
1315  len = red->hdrlen;
1316  for (i = 0; i < red->num_gen; i++)
1317  len += data[i*4+3] = red->len[i];
1318 
1319  /* add primary data to buffer */
1320  memcpy(&data[len], red->t140.data.ptr, red->t140.datalen);
1321  red->t140red.datalen = len + red->t140.datalen;
1322 
1323  /* no primary data and no generations to send */
1324  if (len == red->hdrlen && !red->t140.datalen)
1325  return NULL;
1326 
1327  /* reset t.140 buffer */
1328  red->t140.datalen = 0;
1329 
1330  return &red->t140red;
1331 }
void * ptr
Definition: frame.h:160
for(;;)
Definition: ast_expr2.c:2460
int datalen
Definition: frame.h:148
struct ast_frame t140red
static int len(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t buflen)
struct ast_frame t140
unsigned char len[AST_RED_MAX_GENERATION]
union ast_frame::@172 data
static int red_write ( const void *  data)
static

Write t140 redundacy frame.

Parameters
dataprimary data to be buffered

Definition at line 2637 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), ast_rtp_write(), ast_rtp::red, and rtp_red::t140.

Referenced by rtp_red_init().

2638 {
2639  struct ast_rtp_instance *instance = (struct ast_rtp_instance*) data;
2640  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2641 
2642  ast_rtp_write(instance, &rtp->red->t140);
2643 
2644  return 1;
2645 }
RTP session description.
static int ast_rtp_write(struct ast_rtp_instance *instance, struct ast_frame *frame)
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct ast_frame t140
struct rtp_red * red
static int reload_module ( void  )
static

Definition at line 3066 of file res_rtp_asterisk.c.

References rtp_reload().

3067 {
3068  rtp_reload(1);
3069  return 0;
3070 }
static int rtp_reload(int reload)
static int rtcp_debug_test_addr ( struct ast_sockaddr addr)
inlinestatic

Definition at line 343 of file res_rtp_asterisk.c.

References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), and rtcpdebugaddr.

Referenced by ast_rtcp_read(), ast_rtcp_write_rr(), and ast_rtcp_write_sr().

344 {
345  if (!rtcpdebug) {
346  return 0;
347  }
349  if (rtcpdebugport) {
350  return (ast_sockaddr_cmp(&rtcpdebugaddr, addr) == 0); /* look for RTCP packets from IP+Port */
351  } else {
352  return (ast_sockaddr_cmp_addr(&rtcpdebugaddr, addr) == 0); /* only look for RTCP packets from IP */
353  }
354  }
355 
356  return 1;
357 }
static int rtcpdebugport
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:325
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
static int rtcpdebug
static struct ast_sockaddr rtcpdebugaddr
static char* rtcp_do_debug_ip ( struct ast_cli_args a)
static

Definition at line 2874 of file res_rtp_asterisk.c.

References ast_cli_args::argv, ast_cli(), ast_sockaddr_parse(), ast_sockaddr_split_hostport(), ast_sockaddr_stringify(), ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_SUCCESS, ast_cli_args::fd, and rtcpdebugaddr.

Referenced by handle_cli_rtcp_set_debug().

2875 {
2876  char *arg = ast_strdupa(a->argv[4]);
2877  char *debughost = NULL;
2878  char *debugport = NULL;
2879 
2880  if (!ast_sockaddr_parse(&rtcpdebugaddr, arg, 0) || !ast_sockaddr_split_hostport(arg, &debughost, &debugport, 0)) {
2881  ast_cli(a->fd, "Lookup failed for '%s'\n", arg);
2882  return CLI_FAILURE;
2883  }
2884  rtcpdebugport = (!ast_strlen_zero(debugport) && debugport[0] != '0');
2885  ast_cli(a->fd, "RTCP Debugging Enabled for address: %s\n",
2887  rtcpdebug = 1;
2888  return CLI_SUCCESS;
2889 }
static int rtcpdebugport
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:198
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:132
static int rtcpdebug
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_sockaddr rtcpdebugaddr
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
#define CLI_FAILURE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:43
static int rtcp_recvfrom ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa 
)
static

Definition at line 377 of file res_rtp_asterisk.c.

References __rtp_recvfrom().

Referenced by ast_rtcp_read().

378 {
379  return __rtp_recvfrom(instance, buf, size, flags, sa, 1);
380 }
static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
unsigned int flags
static int rtcp_sendto ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa 
)
static

Definition at line 401 of file res_rtp_asterisk.c.

References __rtp_sendto().

Referenced by ast_rtcp_write_rr(), and ast_rtcp_write_sr().

402 {
403  return __rtp_sendto(instance, buf, size, flags, sa, 1);
404 }
unsigned int flags
static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
static int rtp_debug_test_addr ( struct ast_sockaddr addr)
inlinestatic

Definition at line 327 of file res_rtp_asterisk.c.

References ast_sockaddr_cmp(), ast_sockaddr_cmp_addr(), ast_sockaddr_isnull(), and rtpdebugaddr.

Referenced by ast_rtp_dtmf_begin(), ast_rtp_dtmf_continuation(), ast_rtp_dtmf_end_with_duration(), ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), bridge_p2p_rtp_write(), and process_dtmf_rfc2833().

328 {
329  if (!rtpdebug) {
330  return 0;
331  }
333  if (rtpdebugport) {
334  return (ast_sockaddr_cmp(&rtpdebugaddr, addr) == 0); /* look for RTP packets from IP+Port */
335  } else {
336  return (ast_sockaddr_cmp_addr(&rtpdebugaddr, addr) == 0); /* only look for RTP packets from IP */
337  }
338  }
339 
340  return 1;
341 }
static int rtpdebug
static int rtpdebugport
int ast_sockaddr_cmp(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares two ast_sockaddr structures.
Definition: netsock2.c:300
int ast_sockaddr_cmp_addr(const struct ast_sockaddr *a, const struct ast_sockaddr *b)
Compares the addresses of two ast_sockaddr structures.
Definition: netsock2.c:325
static int ast_sockaddr_isnull(const struct ast_sockaddr *addr)
Checks if the ast_sockaddr is null. &quot;null&quot; in this sense essentially means uninitialized, or having a 0 length.
Definition: netsock2.h:93
static struct ast_sockaddr rtpdebugaddr
static char* rtp_do_debug_ip ( struct ast_cli_args a)
static

Definition at line 2857 of file res_rtp_asterisk.c.

References ast_cli_args::argv, ast_cli(), ast_sockaddr_parse(), ast_sockaddr_split_hostport(), ast_sockaddr_stringify(), ast_strdupa, ast_strlen_zero(), CLI_FAILURE, CLI_SUCCESS, ast_cli_args::fd, and rtpdebugaddr.

Referenced by handle_cli_rtp_set_debug().

2858 {
2859  char *arg = ast_strdupa(a->argv[4]);
2860  char *debughost = NULL;
2861  char *debugport = NULL;
2862 
2863  if (!ast_sockaddr_parse(&rtpdebugaddr, arg, 0) || !ast_sockaddr_split_hostport(arg, &debughost, &debugport, 0)) {
2864  ast_cli(a->fd, "Lookup failed for '%s'\n", arg);
2865  return CLI_FAILURE;
2866  }
2867  rtpdebugport = (!ast_strlen_zero(debugport) && debugport[0] != '0');
2868  ast_cli(a->fd, "RTP Debugging Enabled for address: %s\n",
2870  rtpdebug = 1;
2871  return CLI_SUCCESS;
2872 }
static int rtpdebug
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition: netsock2.c:198
static int rtpdebugport
void ast_cli(int fd, const char *fmt,...)
Definition: cli.c:105
int ast_sockaddr_split_hostport(char *str, char **host, char **port, int flags)
Splits a string into its host and port components.
Definition: netsock2.c:132
const int fd
Definition: cli.h:153
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition: strings.h:63
static struct ast_sockaddr rtpdebugaddr
const char *const * argv
Definition: cli.h:155
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: utils.h:663
static char * ast_sockaddr_stringify(const struct ast_sockaddr *addr)
Wrapper around ast_sockaddr_stringify_fmt() with default format.
Definition: netsock2.h:210
#define CLI_FAILURE
Definition: cli.h:45
#define CLI_SUCCESS
Definition: cli.h:43
static int rtp_get_rate ( format_t  subclass)
static

Definition at line 411 of file res_rtp_asterisk.c.

References AST_FORMAT_G722, and ast_format_rate().

Referenced by ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtp_dtmf_end_with_duration(), ast_rtp_raw_write(), ast_rtp_read(), calc_rxstamp(), process_dtmf_cisco(), and process_dtmf_rfc2833().

412 {
413  return (subclass == AST_FORMAT_G722) ? 8000 : ast_format_rate(subclass);
414 }
static force_inline int ast_format_rate(format_t format)
Get the sample rate for a given format.
Definition: frame.h:809
#define AST_FORMAT_G722
Definition: frame.h:266
static int rtp_learning_rtp_seq_update ( struct ast_rtp rtp,
uint16_t  seq 
)
static

Definition at line 499 of file res_rtp_asterisk.c.

References ast_debug, ast_rtp::learning_max_seq, ast_rtp::learning_probation, and seq.

Referenced by ast_rtp_read().

500 {
501  int probation = 1;
502 
503  ast_debug(1, "%p -- probation = %d, seq = %d\n", rtp, rtp->learning_probation, seq);
504 
505  if (seq == rtp->learning_max_seq + 1) {
506  /* packet is in sequence */
507  rtp->learning_probation--;
508  rtp->learning_max_seq = seq;
509  if (rtp->learning_probation == 0) {
510  probation = 0;
511  }
512  } else {
514  rtp->learning_max_seq = seq;
515  }
516 
517  return probation;
518 }
#define ast_debug(level,...)
Log a DEBUG message.
Definition: logger.h:236
static volatile unsigned int seq
Definition: app_sms.c:118
int learning_probation
static int learning_min_sequential
uint16_t learning_max_seq
static void rtp_learning_seq_init ( struct ast_rtp rtp,
uint16_t  seq 
)
static

Definition at line 484 of file res_rtp_asterisk.c.

References ast_rtp::learning_max_seq, learning_min_sequential, and ast_rtp::learning_probation.

Referenced by ast_rtp_new(), and ast_rtp_remote_address_set().

485 {
486  rtp->learning_max_seq = seq - 1;
488 }
static volatile unsigned int seq
Definition: app_sms.c:118
int learning_probation
static int learning_min_sequential
uint16_t learning_max_seq
static int rtp_recvfrom ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa 
)
static

Definition at line 382 of file res_rtp_asterisk.c.

References __rtp_recvfrom().

Referenced by ast_rtp_read().

383 {
384  return __rtp_recvfrom(instance, buf, size, flags, sa, 0);
385 }
static int __rtp_recvfrom(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
unsigned int flags
static int rtp_red_buffer ( struct ast_rtp_instance instance,
struct ast_frame frame 
)
static

Definition at line 2682 of file res_rtp_asterisk.c.

References ast_rtp_instance_get_data(), rtp_red::buf_data, ast_frame::data, ast_frame::datalen, ast_frame::ptr, ast_rtp::red, rtp_red::t140, and ast_frame::ts.

2683 {
2684  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2685 
2686  if (frame->datalen > -1) {
2687  struct rtp_red *red = rtp->red;
2688  memcpy(&red->buf_data[red->t140.datalen], frame->data.ptr, frame->datalen);
2689  red->t140.datalen += frame->datalen;
2690  red->t140.ts = frame->ts;
2691  }
2692 
2693  return 0;
2694 }
RTP session description.
void * ptr
Definition: frame.h:160
long ts
Definition: frame.h:168
int datalen
Definition: frame.h:148
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
struct ast_frame t140
unsigned char buf_data[64000]
struct rtp_red * red
union ast_frame::@172 data
static int rtp_red_init ( struct ast_rtp_instance instance,
int  buffer_time,
int *  payloads,
int  generations 
)
static

Definition at line 2647 of file res_rtp_asterisk.c.

References ast_calloc, AST_FORMAT_T140RED, AST_FRAME_TEXT, ast_rtp_instance_get_data(), ast_sched_add(), rtp_red::buf_data, ast_frame_subclass::codec, ast_frame::data, ast_frame::datalen, ast_frame::frametype, rtp_red::hdrlen, rtp_red::num_gen, rtp_red::prev_ts, rtp_red::pt, ast_frame::ptr, ast_rtp::red, red_write(), ast_rtp::sched, rtp_red::schedid, ast_frame::subclass, rtp_red::t140, rtp_red::t140red, rtp_red::t140red_data, rtp_red::ti, and ast_frame::ts.

2648 {
2649  struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
2650  int x;
2651 
2652  if (!(rtp->red = ast_calloc(1, sizeof(*rtp->red)))) {
2653  return -1;
2654  }
2655 
2656  rtp->red->t140.frametype = AST_FRAME_TEXT;
2658  rtp->red->t140.data.ptr = &rtp->red->buf_data;
2659 
2660  rtp->red->t140.ts = 0;
2661  rtp->red->t140red = rtp->red->t140;
2662  rtp->red->t140red.data.ptr = &rtp->red->t140red_data;
2663  rtp->red->t140red.datalen = 0;
2664  rtp->red->ti = buffer_time;
2665  rtp->red->num_gen = generations;
2666  rtp->red->hdrlen = generations * 4 + 1;
2667  rtp->red->prev_ts = 0;
2668 
2669  for (x = 0; x < generations; x++) {
2670  rtp->red->pt[x] = payloads[x];
2671  rtp->red->pt[x] |= 1 << 7; /* mark redundant generations pt */
2672  rtp->red->t140red_data[x*4] = rtp->red->pt[x];
2673  }
2674  rtp->red->t140red_data[x*4] = rtp->red->pt[x] = payloads[x]; /* primary pt */
2675  rtp->red->schedid = ast_sched_add(rtp->sched, generations, red_write, instance);
2676 
2677  rtp->red->t140.datalen = 0;
2678 
2679  return 0;
2680 }
union ast_frame_subclass subclass
Definition: frame.h:146
RTP session description.
struct sched_context * sched
void * ptr
Definition: frame.h:160
int ast_sched_add(struct sched_context *con, int when, ast_sched_cb callback, const void *data) attribute_warn_unused_result
Adds a scheduled event Schedule an event to take place at some point in the future. callback will be called with data as the argument, when milliseconds into the future (approximately) If callback returns 0, no further events will be re-scheduled.
Definition: sched.c:446
long ts
Definition: frame.h:168
format_t codec
Definition: frame.h:137
long int prev_ts
#define AST_FORMAT_T140RED
Definition: frame.h:292
int datalen
Definition: frame.h:148
struct ast_frame t140red
unsigned char t140red_data[64000]
void * ast_rtp_instance_get_data(struct ast_rtp_instance *instance)
Get the data portion of an RTP instance.
Definition: rtp_engine.c:369
unsigned char pt[AST_RED_MAX_GENERATION]
struct ast_frame t140
unsigned char buf_data[64000]
struct rtp_red * red
#define ast_calloc(a, b)
Definition: astmm.h:82
static int red_write(const void *data)
Write t140 redundacy frame.
enum ast_frame_type frametype
Definition: frame.h:144
union ast_frame::@172 data
static int rtp_reload ( int  reload)
static

Definition at line 2990 of file res_rtp_asterisk.c.

References ast_config_destroy(), ast_config_load2(), ast_false(), ast_log(), ast_true(), ast_variable_retrieve(), ast_verb, CONFIG_FLAG_FILEUNCHANGED, CONFIG_STATUS_FILEINVALID, CONFIG_STATUS_FILEMISSING, CONFIG_STATUS_FILEUNCHANGED, DEFAULT_DTMF_TIMEOUT, DEFAULT_LEARNING_MIN_SEQUENTIAL, DEFAULT_RTP_END, DEFAULT_RTP_START, LOG_WARNING, MAXIMUM_RTP_PORT, MINIMUM_RTP_PORT, RTCP_MAX_INTERVALMS, RTCP_MIN_INTERVALMS, and STRICT_RTP_OPEN.

Referenced by load_module(), and reload_module().

2991 {
2992  struct ast_config *cfg;
2993  const char *s;
2994  struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
2995 
2996  cfg = ast_config_load2("rtp.conf", "rtp", config_flags);
2998  return 0;
2999  }
3000 
3006  if (cfg) {
3007  if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
3008  rtpstart = atoi(s);
3009  if (rtpstart < MINIMUM_RTP_PORT)
3011  if (rtpstart > MAXIMUM_RTP_PORT)
3013  }
3014  if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) {
3015  rtpend = atoi(s);
3016  if (rtpend < MINIMUM_RTP_PORT)
3018  if (rtpend > MAXIMUM_RTP_PORT)
3020  }
3021  if ((s = ast_variable_retrieve(cfg, "general", "rtcpinterval"))) {
3022  rtcpinterval = atoi(s);
3023  if (rtcpinterval == 0)
3024  rtcpinterval = 0; /* Just so we're clear... it's zero */
3026  rtcpinterval = RTCP_MIN_INTERVALMS; /* This catches negative numbers too */
3029  }
3030  if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
3031 #ifdef SO_NO_CHECK
3032  nochecksums = ast_false(s) ? 1 : 0;
3033 #else
3034  if (ast_false(s))
3035  ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
3036 #endif
3037  }
3038  if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) {
3039  dtmftimeout = atoi(s);
3040  if ((dtmftimeout < 0) || (dtmftimeout > 64000)) {
3041  ast_log(LOG_WARNING, "DTMF timeout of '%d' outside range, using default of '%d' instead\n",
3044  };
3045  }
3046  if ((s = ast_variable_retrieve(cfg, "general", "strictrtp"))) {
3047  strictrtp = ast_true(s);
3048  }
3049  if ((s = ast_variable_retrieve(cfg, "general", "probation"))) {
3050  if ((sscanf(s, "%d", &learning_min_sequential) <= 0) || learning_min_sequential <= 0) {
3051  ast_log(LOG_WARNING, "Value for 'probation' could not be read, using default of '%d' instead\n",
3053  }
3054  }
3055  ast_config_destroy(cfg);
3056  }
3057  if (rtpstart >= rtpend) {
3058  ast_log(LOG_WARNING, "Unreasonable values for RTP start/end port in rtp.conf\n");
3061  }
3062  ast_verb(2, "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
3063  return 0;
3064 }
const char * ast_variable_retrieve(const struct ast_config *config, const char *category, const char *variable)
Gets a variable.
Definition: config.c:625
#define DEFAULT_DTMF_TIMEOUT
static int rtpstart
#define LOG_WARNING
Definition: logger.h:144
#define MINIMUM_RTP_PORT
#define RTCP_MIN_INTERVALMS
#define DEFAULT_RTP_END
static int dtmftimeout
struct ast_config * ast_config_load2(const char *filename, const char *who_asked, struct ast_flags flags)
Load a config file.
Definition: config.c:2499
#define ast_verb(level,...)
Definition: logger.h:243
void ast_config_destroy(struct ast_config *config)
Destroys a config.
Definition: config.c:1037
#define RTCP_MAX_INTERVALMS
#define CONFIG_STATUS_FILEMISSING
Definition: config.h:50
#define MAXIMUM_RTP_PORT
#define DEFAULT_LEARNING_MIN_SEQUENTIAL
static int reload(void)
Definition: app_amd.c:497
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is &quot;true&quot;. This function checks to see whether a string passed to it is an indication of an &quot;true&quot; value. It checks to see if the string is &quot;yes&quot;, &quot;true&quot;, &quot;y&quot;, &quot;t&quot;, &quot;on&quot; or &quot;1&quot;.
Definition: utils.c:1533
#define DEFAULT_RTP_START
static int strictrtp
void ast_log(int level, const char *file, int line, const char *function, const char *fmt,...)
Used for sending a log message This is the standard logger function. Probably the only way you will i...
Definition: logger.c:1207
Structure used to handle boolean flags.
Definition: utils.h:200
int attribute_pure ast_false(const char *val)
Make sure something is false. Determine if a string containing a boolean value is &quot;false&quot;...
Definition: utils.c:1550
static int learning_min_sequential
static int rtcpinterval
#define CONFIG_STATUS_FILEINVALID
Definition: config.h:52
static int rtpend
#define CONFIG_STATUS_FILEUNCHANGED
Definition: config.h:51
static int rtp_sendto ( struct ast_rtp_instance instance,
void *  buf,
size_t  size,
int  flags,
struct ast_sockaddr sa 
)
static

Definition at line 406 of file res_rtp_asterisk.c.

References __rtp_sendto().

Referenced by ast_rtp_dtmf_begin(), ast_rtp_dtmf_continuation(), ast_rtp_dtmf_end_with_duration(), ast_rtp_raw_write(), ast_rtp_sendcng(), and bridge_p2p_rtp_write().

407 {
408  return __rtp_sendto(instance, buf, size, flags, sa, 0);
409 }
unsigned int flags
Definition: utils.h:201
static int __rtp_sendto(struct ast_rtp_instance *instance, void *buf, size_t size, int flags, struct ast_sockaddr *sa, int rtcp)
static double stddev_compute ( double  stddev,
double  sample,
double  normdev,
double  normdev_curent,
unsigned int  sample_count 
)
static

Definition at line 434 of file res_rtp_asterisk.c.

References SQUARE.

Referenced by ast_rtcp_read(), ast_rtcp_write_rr(), and calc_rxstamp().

435 {
436 /*
437  for the formula check http://www.cs.umd.edu/~austinjp/constSD.pdf
438  return sqrt( (sample_count*pow(stddev,2) + sample_count*pow((sample-normdev)/(sample_count+1),2) + pow(sample-normdev_curent,2)) / (sample_count+1));
439  we can compute the sigma^2 and that way we would have to do the sqrt only 1 time at the end and would save another pow 2 compute
440  optimized formula
441 */
442 #define SQUARE(x) ((x) * (x))
443 
444  stddev = sample_count * stddev;
445  sample_count++;
446 
447  return stddev +
448  ( sample_count * SQUARE( (sample - normdev) / sample_count ) ) +
449  ( SQUARE(sample - normdev_curent) / sample_count );
450 
451 #undef SQUARE
452 }
#define SQUARE(x)
static void timeval2ntp ( struct timeval  tv,
unsigned int *  msw,
unsigned int *  lsw 
)
static

Definition at line 897 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_read(), and ast_rtcp_write_sr().

898 {
899  unsigned int sec, usec, frac;
900  sec = tv.tv_sec + 2208988800u; /* Sec between 1900 and 1970 */
901  usec = tv.tv_usec;
902  frac = (usec << 12) + (usec << 8) - ((usec * 3650) >> 6);
903  *msw = sec;
904  *lsw = frac;
905 }
struct timeval tv
static int unload_module ( void  )
static

Definition at line 3088 of file res_rtp_asterisk.c.

References ARRAY_LEN, ast_cli_unregister_multiple(), and ast_rtp_engine_unregister().

3089 {
3092 
3093  return 0;
3094 }
#define ARRAY_LEN(a)
Definition: isdn_lib.c:42
int ast_cli_unregister_multiple(struct ast_cli_entry *e, int len)
Unregister multiple commands.
Definition: cli.c:2177
int ast_rtp_engine_unregister(struct ast_rtp_engine *engine)
Unregister an RTP engine.
Definition: rtp_engine.c:222
static struct ast_cli_entry cli_rtp[]
static struct ast_rtp_engine asterisk_rtp_engine

Variable Documentation

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 = "ac1f6a56484a8820659555499174e588" , .load = load_module, .unload = unload_module, .reload = reload_module, .load_pri = AST_MODPRI_CHANNEL_DEPEND, }
static

Definition at line 3101 of file res_rtp_asterisk.c.

Definition at line 3101 of file res_rtp_asterisk.c.

struct ast_rtp_engine asterisk_rtp_engine
static

Definition at line 299 of file res_rtp_asterisk.c.

struct ast_cli_entry cli_rtp[]
static
Initial value:
= {
AST_CLI_DEFINE(handle_cli_rtp_set_debug, "Enable/Disable RTP debugging"),
AST_CLI_DEFINE(handle_cli_rtcp_set_debug, "Enable/Disable RTCP debugging"),
AST_CLI_DEFINE(handle_cli_rtcp_set_stats, "Enable/Disable RTCP stats"),
}
#define AST_CLI_DEFINE(fn, txt,...)
Definition: cli.h:191
static char * handle_cli_rtp_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_rtcp_set_debug(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)

Definition at line 2984 of file res_rtp_asterisk.c.

int dtmftimeout = DEFAULT_DTMF_TIMEOUT
static

Definition at line 87 of file res_rtp_asterisk.c.

Referenced by process_dtmf_rfc2833().

int learning_min_sequential
static

Definition at line 103 of file res_rtp_asterisk.c.

Referenced by rtp_learning_seq_init().

struct ast_srtp_res* res_srtp

Definition at line 48 of file rtp_engine.c.

int rtcpdebug
static

Are we debugging RTCP?

Definition at line 92 of file res_rtp_asterisk.c.

struct ast_sockaddr rtcpdebugaddr
static

Debug RTCP packets to/from this host

Definition at line 96 of file res_rtp_asterisk.c.

Referenced by handle_cli_rtcp_set_debug(), rtcp_debug_test_addr(), and rtcp_do_debug_ip().

int rtcpdebugport
static

Definition at line 98 of file res_rtp_asterisk.c.

int rtcpinterval = RTCP_DEFAULT_INTERVALMS
static

Time between rtcp reports in millisecs

Definition at line 94 of file res_rtp_asterisk.c.

Referenced by ast_rtcp_calc_interval().

int rtcpstats
static

Are we debugging RTCP?

Definition at line 93 of file res_rtp_asterisk.c.

int rtpdebug
static

Are we debugging?

Definition at line 91 of file res_rtp_asterisk.c.

struct ast_sockaddr rtpdebugaddr
static

Debug packets to/from this host

Definition at line 95 of file res_rtp_asterisk.c.

Referenced by handle_cli_rtp_set_debug(), rtp_debug_test_addr(), and rtp_do_debug_ip().

int rtpdebugport
static

Definition at line 97 of file res_rtp_asterisk.c.

int rtpend = DEFAULT_RTP_END
static

Last port for RTP sessions (set in rtp.conf)

Definition at line 90 of file res_rtp_asterisk.c.

int rtpstart = DEFAULT_RTP_START
static

First port for RTP sessions (set in rtp.conf)

Definition at line 89 of file res_rtp_asterisk.c.

Referenced by ast_rtp_new().

int strictrtp
static

Definition at line 102 of file res_rtp_asterisk.c.