#include "asterisk.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/time.h>
#include <signal.h>
#include <errno.h>
#include <unistd.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <fcntl.h>
#include "asterisk/rtp.h"
#include "asterisk/frame.h"
#include "asterisk/logger.h"
#include "asterisk/options.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/unaligned.h"
Go to the source code of this file.
Data Structures | |
struct | __attribute__ |
struct | ast_rtcp |
Structure defining an RTCP session. More... | |
struct | ast_rtp |
RTP session description. More... | |
struct | rtpPayloadType |
Structure representing a RTP session. More... | |
struct | stun_addr |
struct | stun_attr |
struct | stun_header |
struct | stun_state |
Defines | |
#define | DEFAULT_DTMF_TIMEOUT 3000 |
#define | FLAG_3389_WARNING (1 << 0) |
#define | FLAG_CALLBACK_MODE (1 << 6) |
#define | FLAG_DTMF_COMPENSATE (1 << 7) |
#define | FLAG_HAS_DTMF (1 << 3) |
#define | FLAG_HAS_STUN (1 << 8) |
#define | FLAG_NAT_ACTIVE (3 << 1) |
#define | FLAG_NAT_INACTIVE (0 << 1) |
#define | FLAG_NAT_INACTIVE_NOWARN (1 << 1) |
#define | FLAG_P2P_NEED_DTMF (1 << 5) |
#define | FLAG_P2P_SENT_MARK (1 << 4) |
#define | MAX_TIMESTAMP_SKEW 640 |
#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 | STUN_ACCEPT (1) |
#define | STUN_BINDERR 0x0111 |
#define | STUN_BINDREQ 0x0001 |
#define | STUN_BINDRESP 0x0101 |
#define | STUN_CHANGE_REQUEST 0x0003 |
#define | STUN_CHANGED_ADDRESS 0x0005 |
#define | STUN_ERROR_CODE 0x0009 |
#define | STUN_IGNORE (0) |
#define | STUN_MAPPED_ADDRESS 0x0001 |
#define | STUN_MESSAGE_INTEGRITY 0x0008 |
#define | STUN_PASSWORD 0x0007 |
#define | STUN_REFLECTED_FROM 0x000b |
#define | STUN_RESPONSE_ADDRESS 0x0002 |
#define | STUN_SECERR 0x0112 |
#define | STUN_SECREQ 0x0002 |
#define | STUN_SECRESP 0x0102 |
#define | STUN_SOURCE_ADDRESS 0x0004 |
#define | STUN_UNKNOWN_ATTRIBUTES 0x000a |
#define | STUN_USERNAME 0x0006 |
Functions | |
static void | append_attr_address (struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left) |
static void | append_attr_string (struct stun_attr **attr, int attrval, const char *s, int *len, int *left) |
static | AST_LIST_HEAD_STATIC (protos, ast_rtp_protocol) |
List of current sessions. | |
static unsigned int | ast_rtcp_calc_interval (struct ast_rtp *rtp) |
int | ast_rtcp_fd (struct ast_rtp *rtp) |
static struct ast_rtcp * | ast_rtcp_new (void) |
Initialize a new RTCP session. | |
struct ast_frame * | ast_rtcp_read (struct ast_rtp *rtp) |
int | ast_rtcp_send_h261fur (void *data) |
Public function: Send an H.261 fast update request, some devices need this rather than SIP XML. | |
static int | ast_rtcp_write (const void *data) |
Write and RTCP packet to the far end. | |
static int | ast_rtcp_write_rr (const void *data) |
Send RTCP recepient's report. | |
static int | ast_rtcp_write_sr (const void *data) |
Send RTCP sender's report. | |
size_t | ast_rtp_alloc_size (void) |
Get the amount of space required to hold an RTP session. | |
enum ast_bridge_result | ast_rtp_bridge (struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc, int timeoutms) |
Bridge calls. If possible and allowed, initiate re-invite so the peers exchange media directly outside of Asterisk. | |
int | ast_rtp_codec_getformat (int pt) |
struct ast_codec_pref * | ast_rtp_codec_getpref (struct ast_rtp *rtp) |
int | ast_rtp_codec_setpref (struct ast_rtp *rtp, struct ast_codec_pref *prefs) |
void | ast_rtp_destroy (struct ast_rtp *rtp) |
int | ast_rtp_early_bridge (struct ast_channel *dest, struct ast_channel *src) |
If possible, create an early bridge directly between the devices without having to send a re-invite later. | |
int | ast_rtp_fd (struct ast_rtp *rtp) |
struct ast_rtp * | ast_rtp_get_bridged (struct ast_rtp *rtp) |
void | ast_rtp_get_current_formats (struct ast_rtp *rtp, int *astFormats, int *nonAstFormats) |
Return the union of all of the codecs that were set by rtp_set...() calls They're returned as two distinct sets: AST_FORMATs, and AST_RTPs. | |
int | ast_rtp_get_peer (struct ast_rtp *rtp, struct sockaddr_in *them) |
char * | ast_rtp_get_quality (struct ast_rtp *rtp, struct ast_rtp_quality *qual) |
Return RTCP quality string. | |
int | ast_rtp_get_rtpholdtimeout (struct ast_rtp *rtp) |
Get rtp hold timeout. | |
int | ast_rtp_get_rtpkeepalive (struct ast_rtp *rtp) |
Get RTP keepalive interval. | |
int | ast_rtp_get_rtptimeout (struct ast_rtp *rtp) |
Get rtp timeout. | |
void | ast_rtp_get_us (struct ast_rtp *rtp, struct sockaddr_in *us) |
int | ast_rtp_getnat (struct ast_rtp *rtp) |
void | ast_rtp_init (void) |
Initialize the RTP system in Asterisk. | |
int | ast_rtp_lookup_code (struct ast_rtp *rtp, const int isAstFormat, const int code) |
Looks up an RTP code out of our *static* outbound list. | |
char * | ast_rtp_lookup_mime_multiple (char *buf, size_t size, const int capability, const int isAstFormat, enum ast_rtp_options options) |
Build a string of MIME subtype names from a capability list. | |
const char * | ast_rtp_lookup_mime_subtype (const int isAstFormat, const int code, enum ast_rtp_options options) |
Mapping an Asterisk code into a MIME subtype (string):. | |
struct rtpPayloadType | ast_rtp_lookup_pt (struct ast_rtp *rtp, int pt) |
Mapping between RTP payload format codes and Asterisk codes:. | |
int | ast_rtp_make_compatible (struct ast_channel *dest, struct ast_channel *src, int media) |
struct ast_rtp * | ast_rtp_new (struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode) |
Initializate a RTP session. | |
void | ast_rtp_new_init (struct ast_rtp *rtp) |
Initialize a new RTP structure. | |
struct ast_rtp * | ast_rtp_new_with_bindaddr (struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr) |
Initializate a RTP session using an in_addr structure. | |
int | ast_rtp_proto_register (struct ast_rtp_protocol *proto) |
Register interface to channel driver. | |
void | ast_rtp_proto_unregister (struct ast_rtp_protocol *proto) |
Unregister interface to channel driver. | |
void | ast_rtp_pt_clear (struct ast_rtp *rtp) |
Setting RTP payload types from lines in a SDP description:. | |
void | ast_rtp_pt_copy (struct ast_rtp *dest, struct ast_rtp *src) |
Copy payload types between RTP structures. | |
void | ast_rtp_pt_default (struct ast_rtp *rtp) |
Set payload types to defaults. | |
static int | ast_rtp_raw_write (struct ast_rtp *rtp, struct ast_frame *f, int codec) |
struct ast_frame * | ast_rtp_read (struct ast_rtp *rtp) |
int | ast_rtp_reload (void) |
void | ast_rtp_reset (struct ast_rtp *rtp) |
int | ast_rtp_sendcng (struct ast_rtp *rtp, int level) |
generate comfort noice (CNG) | |
int | ast_rtp_senddigit_begin (struct ast_rtp *rtp, char digit) |
Send begin frames for DTMF. | |
static int | ast_rtp_senddigit_continuation (struct ast_rtp *rtp) |
Send continuation frame for DTMF. | |
int | ast_rtp_senddigit_end (struct ast_rtp *rtp, char digit) |
Send end packets for DTMF. | |
void | ast_rtp_set_callback (struct ast_rtp *rtp, ast_rtp_callback callback) |
void | ast_rtp_set_data (struct ast_rtp *rtp, void *data) |
void | ast_rtp_set_m_type (struct ast_rtp *rtp, int pt) |
Make a note of a RTP payload type that was seen in a SDP "m=" line. By default, use the well-known value for this type (although it may still be set to a different value by a subsequent "a=rtpmap:" line). | |
void | ast_rtp_set_peer (struct ast_rtp *rtp, struct sockaddr_in *them) |
void | ast_rtp_set_rtpholdtimeout (struct ast_rtp *rtp, int timeout) |
Set rtp hold timeout. | |
void | ast_rtp_set_rtpkeepalive (struct ast_rtp *rtp, int period) |
set RTP keepalive interval | |
int | ast_rtp_set_rtpmap_type (struct ast_rtp *rtp, int pt, char *mimeType, char *mimeSubtype, enum ast_rtp_options options) |
Make a note of a RTP payload type (with MIME type) that was seen in an SDP "a=rtpmap:" line. | |
void | ast_rtp_set_rtptimeout (struct ast_rtp *rtp, int timeout) |
Set rtp timeout. | |
void | ast_rtp_set_rtptimers_onhold (struct ast_rtp *rtp) |
void | ast_rtp_setdtmf (struct ast_rtp *rtp, int dtmf) |
Indicate whether this RTP session is carrying DTMF or not. | |
void | ast_rtp_setdtmfcompensate (struct ast_rtp *rtp, int compensate) |
Compensate for devices that send RFC2833 packets all at once. | |
void | ast_rtp_setnat (struct ast_rtp *rtp, int nat) |
void | ast_rtp_setstun (struct ast_rtp *rtp, int stun_enable) |
Enable STUN capability. | |
int | ast_rtp_settos (struct ast_rtp *rtp, int tos) |
void | ast_rtp_stop (struct ast_rtp *rtp) |
void | ast_rtp_stun_request (struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username) |
void | ast_rtp_unset_m_type (struct ast_rtp *rtp, int pt) |
remove setting from payload type list if the rtpmap header indicates an unknown media type | |
int | ast_rtp_write (struct ast_rtp *rtp, struct ast_frame *_f) |
static enum ast_bridge_result | bridge_native_loop (struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, struct ast_rtp *vp0, struct ast_rtp *vp1, struct ast_rtp_protocol *pr0, struct ast_rtp_protocol *pr1, int codec0, int codec1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1) |
Bridge loop for true native bridge (reinvite). | |
static enum ast_bridge_result | bridge_p2p_loop (struct ast_channel *c0, struct ast_channel *c1, struct ast_rtp *p0, struct ast_rtp *p1, int timeoutms, int flags, struct ast_frame **fo, struct ast_channel **rc, void *pvt0, void *pvt1) |
Bridge loop for partial native bridge (packet2packet). | |
static int | bridge_p2p_rtp_write (struct ast_rtp *rtp, struct ast_rtp *bridged, unsigned int *rtpheader, int len, int hdrlen) |
Perform a Packet2Packet RTP write. | |
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_rtp_protocol * | get_proto (struct ast_channel *chan) |
Get channel driver interface structure. | |
static int | p2p_callback_disable (struct ast_channel *chan, struct ast_rtp *rtp, int *fds, int **iod) |
Helper function to switch a channel and RTP stream out of callback mode. | |
static int | p2p_callback_enable (struct ast_channel *chan, struct ast_rtp *rtp, int *fds, int **iod) |
P2P RTP Callback. | |
static void | p2p_set_bridge (struct ast_rtp *rtp0, struct ast_rtp *rtp1) |
Helper function that sets what an RTP structure is bridged to. | |
static struct ast_frame * | process_cisco_dtmf (struct ast_rtp *rtp, unsigned char *data, int len) |
static struct ast_frame * | process_rfc2833 (struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp) |
Process RTP DTMF and events according to RFC 2833. | |
static struct ast_frame * | process_rfc3389 (struct ast_rtp *rtp, unsigned char *data, int len) |
Process Comfort Noise RTP. | |
static int | rtcp_debug_test_addr (struct sockaddr_in *addr) |
static int | rtcp_do_debug (int fd, int argc, char *argv[]) |
static int | rtcp_do_debug_deprecated (int fd, int argc, char *argv[]) |
static int | rtcp_do_debug_ip (int fd, int argc, char *argv[]) |
static int | rtcp_do_debug_ip_deprecated (int fd, int argc, char *argv[]) |
static int | rtcp_do_stats (int fd, int argc, char *argv[]) |
static int | rtcp_do_stats_deprecated (int fd, int argc, char *argv[]) |
static int | rtcp_no_debug (int fd, int argc, char *argv[]) |
static int | rtcp_no_debug_deprecated (int fd, int argc, char *argv[]) |
static int | rtcp_no_stats (int fd, int argc, char *argv[]) |
static int | rtcp_no_stats_deprecated (int fd, int argc, char *argv[]) |
static int | rtp_debug_test_addr (struct sockaddr_in *addr) |
static int | rtp_do_debug (int fd, int argc, char *argv[]) |
static int | rtp_do_debug_ip (int fd, int argc, char *argv[]) |
static int | rtp_no_debug (int fd, int argc, char *argv[]) |
static int | rtp_socket (void) |
static int | rtpread (int *id, int fd, short events, void *cbdata) |
static struct ast_frame * | send_dtmf (struct ast_rtp *rtp, enum ast_frame_type type) |
static const char * | stun_attr2str (int msg) |
static int | stun_do_debug (int fd, int argc, char *argv[]) |
static int | stun_handle_packet (int s, struct sockaddr_in *src, unsigned char *data, size_t len) |
static const char * | stun_msg2str (int msg) |
static int | stun_no_debug (int fd, int argc, char *argv[]) |
static int | stun_process_attr (struct stun_state *state, struct stun_attr *attr) |
static void | stun_req_id (struct stun_header *req) |
static int | stun_send (int s, struct sockaddr_in *dst, struct stun_header *resp) |
static void | timeval2ntp (struct timeval tv, unsigned int *msw, unsigned int *lsw) |
Variables | |
static struct ast_cli_entry | cli_rtp [] |
static struct ast_cli_entry | cli_rtp_no_debug_deprecated |
static struct ast_cli_entry | cli_rtp_rtcp_debug_deprecated |
static struct ast_cli_entry | cli_rtp_rtcp_debug_ip_deprecated |
static struct ast_cli_entry | cli_rtp_rtcp_no_debug_deprecated |
static struct ast_cli_entry | cli_rtp_rtcp_no_stats_deprecated |
static struct ast_cli_entry | cli_rtp_rtcp_stats_deprecated |
static struct ast_cli_entry | cli_stun_no_debug_deprecated |
static char | debug_usage [] |
static int | dtmftimeout = DEFAULT_DTMF_TIMEOUT |
struct { | |
struct rtpPayloadType payloadType | |
char * subtype | |
char * type | |
} | mimeTypes [] |
static char | no_debug_usage [] |
struct stun_header | packed |
static char | rtcp_debug_usage [] |
static char | rtcp_no_debug_usage [] |
static char | rtcp_no_stats_usage [] |
static char | rtcp_stats_usage [] |
static int | rtcpdebug |
static struct sockaddr_in | rtcpdebugaddr |
static int | rtcpinterval = RTCP_DEFAULT_INTERVALMS |
static int | rtcpstats |
static int | rtpdebug |
static struct sockaddr_in | rtpdebugaddr |
static int | rtpend |
static int | rtpstart |
static struct rtpPayloadType | static_RTP_PT [MAX_RTP_PT] |
static char | stun_debug_usage [] |
static char | stun_no_debug_usage [] |
static int | stundebug |
Definition in file rtp.c.
#define DEFAULT_DTMF_TIMEOUT 3000 |
#define FLAG_3389_WARNING (1 << 0) |
#define FLAG_CALLBACK_MODE (1 << 6) |
Definition at line 193 of file rtp.c.
Referenced by ast_rtp_new_with_bindaddr(), and p2p_callback_disable().
#define FLAG_DTMF_COMPENSATE (1 << 7) |
Definition at line 194 of file rtp.c.
Referenced by ast_rtp_bridge(), ast_rtp_setdtmfcompensate(), process_rfc2833(), and send_dtmf().
#define FLAG_HAS_DTMF (1 << 3) |
Definition at line 190 of file rtp.c.
Referenced by ast_rtp_bridge(), ast_rtp_new_init(), and ast_rtp_setdtmf().
#define FLAG_HAS_STUN (1 << 8) |
#define FLAG_NAT_ACTIVE (3 << 1) |
Definition at line 187 of file rtp.c.
Referenced by ast_rtp_early_bridge(), ast_rtp_getnat(), ast_rtp_make_compatible(), ast_rtp_raw_write(), ast_rtp_read(), bridge_native_loop(), and bridge_p2p_rtp_write().
#define FLAG_NAT_INACTIVE (0 << 1) |
Definition at line 188 of file rtp.c.
Referenced by ast_rtp_raw_write(), and bridge_p2p_rtp_write().
#define FLAG_NAT_INACTIVE_NOWARN (1 << 1) |
Definition at line 189 of file rtp.c.
Referenced by ast_rtp_raw_write(), and bridge_p2p_rtp_write().
#define FLAG_P2P_NEED_DTMF (1 << 5) |
#define FLAG_P2P_SENT_MARK (1 << 4) |
Definition at line 191 of file rtp.c.
Referenced by ast_rtp_stop(), bridge_p2p_loop(), and bridge_p2p_rtp_write().
#define MAX_TIMESTAMP_SKEW 640 |
Definition at line 60 of file rtp.c.
Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp().
#define RTCP_DEFAULT_INTERVALMS 5000 |
#define RTCP_MAX_INTERVALMS 60000 |
Max milli-seconds between RTCP reports we send
Definition at line 65 of file rtp.c.
Referenced by ast_rtp_reload().
#define RTCP_MIN_INTERVALMS 500 |
Min milli-seconds between RTCP reports we send
Definition at line 64 of file rtp.c.
Referenced by ast_rtp_reload().
#define RTCP_PT_BYE 203 |
#define RTCP_PT_FUR 192 |
Definition at line 67 of file rtp.c.
Referenced by ast_rtcp_read(), ast_rtcp_write_rr(), and ast_rtcp_write_sr().
#define RTCP_PT_RR 201 |
#define RTCP_PT_SDES 202 |
Definition at line 70 of file rtp.c.
Referenced by ast_rtcp_read(), ast_rtcp_write_rr(), and ast_rtcp_write_sr().
#define RTCP_PT_SR 200 |
#define RTP_SEQ_MOD (1<<16) |
A sequence number can't be more than 16 bits
Definition at line 62 of file rtp.c.
Referenced by ast_rtp_read().
#define STUN_ACCEPT (1) |
#define STUN_BINDERR 0x0111 |
#define STUN_BINDREQ 0x0001 |
Definition at line 261 of file rtp.c.
Referenced by ast_rtp_stun_request(), stun_handle_packet(), and stun_msg2str().
#define STUN_BINDRESP 0x0101 |
#define STUN_CHANGE_REQUEST 0x0003 |
#define STUN_CHANGED_ADDRESS 0x0005 |
#define STUN_ERROR_CODE 0x0009 |
#define STUN_IGNORE (0) |
#define STUN_MAPPED_ADDRESS 0x0001 |
#define STUN_MESSAGE_INTEGRITY 0x0008 |
#define STUN_PASSWORD 0x0007 |
#define STUN_REFLECTED_FROM 0x000b |
#define STUN_RESPONSE_ADDRESS 0x0002 |
#define STUN_SECERR 0x0112 |
#define STUN_SECREQ 0x0002 |
#define STUN_SECRESP 0x0102 |
#define STUN_SOURCE_ADDRESS 0x0004 |
#define STUN_UNKNOWN_ATTRIBUTES 0x000a |
#define STUN_USERNAME 0x0006 |
Definition at line 273 of file rtp.c.
Referenced by ast_rtp_stun_request(), stun_attr2str(), stun_handle_packet(), and stun_process_attr().
static void append_attr_address | ( | struct stun_attr ** | attr, | |
int | attrval, | |||
struct sockaddr_in * | sin, | |||
int * | len, | |||
int * | left | |||
) | [static] |
Definition at line 366 of file rtp.c.
References stun_addr::addr, stun_addr::family, stun_addr::port, and stun_addr::unused.
Referenced by stun_handle_packet().
00367 { 00368 int size = sizeof(**attr) + 8; 00369 struct stun_addr *addr; 00370 if (*left > size) { 00371 (*attr)->attr = htons(attrval); 00372 (*attr)->len = htons(8); 00373 addr = (struct stun_addr *)((*attr)->value); 00374 addr->unused = 0; 00375 addr->family = 0x01; 00376 addr->port = sin->sin_port; 00377 addr->addr = sin->sin_addr.s_addr; 00378 (*attr) = (struct stun_attr *)((*attr)->value + 8); 00379 *len += size; 00380 *left -= size; 00381 } 00382 }
static void append_attr_string | ( | struct stun_attr ** | attr, | |
int | attrval, | |||
const char * | s, | |||
int * | len, | |||
int * | left | |||
) | [static] |
Definition at line 353 of file rtp.c.
Referenced by ast_rtp_stun_request(), and stun_handle_packet().
00354 { 00355 int size = sizeof(**attr) + strlen(s); 00356 if (*left > size) { 00357 (*attr)->attr = htons(attrval); 00358 (*attr)->len = htons(strlen(s)); 00359 memcpy((*attr)->value, s, strlen(s)); 00360 (*attr) = (struct stun_attr *)((*attr)->value + strlen(s)); 00361 *len += size; 00362 *left -= size; 00363 } 00364 }
static AST_LIST_HEAD_STATIC | ( | protos | , | |
ast_rtp_protocol | ||||
) | [static] |
List of current sessions.
unsigned int ast_rtcp_calc_interval | ( | struct ast_rtp * | rtp | ) | [static] |
Definition at line 524 of file rtp.c.
Referenced by ast_rtp_raw_write(), and ast_rtp_read().
00525 { 00526 unsigned int interval; 00527 /*! \todo XXX Do a more reasonable calculation on this one 00528 * Look in RFC 3550 Section A.7 for an example*/ 00529 interval = rtcpinterval; 00530 return interval; 00531 }
int ast_rtcp_fd | ( | struct ast_rtp * | rtp | ) |
Definition at line 517 of file rtp.c.
References ast_rtp::rtcp, and ast_rtcp::s.
Referenced by __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), gtalk_new(), sip_new(), and start_rtp().
static struct ast_rtcp* ast_rtcp_new | ( | void | ) | [static, read] |
Initialize a new RTCP session.
Definition at line 1854 of file rtp.c.
References ast_calloc, ast_log(), errno, free, LOG_WARNING, rtp_socket(), ast_rtcp::s, ast_rtcp::them, and ast_rtcp::us.
Referenced by ast_rtp_new_with_bindaddr().
01855 { 01856 struct ast_rtcp *rtcp; 01857 01858 if (!(rtcp = ast_calloc(1, sizeof(*rtcp)))) 01859 return NULL; 01860 rtcp->s = rtp_socket(); 01861 rtcp->us.sin_family = AF_INET; 01862 rtcp->them.sin_family = AF_INET; 01863 01864 if (rtcp->s < 0) { 01865 free(rtcp); 01866 ast_log(LOG_WARNING, "Unable to allocate RTCP socket: %s\n", strerror(errno)); 01867 return NULL; 01868 } 01869 01870 return rtcp; 01871 }
Definition at line 826 of file rtp.c.
References ast_rtcp::accumulated_transit, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_null_frame, ast_verbose(), CRASH, ast_frame::datalen, errno, ast_rtp::f, f, ast_frame::frametype, len, LOG_DEBUG, LOG_WARNING, ast_frame::mallocd, ast_rtcp::maxrtt, ast_rtcp::minrtt, ast_rtp::nat, option_debug, ast_rtcp::reported_jitter, ast_rtcp::reported_lost, ast_rtp::rtcp, rtcp_debug_test_addr(), RTCP_PT_BYE, RTCP_PT_FUR, RTCP_PT_RR, RTCP_PT_SDES, RTCP_PT_SR, ast_rtcp::rtt, ast_rtcp::rxlsr, ast_rtcp::s, ast_frame::samples, ast_rtcp::soc, ast_rtcp::spc, ast_frame::src, ast_frame::subclass, ast_rtcp::them, ast_rtcp::themrxlsr, and timeval2ntp().
Referenced by oh323_read(), sip_rtp_read(), and skinny_rtp_read().
00827 { 00828 socklen_t len; 00829 int position, i, packetwords; 00830 int res; 00831 struct sockaddr_in sin; 00832 unsigned int rtcpdata[8192 + AST_FRIENDLY_OFFSET]; 00833 unsigned int *rtcpheader; 00834 int pt; 00835 struct timeval now; 00836 unsigned int length; 00837 int rc; 00838 double rttsec; 00839 uint64_t rtt = 0; 00840 unsigned int dlsr; 00841 unsigned int lsr; 00842 unsigned int msw; 00843 unsigned int lsw; 00844 unsigned int comp; 00845 struct ast_frame *f = &ast_null_frame; 00846 00847 if (!rtp || !rtp->rtcp) 00848 return &ast_null_frame; 00849 00850 len = sizeof(sin); 00851 00852 res = recvfrom(rtp->rtcp->s, rtcpdata + AST_FRIENDLY_OFFSET, sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET, 00853 0, (struct sockaddr *)&sin, &len); 00854 rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET); 00855 00856 if (res < 0) { 00857 if (errno == EBADF) 00858 CRASH; 00859 if (errno != EAGAIN) { 00860 ast_log(LOG_WARNING, "RTCP Read error: %s. Hanging up.\n", strerror(errno)); 00861 return NULL; 00862 } 00863 return &ast_null_frame; 00864 } 00865 00866 packetwords = res / 4; 00867 00868 if (rtp->nat) { 00869 /* Send to whoever sent to us */ 00870 if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || 00871 (rtp->rtcp->them.sin_port != sin.sin_port)) { 00872 memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them)); 00873 if (option_debug || rtpdebug) 00874 ast_log(LOG_DEBUG, "RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); 00875 } 00876 } 00877 00878 if (option_debug) 00879 ast_log(LOG_DEBUG, "Got RTCP report of %d bytes\n", res); 00880 00881 /* Process a compound packet */ 00882 position = 0; 00883 while (position < packetwords) { 00884 i = position; 00885 length = ntohl(rtcpheader[i]); 00886 pt = (length & 0xff0000) >> 16; 00887 rc = (length & 0x1f000000) >> 24; 00888 length &= 0xffff; 00889 00890 if ((i + length) > packetwords) { 00891 ast_log(LOG_WARNING, "RTCP Read too short\n"); 00892 return &ast_null_frame; 00893 } 00894 00895 if (rtcp_debug_test_addr(&sin)) { 00896 ast_verbose("\n\nGot RTCP from %s:%d\n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port)); 00897 ast_verbose("PT: %d(%s)\n", pt, (pt == 200) ? "Sender Report" : (pt == 201) ? "Receiver Report" : (pt == 192) ? "H.261 FUR" : "Unknown"); 00898 ast_verbose("Reception reports: %d\n", rc); 00899 ast_verbose("SSRC of sender: %u\n", rtcpheader[i + 1]); 00900 } 00901 00902 i += 2; /* Advance past header and ssrc */ 00903 00904 switch (pt) { 00905 case RTCP_PT_SR: 00906 gettimeofday(&rtp->rtcp->rxlsr,NULL); /* To be able to populate the dlsr */ 00907 rtp->rtcp->spc = ntohl(rtcpheader[i+3]); 00908 rtp->rtcp->soc = ntohl(rtcpheader[i + 4]); 00909 rtp->rtcp->themrxlsr = ((ntohl(rtcpheader[i]) & 0x0000ffff) << 16) | ((ntohl(rtcpheader[i + 1]) & 0xffff0000) >> 16); /* Going to LSR in RR*/ 00910 00911 if (rtcp_debug_test_addr(&sin)) { 00912 ast_verbose("NTP timestamp: %lu.%010lu\n", (unsigned long) ntohl(rtcpheader[i]), (unsigned long) ntohl(rtcpheader[i + 1]) * 4096); 00913 ast_verbose("RTP timestamp: %lu\n", (unsigned long) ntohl(rtcpheader[i + 2])); 00914 ast_verbose("SPC: %lu\tSOC: %lu\n", (unsigned long) ntohl(rtcpheader[i + 3]), (unsigned long) ntohl(rtcpheader[i + 4])); 00915 } 00916 i += 5; 00917 if (rc < 1) 00918 break; 00919 /* Intentional fall through */ 00920 case RTCP_PT_RR: 00921 /* Don't handle multiple reception reports (rc > 1) yet */ 00922 /* Calculate RTT per RFC */ 00923 gettimeofday(&now, NULL); 00924 timeval2ntp(now, &msw, &lsw); 00925 if (ntohl(rtcpheader[i + 4]) && ntohl(rtcpheader[i + 5])) { /* We must have the LSR && DLSR */ 00926 comp = ((msw & 0xffff) << 16) | ((lsw & 0xffff0000) >> 16); 00927 lsr = ntohl(rtcpheader[i + 4]); 00928 dlsr = ntohl(rtcpheader[i + 5]); 00929 rtt = comp - lsr - dlsr; 00930 00931 /* Convert end to end delay to usec (keeping the calculation in 64bit space) 00932 sess->ee_delay = (eedelay * 1000) / 65536; */ 00933 if (rtt < 4294) { 00934 rtt = (rtt * 1000000) >> 16; 00935 } else { 00936 rtt = (rtt * 1000) >> 16; 00937 rtt *= 1000; 00938 } 00939 rtt = rtt / 1000.; 00940 rttsec = rtt / 1000.; 00941 00942 if (comp - dlsr >= lsr) { 00943 rtp->rtcp->accumulated_transit += rttsec; 00944 rtp->rtcp->rtt = rttsec; 00945 if (rtp->rtcp->maxrtt<rttsec) 00946 rtp->rtcp->maxrtt = rttsec; 00947 if (rtp->rtcp->minrtt>rttsec) 00948 rtp->rtcp->minrtt = rttsec; 00949 } else if (rtcp_debug_test_addr(&sin)) { 00950 ast_verbose("Internal RTCP NTP clock skew detected: " 00951 "lsr=%u, now=%u, dlsr=%u (%d:%03dms), " 00952 "diff=%d\n", 00953 lsr, comp, dlsr, dlsr / 65536, 00954 (dlsr % 65536) * 1000 / 65536, 00955 dlsr - (comp - lsr)); 00956 } 00957 } 00958 00959 rtp->rtcp->reported_jitter = ntohl(rtcpheader[i + 3]); 00960 rtp->rtcp->reported_lost = ntohl(rtcpheader[i + 1]) & 0xffffff; 00961 if (rtcp_debug_test_addr(&sin)) { 00962 ast_verbose(" Fraction lost: %ld\n", (((long) ntohl(rtcpheader[i + 1]) & 0xff000000) >> 24)); 00963 ast_verbose(" Packets lost so far: %d\n", rtp->rtcp->reported_lost); 00964 ast_verbose(" Highest sequence number: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff)); 00965 ast_verbose(" Sequence number cycles: %ld\n", (long) (ntohl(rtcpheader[i + 2]) & 0xffff) >> 16); 00966 ast_verbose(" Interarrival jitter: %u\n", rtp->rtcp->reported_jitter); 00967 ast_verbose(" Last SR(our NTP): %lu.%010lu\n",(unsigned long) ntohl(rtcpheader[i + 4]) >> 16,((unsigned long) ntohl(rtcpheader[i + 4]) << 16) * 4096); 00968 ast_verbose(" DLSR: %4.4f (sec)\n",ntohl(rtcpheader[i + 5])/65536.0); 00969 if (rtt) 00970 ast_verbose(" RTT: %lu(sec)\n", (unsigned long) rtt); 00971 } 00972 break; 00973 case RTCP_PT_FUR: 00974 if (rtcp_debug_test_addr(&sin)) 00975 ast_verbose("Received an RTCP Fast Update Request\n"); 00976 rtp->f.frametype = AST_FRAME_CONTROL; 00977 rtp->f.subclass = AST_CONTROL_VIDUPDATE; 00978 rtp->f.datalen = 0; 00979 rtp->f.samples = 0; 00980 rtp->f.mallocd = 0; 00981 rtp->f.src = "RTP"; 00982 f = &rtp->f; 00983 break; 00984 case RTCP_PT_SDES: 00985 if (rtcp_debug_test_addr(&sin)) 00986 ast_verbose("Received an SDES from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); 00987 break; 00988 case RTCP_PT_BYE: 00989 if (rtcp_debug_test_addr(&sin)) 00990 ast_verbose("Received a BYE from %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); 00991 break; 00992 default: 00993 if (option_debug) 00994 ast_log(LOG_DEBUG, "Unknown RTCP packet (pt=%d) received from %s:%d\n", pt, ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); 00995 break; 00996 } 00997 position += (length + 1); 00998 } 00999 01000 return f; 01001 }
int ast_rtcp_send_h261fur | ( | void * | data | ) |
Public function: Send an H.261 fast update request, some devices need this rather than SIP XML.
Send an H.261 fast update request. Some devices need this rather than the XML message in SIP.
Definition at line 2333 of file rtp.c.
References ast_rtcp_write(), ast_rtp::rtcp, and ast_rtcp::sendfur.
02334 { 02335 struct ast_rtp *rtp = data; 02336 int res; 02337 02338 rtp->rtcp->sendfur = 1; 02339 res = ast_rtcp_write(data); 02340 02341 return res; 02342 }
static int ast_rtcp_write | ( | const void * | data | ) | [static] |
Write and RTCP packet to the far end.
Definition at line 2558 of file rtp.c.
References ast_rtcp_write_rr(), ast_rtcp_write_sr(), ast_rtcp::lastsrtxcount, ast_rtp::rtcp, and ast_rtp::txcount.
Referenced by ast_rtcp_send_h261fur(), ast_rtp_raw_write(), and ast_rtp_read().
02559 { 02560 struct ast_rtp *rtp = (struct ast_rtp *)data; 02561 int res; 02562 02563 if (!rtp || !rtp->rtcp) 02564 return 0; 02565 02566 if (rtp->txcount > rtp->rtcp->lastsrtxcount) 02567 res = ast_rtcp_write_sr(data); 02568 else 02569 res = ast_rtcp_write_rr(data); 02570 02571 return res; 02572 }
static int ast_rtcp_write_rr | ( | const void * | data | ) | [static] |
Send RTCP recepient's report.
Definition at line 2459 of file rtp.c.
References ast_inet_ntoa(), ast_log(), ast_sched_del(), ast_verbose(), ast_rtp::cycles, errno, ast_rtcp::expected_prior, ast_rtp::lastrxseqno, len, LOG_ERROR, ast_rtcp::received_prior, ast_rtcp::rr_count, ast_rtp::rtcp, rtcp_debug_test_addr(), RTCP_PT_FUR, RTCP_PT_RR, RTCP_PT_SDES, ast_rtp::rxcount, ast_rtp::rxjitter, ast_rtcp::rxlsr, ast_rtcp::s, ast_rtp::sched, ast_rtcp::schedid, ast_rtp::seedrxseqno, ast_rtcp::sendfur, ast_rtp::ssrc, ast_rtcp::them, ast_rtcp::themrxlsr, and ast_rtp::themssrc.
Referenced by ast_rtcp_write().
02460 { 02461 struct ast_rtp *rtp = (struct ast_rtp *)data; 02462 int res; 02463 int len = 32; 02464 unsigned int lost; 02465 unsigned int extended; 02466 unsigned int expected; 02467 unsigned int expected_interval; 02468 unsigned int received_interval; 02469 int lost_interval; 02470 struct timeval now; 02471 unsigned int *rtcpheader; 02472 char bdata[1024]; 02473 struct timeval dlsr; 02474 int fraction; 02475 02476 if (!rtp || !rtp->rtcp || (&rtp->rtcp->them.sin_addr == 0)) 02477 return 0; 02478 02479 if (!rtp->rtcp->them.sin_addr.s_addr) { 02480 ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted\n"); 02481 if (rtp->rtcp->schedid > 0) 02482 ast_sched_del(rtp->sched, rtp->rtcp->schedid); 02483 rtp->rtcp->schedid = -1; 02484 return 0; 02485 } 02486 02487 extended = rtp->cycles + rtp->lastrxseqno; 02488 expected = extended - rtp->seedrxseqno + 1; 02489 lost = expected - rtp->rxcount; 02490 expected_interval = expected - rtp->rtcp->expected_prior; 02491 rtp->rtcp->expected_prior = expected; 02492 received_interval = rtp->rxcount - rtp->rtcp->received_prior; 02493 rtp->rtcp->received_prior = rtp->rxcount; 02494 lost_interval = expected_interval - received_interval; 02495 if (expected_interval == 0 || lost_interval <= 0) 02496 fraction = 0; 02497 else 02498 fraction = (lost_interval << 8) / expected_interval; 02499 gettimeofday(&now, NULL); 02500 timersub(&now, &rtp->rtcp->rxlsr, &dlsr); 02501 rtcpheader = (unsigned int *)bdata; 02502 rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_RR << 16) | ((len/4)-1)); 02503 rtcpheader[1] = htonl(rtp->ssrc); 02504 rtcpheader[2] = htonl(rtp->themssrc); 02505 rtcpheader[3] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff)); 02506 rtcpheader[4] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff))); 02507 rtcpheader[5] = htonl((unsigned int)(rtp->rxjitter * 65536.)); 02508 rtcpheader[6] = htonl(rtp->rtcp->themrxlsr); 02509 rtcpheader[7] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000); 02510 02511 if (rtp->rtcp->sendfur) { 02512 rtcpheader[8] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_FUR << 16) | 1); /* Header from page 36 in RFC 3550 */ 02513 rtcpheader[9] = htonl(rtp->ssrc); /* Our SSRC */ 02514 len += 8; 02515 rtp->rtcp->sendfur = 0; 02516 } 02517 02518 /*! \note Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos 02519 it can change mid call, and SDES can't) */ 02520 rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2); 02521 rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */ 02522 rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */ 02523 len += 12; 02524 02525 res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them)); 02526 02527 if (res < 0) { 02528 ast_log(LOG_ERROR, "RTCP RR transmission error, rtcp halted: %s\n",strerror(errno)); 02529 /* Remove the scheduler */ 02530 if (rtp->rtcp->schedid > 0) 02531 ast_sched_del(rtp->sched, rtp->rtcp->schedid); 02532 rtp->rtcp->schedid = -1; 02533 return 0; 02534 } 02535 02536 rtp->rtcp->rr_count++; 02537 02538 if (rtcp_debug_test_addr(&rtp->rtcp->them)) { 02539 ast_verbose("\n* Sending RTCP RR to %s:%d\n" 02540 " Our SSRC: %u\nTheir SSRC: %u\niFraction lost: %d\nCumulative loss: %u\n" 02541 " IA jitter: %.4f\n" 02542 " Their last SR: %u\n" 02543 " DLSR: %4.4f (sec)\n\n", 02544 ast_inet_ntoa(rtp->rtcp->them.sin_addr), 02545 ntohs(rtp->rtcp->them.sin_port), 02546 rtp->ssrc, rtp->themssrc, fraction, lost, 02547 rtp->rxjitter, 02548 rtp->rtcp->themrxlsr, 02549 (double)(ntohl(rtcpheader[7])/65536.0)); 02550 } 02551 02552 return res; 02553 }
static int ast_rtcp_write_sr | ( | const void * | data | ) | [static] |
Send RTCP sender's report.
Definition at line 2345 of file rtp.c.
References ast_inet_ntoa(), ast_log(), ast_sched_del(), ast_verbose(), ast_rtp::cycles, errno, ast_rtcp::expected_prior, ast_rtp::lastrxseqno, ast_rtcp::lastsrtxcount, ast_rtp::lastts, len, LOG_ERROR, ast_rtcp::received_prior, ast_rtp::rtcp, rtcp_debug_test_addr(), RTCP_PT_FUR, RTCP_PT_SDES, RTCP_PT_SR, ast_rtp::rxcount, ast_rtp::rxjitter, ast_rtcp::rxlsr, ast_rtcp::s, ast_rtp::sched, ast_rtcp::schedid, ast_rtp::seedrxseqno, ast_rtcp::sendfur, ast_rtcp::sr_count, ast_rtp::ssrc, ast_rtcp::them, ast_rtcp::themrxlsr, ast_rtp::themssrc, timeval2ntp(), ast_rtp::txcount, ast_rtcp::txlsr, and ast_rtp::txoctetcount.
Referenced by ast_rtcp_write().
02346 { 02347 struct ast_rtp *rtp = (struct ast_rtp *)data; 02348 int res; 02349 int len = 0; 02350 struct timeval now; 02351 unsigned int now_lsw; 02352 unsigned int now_msw; 02353 unsigned int *rtcpheader; 02354 unsigned int lost; 02355 unsigned int extended; 02356 unsigned int expected; 02357 unsigned int expected_interval; 02358 unsigned int received_interval; 02359 int lost_interval; 02360 int fraction; 02361 struct timeval dlsr; 02362 char bdata[512]; 02363 02364 /* Commented condition is always not NULL if rtp->rtcp is not NULL */ 02365 if (!rtp || !rtp->rtcp/* || (&rtp->rtcp->them.sin_addr == 0)*/) 02366 return 0; 02367 02368 if (!rtp->rtcp->them.sin_addr.s_addr) { /* This'll stop rtcp for this rtp session */ 02369 ast_verbose("RTCP SR transmission error, rtcp halted\n"); 02370 if (rtp->rtcp->schedid > 0) 02371 ast_sched_del(rtp->sched, rtp->rtcp->schedid); 02372 rtp->rtcp->schedid = -1; 02373 return 0; 02374 } 02375 02376 gettimeofday(&now, NULL); 02377 timeval2ntp(now, &now_msw, &now_lsw); /* fill thses ones in from utils.c*/ 02378 rtcpheader = (unsigned int *)bdata; 02379 rtcpheader[1] = htonl(rtp->ssrc); /* Our SSRC */ 02380 rtcpheader[2] = htonl(now_msw); /* now, MSW. gettimeofday() + SEC_BETWEEN_1900_AND_1970*/ 02381 rtcpheader[3] = htonl(now_lsw); /* now, LSW */ 02382 rtcpheader[4] = htonl(rtp->lastts); /* FIXME shouldn't be that, it should be now */ 02383 rtcpheader[5] = htonl(rtp->txcount); /* No. packets sent */ 02384 rtcpheader[6] = htonl(rtp->txoctetcount); /* No. bytes sent */ 02385 len += 28; 02386 02387 extended = rtp->cycles + rtp->lastrxseqno; 02388 expected = extended - rtp->seedrxseqno + 1; 02389 if (rtp->rxcount > expected) 02390 expected += rtp->rxcount - expected; 02391 lost = expected - rtp->rxcount; 02392 expected_interval = expected - rtp->rtcp->expected_prior; 02393 rtp->rtcp->expected_prior = expected; 02394 received_interval = rtp->rxcount - rtp->rtcp->received_prior; 02395 rtp->rtcp->received_prior = rtp->rxcount; 02396 lost_interval = expected_interval - received_interval; 02397 if (expected_interval == 0 || lost_interval <= 0) 02398 fraction = 0; 02399 else 02400 fraction = (lost_interval << 8) / expected_interval; 02401 timersub(&now, &rtp->rtcp->rxlsr, &dlsr); 02402 rtcpheader[7] = htonl(rtp->themssrc); 02403 rtcpheader[8] = htonl(((fraction & 0xff) << 24) | (lost & 0xffffff)); 02404 rtcpheader[9] = htonl((rtp->cycles) | ((rtp->lastrxseqno & 0xffff))); 02405 rtcpheader[10] = htonl((unsigned int)(rtp->rxjitter * 65536.)); 02406 rtcpheader[11] = htonl(rtp->rtcp->themrxlsr); 02407 rtcpheader[12] = htonl((((dlsr.tv_sec * 1000) + (dlsr.tv_usec / 1000)) * 65536) / 1000); 02408 len += 24; 02409 02410 rtcpheader[0] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SR << 16) | ((len/4)-1)); 02411 02412 if (rtp->rtcp->sendfur) { 02413 rtcpheader[13] = htonl((2 << 30) | (0 << 24) | (RTCP_PT_FUR << 16) | 1); 02414 rtcpheader[14] = htonl(rtp->ssrc); /* Our SSRC */ 02415 len += 8; 02416 rtp->rtcp->sendfur = 0; 02417 } 02418 02419 /* Insert SDES here. Probably should make SDES text equal to mimetypes[code].type (not subtype 'cos */ 02420 /* it can change mid call, and SDES can't) */ 02421 rtcpheader[len/4] = htonl((2 << 30) | (1 << 24) | (RTCP_PT_SDES << 16) | 2); 02422 rtcpheader[(len/4)+1] = htonl(rtp->ssrc); /* Our SSRC */ 02423 rtcpheader[(len/4)+2] = htonl(0x01 << 24); /* Empty for the moment */ 02424 len += 12; 02425 02426 res = sendto(rtp->rtcp->s, (unsigned int *)rtcpheader, len, 0, (struct sockaddr *)&rtp->rtcp->them, sizeof(rtp->rtcp->them)); 02427 if (res < 0) { 02428 ast_log(LOG_ERROR, "RTCP SR transmission error to %s:%d, rtcp halted %s\n",ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port), strerror(errno)); 02429 if (rtp->rtcp->schedid > 0) 02430 ast_sched_del(rtp->sched, rtp->rtcp->schedid); 02431 rtp->rtcp->schedid = -1; 02432 return 0; 02433 } 02434 02435 /* FIXME Don't need to get a new one */ 02436 gettimeofday(&rtp->rtcp->txlsr, NULL); 02437 rtp->rtcp->sr_count++; 02438 02439 rtp->rtcp->lastsrtxcount = rtp->txcount; 02440 02441 if (rtcp_debug_test_addr(&rtp->rtcp->them)) { 02442 ast_verbose("* Sent RTCP SR to %s:%d\n", ast_inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); 02443 ast_verbose(" Our SSRC: %u\n", rtp->ssrc); 02444 ast_verbose(" Sent(NTP): %u.%010u\n", (unsigned int)now.tv_sec, (unsigned int)now.tv_usec*4096); 02445 ast_verbose(" Sent(RTP): %u\n", rtp->lastts); 02446 ast_verbose(" Sent packets: %u\n", rtp->txcount); 02447 ast_verbose(" Sent octets: %u\n", rtp->txoctetcount); 02448 ast_verbose(" Report block:\n"); 02449 ast_verbose(" Fraction lost: %u\n", fraction); 02450 ast_verbose(" Cumulative loss: %u\n", lost); 02451 ast_verbose(" IA jitter: %.4f\n", rtp->rxjitter); 02452 ast_verbose(" Their last SR: %u\n", rtp->rtcp->themrxlsr); 02453 ast_verbose(" DLSR: %4.4f (sec)\n\n", (double)(ntohl(rtcpheader[12])/65536.0)); 02454 } 02455 return res; 02456 }
size_t ast_rtp_alloc_size | ( | void | ) |
Get the amount of space required to hold an RTP session.
Definition at line 397 of file rtp.c.
Referenced by process_sdp().
00398 { 00399 return sizeof(struct ast_rtp); 00400 }
enum ast_bridge_result ast_rtp_bridge | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
int | timeoutms | |||
) |
Bridge calls. If possible and allowed, initiate re-invite so the peers exchange media directly outside of Asterisk.
Definition at line 3253 of file rtp.c.
References AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_codec_pref_getsize(), ast_log(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, AST_RTP_TRY_PARTIAL, ast_set_flag, ast_test_flag, ast_verbose(), bridge_native_loop(), bridge_p2p_loop(), ast_format_list::cur_ms, FLAG_DTMF_COMPENSATE, FLAG_HAS_DTMF, FLAG_P2P_NEED_DTMF, ast_rtp_protocol::get_codec, get_proto(), ast_rtp_protocol::get_rtp_info, ast_rtp_protocol::get_vrtp_info, LOG_DEBUG, LOG_WARNING, option_debug, option_verbose, ast_rtp::pref, ast_channel::rawreadformat, ast_channel::rawwriteformat, ast_channel_tech::send_digit_begin, ast_channel::tech, ast_channel::tech_pvt, and VERBOSE_PREFIX_3.
03254 { 03255 struct ast_rtp *p0 = NULL, *p1 = NULL; /* Audio RTP Channels */ 03256 struct ast_rtp *vp0 = NULL, *vp1 = NULL; /* Video RTP channels */ 03257 struct ast_rtp_protocol *pr0 = NULL, *pr1 = NULL; 03258 enum ast_rtp_get_result audio_p0_res = AST_RTP_GET_FAILED, video_p0_res = AST_RTP_GET_FAILED; 03259 enum ast_rtp_get_result audio_p1_res = AST_RTP_GET_FAILED, video_p1_res = AST_RTP_GET_FAILED; 03260 enum ast_bridge_result res = AST_BRIDGE_FAILED; 03261 int codec0 = 0, codec1 = 0; 03262 void *pvt0 = NULL, *pvt1 = NULL; 03263 03264 /* Lock channels */ 03265 ast_channel_lock(c0); 03266 while(ast_channel_trylock(c1)) { 03267 ast_channel_unlock(c0); 03268 usleep(1); 03269 ast_channel_lock(c0); 03270 } 03271 03272 /* Find channel driver interfaces */ 03273 if (!(pr0 = get_proto(c0))) { 03274 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name); 03275 ast_channel_unlock(c0); 03276 ast_channel_unlock(c1); 03277 return AST_BRIDGE_FAILED; 03278 } 03279 if (!(pr1 = get_proto(c1))) { 03280 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name); 03281 ast_channel_unlock(c0); 03282 ast_channel_unlock(c1); 03283 return AST_BRIDGE_FAILED; 03284 } 03285 03286 /* Get channel specific interface structures */ 03287 pvt0 = c0->tech_pvt; 03288 pvt1 = c1->tech_pvt; 03289 03290 /* Get audio and video interface (if native bridge is possible) */ 03291 audio_p0_res = pr0->get_rtp_info(c0, &p0); 03292 video_p0_res = pr0->get_vrtp_info ? pr0->get_vrtp_info(c0, &vp0) : AST_RTP_GET_FAILED; 03293 audio_p1_res = pr1->get_rtp_info(c1, &p1); 03294 video_p1_res = pr1->get_vrtp_info ? pr1->get_vrtp_info(c1, &vp1) : AST_RTP_GET_FAILED; 03295 03296 /* If we are carrying video, and both sides are not reinviting... then fail the native bridge */ 03297 if (video_p0_res != AST_RTP_GET_FAILED && (audio_p0_res != AST_RTP_TRY_NATIVE || video_p0_res != AST_RTP_TRY_NATIVE)) 03298 audio_p0_res = AST_RTP_GET_FAILED; 03299 if (video_p1_res != AST_RTP_GET_FAILED && (audio_p1_res != AST_RTP_TRY_NATIVE || video_p1_res != AST_RTP_TRY_NATIVE)) 03300 audio_p1_res = AST_RTP_GET_FAILED; 03301 03302 /* Check if a bridge is possible (partial/native) */ 03303 if (audio_p0_res == AST_RTP_GET_FAILED || audio_p1_res == AST_RTP_GET_FAILED) { 03304 /* Somebody doesn't want to play... */ 03305 ast_channel_unlock(c0); 03306 ast_channel_unlock(c1); 03307 return AST_BRIDGE_FAILED_NOWARN; 03308 } 03309 03310 /* If we need to feed DTMF frames into the core then only do a partial native bridge */ 03311 if (ast_test_flag(p0, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 03312 ast_set_flag(p0, FLAG_P2P_NEED_DTMF); 03313 audio_p0_res = AST_RTP_TRY_PARTIAL; 03314 } 03315 03316 if (ast_test_flag(p1, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)) { 03317 ast_set_flag(p1, FLAG_P2P_NEED_DTMF); 03318 audio_p1_res = AST_RTP_TRY_PARTIAL; 03319 } 03320 03321 /* If both sides are not using the same method of DTMF transmission 03322 * (ie: one is RFC2833, other is INFO... then we can not do direct media. 03323 * -------------------------------------------------- 03324 * | DTMF Mode | HAS_DTMF | Accepts Begin Frames | 03325 * |-----------|------------|-----------------------| 03326 * | Inband | False | True | 03327 * | RFC2833 | True | True | 03328 * | SIP INFO | False | False | 03329 * -------------------------------------------------- 03330 * However, if DTMF from both channels is being monitored by the core, then 03331 * we can still do packet-to-packet bridging, because passing through the 03332 * core will handle DTMF mode translation. 03333 */ 03334 if ( (ast_test_flag(p0, FLAG_HAS_DTMF) != ast_test_flag(p1, FLAG_HAS_DTMF)) || 03335 (!c0->tech->send_digit_begin != !c1->tech->send_digit_begin)) { 03336 if (!ast_test_flag(p0, FLAG_P2P_NEED_DTMF) || !ast_test_flag(p1, FLAG_P2P_NEED_DTMF)) { 03337 ast_channel_unlock(c0); 03338 ast_channel_unlock(c1); 03339 return AST_BRIDGE_FAILED_NOWARN; 03340 } 03341 audio_p0_res = AST_RTP_TRY_PARTIAL; 03342 audio_p1_res = AST_RTP_TRY_PARTIAL; 03343 } 03344 03345 /* If the core will need to compensate and the P2P bridge will need to feed up DTMF frames then we can not reliably do so yet, so do not P2P bridge */ 03346 if ((audio_p0_res == AST_RTP_TRY_PARTIAL && ast_test_flag(p0, FLAG_P2P_NEED_DTMF) && ast_test_flag(p0, FLAG_DTMF_COMPENSATE)) || 03347 (audio_p1_res == AST_RTP_TRY_PARTIAL && ast_test_flag(p1, FLAG_P2P_NEED_DTMF) && ast_test_flag(p1, FLAG_DTMF_COMPENSATE))) { 03348 ast_channel_unlock(c0); 03349 ast_channel_unlock(c1); 03350 return AST_BRIDGE_FAILED_NOWARN; 03351 } 03352 03353 /* Get codecs from both sides */ 03354 codec0 = pr0->get_codec ? pr0->get_codec(c0) : 0; 03355 codec1 = pr1->get_codec ? pr1->get_codec(c1) : 0; 03356 if (codec0 && codec1 && !(codec0 & codec1)) { 03357 /* Hey, we can't do native bridging if both parties speak different codecs */ 03358 if (option_debug) 03359 ast_log(LOG_DEBUG, "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", codec0, codec1); 03360 ast_channel_unlock(c0); 03361 ast_channel_unlock(c1); 03362 return AST_BRIDGE_FAILED_NOWARN; 03363 } 03364 03365 /* If either side can only do a partial bridge, then don't try for a true native bridge */ 03366 if (audio_p0_res == AST_RTP_TRY_PARTIAL || audio_p1_res == AST_RTP_TRY_PARTIAL) { 03367 struct ast_format_list fmt0, fmt1; 03368 03369 /* In order to do Packet2Packet bridging both sides must be in the same rawread/rawwrite */ 03370 if (c0->rawreadformat != c1->rawwriteformat || c1->rawreadformat != c0->rawwriteformat) { 03371 if (option_debug) 03372 ast_log(LOG_DEBUG, "Cannot packet2packet bridge - raw formats are incompatible\n"); 03373 ast_channel_unlock(c0); 03374 ast_channel_unlock(c1); 03375 return AST_BRIDGE_FAILED_NOWARN; 03376 } 03377 /* They must also be using the same packetization */ 03378 fmt0 = ast_codec_pref_getsize(&p0->pref, c0->rawreadformat); 03379 fmt1 = ast_codec_pref_getsize(&p1->pref, c1->rawreadformat); 03380 if (fmt0.cur_ms != fmt1.cur_ms) { 03381 if (option_debug) 03382 ast_log(LOG_DEBUG, "Cannot packet2packet bridge - packetization settings prevent it\n"); 03383 ast_channel_unlock(c0); 03384 ast_channel_unlock(c1); 03385 return AST_BRIDGE_FAILED_NOWARN; 03386 } 03387 03388 if (option_verbose > 2) 03389 ast_verbose(VERBOSE_PREFIX_3 "Packet2Packet bridging %s and %s\n", c0->name, c1->name); 03390 res = bridge_p2p_loop(c0, c1, p0, p1, timeoutms, flags, fo, rc, pvt0, pvt1); 03391 } else { 03392 if (option_verbose > 2) 03393 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03394 res = bridge_native_loop(c0, c1, p0, p1, vp0, vp1, pr0, pr1, codec0, codec1, timeoutms, flags, fo, rc, pvt0, pvt1); 03395 } 03396 03397 return res; 03398 }
int ast_rtp_codec_getformat | ( | int | pt | ) |
Definition at line 2716 of file rtp.c.
References rtpPayloadType::code, and MAX_RTP_PT.
Referenced by process_sdp().
02717 { 02718 if (pt < 0 || pt > MAX_RTP_PT) 02719 return 0; /* bogus payload type */ 02720 02721 if (static_RTP_PT[pt].isAstFormat) 02722 return static_RTP_PT[pt].code; 02723 else 02724 return 0; 02725 }
struct ast_codec_pref* ast_rtp_codec_getpref | ( | struct ast_rtp * | rtp | ) | [read] |
Definition at line 2711 of file rtp.c.
References ast_rtp::pref.
Referenced by add_codec_to_sdp(), and process_sdp().
02712 { 02713 return &rtp->pref; 02714 }
int ast_rtp_codec_setpref | ( | struct ast_rtp * | rtp, | |
struct ast_codec_pref * | prefs | |||
) |
Definition at line 2698 of file rtp.c.
References ast_smoother_free(), ast_codec_pref::framing, ast_codec_pref::order, ast_rtp::pref, and ast_rtp::smoother.
Referenced by __oh323_rtp_create(), check_user_full(), create_addr_from_peer(), process_sdp(), register_verify(), set_peer_capabilities(), start_rtp(), and transmit_response_with_sdp().
02699 { 02700 int x; 02701 for (x = 0; x < 32; x++) { /* Ugly way */ 02702 rtp->pref.order[x] = prefs->order[x]; 02703 rtp->pref.framing[x] = prefs->framing[x]; 02704 } 02705 if (rtp->smoother) 02706 ast_smoother_free(rtp->smoother); 02707 rtp->smoother = NULL; 02708 return 0; 02709 }
void ast_rtp_destroy | ( | struct ast_rtp * | rtp | ) |
Definition at line 2115 of file rtp.c.
References ast_io_remove(), ast_mutex_destroy(), ast_sched_del(), ast_smoother_free(), ast_verbose(), ast_rtp::bridge_lock, ast_rtcp::expected_prior, free, ast_rtp::io, ast_rtp::ioid, ast_rtcp::received_prior, ast_rtcp::reported_jitter, ast_rtcp::reported_lost, ast_rtcp::rr_count, ast_rtp::rtcp, rtcp_debug_test_addr(), ast_rtcp::rtt, ast_rtp::rxcount, ast_rtp::rxjitter, ast_rtp::rxtransit, ast_rtcp::s, ast_rtp::s, ast_rtp::sched, ast_rtcp::schedid, ast_rtp::smoother, ast_rtcp::sr_count, ast_rtp::ssrc, ast_rtp::them, ast_rtp::themssrc, and ast_rtp::txcount.
Referenced by __oh323_destroy(), __sip_destroy(), check_user_full(), cleanup_connection(), create_addr_from_peer(), destroy_endpoint(), gtalk_free_pvt(), mgcp_hangup(), oh323_alloc(), skinny_hangup(), start_rtp(), and unalloc_sub().
02116 { 02117 if (rtcp_debug_test_addr(&rtp->them) || rtcpstats) { 02118 /*Print some info on the call here */ 02119 ast_verbose(" RTP-stats\n"); 02120 ast_verbose("* Our Receiver:\n"); 02121 ast_verbose(" SSRC: %u\n", rtp->themssrc); 02122 ast_verbose(" Received packets: %u\n", rtp->rxcount); 02123 ast_verbose(" Lost packets: %u\n", rtp->rtcp->expected_prior - rtp->rtcp->received_prior); 02124 ast_verbose(" Jitter: %.4f\n", rtp->rxjitter); 02125 ast_verbose(" Transit: %.4f\n", rtp->rxtransit); 02126 ast_verbose(" RR-count: %u\n", rtp->rtcp->rr_count); 02127 ast_verbose("* Our Sender:\n"); 02128 ast_verbose(" SSRC: %u\n", rtp->ssrc); 02129 ast_verbose(" Sent packets: %u\n", rtp->txcount); 02130 ast_verbose(" Lost packets: %u\n", rtp->rtcp->reported_lost); 02131 ast_verbose(" Jitter: %u\n", rtp->rtcp->reported_jitter / (unsigned int)65536.0); 02132 ast_verbose(" SR-count: %u\n", rtp->rtcp->sr_count); 02133 ast_verbose(" RTT: %f\n", rtp->rtcp->rtt); 02134 } 02135 02136 if (rtp->smoother) 02137 ast_smoother_free(rtp->smoother); 02138 if (rtp->ioid) 02139 ast_io_remove(rtp->io, rtp->ioid); 02140 if (rtp->s > -1) 02141 close(rtp->s); 02142 if (rtp->rtcp) { 02143 if (rtp->rtcp->schedid > 0) 02144 ast_sched_del(rtp->sched, rtp->rtcp->schedid); 02145 close(rtp->rtcp->s); 02146 free(rtp->rtcp); 02147 rtp->rtcp=NULL; 02148 } 02149 02150 ast_mutex_destroy(&rtp->bridge_lock); 02151 02152 free(rtp); 02153 }
int ast_rtp_early_bridge | ( | struct ast_channel * | dest, | |
struct ast_channel * | src | |||
) |
If possible, create an early bridge directly between the devices without having to send a re-invite later.
Definition at line 1471 of file rtp.c.
References ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_log(), AST_RTP_GET_FAILED, AST_RTP_TRY_NATIVE, ast_test_flag, FLAG_NAT_ACTIVE, ast_rtp_protocol::get_codec, get_proto(), ast_rtp_protocol::get_rtp_info, ast_rtp_protocol::get_vrtp_info, LOG_DEBUG, LOG_WARNING, option_debug, and ast_rtp_protocol::set_rtp_peer.
Referenced by wait_for_answer().
01472 { 01473 struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */ 01474 struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */ 01475 struct ast_rtp_protocol *destpr = NULL, *srcpr = NULL; 01476 enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = AST_RTP_GET_FAILED; 01477 enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = AST_RTP_GET_FAILED; 01478 int srccodec, destcodec, nat_active = 0; 01479 01480 /* Lock channels */ 01481 ast_channel_lock(dest); 01482 if (src) { 01483 while(ast_channel_trylock(src)) { 01484 ast_channel_unlock(dest); 01485 usleep(1); 01486 ast_channel_lock(dest); 01487 } 01488 } 01489 01490 /* Find channel driver interfaces */ 01491 destpr = get_proto(dest); 01492 if (src) 01493 srcpr = get_proto(src); 01494 if (!destpr) { 01495 if (option_debug) 01496 ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name); 01497 ast_channel_unlock(dest); 01498 if (src) 01499 ast_channel_unlock(src); 01500 return 0; 01501 } 01502 if (!srcpr) { 01503 if (option_debug) 01504 ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", src ? src->name : "<unspecified>"); 01505 ast_channel_unlock(dest); 01506 if (src) 01507 ast_channel_unlock(src); 01508 return 0; 01509 } 01510 01511 /* Get audio and video interface (if native bridge is possible) */ 01512 audio_dest_res = destpr->get_rtp_info(dest, &destp); 01513 video_dest_res = destpr->get_vrtp_info ? destpr->get_vrtp_info(dest, &vdestp) : AST_RTP_GET_FAILED; 01514 if (srcpr) { 01515 audio_src_res = srcpr->get_rtp_info(src, &srcp); 01516 video_src_res = srcpr->get_vrtp_info ? srcpr->get_vrtp_info(src, &vsrcp) : AST_RTP_GET_FAILED; 01517 } 01518 01519 /* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */ 01520 if (audio_dest_res != AST_RTP_TRY_NATIVE) { 01521 /* Somebody doesn't want to play... */ 01522 ast_channel_unlock(dest); 01523 if (src) 01524 ast_channel_unlock(src); 01525 return 0; 01526 } 01527 if (audio_src_res == AST_RTP_TRY_NATIVE && srcpr->get_codec) 01528 srccodec = srcpr->get_codec(src); 01529 else 01530 srccodec = 0; 01531 if (audio_dest_res == AST_RTP_TRY_NATIVE && destpr->get_codec) 01532 destcodec = destpr->get_codec(dest); 01533 else 01534 destcodec = 0; 01535 /* Ensure we have at least one matching codec */ 01536 if (!(srccodec & destcodec)) { 01537 ast_channel_unlock(dest); 01538 if (src) 01539 ast_channel_unlock(src); 01540 return 0; 01541 } 01542 /* Consider empty media as non-existant */ 01543 if (audio_src_res == AST_RTP_TRY_NATIVE && !srcp->them.sin_addr.s_addr) 01544 srcp = NULL; 01545 /* If the client has NAT stuff turned on then just safe NAT is active */ 01546 if (srcp && (srcp->nat || ast_test_flag(srcp, FLAG_NAT_ACTIVE))) 01547 nat_active = 1; 01548 /* Bridge media early */ 01549 if (destpr->set_rtp_peer(dest, srcp, vsrcp, srccodec, nat_active)) 01550 ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", dest->name, src ? src->name : "<unspecified>"); 01551 ast_channel_unlock(dest); 01552 if (src) 01553 ast_channel_unlock(src); 01554 if (option_debug) 01555 ast_log(LOG_DEBUG, "Setting early bridge SDP of '%s' with that of '%s'\n", dest->name, src ? src->name : "<unspecified>"); 01556 return 1; 01557 }
int ast_rtp_fd | ( | struct ast_rtp * | rtp | ) |
Definition at line 512 of file rtp.c.
References ast_rtp::s.
Referenced by __oh323_new(), __oh323_rtp_create(), __oh323_update_info(), gtalk_new(), mgcp_new(), sip_new(), skinny_new(), and start_rtp().
00513 { 00514 return rtp->s; 00515 }
Definition at line 2023 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, and ast_rtp::bridged.
Referenced by ast_rtp_read().
02024 { 02025 struct ast_rtp *bridged = NULL; 02026 02027 ast_mutex_lock(&rtp->bridge_lock); 02028 bridged = rtp->bridged; 02029 ast_mutex_unlock(&rtp->bridge_lock); 02030 02031 return bridged; 02032 }
void ast_rtp_get_current_formats | ( | struct ast_rtp * | rtp, | |
int * | astFormats, | |||
int * | nonAstFormats | |||
) |
Return the union of all of the codecs that were set by rtp_set...() calls They're returned as two distinct sets: AST_FORMATs, and AST_RTPs.
Definition at line 1693 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, rtpPayloadType::code, ast_rtp::current_RTP_PT, rtpPayloadType::isAstFormat, and MAX_RTP_PT.
Referenced by process_sdp().
01695 { 01696 int pt; 01697 01698 ast_mutex_lock(&rtp->bridge_lock); 01699 01700 *astFormats = *nonAstFormats = 0; 01701 for (pt = 0; pt < MAX_RTP_PT; ++pt) { 01702 if (rtp->current_RTP_PT[pt].isAstFormat) { 01703 *astFormats |= rtp->current_RTP_PT[pt].code; 01704 } else { 01705 *nonAstFormats |= rtp->current_RTP_PT[pt].code; 01706 } 01707 } 01708 01709 ast_mutex_unlock(&rtp->bridge_lock); 01710 01711 return; 01712 }
int ast_rtp_get_peer | ( | struct ast_rtp * | rtp, | |
struct sockaddr_in * | them | |||
) |
Definition at line 2005 of file rtp.c.
References ast_rtp::them.
Referenced by add_sdp(), bridge_native_loop(), do_monitor(), gtalk_update_stun(), oh323_set_rtp_peer(), sip_set_rtp_peer(), and transmit_modify_with_sdp().
02006 { 02007 if ((them->sin_family != AF_INET) || 02008 (them->sin_port != rtp->them.sin_port) || 02009 (them->sin_addr.s_addr != rtp->them.sin_addr.s_addr)) { 02010 them->sin_family = AF_INET; 02011 them->sin_port = rtp->them.sin_port; 02012 them->sin_addr = rtp->them.sin_addr; 02013 return 1; 02014 } 02015 return 0; 02016 }
char* ast_rtp_get_quality | ( | struct ast_rtp * | rtp, | |
struct ast_rtp_quality * | qual | |||
) |
Return RTCP quality string.
Definition at line 2071 of file rtp.c.
References ast_rtcp::expected_prior, ast_rtp_quality::local_count, ast_rtp_quality::local_jitter, ast_rtp_quality::local_lostpackets, ast_rtp_quality::local_ssrc, ast_rtcp::quality, ast_rtcp::received_prior, ast_rtp_quality::remote_count, ast_rtp_quality::remote_jitter, ast_rtp_quality::remote_lostpackets, ast_rtp_quality::remote_ssrc, ast_rtcp::reported_jitter, ast_rtcp::reported_lost, ast_rtp::rtcp, ast_rtcp::rtt, ast_rtp_quality::rtt, ast_rtp::rxcount, ast_rtp::rxjitter, ast_rtp::ssrc, ast_rtp::themssrc, and ast_rtp::txcount.
Referenced by acf_channel_read(), handle_request_bye(), and sip_hangup().
02072 { 02073 /* 02074 *ssrc our ssrc 02075 *themssrc their ssrc 02076 *lp lost packets 02077 *rxjitter our calculated jitter(rx) 02078 *rxcount no. received packets 02079 *txjitter reported jitter of the other end 02080 *txcount transmitted packets 02081 *rlp remote lost packets 02082 *rtt round trip time 02083 */ 02084 02085 if (qual && rtp) { 02086 qual->local_ssrc = rtp->ssrc; 02087 qual->local_jitter = rtp->rxjitter; 02088 qual->local_count = rtp->rxcount; 02089 qual->remote_ssrc = rtp->themssrc; 02090 qual->remote_count = rtp->txcount; 02091 if (rtp->rtcp) { 02092 qual->local_lostpackets = rtp->rtcp->expected_prior - rtp->rtcp->received_prior; 02093 qual->remote_lostpackets = rtp->rtcp->reported_lost; 02094 qual->remote_jitter = rtp->rtcp->reported_jitter / 65536.0; 02095 qual->rtt = rtp->rtcp->rtt; 02096 } 02097 } 02098 if (rtp->rtcp) { 02099 snprintf(rtp->rtcp->quality, sizeof(rtp->rtcp->quality), 02100 "ssrc=%u;themssrc=%u;lp=%u;rxjitter=%f;rxcount=%u;txjitter=%f;txcount=%u;rlp=%u;rtt=%f", 02101 rtp->ssrc, 02102 rtp->themssrc, 02103 rtp->rtcp->expected_prior - rtp->rtcp->received_prior, 02104 rtp->rxjitter, 02105 rtp->rxcount, 02106 (double)rtp->rtcp->reported_jitter / 65536.0, 02107 rtp->txcount, 02108 rtp->rtcp->reported_lost, 02109 rtp->rtcp->rtt); 02110 return rtp->rtcp->quality; 02111 } else 02112 return "<Unknown> - RTP/RTCP has already been destroyed"; 02113 }
int ast_rtp_get_rtpholdtimeout | ( | struct ast_rtp * | rtp | ) |
Get rtp hold timeout.
Definition at line 567 of file rtp.c.
References ast_rtp::rtpholdtimeout, and ast_rtp::rtptimeout.
Referenced by do_monitor().
00568 { 00569 if (rtp->rtptimeout < 0) /* We're not checking, but remembering the setting (during T.38 transmission) */ 00570 return 0; 00571 return rtp->rtpholdtimeout; 00572 }
int ast_rtp_get_rtpkeepalive | ( | struct ast_rtp * | rtp | ) |
Get RTP keepalive interval.
Definition at line 575 of file rtp.c.
References ast_rtp::rtpkeepalive.
Referenced by do_monitor().
00576 { 00577 return rtp->rtpkeepalive; 00578 }
int ast_rtp_get_rtptimeout | ( | struct ast_rtp * | rtp | ) |
Get rtp timeout.
Definition at line 559 of file rtp.c.
References ast_rtp::rtptimeout.
Referenced by do_monitor().
00560 { 00561 if (rtp->rtptimeout < 0) /* We're not checking, but remembering the setting (during T.38 transmission) */ 00562 return 0; 00563 return rtp->rtptimeout; 00564 }
void ast_rtp_get_us | ( | struct ast_rtp * | rtp, | |
struct sockaddr_in * | us | |||
) |
Definition at line 2018 of file rtp.c.
References ast_rtp::us.
Referenced by add_sdp(), external_rtp_create(), gtalk_create_candidates(), handle_open_receive_channel_ack_message(), and oh323_set_rtp_peer().
int ast_rtp_getnat | ( | struct ast_rtp * | rtp | ) |
Definition at line 595 of file rtp.c.
References ast_test_flag, and FLAG_NAT_ACTIVE.
Referenced by sip_get_rtp_peer().
00596 { 00597 return ast_test_flag(rtp, FLAG_NAT_ACTIVE); 00598 }
void ast_rtp_init | ( | void | ) |
Initialize the RTP system in Asterisk.
Definition at line 3783 of file rtp.c.
References ast_cli_register_multiple(), and ast_rtp_reload().
Referenced by main().
03784 { 03785 ast_cli_register_multiple(cli_rtp, sizeof(cli_rtp) / sizeof(struct ast_cli_entry)); 03786 ast_rtp_reload(); 03787 }
int ast_rtp_lookup_code | ( | struct ast_rtp * | rtp, | |
const int | isAstFormat, | |||
const int | code | |||
) |
Looks up an RTP code out of our *static* outbound list.
Definition at line 1736 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, rtpPayloadType::code, ast_rtp::current_RTP_PT, rtpPayloadType::isAstFormat, MAX_RTP_PT, ast_rtp::rtp_lookup_code_cache_code, ast_rtp::rtp_lookup_code_cache_isAstFormat, and ast_rtp::rtp_lookup_code_cache_result.
Referenced by add_codec_to_answer(), add_codec_to_sdp(), add_noncodec_to_sdp(), add_sdp(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_write(), and bridge_p2p_rtp_write().
01737 { 01738 int pt = 0; 01739 01740 ast_mutex_lock(&rtp->bridge_lock); 01741 01742 if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat && 01743 code == rtp->rtp_lookup_code_cache_code) { 01744 /* Use our cached mapping, to avoid the overhead of the loop below */ 01745 pt = rtp->rtp_lookup_code_cache_result; 01746 ast_mutex_unlock(&rtp->bridge_lock); 01747 return pt; 01748 } 01749 01750 /* Check the dynamic list first */ 01751 for (pt = 0; pt < MAX_RTP_PT; ++pt) { 01752 if (rtp->current_RTP_PT[pt].code == code && rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) { 01753 rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat; 01754 rtp->rtp_lookup_code_cache_code = code; 01755 rtp->rtp_lookup_code_cache_result = pt; 01756 ast_mutex_unlock(&rtp->bridge_lock); 01757 return pt; 01758 } 01759 } 01760 01761 /* Then the static list */ 01762 for (pt = 0; pt < MAX_RTP_PT; ++pt) { 01763 if (static_RTP_PT[pt].code == code && static_RTP_PT[pt].isAstFormat == isAstFormat) { 01764 rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat; 01765 rtp->rtp_lookup_code_cache_code = code; 01766 rtp->rtp_lookup_code_cache_result = pt; 01767 ast_mutex_unlock(&rtp->bridge_lock); 01768 return pt; 01769 } 01770 } 01771 01772 ast_mutex_unlock(&rtp->bridge_lock); 01773 01774 return -1; 01775 }
char* ast_rtp_lookup_mime_multiple | ( | char * | buf, | |
size_t | size, | |||
const int | capability, | |||
const int | isAstFormat, | |||
enum ast_rtp_options | options | |||
) |
Build a string of MIME subtype names from a capability list.
Definition at line 1796 of file rtp.c.
References ast_rtp_lookup_mime_subtype(), AST_RTP_MAX, format, len, and name.
Referenced by process_sdp().
01798 { 01799 int format; 01800 unsigned len; 01801 char *end = buf; 01802 char *start = buf; 01803 01804 if (!buf || !size) 01805 return NULL; 01806 01807 snprintf(end, size, "0x%x (", capability); 01808 01809 len = strlen(end); 01810 end += len; 01811 size -= len; 01812 start = end; 01813 01814 for (format = 1; format < AST_RTP_MAX; format <<= 1) { 01815 if (capability & format) { 01816 const char *name = ast_rtp_lookup_mime_subtype(isAstFormat, format, options); 01817 01818 snprintf(end, size, "%s|", name); 01819 len = strlen(end); 01820 end += len; 01821 size -= len; 01822 } 01823 } 01824 01825 if (start == end) 01826 snprintf(start, size, "nothing)"); 01827 else if (size > 1) 01828 *(end -1) = ')'; 01829 01830 return buf; 01831 }
const char* ast_rtp_lookup_mime_subtype | ( | const int | isAstFormat, | |
const int | code, | |||
enum ast_rtp_options | options | |||
) |
Mapping an Asterisk code into a MIME subtype (string):.
Definition at line 1777 of file rtp.c.
References AST_FORMAT_G726_AAL2, AST_RTP_OPT_G726_NONSTANDARD, rtpPayloadType::code, mimeTypes, and payloadType.
Referenced by add_codec_to_sdp(), add_noncodec_to_sdp(), add_sdp(), ast_rtp_lookup_mime_multiple(), transmit_connect_with_sdp(), and transmit_modify_with_sdp().
01779 { 01780 unsigned int i; 01781 01782 for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) { 01783 if ((mimeTypes[i].payloadType.code == code) && (mimeTypes[i].payloadType.isAstFormat == isAstFormat)) { 01784 if (isAstFormat && 01785 (code == AST_FORMAT_G726_AAL2) && 01786 (options & AST_RTP_OPT_G726_NONSTANDARD)) 01787 return "G726-32"; 01788 else 01789 return mimeTypes[i].subtype; 01790 } 01791 } 01792 01793 return ""; 01794 }
struct rtpPayloadType ast_rtp_lookup_pt | ( | struct ast_rtp * | rtp, | |
int | pt | |||
) | [read] |
Mapping between RTP payload format codes and Asterisk codes:.
Definition at line 1714 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), rtpPayloadType::code, rtpPayloadType::isAstFormat, and MAX_RTP_PT.
Referenced by ast_rtp_read(), bridge_p2p_rtp_write(), and setup_rtp_connection().
01715 { 01716 struct rtpPayloadType result; 01717 01718 result.isAstFormat = result.code = 0; 01719 01720 if (pt < 0 || pt > MAX_RTP_PT) 01721 return result; /* bogus payload type */ 01722 01723 /* Start with negotiated codecs */ 01724 ast_mutex_lock(&rtp->bridge_lock); 01725 result = rtp->current_RTP_PT[pt]; 01726 ast_mutex_unlock(&rtp->bridge_lock); 01727 01728 /* If it doesn't exist, check our static RTP type list, just in case */ 01729 if (!result.code) 01730 result = static_RTP_PT[pt]; 01731 01732 return result; 01733 }
int ast_rtp_make_compatible | ( | struct ast_channel * | dest, | |
struct ast_channel * | src, | |||
int | media | |||
) |
Definition at line 1559 of file rtp.c.
References ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_log(), AST_RTP_GET_FAILED, ast_rtp_pt_copy(), AST_RTP_TRY_NATIVE, ast_test_flag, FLAG_NAT_ACTIVE, ast_rtp_protocol::get_codec, get_proto(), ast_rtp_protocol::get_rtp_info, ast_rtp_protocol::get_vrtp_info, LOG_DEBUG, LOG_WARNING, option_debug, and ast_rtp_protocol::set_rtp_peer.
Referenced by wait_for_answer().
01560 { 01561 struct ast_rtp *destp = NULL, *srcp = NULL; /* Audio RTP Channels */ 01562 struct ast_rtp *vdestp = NULL, *vsrcp = NULL; /* Video RTP channels */ 01563 struct ast_rtp_protocol *destpr = NULL, *srcpr = NULL; 01564 enum ast_rtp_get_result audio_dest_res = AST_RTP_GET_FAILED, video_dest_res = AST_RTP_GET_FAILED; 01565 enum ast_rtp_get_result audio_src_res = AST_RTP_GET_FAILED, video_src_res = AST_RTP_GET_FAILED; 01566 int srccodec, destcodec; 01567 01568 /* Lock channels */ 01569 ast_channel_lock(dest); 01570 while(ast_channel_trylock(src)) { 01571 ast_channel_unlock(dest); 01572 usleep(1); 01573 ast_channel_lock(dest); 01574 } 01575 01576 /* Find channel driver interfaces */ 01577 if (!(destpr = get_proto(dest))) { 01578 if (option_debug) 01579 ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", dest->name); 01580 ast_channel_unlock(dest); 01581 ast_channel_unlock(src); 01582 return 0; 01583 } 01584 if (!(srcpr = get_proto(src))) { 01585 if (option_debug) 01586 ast_log(LOG_DEBUG, "Channel '%s' has no RTP, not doing anything\n", src->name); 01587 ast_channel_unlock(dest); 01588 ast_channel_unlock(src); 01589 return 0; 01590 } 01591 01592 /* Get audio and video interface (if native bridge is possible) */ 01593 audio_dest_res = destpr->get_rtp_info(dest, &destp); 01594 video_dest_res = destpr->get_vrtp_info ? destpr->get_vrtp_info(dest, &vdestp) : AST_RTP_GET_FAILED; 01595 audio_src_res = srcpr->get_rtp_info(src, &srcp); 01596 video_src_res = srcpr->get_vrtp_info ? srcpr->get_vrtp_info(src, &vsrcp) : AST_RTP_GET_FAILED; 01597 01598 /* Ensure we have at least one matching codec */ 01599 if (srcpr->get_codec) 01600 srccodec = srcpr->get_codec(src); 01601 else 01602 srccodec = 0; 01603 if (destpr->get_codec) 01604 destcodec = destpr->get_codec(dest); 01605 else 01606 destcodec = 0; 01607 01608 /* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */ 01609 if (audio_dest_res != AST_RTP_TRY_NATIVE || audio_src_res != AST_RTP_TRY_NATIVE || !(srccodec & destcodec)) { 01610 /* Somebody doesn't want to play... */ 01611 ast_channel_unlock(dest); 01612 ast_channel_unlock(src); 01613 return 0; 01614 } 01615 ast_rtp_pt_copy(destp, srcp); 01616 if (vdestp && vsrcp) 01617 ast_rtp_pt_copy(vdestp, vsrcp); 01618 if (media) { 01619 /* Bridge early */ 01620 if (destpr->set_rtp_peer(dest, srcp, vsrcp, srccodec, ast_test_flag(srcp, FLAG_NAT_ACTIVE))) 01621 ast_log(LOG_WARNING, "Channel '%s' failed to setup early bridge to '%s'\n", dest->name, src->name); 01622 } 01623 ast_channel_unlock(dest); 01624 ast_channel_unlock(src); 01625 if (option_debug) 01626 ast_log(LOG_DEBUG, "Seeded SDP of '%s' with that of '%s'\n", dest->name, src->name); 01627 return 1; 01628 }
struct ast_rtp* ast_rtp_new | ( | struct sched_context * | sched, | |
struct io_context * | io, | |||
int | rtcpenable, | |||
int | callbackmode | |||
) | [read] |
Initializate a RTP session.
sched | ||
io | ||
rtcpenable | ||
callbackmode |
Definition at line 1977 of file rtp.c.
References ast_rtp_new_with_bindaddr().
01978 { 01979 struct in_addr ia; 01980 01981 memset(&ia, 0, sizeof(ia)); 01982 return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia); 01983 }
void ast_rtp_new_init | ( | struct ast_rtp * | rtp | ) |
Initialize a new RTP structure.
Definition at line 1877 of file rtp.c.
References ast_mutex_init(), ast_random(), ast_set_flag, ast_rtp::bridge_lock, FLAG_HAS_DTMF, ast_rtp::seqno, ast_rtp::ssrc, ast_rtp::them, and ast_rtp::us.
Referenced by ast_rtp_new_with_bindaddr(), and process_sdp().
01878 { 01879 ast_mutex_init(&rtp->bridge_lock); 01880 01881 rtp->them.sin_family = AF_INET; 01882 rtp->us.sin_family = AF_INET; 01883 rtp->ssrc = ast_random(); 01884 rtp->seqno = ast_random() & 0xffff; 01885 ast_set_flag(rtp, FLAG_HAS_DTMF); 01886 01887 return; 01888 }
struct ast_rtp* ast_rtp_new_with_bindaddr | ( | struct sched_context * | sched, | |
struct io_context * | io, | |||
int | rtcpenable, | |||
int | callbackmode, | |||
struct in_addr | in | |||
) | [read] |
Initializate a RTP session using an in_addr structure.
This fuction gets called by ast_rtp_new().
sched | ||
io | ||
rtcpenable | ||
callbackmode | ||
in |
Definition at line 1890 of file rtp.c.
References ast_calloc, ast_io_add(), AST_IO_IN, ast_log(), ast_random(), ast_rtcp_new(), ast_rtp_new_init(), ast_rtp_pt_default(), ast_set_flag, errno, FLAG_CALLBACK_MODE, free, ast_rtp::io, ast_rtp::ioid, LOG_ERROR, ast_rtp::rtcp, rtp_socket(), rtpread(), ast_rtcp::s, ast_rtp::s, ast_rtp::sched, ast_rtcp::us, and ast_rtp::us.
Referenced by __oh323_rtp_create(), ast_rtp_new(), gtalk_alloc(), sip_alloc(), and start_rtp().
01891 { 01892 struct ast_rtp *rtp; 01893 int x; 01894 int first; 01895 int startplace; 01896 01897 if (!(rtp = ast_calloc(1, sizeof(*rtp)))) 01898 return NULL; 01899 01900 ast_rtp_new_init(rtp); 01901 01902 rtp->s = rtp_socket(); 01903 if (rtp->s < 0) { 01904 free(rtp); 01905 ast_log(LOG_ERROR, "Unable to allocate socket: %s\n", strerror(errno)); 01906 return NULL; 01907 } 01908 if (sched && rtcpenable) { 01909 rtp->sched = sched; 01910 rtp->rtcp = ast_rtcp_new(); 01911 } 01912 01913 /* Select a random port number in the range of possible RTP */ 01914 x = (ast_random() % (rtpend-rtpstart)) + rtpstart; 01915 x = x & ~1; 01916 /* Save it for future references. */ 01917 startplace = x; 01918 /* Iterate tring to bind that port and incrementing it otherwise untill a port was found or no ports are available. */ 01919 for (;;) { 01920 /* Must be an even port number by RTP spec */ 01921 rtp->us.sin_port = htons(x); 01922 rtp->us.sin_addr = addr; 01923 /* If there's rtcp, initialize it as well. */ 01924 if (rtp->rtcp) { 01925 rtp->rtcp->us.sin_port = htons(x + 1); 01926 rtp->rtcp->us.sin_addr = addr; 01927 } 01928 /* Try to bind it/them. */ 01929 if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) && 01930 (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us)))) 01931 break; 01932 if (!first) { 01933 /* Primary bind succeeded! Gotta recreate it */ 01934 close(rtp->s); 01935 rtp->s = rtp_socket(); 01936 } 01937 if (errno != EADDRINUSE) { 01938 /* We got an error that wasn't expected, abort! */ 01939 ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno)); 01940 close(rtp->s); 01941 if (rtp->rtcp) { 01942 close(rtp->rtcp->s); 01943 free(rtp->rtcp); 01944 } 01945 free(rtp); 01946 return NULL; 01947 } 01948 /* The port was used, increment it (by two). */ 01949 x += 2; 01950 /* Did we go over the limit ? */ 01951 if (x > rtpend) 01952 /* then, start from the begingig. */ 01953 x = (rtpstart + 1) & ~1; 01954 /* Check if we reached the place were we started. */ 01955 if (x == startplace) { 01956 /* If so, there's no ports available. */ 01957 ast_log(LOG_ERROR, "No RTP ports remaining. Can't setup media stream for this call.\n"); 01958 close(rtp->s); 01959 if (rtp->rtcp) { 01960 close(rtp->rtcp->s); 01961 free(rtp->rtcp); 01962 } 01963 free(rtp); 01964 return NULL; 01965 } 01966 } 01967 rtp->sched = sched; 01968 rtp->io = io; 01969 if (callbackmode) { 01970 rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp); 01971 ast_set_flag(rtp, FLAG_CALLBACK_MODE); 01972 } 01973 ast_rtp_pt_default(rtp); 01974 return rtp; 01975 }
int ast_rtp_proto_register | ( | struct ast_rtp_protocol * | proto | ) |
Register interface to channel driver.
Definition at line 2816 of file rtp.c.
References AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), LOG_WARNING, protos, and ast_rtp_protocol::type.
Referenced by load_module().
02817 { 02818 struct ast_rtp_protocol *cur; 02819 02820 AST_LIST_LOCK(&protos); 02821 AST_LIST_TRAVERSE(&protos, cur, list) { 02822 if (!strcmp(cur->type, proto->type)) { 02823 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type); 02824 AST_LIST_UNLOCK(&protos); 02825 return -1; 02826 } 02827 } 02828 AST_LIST_INSERT_HEAD(&protos, proto, list); 02829 AST_LIST_UNLOCK(&protos); 02830 02831 return 0; 02832 }
void ast_rtp_proto_unregister | ( | struct ast_rtp_protocol * | proto | ) |
Unregister interface to channel driver.
Definition at line 2808 of file rtp.c.
References AST_LIST_LOCK, AST_LIST_REMOVE, AST_LIST_UNLOCK, and protos.
Referenced by load_module(), and unload_module().
02809 { 02810 AST_LIST_LOCK(&protos); 02811 AST_LIST_REMOVE(&protos, proto, list); 02812 AST_LIST_UNLOCK(&protos); 02813 }
void ast_rtp_pt_clear | ( | struct ast_rtp * | rtp | ) |
Setting RTP payload types from lines in a SDP description:.
Definition at line 1395 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, rtpPayloadType::code, ast_rtp::current_RTP_PT, rtpPayloadType::isAstFormat, MAX_RTP_PT, ast_rtp::rtp_lookup_code_cache_code, ast_rtp::rtp_lookup_code_cache_isAstFormat, and ast_rtp::rtp_lookup_code_cache_result.
Referenced by process_sdp().
01396 { 01397 int i; 01398 01399 if (!rtp) 01400 return; 01401 01402 ast_mutex_lock(&rtp->bridge_lock); 01403 01404 for (i = 0; i < MAX_RTP_PT; ++i) { 01405 rtp->current_RTP_PT[i].isAstFormat = 0; 01406 rtp->current_RTP_PT[i].code = 0; 01407 } 01408 01409 rtp->rtp_lookup_code_cache_isAstFormat = 0; 01410 rtp->rtp_lookup_code_cache_code = 0; 01411 rtp->rtp_lookup_code_cache_result = 0; 01412 01413 ast_mutex_unlock(&rtp->bridge_lock); 01414 }
Copy payload types between RTP structures.
Definition at line 1435 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, rtpPayloadType::code, ast_rtp::current_RTP_PT, rtpPayloadType::isAstFormat, MAX_RTP_PT, ast_rtp::rtp_lookup_code_cache_code, ast_rtp::rtp_lookup_code_cache_isAstFormat, and ast_rtp::rtp_lookup_code_cache_result.
Referenced by ast_rtp_make_compatible(), and process_sdp().
01436 { 01437 unsigned int i; 01438 01439 ast_mutex_lock(&dest->bridge_lock); 01440 ast_mutex_lock(&src->bridge_lock); 01441 01442 for (i=0; i < MAX_RTP_PT; ++i) { 01443 dest->current_RTP_PT[i].isAstFormat = 01444 src->current_RTP_PT[i].isAstFormat; 01445 dest->current_RTP_PT[i].code = 01446 src->current_RTP_PT[i].code; 01447 } 01448 dest->rtp_lookup_code_cache_isAstFormat = 0; 01449 dest->rtp_lookup_code_cache_code = 0; 01450 dest->rtp_lookup_code_cache_result = 0; 01451 01452 ast_mutex_unlock(&src->bridge_lock); 01453 ast_mutex_unlock(&dest->bridge_lock); 01454 }
void ast_rtp_pt_default | ( | struct ast_rtp * | rtp | ) |
Set payload types to defaults.
Definition at line 1416 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, rtpPayloadType::code, ast_rtp::current_RTP_PT, rtpPayloadType::isAstFormat, MAX_RTP_PT, ast_rtp::rtp_lookup_code_cache_code, ast_rtp::rtp_lookup_code_cache_isAstFormat, and ast_rtp::rtp_lookup_code_cache_result.
Referenced by ast_rtp_new_with_bindaddr().
01417 { 01418 int i; 01419 01420 ast_mutex_lock(&rtp->bridge_lock); 01421 01422 /* Initialize to default payload types */ 01423 for (i = 0; i < MAX_RTP_PT; ++i) { 01424 rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat; 01425 rtp->current_RTP_PT[i].code = static_RTP_PT[i].code; 01426 } 01427 01428 rtp->rtp_lookup_code_cache_isAstFormat = 0; 01429 rtp->rtp_lookup_code_cache_code = 0; 01430 rtp->rtp_lookup_code_cache_result = 0; 01431 01432 ast_mutex_unlock(&rtp->bridge_lock); 01433 }
Definition at line 2609 of file rtp.c.
References AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_rtcp_calc_interval(), ast_rtcp_write(), ast_sched_add(), ast_set_flag, ast_test_flag, ast_verbose(), calc_txstamp(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, FLAG_NAT_ACTIVE, FLAG_NAT_INACTIVE, FLAG_NAT_INACTIVE_NOWARN, ast_frame::has_timing_info, ast_rtp::lastdigitts, ast_rtp::lastovidtimestamp, ast_rtp::lastts, LOG_DEBUG, MAX_TIMESTAMP_SKEW, ast_rtp::nat, option_debug, put_unaligned_uint32(), ast_rtp::rtcp, rtp_debug_test_addr(), ast_rtp::s, ast_frame::samples, ast_rtp::sched, ast_rtcp::schedid, ast_rtp::seqno, ast_rtp::ssrc, ast_frame::subclass, ast_rtp::them, ast_frame::ts, ast_rtp::txcount, and ast_rtp::txoctetcount.
Referenced by ast_rtp_write().
02610 { 02611 unsigned char *rtpheader; 02612 int hdrlen = 12; 02613 int res; 02614 unsigned int ms; 02615 int pred; 02616 int mark = 0; 02617 02618 ms = calc_txstamp(rtp, &f->delivery); 02619 /* Default prediction */ 02620 if (f->subclass < AST_FORMAT_MAX_AUDIO) { 02621 pred = rtp->lastts + f->samples; 02622 02623 /* Re-calculate last TS */ 02624 rtp->lastts = rtp->lastts + ms * 8; 02625 if (ast_tvzero(f->delivery)) { 02626 /* If this isn't an absolute delivery time, Check if it is close to our prediction, 02627 and if so, go with our prediction */ 02628 if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW) 02629 rtp->lastts = pred; 02630 else { 02631 if (option_debug > 2) 02632 ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms); 02633 mark = 1; 02634 } 02635 } 02636 } else { 02637 mark = f->subclass & 0x1; 02638 pred = rtp->lastovidtimestamp + f->samples; 02639 /* Re-calculate last TS */ 02640 rtp->lastts = rtp->lastts + ms * 90; 02641 /* If it's close to our prediction, go for it */ 02642 if (ast_tvzero(f->delivery)) { 02643 if (abs(rtp->lastts - pred) < 7200) { 02644 rtp->lastts = pred; 02645 rtp->lastovidtimestamp += f->samples; 02646 } else { 02647 if (option_debug > 2) 02648 ast_log(LOG_DEBUG, "Difference is %d, ms is %d (%d), pred/ts/samples %d/%d/%d\n", abs(rtp->lastts - pred), ms, ms * 90, rtp->lastts, pred, f->samples); 02649 rtp->lastovidtimestamp = rtp->lastts; 02650 } 02651 } 02652 } 02653 /* If the timestamp for non-digit packets has moved beyond the timestamp 02654 for digits, update the digit timestamp. 02655 */ 02656 if (rtp->lastts > rtp->lastdigitts) 02657 rtp->lastdigitts = rtp->lastts; 02658 02659 if (f->has_timing_info) 02660 rtp->lastts = f->ts * 8; 02661 02662 /* Get a pointer to the header */ 02663 rtpheader = (unsigned char *)(f->data - hdrlen); 02664 02665 put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23))); 02666 put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts)); 02667 put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc)); 02668 02669 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { 02670 res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); 02671 if (res <0) { 02672 if (!rtp->nat || (rtp->nat && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) { 02673 ast_log(LOG_DEBUG, "RTP Transmission error of packet %d to %s:%d: %s\n", rtp->seqno, ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); 02674 } else if (((ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(rtp, FLAG_NAT_INACTIVE_NOWARN)) { 02675 /* Only give this error message once if we are not RTP debugging */ 02676 if (option_debug || rtpdebug) 02677 ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); 02678 ast_set_flag(rtp, FLAG_NAT_INACTIVE_NOWARN); 02679 } 02680 } else { 02681 rtp->txcount++; 02682 rtp->txoctetcount +=(res - hdrlen); 02683 02684 if (rtp->rtcp && rtp->rtcp->schedid < 1) 02685 rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp); 02686 } 02687 02688 if (rtp_debug_test_addr(&rtp->them)) 02689 ast_verbose("Sent RTP packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", 02690 ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen); 02691 } 02692 02693 rtp->seqno++; 02694 02695 return 0; 02696 }
Definition at line 1101 of file rtp.c.
References ast_codec_get_samples(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_null_frame, ast_rtcp_calc_interval(), ast_rtcp_write(), AST_RTP_CISCO_DTMF, AST_RTP_CN, AST_RTP_DTMF, ast_rtp_get_bridged(), ast_rtp_lookup_pt(), ast_rtp_senddigit_continuation(), ast_sched_add(), ast_set_flag, ast_verbose(), bridge_p2p_rtp_write(), ast_rtp::bridged, calc_rxstamp(), rtpPayloadType::code, CRASH, ast_rtp::cycles, ast_frame::data, ast_frame::datalen, ast_frame::delivery, errno, event, ext, ast_rtp::f, f, FLAG_NAT_ACTIVE, ast_frame::frametype, ast_frame::has_timing_info, rtpPayloadType::isAstFormat, ast_rtp::lastevent, ast_rtp::lastividtimestamp, ast_rtp::lastrxformat, ast_rtp::lastrxseqno, ast_rtp::lastrxts, ast_frame::len, len, LOG_DEBUG, LOG_NOTICE, LOG_WARNING, ast_frame::mallocd, ast_rtp::nat, ast_frame::offset, option_debug, process_cisco_dtmf(), process_rfc2833(), process_rfc3389(), ast_rtp::rawdata, ast_rtp::rtcp, rtp_debug_test_addr(), 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, STUN_ACCEPT, stun_handle_packet(), ast_frame::subclass, ast_rtcp::them, ast_rtp::them, ast_rtp::themssrc, and ast_frame::ts.
Referenced by gtalk_rtp_read(), mgcp_rtp_read(), oh323_rtp_read(), rtpread(), sip_rtp_read(), and skinny_rtp_read().
01102 { 01103 int res; 01104 struct sockaddr_in sin; 01105 socklen_t len; 01106 unsigned int seqno; 01107 int version; 01108 int payloadtype; 01109 int hdrlen = 12; 01110 int padding; 01111 int mark; 01112 int ext; 01113 int cc; 01114 unsigned int ssrc; 01115 unsigned int timestamp; 01116 unsigned int *rtpheader; 01117 struct rtpPayloadType rtpPT; 01118 struct ast_rtp *bridged = NULL; 01119 01120 /* If time is up, kill it */ 01121 if (rtp->sending_digit) 01122 ast_rtp_senddigit_continuation(rtp); 01123 01124 len = sizeof(sin); 01125 01126 /* Cache where the header will go */ 01127 res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 01128 0, (struct sockaddr *)&sin, &len); 01129 01130 rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET); 01131 if (res < 0) { 01132 if (errno == EBADF) 01133 CRASH; 01134 if (errno != EAGAIN) { 01135 ast_log(LOG_WARNING, "RTP Read error: %s. Hanging up.\n", strerror(errno)); 01136 return NULL; 01137 } 01138 return &ast_null_frame; 01139 } 01140 01141 if (res < hdrlen) { 01142 ast_log(LOG_WARNING, "RTP Read too short\n"); 01143 return &ast_null_frame; 01144 } 01145 01146 /* Get fields */ 01147 seqno = ntohl(rtpheader[0]); 01148 01149 /* Check RTP version */ 01150 version = (seqno & 0xC0000000) >> 30; 01151 if (!version) { 01152 if ((stun_handle_packet(rtp->s, &sin, rtp->rawdata + AST_FRIENDLY_OFFSET, res) == STUN_ACCEPT) && 01153 (!rtp->them.sin_port && !rtp->them.sin_addr.s_addr)) { 01154 memcpy(&rtp->them, &sin, sizeof(rtp->them)); 01155 } 01156 return &ast_null_frame; 01157 } 01158 01159 #if 0 /* Allow to receive RTP stream with closed transmission path */ 01160 /* If we don't have the other side's address, then ignore this */ 01161 if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) 01162 return &ast_null_frame; 01163 #endif 01164 01165 /* Send to whoever send to us if NAT is turned on */ 01166 if (rtp->nat) { 01167 if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || 01168 (rtp->them.sin_port != sin.sin_port)) { 01169 rtp->them = sin; 01170 if (rtp->rtcp) { 01171 memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them)); 01172 rtp->rtcp->them.sin_port = htons(ntohs(rtp->them.sin_port)+1); 01173 } 01174 rtp->rxseqno = 0; 01175 ast_set_flag(rtp, FLAG_NAT_ACTIVE); 01176 if (option_debug || rtpdebug) 01177 ast_log(LOG_DEBUG, "RTP NAT: Got audio from other end. Now sending to address %s:%d\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port)); 01178 } 01179 } 01180 01181 /* If we are bridged to another RTP stream, send direct */ 01182 if ((bridged = ast_rtp_get_bridged(rtp)) && !bridge_p2p_rtp_write(rtp, bridged, rtpheader, res, hdrlen)) 01183 return &ast_null_frame; 01184 01185 if (version != 2) 01186 return &ast_null_frame; 01187 01188 payloadtype = (seqno & 0x7f0000) >> 16; 01189 padding = seqno & (1 << 29); 01190 mark = seqno & (1 << 23); 01191 ext = seqno & (1 << 28); 01192 cc = (seqno & 0xF000000) >> 24; 01193 seqno &= 0xffff; 01194 timestamp = ntohl(rtpheader[1]); 01195 ssrc = ntohl(rtpheader[2]); 01196 01197 if (!mark && rtp->rxssrc && rtp->rxssrc != ssrc) { 01198 if (option_debug || rtpdebug) 01199 ast_log(LOG_DEBUG, "Forcing Marker bit, because SSRC has changed\n"); 01200 mark = 1; 01201 } 01202 01203 rtp->rxssrc = ssrc; 01204 01205 if (padding) { 01206 /* Remove padding bytes */ 01207 res -= rtp->rawdata[AST_FRIENDLY_OFFSET + res - 1]; 01208 } 01209 01210 if (cc) { 01211 /* CSRC fields present */ 01212 hdrlen += cc*4; 01213 } 01214 01215 if (ext) { 01216 /* RTP Extension present */ 01217 hdrlen += (ntohl(rtpheader[hdrlen/4]) & 0xffff) << 2; 01218 hdrlen += 4; 01219 } 01220 01221 if (res < hdrlen) { 01222 ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen); 01223 return &ast_null_frame; 01224 } 01225 01226 rtp->rxcount++; /* Only count reasonably valid packets, this'll make the rtcp stats more accurate */ 01227 01228 if (rtp->rxcount==1) { 01229 /* This is the first RTP packet successfully received from source */ 01230 rtp->seedrxseqno = seqno; 01231 } 01232 01233 /* Do not schedule RR if RTCP isn't run */ 01234 if (rtp->rtcp && rtp->rtcp->them.sin_addr.s_addr && rtp->rtcp->schedid < 1) { 01235 /* Schedule transmission of Receiver Report */ 01236 rtp->rtcp->schedid = ast_sched_add(rtp->sched, ast_rtcp_calc_interval(rtp), ast_rtcp_write, rtp); 01237 } 01238 if ( (int)rtp->lastrxseqno - (int)seqno > 100) /* if so it would indicate that the sender cycled; allow for misordering */ 01239 rtp->cycles += RTP_SEQ_MOD; 01240 01241 rtp->lastrxseqno = seqno; 01242 01243 if (rtp->themssrc==0) 01244 rtp->themssrc = ntohl(rtpheader[2]); /* Record their SSRC to put in future RR */ 01245 01246 if (rtp_debug_test_addr(&sin)) 01247 ast_verbose("Got RTP packet from %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", 01248 ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); 01249 01250 rtpPT = ast_rtp_lookup_pt(rtp, payloadtype); 01251 if (!rtpPT.isAstFormat) { 01252 struct ast_frame *f = NULL; 01253 01254 /* This is special in-band data that's not one of our codecs */ 01255 if (rtpPT.code == AST_RTP_DTMF) { 01256 /* It's special -- rfc2833 process it */ 01257 if (rtp_debug_test_addr(&sin)) { 01258 unsigned char *data; 01259 unsigned int event; 01260 unsigned int event_end; 01261 unsigned int duration; 01262 data = rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen; 01263 event = ntohl(*((unsigned int *)(data))); 01264 event >>= 24; 01265 event_end = ntohl(*((unsigned int *)(data))); 01266 event_end <<= 8; 01267 event_end >>= 24; 01268 duration = ntohl(*((unsigned int *)(data))); 01269 duration &= 0xFFFF; 01270 ast_verbose("Got RTP RFC2833 from %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u, mark %d, event %08x, end %d, duration %-5.5d) \n", ast_inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration); 01271 } 01272 f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno, timestamp); 01273 } else if (rtpPT.code == AST_RTP_CISCO_DTMF) { 01274 /* It's really special -- process it the Cisco way */ 01275 if (rtp->lastevent <= seqno || (rtp->lastevent >= 65530 && seqno <= 6)) { 01276 f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); 01277 rtp->lastevent = seqno; 01278 } 01279 } else if (rtpPT.code == AST_RTP_CN) { 01280 /* Comfort Noise */ 01281 f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); 01282 } else { 01283 ast_log(LOG_NOTICE, "Unknown RTP codec %d received from '%s'\n", payloadtype, ast_inet_ntoa(rtp->them.sin_addr)); 01284 } 01285 return f ? f : &ast_null_frame; 01286 } 01287 rtp->lastrxformat = rtp->f.subclass = rtpPT.code; 01288 rtp->f.frametype = (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) ? AST_FRAME_VOICE : AST_FRAME_VIDEO; 01289 01290 if (!rtp->lastrxts) 01291 rtp->lastrxts = timestamp; 01292 01293 rtp->rxseqno = seqno; 01294 01295 /* Record received timestamp as last received now */ 01296 rtp->lastrxts = timestamp; 01297 01298 rtp->f.mallocd = 0; 01299 rtp->f.datalen = res - hdrlen; 01300 rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET; 01301 rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET; 01302 rtp->f.seqno = seqno; 01303 if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) { 01304 rtp->f.samples = ast_codec_get_samples(&rtp->f); 01305 if (rtp->f.subclass == AST_FORMAT_SLINEAR) 01306 ast_frame_byteswap_be(&rtp->f); 01307 calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark); 01308 /* Add timing data to let ast_generic_bridge() put the frame into a jitterbuf */ 01309 rtp->f.has_timing_info = 1; 01310 rtp->f.ts = timestamp / 8; 01311 rtp->f.len = rtp->f.samples / 8; 01312 } else { 01313 /* Video -- samples is # of samples vs. 90000 */ 01314 if (!rtp->lastividtimestamp) 01315 rtp->lastividtimestamp = timestamp; 01316 rtp->f.samples = timestamp - rtp->lastividtimestamp; 01317 rtp->lastividtimestamp = timestamp; 01318 rtp->f.delivery.tv_sec = 0; 01319 rtp->f.delivery.tv_usec = 0; 01320 if (mark) 01321 rtp->f.subclass |= 0x1; 01322 01323 } 01324 rtp->f.src = "RTP"; 01325 return &rtp->f; 01326 }
int ast_rtp_reload | ( | void | ) |
Definition at line 3718 of file rtp.c.
References ast_config_destroy(), ast_config_load(), ast_false(), ast_log(), ast_variable_retrieve(), ast_verbose(), DEFAULT_DTMF_TIMEOUT, LOG_WARNING, option_verbose, RTCP_MAX_INTERVALMS, RTCP_MIN_INTERVALMS, s, and VERBOSE_PREFIX_2.
Referenced by ast_rtp_init().
03719 { 03720 struct ast_config *cfg; 03721 const char *s; 03722 03723 rtpstart = 5000; 03724 rtpend = 31000; 03725 dtmftimeout = DEFAULT_DTMF_TIMEOUT; 03726 cfg = ast_config_load("rtp.conf"); 03727 if (cfg) { 03728 if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) { 03729 rtpstart = atoi(s); 03730 if (rtpstart < 1024) 03731 rtpstart = 1024; 03732 if (rtpstart > 65535) 03733 rtpstart = 65535; 03734 } 03735 if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) { 03736 rtpend = atoi(s); 03737 if (rtpend < 1024) 03738 rtpend = 1024; 03739 if (rtpend > 65535) 03740 rtpend = 65535; 03741 } 03742 if ((s = ast_variable_retrieve(cfg, "general", "rtcpinterval"))) { 03743 rtcpinterval = atoi(s); 03744 if (rtcpinterval == 0) 03745 rtcpinterval = 0; /* Just so we're clear... it's zero */ 03746 if (rtcpinterval < RTCP_MIN_INTERVALMS) 03747 rtcpinterval = RTCP_MIN_INTERVALMS; /* This catches negative numbers too */ 03748 if (rtcpinterval > RTCP_MAX_INTERVALMS) 03749 rtcpinterval = RTCP_MAX_INTERVALMS; 03750 } 03751 if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) { 03752 #ifdef SO_NO_CHECK 03753 if (ast_false(s)) 03754 nochecksums = 1; 03755 else 03756 nochecksums = 0; 03757 #else 03758 if (ast_false(s)) 03759 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 03760 #endif 03761 } 03762 if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) { 03763 dtmftimeout = atoi(s); 03764 if ((dtmftimeout < 0) || (dtmftimeout > 20000)) { 03765 ast_log(LOG_WARNING, "DTMF timeout of '%d' outside range, using default of '%d' instead\n", 03766 dtmftimeout, DEFAULT_DTMF_TIMEOUT); 03767 dtmftimeout = DEFAULT_DTMF_TIMEOUT; 03768 }; 03769 } 03770 ast_config_destroy(cfg); 03771 } 03772 if (rtpstart >= rtpend) { 03773 ast_log(LOG_WARNING, "Unreasonable values for RTP start/end port in rtp.conf\n"); 03774 rtpstart = 5000; 03775 rtpend = 31000; 03776 } 03777 if (option_verbose > 1) 03778 ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend); 03779 return 0; 03780 }
void ast_rtp_reset | ( | struct ast_rtp * | rtp | ) |
Definition at line 2051 of file rtp.c.
References ast_rtp::dtmfcount, ast_rtp::dtmfmute, ast_rtp::dtmfsamples, ast_rtp::lastdigitts, ast_rtp::lastevent, ast_rtp::lasteventseqn, ast_rtp::lastividtimestamp, ast_rtp::lastovidtimestamp, ast_rtp::lastrxformat, ast_rtp::lastrxts, ast_rtp::lastts, ast_rtp::lasttxformat, ast_rtp::rxcore, ast_rtp::rxseqno, ast_rtp::seqno, and ast_rtp::txcore.
02052 { 02053 memset(&rtp->rxcore, 0, sizeof(rtp->rxcore)); 02054 memset(&rtp->txcore, 0, sizeof(rtp->txcore)); 02055 memset(&rtp->dtmfmute, 0, sizeof(rtp->dtmfmute)); 02056 rtp->lastts = 0; 02057 rtp->lastdigitts = 0; 02058 rtp->lastrxts = 0; 02059 rtp->lastividtimestamp = 0; 02060 rtp->lastovidtimestamp = 0; 02061 rtp->lasteventseqn = 0; 02062 rtp->lastevent = 0; 02063 rtp->lasttxformat = 0; 02064 rtp->lastrxformat = 0; 02065 rtp->dtmfcount = 0; 02066 rtp->dtmfsamples = 0; 02067 rtp->seqno = 0; 02068 rtp->rxseqno = 0; 02069 }
int ast_rtp_sendcng | ( | struct ast_rtp * | rtp, | |
int | level | |||
) |
generate comfort noice (CNG)
Definition at line 2575 of file rtp.c.
References ast_inet_ntoa(), ast_log(), AST_RTP_CN, ast_rtp_lookup_code(), ast_tvadd(), ast_verbose(), ast_rtp::data, ast_rtp::dtmfmute, errno, ast_rtp::lastts, LOG_ERROR, rtp_debug_test_addr(), ast_rtp::s, ast_rtp::seqno, ast_rtp::ssrc, and ast_rtp::them.
Referenced by do_monitor().
02576 { 02577 unsigned int *rtpheader; 02578 int hdrlen = 12; 02579 int res; 02580 int payload; 02581 char data[256]; 02582 level = 127 - (level & 0x7f); 02583 payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN); 02584 02585 /* If we have no peer, return immediately */ 02586 if (!rtp->them.sin_addr.s_addr) 02587 return 0; 02588 02589 rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); 02590 02591 /* Get a pointer to the header */ 02592 rtpheader = (unsigned int *)data; 02593 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++)); 02594 rtpheader[1] = htonl(rtp->lastts); 02595 rtpheader[2] = htonl(rtp->ssrc); 02596 data[12] = level; 02597 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { 02598 res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); 02599 if (res <0) 02600 ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); 02601 if (rtp_debug_test_addr(&rtp->them)) 02602 ast_verbose("Sent Comfort Noise RTP packet to %s:%u (type %d, seq %u, ts %u, len %d)\n" 02603 , ast_inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen); 02604 02605 } 02606 return 0; 02607 }
int ast_rtp_senddigit_begin | ( | struct ast_rtp * | rtp, | |
char | digit | |||
) |
Send begin frames for DTMF.
Definition at line 2175 of file rtp.c.
References ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_lookup_code(), ast_tvadd(), ast_verbose(), ast_rtp::dtmfmute, errno, ast_rtp::lastdigitts, LOG_ERROR, LOG_WARNING, rtp_debug_test_addr(), ast_rtp::s, ast_rtp::send_digit, ast_rtp::send_duration, ast_rtp::send_payload, ast_rtp::sending_digit, ast_rtp::seqno, ast_rtp::ssrc, and ast_rtp::them.
Referenced by oh323_digit_begin(), and sip_senddigit_begin().
02176 { 02177 unsigned int *rtpheader; 02178 int hdrlen = 12, res = 0, i = 0, payload = 0; 02179 char data[256]; 02180 02181 if ((digit <= '9') && (digit >= '0')) 02182 digit -= '0'; 02183 else if (digit == '*') 02184 digit = 10; 02185 else if (digit == '#') 02186 digit = 11; 02187 else if ((digit >= 'A') && (digit <= 'D')) 02188 digit = digit - 'A' + 12; 02189 else if ((digit >= 'a') && (digit <= 'd')) 02190 digit = digit - 'a' + 12; 02191 else { 02192 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit); 02193 return 0; 02194 } 02195 02196 /* If we have no peer, return immediately */ 02197 if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) 02198 return 0; 02199 02200 payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF); 02201 02202 rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); 02203 rtp->send_duration = 160; 02204 02205 /* Get a pointer to the header */ 02206 rtpheader = (unsigned int *)data; 02207 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno)); 02208 rtpheader[1] = htonl(rtp->lastdigitts); 02209 rtpheader[2] = htonl(rtp->ssrc); 02210 02211 for (i = 0; i < 2; i++) { 02212 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration)); 02213 res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); 02214 if (res < 0) 02215 ast_log(LOG_ERROR, "RTP Transmission error to %s:%u: %s\n", 02216 ast_inet_ntoa(rtp->them.sin_addr), 02217 ntohs(rtp->them.sin_port), strerror(errno)); 02218 if (rtp_debug_test_addr(&rtp->them)) 02219 ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", 02220 ast_inet_ntoa(rtp->them.sin_addr), 02221 ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); 02222 /* Increment sequence number */ 02223 rtp->seqno++; 02224 /* Increment duration */ 02225 rtp->send_duration += 160; 02226 /* Clear marker bit and set seqno */ 02227 rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno)); 02228 } 02229 02230 /* Since we received a begin, we can safely store the digit and disable any compensation */ 02231 rtp->sending_digit = 1; 02232 rtp->send_digit = digit; 02233 rtp->send_payload = payload; 02234 02235 return 0; 02236 }
static int ast_rtp_senddigit_continuation | ( | struct ast_rtp * | rtp | ) | [static] |
Send continuation frame for DTMF.
Definition at line 2239 of file rtp.c.
References ast_inet_ntoa(), ast_log(), ast_verbose(), errno, ast_rtp::lastdigitts, LOG_ERROR, rtp_debug_test_addr(), ast_rtp::s, ast_rtp::send_digit, ast_rtp::send_duration, ast_rtp::send_payload, ast_rtp::seqno, ast_rtp::ssrc, and ast_rtp::them.
Referenced by ast_rtp_read().
02240 { 02241 unsigned int *rtpheader; 02242 int hdrlen = 12, res = 0; 02243 char data[256]; 02244 02245 if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) 02246 return 0; 02247 02248 /* Setup packet to send */ 02249 rtpheader = (unsigned int *)data; 02250 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno)); 02251 rtpheader[1] = htonl(rtp->lastdigitts); 02252 rtpheader[2] = htonl(rtp->ssrc); 02253 rtpheader[3] = htonl((rtp->send_digit << 24) | (0xa << 16) | (rtp->send_duration)); 02254 rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno)); 02255 02256 /* Transmit */ 02257 res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); 02258 if (res < 0) 02259 ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", 02260 ast_inet_ntoa(rtp->them.sin_addr), 02261 ntohs(rtp->them.sin_port), strerror(errno)); 02262 if (rtp_debug_test_addr(&rtp->them)) 02263 ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", 02264 ast_inet_ntoa(rtp->them.sin_addr), 02265 ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); 02266 02267 /* Increment sequence number */ 02268 rtp->seqno++; 02269 /* Increment duration */ 02270 rtp->send_duration += 160; 02271 02272 return 0; 02273 }
int ast_rtp_senddigit_end | ( | struct ast_rtp * | rtp, | |
char | digit | |||
) |
Send end packets for DTMF.
Definition at line 2276 of file rtp.c.
References ast_inet_ntoa(), ast_log(), ast_tvadd(), ast_verbose(), ast_rtp::dtmfmute, errno, ast_rtp::lastdigitts, LOG_ERROR, LOG_WARNING, rtp_debug_test_addr(), ast_rtp::s, ast_rtp::send_digit, ast_rtp::send_duration, ast_rtp::send_payload, ast_rtp::sending_digit, ast_rtp::seqno, ast_rtp::ssrc, and ast_rtp::them.
Referenced by oh323_digit_end(), and sip_senddigit_end().
02277 { 02278 unsigned int *rtpheader; 02279 int hdrlen = 12, res = 0, i = 0; 02280 char data[256]; 02281 02282 /* If no address, then bail out */ 02283 if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) 02284 return 0; 02285 02286 if ((digit <= '9') && (digit >= '0')) 02287 digit -= '0'; 02288 else if (digit == '*') 02289 digit = 10; 02290 else if (digit == '#') 02291 digit = 11; 02292 else if ((digit >= 'A') && (digit <= 'D')) 02293 digit = digit - 'A' + 12; 02294 else if ((digit >= 'a') && (digit <= 'd')) 02295 digit = digit - 'a' + 12; 02296 else { 02297 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit); 02298 return 0; 02299 } 02300 02301 rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); 02302 02303 rtpheader = (unsigned int *)data; 02304 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (rtp->send_payload << 16) | (rtp->seqno)); 02305 rtpheader[1] = htonl(rtp->lastdigitts); 02306 rtpheader[2] = htonl(rtp->ssrc); 02307 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (rtp->send_duration)); 02308 /* Set end bit */ 02309 rtpheader[3] |= htonl((1 << 23)); 02310 rtpheader[0] = htonl((2 << 30) | (rtp->send_payload << 16) | (rtp->seqno)); 02311 /* Send 3 termination packets */ 02312 for (i = 0; i < 3; i++) { 02313 res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); 02314 if (res < 0) 02315 ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", 02316 ast_inet_ntoa(rtp->them.sin_addr), 02317 ntohs(rtp->them.sin_port), strerror(errno)); 02318 if (rtp_debug_test_addr(&rtp->them)) 02319 ast_verbose("Sent RTP DTMF packet to %s:%u (type %-2.2d, seq %-6.6u, ts %-6.6u, len %-6.6u)\n", 02320 ast_inet_ntoa(rtp->them.sin_addr), 02321 ntohs(rtp->them.sin_port), rtp->send_payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); 02322 } 02323 rtp->sending_digit = 0; 02324 rtp->send_digit = 0; 02325 /* Increment lastdigitts */ 02326 rtp->lastdigitts += 960; 02327 rtp->seqno++; 02328 02329 return res; 02330 }
void ast_rtp_set_callback | ( | struct ast_rtp * | rtp, | |
ast_rtp_callback | callback | |||
) |
Definition at line 585 of file rtp.c.
References ast_rtp::callback.
Referenced by start_rtp().
00586 { 00587 rtp->callback = callback; 00588 }
void ast_rtp_set_data | ( | struct ast_rtp * | rtp, | |
void * | data | |||
) |
Definition at line 580 of file rtp.c.
References ast_rtp::data.
Referenced by start_rtp().
00581 { 00582 rtp->data = data; 00583 }
void ast_rtp_set_m_type | ( | struct ast_rtp * | rtp, | |
int | pt | |||
) |
Make a note of a RTP payload type that was seen in a SDP "m=" line. By default, use the well-known value for this type (although it may still be set to a different value by a subsequent "a=rtpmap:" line).
Activate payload type.
Definition at line 1634 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, ast_rtp::current_RTP_PT, and MAX_RTP_PT.
Referenced by gtalk_newcall(), and process_sdp().
01635 { 01636 if (pt < 0 || pt > MAX_RTP_PT || static_RTP_PT[pt].code == 0) 01637 return; /* bogus payload type */ 01638 01639 ast_mutex_lock(&rtp->bridge_lock); 01640 rtp->current_RTP_PT[pt] = static_RTP_PT[pt]; 01641 ast_mutex_unlock(&rtp->bridge_lock); 01642 }
void ast_rtp_set_peer | ( | struct ast_rtp * | rtp, | |
struct sockaddr_in * | them | |||
) |
Definition at line 1994 of file rtp.c.
References ast_rtp::rtcp, ast_rtp::rxseqno, ast_rtcp::them, and ast_rtp::them.
Referenced by handle_open_receive_channel_ack_message(), process_sdp(), and setup_rtp_connection().
01995 { 01996 rtp->them.sin_port = them->sin_port; 01997 rtp->them.sin_addr = them->sin_addr; 01998 if (rtp->rtcp) { 01999 rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1); 02000 rtp->rtcp->them.sin_addr = them->sin_addr; 02001 } 02002 rtp->rxseqno = 0; 02003 }
void ast_rtp_set_rtpholdtimeout | ( | struct ast_rtp * | rtp, | |
int | timeout | |||
) |
Set rtp hold timeout.
Definition at line 547 of file rtp.c.
References ast_rtp::rtpholdtimeout.
Referenced by create_addr_from_peer(), do_monitor(), and sip_alloc().
00548 { 00549 rtp->rtpholdtimeout = timeout; 00550 }
void ast_rtp_set_rtpkeepalive | ( | struct ast_rtp * | rtp, | |
int | period | |||
) |
set RTP keepalive interval
Definition at line 553 of file rtp.c.
References ast_rtp::rtpkeepalive.
Referenced by create_addr_from_peer(), and sip_alloc().
00554 { 00555 rtp->rtpkeepalive = period; 00556 }
int ast_rtp_set_rtpmap_type | ( | struct ast_rtp * | rtp, | |
int | pt, | |||
char * | mimeType, | |||
char * | mimeSubtype, | |||
enum ast_rtp_options | options | |||
) |
Make a note of a RTP payload type (with MIME type) that was seen in an SDP "a=rtpmap:" line.
Initiate payload type to a known MIME media type for a codec.
Definition at line 1661 of file rtp.c.
References AST_FORMAT_G726, AST_FORMAT_G726_AAL2, ast_mutex_lock(), ast_mutex_unlock(), AST_RTP_OPT_G726_NONSTANDARD, ast_rtp::bridge_lock, rtpPayloadType::code, ast_rtp::current_RTP_PT, MAX_RTP_PT, mimeTypes, payloadType, subtype, and type.
Referenced by __oh323_rtp_create(), gtalk_newcall(), process_sdp(), and set_dtmf_payload().
01664 { 01665 unsigned int i; 01666 int found = 0; 01667 01668 if (pt < 0 || pt > MAX_RTP_PT) 01669 return -1; /* bogus payload type */ 01670 01671 ast_mutex_lock(&rtp->bridge_lock); 01672 01673 for (i = 0; i < sizeof(mimeTypes)/sizeof(mimeTypes[0]); ++i) { 01674 if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 && 01675 strcasecmp(mimeType, mimeTypes[i].type) == 0) { 01676 found = 1; 01677 rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType; 01678 if ((mimeTypes[i].payloadType.code == AST_FORMAT_G726) && 01679 mimeTypes[i].payloadType.isAstFormat && 01680 (options & AST_RTP_OPT_G726_NONSTANDARD)) 01681 rtp->current_RTP_PT[pt].code = AST_FORMAT_G726_AAL2; 01682 break; 01683 } 01684 } 01685 01686 ast_mutex_unlock(&rtp->bridge_lock); 01687 01688 return (found ? 0 : -1); 01689 }
void ast_rtp_set_rtptimeout | ( | struct ast_rtp * | rtp, | |
int | timeout | |||
) |
Set rtp timeout.
Definition at line 541 of file rtp.c.
References ast_rtp::rtptimeout.
Referenced by create_addr_from_peer(), do_monitor(), and sip_alloc().
00542 { 00543 rtp->rtptimeout = timeout; 00544 }
void ast_rtp_set_rtptimers_onhold | ( | struct ast_rtp * | rtp | ) |
Definition at line 534 of file rtp.c.
References ast_rtp::rtpholdtimeout, and ast_rtp::rtptimeout.
Referenced by handle_response_invite().
00535 { 00536 rtp->rtptimeout = (-1) * rtp->rtptimeout; 00537 rtp->rtpholdtimeout = (-1) * rtp->rtpholdtimeout; 00538 }
void ast_rtp_setdtmf | ( | struct ast_rtp * | rtp, | |
int | dtmf | |||
) |
Indicate whether this RTP session is carrying DTMF or not.
Definition at line 600 of file rtp.c.
References ast_set2_flag, and FLAG_HAS_DTMF.
Referenced by create_addr_from_peer(), handle_request_invite(), process_sdp(), sip_alloc(), and sip_dtmfmode().
00601 { 00602 ast_set2_flag(rtp, dtmf ? 1 : 0, FLAG_HAS_DTMF); 00603 }
void ast_rtp_setdtmfcompensate | ( | struct ast_rtp * | rtp, | |
int | compensate | |||
) |
Compensate for devices that send RFC2833 packets all at once.
Definition at line 605 of file rtp.c.
References ast_set2_flag, and FLAG_DTMF_COMPENSATE.
Referenced by create_addr_from_peer(), handle_request_invite(), process_sdp(), and sip_alloc().
00606 { 00607 ast_set2_flag(rtp, compensate ? 1 : 0, FLAG_DTMF_COMPENSATE); 00608 }
void ast_rtp_setnat | ( | struct ast_rtp * | rtp, | |
int | nat | |||
) |
Definition at line 590 of file rtp.c.
References ast_rtp::nat.
Referenced by __oh323_rtp_create(), do_setnat(), oh323_rtp_read(), and start_rtp().
void ast_rtp_setstun | ( | struct ast_rtp * | rtp, | |
int | stun_enable | |||
) |
Enable STUN capability.
Definition at line 610 of file rtp.c.
References ast_set2_flag, and FLAG_HAS_STUN.
Referenced by gtalk_new().
00611 { 00612 ast_set2_flag(rtp, stun_enable ? 1 : 0, FLAG_HAS_STUN); 00613 }
int ast_rtp_settos | ( | struct ast_rtp * | rtp, | |
int | tos | |||
) |
Definition at line 1985 of file rtp.c.
References ast_log(), LOG_WARNING, and ast_rtp::s.
Referenced by __oh323_rtp_create(), and sip_alloc().
01986 { 01987 int res; 01988 01989 if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) 01990 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 01991 return res; 01992 }
void ast_rtp_stop | ( | struct ast_rtp * | rtp | ) |
Definition at line 2034 of file rtp.c.
References ast_clear_flag, ast_sched_del(), FLAG_P2P_SENT_MARK, ast_rtp::rtcp, ast_rtp::sched, ast_rtcp::schedid, ast_rtcp::them, and ast_rtp::them.
Referenced by process_sdp(), setup_rtp_connection(), and stop_media_flows().
02035 { 02036 if (rtp->rtcp && rtp->rtcp->schedid > 0) { 02037 ast_sched_del(rtp->sched, rtp->rtcp->schedid); 02038 rtp->rtcp->schedid = -1; 02039 } 02040 02041 memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr)); 02042 memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port)); 02043 if (rtp->rtcp) { 02044 memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->rtcp->them.sin_addr)); 02045 memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->rtcp->them.sin_port)); 02046 } 02047 02048 ast_clear_flag(rtp, FLAG_P2P_SENT_MARK); 02049 }
void ast_rtp_stun_request | ( | struct ast_rtp * | rtp, | |
struct sockaddr_in * | suggestion, | |||
const char * | username | |||
) |
Definition at line 402 of file rtp.c.
References append_attr_string(), stun_attr::attr, stun_header::ies, stun_header::msglen, stun_header::msgtype, ast_rtp::s, STUN_BINDREQ, stun_req_id(), stun_send(), and STUN_USERNAME.
Referenced by gtalk_update_stun().
00403 { 00404 struct stun_header *req; 00405 unsigned char reqdata[1024]; 00406 int reqlen, reqleft; 00407 struct stun_attr *attr; 00408 00409 req = (struct stun_header *)reqdata; 00410 stun_req_id(req); 00411 reqlen = 0; 00412 reqleft = sizeof(reqdata) - sizeof(struct stun_header); 00413 req->msgtype = 0; 00414 req->msglen = 0; 00415 attr = (struct stun_attr *)req->ies; 00416 if (username) 00417 append_attr_string(&attr, STUN_USERNAME, username, &reqlen, &reqleft); 00418 req->msglen = htons(reqlen); 00419 req->msgtype = htons(STUN_BINDREQ); 00420 stun_send(rtp->s, suggestion, req); 00421 }
void ast_rtp_unset_m_type | ( | struct ast_rtp * | rtp, | |
int | pt | |||
) |
remove setting from payload type list if the rtpmap header indicates an unknown media type
clear payload type
Definition at line 1646 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, rtpPayloadType::code, ast_rtp::current_RTP_PT, rtpPayloadType::isAstFormat, and MAX_RTP_PT.
Referenced by process_sdp().
01647 { 01648 if (pt < 0 || pt > MAX_RTP_PT) 01649 return; /* bogus payload type */ 01650 01651 ast_mutex_lock(&rtp->bridge_lock); 01652 rtp->current_RTP_PT[pt].isAstFormat = 0; 01653 rtp->current_RTP_PT[pt].code = 0; 01654 ast_mutex_unlock(&rtp->bridge_lock); 01655 }
Definition at line 2727 of file rtp.c.
References ast_codec_pref_getsize(), AST_FORMAT_G723_1, AST_FORMAT_SPEEX, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup(), ast_frfree, ast_getformatname(), ast_log(), ast_rtp_lookup_code(), 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_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_DEBUG, LOG_WARNING, ast_frame::offset, option_debug, ast_rtp::pref, ast_rtp::smoother, ast_frame::subclass, and ast_rtp::them.
Referenced by gtalk_write(), mgcp_write(), oh323_write(), sip_write(), and skinny_write().
02728 { 02729 struct ast_frame *f; 02730 int codec; 02731 int hdrlen = 12; 02732 int subclass; 02733 02734 02735 /* If we have no peer, return immediately */ 02736 if (!rtp->them.sin_addr.s_addr) 02737 return 0; 02738 02739 /* If there is no data length, return immediately */ 02740 if (!_f->datalen) 02741 return 0; 02742 02743 /* Make sure we have enough space for RTP header */ 02744 if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) { 02745 ast_log(LOG_WARNING, "RTP can only send voice and video\n"); 02746 return -1; 02747 } 02748 02749 subclass = _f->subclass; 02750 if (_f->frametype == AST_FRAME_VIDEO) 02751 subclass &= ~0x1; 02752 02753 codec = ast_rtp_lookup_code(rtp, 1, subclass); 02754 if (codec < 0) { 02755 ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass)); 02756 return -1; 02757 } 02758 02759 if (rtp->lasttxformat != subclass) { 02760 /* New format, reset the smoother */ 02761 if (option_debug) 02762 ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass)); 02763 rtp->lasttxformat = subclass; 02764 if (rtp->smoother) 02765 ast_smoother_free(rtp->smoother); 02766 rtp->smoother = NULL; 02767 } 02768 02769 if (!rtp->smoother && subclass != AST_FORMAT_SPEEX && subclass != AST_FORMAT_G723_1) { 02770 struct ast_format_list fmt = ast_codec_pref_getsize(&rtp->pref, subclass); 02771 if (fmt.inc_ms) { /* if codec parameters is set / avoid division by zero */ 02772 if (!(rtp->smoother = ast_smoother_new((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms))) { 02773 ast_log(LOG_WARNING, "Unable to create smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms)); 02774 return -1; 02775 } 02776 if (fmt.flags) 02777 ast_smoother_set_flags(rtp->smoother, fmt.flags); 02778 if (option_debug) 02779 ast_log(LOG_DEBUG, "Created smoother: format: %d ms: %d len: %d\n", subclass, fmt.cur_ms, ((fmt.cur_ms * fmt.fr_len) / fmt.inc_ms)); 02780 } 02781 } 02782 if (rtp->smoother) { 02783 if (ast_smoother_test_flag(rtp->smoother, AST_SMOOTHER_FLAG_BE)) { 02784 ast_smoother_feed_be(rtp->smoother, _f); 02785 } else { 02786 ast_smoother_feed(rtp->smoother, _f); 02787 } 02788 02789 while((f = ast_smoother_read(rtp->smoother)) && (f->data)) 02790 ast_rtp_raw_write(rtp, f, codec); 02791 } else { 02792 /* Don't buffer outgoing frames; send them one-per-packet: */ 02793 if (_f->offset < hdrlen) { 02794 f = ast_frdup(_f); 02795 } else { 02796 f = _f; 02797 } 02798 if (f->data) 02799 ast_rtp_raw_write(rtp, f, codec); 02800 if (f != _f) 02801 ast_frfree(f); 02802 } 02803 02804 return 0; 02805 }
static enum ast_bridge_result bridge_native_loop | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
struct ast_rtp * | p0, | |||
struct ast_rtp * | p1, | |||
struct ast_rtp * | vp0, | |||
struct ast_rtp * | vp1, | |||
struct ast_rtp_protocol * | pr0, | |||
struct ast_rtp_protocol * | pr1, | |||
int | codec0, | |||
int | codec1, | |||
int | timeoutms, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
void * | pvt0, | |||
void * | pvt1 | |||
) | [static] |
Bridge loop for true native bridge (reinvite).
Definition at line 2835 of file rtp.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_channel_unlock, ast_check_hangup(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate_data(), ast_inet_ntoa(), ast_log(), ast_read(), ast_rtp_get_peer(), ast_test_flag, ast_waitfor_n(), ast_write(), ast_frame::data, ast_frame::datalen, FLAG_NAT_ACTIVE, ast_frame::frametype, ast_rtp_protocol::get_codec, inaddrcmp(), LOG_DEBUG, LOG_WARNING, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, option_debug, ast_rtp_protocol::set_rtp_peer, ast_channel::spies, ast_frame::subclass, and ast_channel::tech_pvt.
Referenced by ast_rtp_bridge().
02836 { 02837 struct ast_frame *fr = NULL; 02838 struct ast_channel *who = NULL, *other = NULL, *cs[3] = {NULL, }; 02839 int oldcodec0 = codec0, oldcodec1 = codec1; 02840 struct sockaddr_in ac1 = {0,}, vac1 = {0,}, ac0 = {0,}, vac0 = {0,}; 02841 struct sockaddr_in t1 = {0,}, vt1 = {0,}, t0 = {0,}, vt0 = {0,}; 02842 02843 /* Set it up so audio goes directly between the two endpoints */ 02844 02845 /* Test the first channel */ 02846 if (!(pr0->set_rtp_peer(c0, p1, vp1, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE)))) { 02847 ast_rtp_get_peer(p1, &ac1); 02848 if (vp1) 02849 ast_rtp_get_peer(vp1, &vac1); 02850 } else 02851 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name); 02852 02853 /* Test the second channel */ 02854 if (!(pr1->set_rtp_peer(c1, p0, vp0, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE)))) { 02855 ast_rtp_get_peer(p0, &ac0); 02856 if (vp0) 02857 ast_rtp_get_peer(vp0, &vac0); 02858 } else 02859 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c1->name, c0->name); 02860 02861 /* Now we can unlock and move into our loop */ 02862 ast_channel_unlock(c0); 02863 ast_channel_unlock(c1); 02864 02865 /* Throw our channels into the structure and enter the loop */ 02866 cs[0] = c0; 02867 cs[1] = c1; 02868 cs[2] = NULL; 02869 for (;;) { 02870 /* Check if anything changed */ 02871 if ((c0->tech_pvt != pvt0) || 02872 (c1->tech_pvt != pvt1) || 02873 (c0->masq || c0->masqr || c1->masq || c1->masqr) || 02874 (c0->monitor || c0->spies || c1->monitor || c1->spies)) { 02875 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n"); 02876 if (c0->tech_pvt == pvt0) 02877 if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) 02878 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); 02879 if (c1->tech_pvt == pvt1) 02880 if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) 02881 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); 02882 return AST_BRIDGE_RETRY; 02883 } 02884 02885 /* Check if they have changed their address */ 02886 ast_rtp_get_peer(p1, &t1); 02887 if (vp1) 02888 ast_rtp_get_peer(vp1, &vt1); 02889 if (pr1->get_codec) 02890 codec1 = pr1->get_codec(c1); 02891 ast_rtp_get_peer(p0, &t0); 02892 if (vp0) 02893 ast_rtp_get_peer(vp0, &vt0); 02894 if (pr0->get_codec) 02895 codec0 = pr0->get_codec(c0); 02896 if ((inaddrcmp(&t1, &ac1)) || 02897 (vp1 && inaddrcmp(&vt1, &vac1)) || 02898 (codec1 != oldcodec1)) { 02899 if (option_debug > 1) { 02900 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 02901 c1->name, ast_inet_ntoa(t1.sin_addr), ntohs(t1.sin_port), codec1); 02902 ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", 02903 c1->name, ast_inet_ntoa(vt1.sin_addr), ntohs(vt1.sin_port), codec1); 02904 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 02905 c1->name, ast_inet_ntoa(ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1); 02906 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 02907 c1->name, ast_inet_ntoa(vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1); 02908 } 02909 if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE))) 02910 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name); 02911 memcpy(&ac1, &t1, sizeof(ac1)); 02912 memcpy(&vac1, &vt1, sizeof(vac1)); 02913 oldcodec1 = codec1; 02914 } 02915 if ((inaddrcmp(&t0, &ac0)) || 02916 (vp0 && inaddrcmp(&vt0, &vac0))) { 02917 if (option_debug > 1) { 02918 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 02919 c0->name, ast_inet_ntoa(t0.sin_addr), ntohs(t0.sin_port), codec0); 02920 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 02921 c0->name, ast_inet_ntoa(ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0); 02922 } 02923 if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE))) 02924 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name); 02925 memcpy(&ac0, &t0, sizeof(ac0)); 02926 memcpy(&vac0, &vt0, sizeof(vac0)); 02927 oldcodec0 = codec0; 02928 } 02929 02930 /* Wait for frame to come in on the channels */ 02931 if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) { 02932 if (!timeoutms) { 02933 if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) 02934 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); 02935 if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) 02936 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); 02937 return AST_BRIDGE_RETRY; 02938 } 02939 if (option_debug) 02940 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 02941 if (ast_check_hangup(c0) || ast_check_hangup(c1)) 02942 break; 02943 continue; 02944 } 02945 fr = ast_read(who); 02946 other = (who == c0) ? c1 : c0; 02947 if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) && 02948 (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || 02949 ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) { 02950 /* Break out of bridge */ 02951 *fo = fr; 02952 *rc = who; 02953 if (option_debug) 02954 ast_log(LOG_DEBUG, "Oooh, got a %s\n", fr ? "digit" : "hangup"); 02955 if (c0->tech_pvt == pvt0) 02956 if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) 02957 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); 02958 if (c1->tech_pvt == pvt1) 02959 if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) 02960 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); 02961 return AST_BRIDGE_COMPLETE; 02962 } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 02963 if ((fr->subclass == AST_CONTROL_HOLD) || 02964 (fr->subclass == AST_CONTROL_UNHOLD) || 02965 (fr->subclass == AST_CONTROL_VIDUPDATE)) { 02966 if (fr->subclass == AST_CONTROL_HOLD) { 02967 /* If we someone went on hold we want the other side to reinvite back to us */ 02968 if (who == c0) 02969 pr1->set_rtp_peer(c1, NULL, NULL, 0, 0); 02970 else 02971 pr0->set_rtp_peer(c0, NULL, NULL, 0, 0); 02972 } else if (fr->subclass == AST_CONTROL_UNHOLD) { 02973 /* If they went off hold they should go back to being direct */ 02974 if (who == c0) 02975 pr1->set_rtp_peer(c1, p0, vp0, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE)); 02976 else 02977 pr0->set_rtp_peer(c0, p1, vp1, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE)); 02978 } 02979 /* Update local address information */ 02980 ast_rtp_get_peer(p0, &t0); 02981 memcpy(&ac0, &t0, sizeof(ac0)); 02982 ast_rtp_get_peer(p1, &t1); 02983 memcpy(&ac1, &t1, sizeof(ac1)); 02984 /* Update codec information */ 02985 if (pr0->get_codec && c0->tech_pvt) 02986 oldcodec0 = codec0 = pr0->get_codec(c0); 02987 if (pr1->get_codec && c1->tech_pvt) 02988 oldcodec1 = codec1 = pr1->get_codec(c1); 02989 ast_indicate_data(other, fr->subclass, fr->data, fr->datalen); 02990 ast_frfree(fr); 02991 } else { 02992 *fo = fr; 02993 *rc = who; 02994 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name); 02995 return AST_BRIDGE_COMPLETE; 02996 } 02997 } else { 02998 if ((fr->frametype == AST_FRAME_DTMF_BEGIN) || 02999 (fr->frametype == AST_FRAME_DTMF_END) || 03000 (fr->frametype == AST_FRAME_VOICE) || 03001 (fr->frametype == AST_FRAME_VIDEO) || 03002 (fr->frametype == AST_FRAME_IMAGE) || 03003 (fr->frametype == AST_FRAME_HTML) || 03004 (fr->frametype == AST_FRAME_MODEM) || 03005 (fr->frametype == AST_FRAME_TEXT)) { 03006 ast_write(other, fr); 03007 } 03008 ast_frfree(fr); 03009 } 03010 /* Swap priority */ 03011 cs[2] = cs[0]; 03012 cs[0] = cs[1]; 03013 cs[1] = cs[2]; 03014 } 03015 03016 if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) 03017 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); 03018 if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) 03019 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); 03020 03021 return AST_BRIDGE_FAILED; 03022 }
static enum ast_bridge_result bridge_p2p_loop | ( | struct ast_channel * | c0, | |
struct ast_channel * | c1, | |||
struct ast_rtp * | p0, | |||
struct ast_rtp * | p1, | |||
int | timeoutms, | |||
int | flags, | |||
struct ast_frame ** | fo, | |||
struct ast_channel ** | rc, | |||
void * | pvt0, | |||
void * | pvt1 | |||
) | [static] |
Bridge loop for partial native bridge (packet2packet).
Definition at line 3120 of file rtp.c.
References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_channel_unlock, ast_check_hangup(), ast_clear_flag, AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, AST_FRAME_HTML, AST_FRAME_IMAGE, AST_FRAME_MODEM, AST_FRAME_TEXT, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree, ast_indicate_data(), ast_log(), ast_read(), ast_waitfor_n(), ast_write(), ast_frame::data, ast_frame::datalen, FLAG_P2P_SENT_MARK, ast_frame::frametype, LOG_DEBUG, LOG_NOTICE, ast_channel::masq, ast_channel::masqr, ast_channel::monitor, option_debug, p2p_callback_disable(), p2p_callback_enable(), p2p_set_bridge(), ast_channel::spies, ast_frame::subclass, and ast_channel::tech_pvt.
Referenced by ast_rtp_bridge().
03121 { 03122 struct ast_frame *fr = NULL; 03123 struct ast_channel *who = NULL, *other = NULL, *cs[3] = {NULL, }; 03124 int p0_fds[2] = {-1, -1}, p1_fds[2] = {-1, -1}; 03125 int *p0_iod[2] = {NULL, NULL}, *p1_iod[2] = {NULL, NULL}; 03126 int p0_callback = 0, p1_callback = 0; 03127 enum ast_bridge_result res = AST_BRIDGE_FAILED; 03128 03129 /* Okay, setup each RTP structure to do P2P forwarding */ 03130 ast_clear_flag(p0, FLAG_P2P_SENT_MARK); 03131 p2p_set_bridge(p0, p1); 03132 ast_clear_flag(p1, FLAG_P2P_SENT_MARK); 03133 p2p_set_bridge(p1, p0); 03134 03135 /* Activate callback modes if possible */ 03136 p0_callback = p2p_callback_enable(c0, p0, &p0_fds[0], &p0_iod[0]); 03137 p1_callback = p2p_callback_enable(c1, p1, &p1_fds[0], &p1_iod[0]); 03138 03139 /* Now let go of the channel locks and be on our way */ 03140 ast_channel_unlock(c0); 03141 ast_channel_unlock(c1); 03142 03143 /* Go into a loop forwarding frames until we don't need to anymore */ 03144 cs[0] = c0; 03145 cs[1] = c1; 03146 cs[2] = NULL; 03147 for (;;) { 03148 /* Check if anything changed */ 03149 if ((c0->tech_pvt != pvt0) || 03150 (c1->tech_pvt != pvt1) || 03151 (c0->masq || c0->masqr || c1->masq || c1->masqr) || 03152 (c0->monitor || c0->spies || c1->monitor || c1->spies)) { 03153 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n"); 03154 if ((c0->masq || c0->masqr) && (fr = ast_read(c0))) 03155 ast_frfree(fr); 03156 if ((c1->masq || c1->masqr) && (fr = ast_read(c1))) 03157 ast_frfree(fr); 03158 res = AST_BRIDGE_RETRY; 03159 break; 03160 } 03161 /* Wait on a channel to feed us a frame */ 03162 if (!(who = ast_waitfor_n(cs, 2, &timeoutms))) { 03163 if (!timeoutms) { 03164 res = AST_BRIDGE_RETRY; 03165 break; 03166 } 03167 if (option_debug) 03168 ast_log(LOG_NOTICE, "Ooh, empty read...\n"); 03169 if (ast_check_hangup(c0) || ast_check_hangup(c1)) 03170 break; 03171 continue; 03172 } 03173 /* Read in frame from channel */ 03174 fr = ast_read(who); 03175 other = (who == c0) ? c1 : c0; 03176 /* Dependong on the frame we may need to break out of our bridge */ 03177 if (!fr || ((fr->frametype == AST_FRAME_DTMF_BEGIN || fr->frametype == AST_FRAME_DTMF_END) && 03178 ((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) | 03179 ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)))) { 03180 /* Record received frame and who */ 03181 *fo = fr; 03182 *rc = who; 03183 if (option_debug) 03184 ast_log(LOG_DEBUG, "Oooh, got a %s\n", fr ? "digit" : "hangup"); 03185 res = AST_BRIDGE_COMPLETE; 03186 break; 03187 } else if ((fr->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 03188 if ((fr->subclass == AST_CONTROL_HOLD) || 03189 (fr->subclass == AST_CONTROL_UNHOLD) || 03190 (fr->subclass == AST_CONTROL_VIDUPDATE)) { 03191 /* If we are going on hold, then break callback mode and P2P bridging */ 03192 if (fr->subclass == AST_CONTROL_HOLD) { 03193 if (p0_callback) 03194 p0_callback = p2p_callback_disable(c0, p0, &p0_fds[0], &p0_iod[0]); 03195 if (p1_callback) 03196 p1_callback = p2p_callback_disable(c1, p1, &p1_fds[0], &p1_iod[0]); 03197 p2p_set_bridge(p0, NULL); 03198 p2p_set_bridge(p1, NULL); 03199 } else if (fr->subclass == AST_CONTROL_UNHOLD) { 03200 /* If we are off hold, then go back to callback mode and P2P bridging */ 03201 ast_clear_flag(p0, FLAG_P2P_SENT_MARK); 03202 p2p_set_bridge(p0, p1); 03203 ast_clear_flag(p1, FLAG_P2P_SENT_MARK); 03204 p2p_set_bridge(p1, p0); 03205 p0_callback = p2p_callback_enable(c0, p0, &p0_fds[0], &p0_iod[0]); 03206 p1_callback = p2p_callback_enable(c1, p1, &p1_fds[0], &p1_iod[0]); 03207 } 03208 ast_indicate_data(other, fr->subclass, fr->data, fr->datalen); 03209 ast_frfree(fr); 03210 } else { 03211 *fo = fr; 03212 *rc = who; 03213 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", fr->subclass, who->name); 03214 res = AST_BRIDGE_COMPLETE; 03215 break; 03216 } 03217 } else { 03218 if ((fr->frametype == AST_FRAME_DTMF_BEGIN) || 03219 (fr->frametype == AST_FRAME_DTMF_END) || 03220 (fr->frametype == AST_FRAME_VOICE) || 03221 (fr->frametype == AST_FRAME_VIDEO) || 03222 (fr->frametype == AST_FRAME_IMAGE) || 03223 (fr->frametype == AST_FRAME_HTML) || 03224 (fr->frametype == AST_FRAME_MODEM) || 03225 (fr->frametype == AST_FRAME_TEXT)) { 03226 ast_write(other, fr); 03227 } 03228 03229 ast_frfree(fr); 03230 } 03231 /* Swap priority */ 03232 cs[2] = cs[0]; 03233 cs[0] = cs[1]; 03234 cs[1] = cs[2]; 03235 } 03236 03237 /* If we are totally avoiding the core, then restore our link to it */ 03238 if (p0_callback) 03239 p0_callback = p2p_callback_disable(c0, p0, &p0_fds[0], &p0_iod[0]); 03240 if (p1_callback) 03241 p1_callback = p2p_callback_disable(c1, p1, &p1_fds[0], &p1_iod[0]); 03242 03243 /* Break out of the direct bridge */ 03244 p2p_set_bridge(p0, NULL); 03245 p2p_set_bridge(p1, NULL); 03246 03247 return res; 03248 }
static int bridge_p2p_rtp_write | ( | struct ast_rtp * | rtp, | |
struct ast_rtp * | bridged, | |||
unsigned int * | rtpheader, | |||
int | len, | |||
int | hdrlen | |||
) | [static] |
Perform a Packet2Packet RTP write.
Definition at line 1052 of file rtp.c.
References ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_lookup_code(), ast_rtp_lookup_pt(), ast_set_flag, ast_test_flag, ast_verbose(), rtpPayloadType::code, errno, FLAG_NAT_ACTIVE, FLAG_NAT_INACTIVE, FLAG_NAT_INACTIVE_NOWARN, FLAG_P2P_NEED_DTMF, FLAG_P2P_SENT_MARK, rtpPayloadType::isAstFormat, LOG_DEBUG, ast_rtp::nat, option_debug, reconstruct(), rtp_debug_test_addr(), ast_rtp::s, and ast_rtp::them.
Referenced by ast_rtp_read().
01053 { 01054 int res = 0, payload = 0, bridged_payload = 0, mark; 01055 struct rtpPayloadType rtpPT; 01056 int reconstruct = ntohl(rtpheader[0]); 01057 01058 /* Get fields from packet */ 01059 payload = (reconstruct & 0x7f0000) >> 16; 01060 mark = (((reconstruct & 0x800000) >> 23) != 0); 01061 01062 /* Check what the payload value should be */ 01063 rtpPT = ast_rtp_lookup_pt(rtp, payload); 01064 01065 /* If the payload is DTMF, and we are listening for DTMF - then feed it into the core */ 01066 if (ast_test_flag(rtp, FLAG_P2P_NEED_DTMF) && !rtpPT.isAstFormat && rtpPT.code == AST_RTP_DTMF) 01067 return -1; 01068 01069 /* Otherwise adjust bridged payload to match */ 01070 bridged_payload = ast_rtp_lookup_code(bridged, rtpPT.isAstFormat, rtpPT.code); 01071 01072 /* If the mark bit has not been sent yet... do it now */ 01073 if (!ast_test_flag(rtp, FLAG_P2P_SENT_MARK)) { 01074 mark = 1; 01075 ast_set_flag(rtp, FLAG_P2P_SENT_MARK); 01076 } 01077 01078 /* Reconstruct part of the packet */ 01079 reconstruct &= 0xFF80FFFF; 01080 reconstruct |= (bridged_payload << 16); 01081 reconstruct |= (mark << 23); 01082 rtpheader[0] = htonl(reconstruct); 01083 01084 /* Send the packet back out */ 01085 res = sendto(bridged->s, (void *)rtpheader, len, 0, (struct sockaddr *)&bridged->them, sizeof(bridged->them)); 01086 if (res < 0) { 01087 if (!bridged->nat || (bridged->nat && (ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) { 01088 ast_log(LOG_DEBUG, "RTP Transmission error of packet to %s:%d: %s\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), strerror(errno)); 01089 } else if (((ast_test_flag(bridged, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) && !ast_test_flag(bridged, FLAG_NAT_INACTIVE_NOWARN)) { 01090 if (option_debug || rtpdebug) 01091 ast_log(LOG_DEBUG, "RTP NAT: Can't write RTP to private address %s:%d, waiting for other end to send audio...\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port)); 01092 ast_set_flag(bridged, FLAG_NAT_INACTIVE_NOWARN); 01093 } 01094 return 0; 01095 } else if (rtp_debug_test_addr(&bridged->them)) 01096 ast_verbose("Sent RTP P2P packet to %s:%u (type %-2.2d, len %-6.6u)\n", ast_inet_ntoa(bridged->them.sin_addr), ntohs(bridged->them.sin_port), bridged_payload, len - hdrlen); 01097 01098 return 0; 01099 }
static void calc_rxstamp | ( | struct timeval * | tv, | |
struct ast_rtp * | rtp, | |||
unsigned int | timestamp, | |||
int | mark | |||
) | [static] |
Definition at line 1003 of file rtp.c.
References ast_rtp::drxcore, ast_rtcp::maxrxjitter, ast_rtcp::minrxjitter, ast_rtp::rtcp, ast_rtp::rxcore, ast_rtp::rxjitter, ast_rtp::rxtransit, and ast_rtp::seedrxts.
Referenced by ast_rtp_read(), and schedule_delivery().
01004 { 01005 struct timeval now; 01006 double transit; 01007 double current_time; 01008 double d; 01009 double dtv; 01010 double prog; 01011 01012 if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) { 01013 gettimeofday(&rtp->rxcore, NULL); 01014 rtp->drxcore = (double) rtp->rxcore.tv_sec + (double) rtp->rxcore.tv_usec / 1000000; 01015 /* map timestamp to a real time */ 01016 rtp->seedrxts = timestamp; /* Their RTP timestamp started with this */ 01017 rtp->rxcore.tv_sec -= timestamp / 8000; 01018 rtp->rxcore.tv_usec -= (timestamp % 8000) * 125; 01019 /* Round to 0.1ms for nice, pretty timestamps */ 01020 rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 100; 01021 if (rtp->rxcore.tv_usec < 0) { 01022 /* Adjust appropriately if necessary */ 01023 rtp->rxcore.tv_usec += 1000000; 01024 rtp->rxcore.tv_sec -= 1; 01025 } 01026 } 01027 01028 gettimeofday(&now,NULL); 01029 /* rxcore is the mapping between the RTP timestamp and _our_ real time from gettimeofday() */ 01030 tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000; 01031 tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125; 01032 if (tv->tv_usec >= 1000000) { 01033 tv->tv_usec -= 1000000; 01034 tv->tv_sec += 1; 01035 } 01036 prog = (double)((timestamp-rtp->seedrxts)/8000.); 01037 dtv = (double)rtp->drxcore + (double)(prog); 01038 current_time = (double)now.tv_sec + (double)now.tv_usec/1000000; 01039 transit = current_time - dtv; 01040 d = transit - rtp->rxtransit; 01041 rtp->rxtransit = transit; 01042 if (d<0) 01043 d=-d; 01044 rtp->rxjitter += (1./16.) * (d - rtp->rxjitter); 01045 if (rtp->rtcp && rtp->rxjitter > rtp->rtcp->maxrxjitter) 01046 rtp->rtcp->maxrxjitter = rtp->rxjitter; 01047 if (rtp->rtcp && rtp->rxjitter < rtp->rtcp->minrxjitter) 01048 rtp->rtcp->minrxjitter = rtp->rxjitter; 01049 }
static unsigned int calc_txstamp | ( | struct ast_rtp * | rtp, | |
struct timeval * | delivery | |||
) | [static] |
Definition at line 2155 of file rtp.c.
References ast_rtp::txcore.
Referenced by ast_rtp_raw_write().
02156 { 02157 struct timeval t; 02158 long ms; 02159 if (ast_tvzero(rtp->txcore)) { 02160 rtp->txcore = ast_tvnow(); 02161 /* Round to 20ms for nice, pretty timestamps */ 02162 rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000; 02163 } 02164 /* Use previous txcore if available */ 02165 t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow(); 02166 ms = ast_tvdiff_ms(t, rtp->txcore); 02167 if (ms < 0) 02168 ms = 0; 02169 /* Use what we just got for next time */ 02170 rtp->txcore = t; 02171 return (unsigned int) ms; 02172 }
static struct ast_rtp_protocol* get_proto | ( | struct ast_channel * | chan | ) | [static, read] |
Get channel driver interface structure.
Definition at line 1457 of file rtp.c.
References AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, protos, ast_channel::tech, ast_channel_tech::type, and ast_rtp_protocol::type.
Referenced by ast_rtp_bridge(), ast_rtp_early_bridge(), ast_rtp_make_compatible(), and ast_udptl_bridge().
01458 { 01459 struct ast_rtp_protocol *cur = NULL; 01460 01461 AST_LIST_LOCK(&protos); 01462 AST_LIST_TRAVERSE(&protos, cur, list) { 01463 if (cur->type == chan->tech->type) 01464 break; 01465 } 01466 AST_LIST_UNLOCK(&protos); 01467 01468 return cur; 01469 }
static int p2p_callback_disable | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
int * | fds, | |||
int ** | iod | |||
) | [static] |
Helper function to switch a channel and RTP stream out of callback mode.
Definition at line 3091 of file rtp.c.
References ast_channel_lock, ast_channel_unlock, ast_io_add(), AST_IO_IN, ast_io_remove(), ast_test_flag, ast_channel::fds, FLAG_CALLBACK_MODE, ast_rtp::io, ast_rtp::ioid, rtpread(), and ast_rtp::s.
Referenced by bridge_p2p_loop().
03092 { 03093 ast_channel_lock(chan); 03094 03095 /* Remove the callback from the IO context */ 03096 ast_io_remove(rtp->io, iod[0]); 03097 03098 /* Restore file descriptors */ 03099 chan->fds[0] = fds[0]; 03100 ast_channel_unlock(chan); 03101 03102 /* Restore callback mode if previously used */ 03103 if (ast_test_flag(rtp, FLAG_CALLBACK_MODE)) 03104 rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp); 03105 03106 return 0; 03107 }
static int p2p_callback_enable | ( | struct ast_channel * | chan, | |
struct ast_rtp * | rtp, | |||
int * | fds, | |||
int ** | iod | |||
) | [static] |
Helper function that sets what an RTP structure is bridged to.
Definition at line 3110 of file rtp.c.
References ast_mutex_lock(), ast_mutex_unlock(), ast_rtp::bridge_lock, and ast_rtp::bridged.
Referenced by bridge_p2p_loop().
03111 { 03112 ast_mutex_lock(&rtp0->bridge_lock); 03113 rtp0->bridged = rtp1; 03114 ast_mutex_unlock(&rtp0->bridge_lock); 03115 03116 return; 03117 }
static struct ast_frame* process_cisco_dtmf | ( | struct ast_rtp * | rtp, | |
unsigned char * | data, | |||
int | len | |||
) | [static, read] |
Definition at line 669 of file rtp.c.
References AST_FRAME_DTMF_END, ast_log(), ast_rtp::dtmfcount, event, f, LOG_DEBUG, option_debug, ast_rtp::resp, and send_dtmf().
Referenced by ast_rtp_read().
00670 { 00671 unsigned int event; 00672 char resp = 0; 00673 struct ast_frame *f = NULL; 00674 event = ntohl(*((unsigned int *)(data))); 00675 event &= 0x001F; 00676 if (option_debug > 2 || rtpdebug) 00677 ast_log(LOG_DEBUG, "Cisco DTMF Digit: %08x (len = %d)\n", event, len); 00678 if (event < 10) { 00679 resp = '0' + event; 00680 } else if (event < 11) { 00681 resp = '*'; 00682 } else if (event < 12) { 00683 resp = '#'; 00684 } else if (event < 16) { 00685 resp = 'A' + (event - 12); 00686 } else if (event < 17) { 00687 resp = 'X'; 00688 } 00689 if (rtp->resp && (rtp->resp != resp)) { 00690 f = send_dtmf(rtp, AST_FRAME_DTMF_END); 00691 } 00692 rtp->resp = resp; 00693 rtp->dtmfcount = dtmftimeout; 00694 return f; 00695 }
static struct ast_frame* process_rfc2833 | ( | struct ast_rtp * | rtp, | |
unsigned char * | data, | |||
int | len, | |||
unsigned int | seqno, | |||
unsigned int | timestamp | |||
) | [static, read] |
Process RTP DTMF and events according to RFC 2833.
RFC 2833 is "RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals".
rtp | ||
data | ||
len | ||
seqno |
Definition at line 708 of file rtp.c.
References AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_log(), ast_null_frame, ast_test_flag, ast_rtp::dtmfcount, ast_rtp::dtmfsamples, event, f, FLAG_DTMF_COMPENSATE, ast_rtp::lastevent, ast_frame::len, LOG_DEBUG, option_debug, ast_rtp::resp, ast_frame::samples, and send_dtmf().
Referenced by ast_rtp_read().
00709 { 00710 unsigned int event; 00711 unsigned int event_end; 00712 unsigned int samples; 00713 char resp = 0; 00714 struct ast_frame *f = NULL; 00715 00716 /* Figure out event, event end, and samples */ 00717 event = ntohl(*((unsigned int *)(data))); 00718 event >>= 24; 00719 event_end = ntohl(*((unsigned int *)(data))); 00720 event_end <<= 8; 00721 event_end >>= 24; 00722 samples = ntohl(*((unsigned int *)(data))); 00723 samples &= 0xFFFF; 00724 00725 /* Print out debug if turned on */ 00726 if (rtpdebug || option_debug > 2) 00727 ast_log(LOG_DEBUG, "- RTP 2833 Event: %08x (len = %d)\n", event, len); 00728 00729 /* Figure out what digit was pressed */ 00730 if (event < 10) { 00731 resp = '0' + event; 00732 } else if (event < 11) { 00733 resp = '*'; 00734 } else if (event < 12) { 00735 resp = '#'; 00736 } else if (event < 16) { 00737 resp = 'A' + (event - 12); 00738 } else if (event < 17) { /* Event 16: Hook flash */ 00739 resp = 'X'; 00740 } else { 00741 /* Not a supported event */ 00742 ast_log(LOG_DEBUG, "Ignoring RTP 2833 Event: %08x. Not a DTMF Digit.\n", event); 00743 return &ast_null_frame; 00744 } 00745 00746 if (ast_test_flag(rtp, FLAG_DTMF_COMPENSATE)) { 00747 if ((rtp->lastevent != timestamp) || (rtp->resp && rtp->resp != resp)) { 00748 rtp->resp = resp; 00749 f = send_dtmf(rtp, AST_FRAME_DTMF_END); 00750 f->len = 0; 00751 rtp->lastevent = timestamp; 00752 } 00753 } else { 00754 if ((!(rtp->resp) && (!(event_end & 0x80))) || (rtp->resp && rtp->resp != resp)) { 00755 rtp->resp = resp; 00756 f = send_dtmf(rtp, AST_FRAME_DTMF_BEGIN); 00757 } else if ((event_end & 0x80) && (rtp->lastevent != seqno) && rtp->resp) { 00758 f = send_dtmf(rtp, AST_FRAME_DTMF_END); 00759 f->len = ast_tvdiff_ms(ast_samp2tv(samples, 8000), ast_tv(0, 0)); /* XXX hard coded 8kHz */ 00760 rtp->resp = 0; 00761 rtp->lastevent = seqno; 00762 } 00763 } 00764 00765 rtp->dtmfcount = dtmftimeout; 00766 rtp->dtmfsamples = samples; 00767 00768 return f; 00769 }
static struct ast_frame* process_rfc3389 | ( | struct ast_rtp * | rtp, | |
unsigned char * | data, | |||
int | len | |||
) | [static, read] |
Process Comfort Noise RTP.
This is incomplete at the moment.
Definition at line 777 of file rtp.c.
References AST_FRAME_CNG, AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_rtp::f, f, FLAG_3389_WARNING, ast_frame::frametype, ast_rtp::lastrxformat, LOG_DEBUG, LOG_NOTICE, ast_frame::offset, ast_rtp::rawdata, ast_frame::samples, ast_frame::subclass, and ast_rtp::them.
Referenced by ast_rtp_read().
00778 { 00779 struct ast_frame *f = NULL; 00780 /* Convert comfort noise into audio with various codecs. Unfortunately this doesn't 00781 totally help us out becuase we don't have an engine to keep it going and we are not 00782 guaranteed to have it every 20ms or anything */ 00783 if (rtpdebug) 00784 ast_log(LOG_DEBUG, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", rtp->lastrxformat, len); 00785 00786 if (!(ast_test_flag(rtp, FLAG_3389_WARNING))) { 00787 ast_log(LOG_NOTICE, "Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client IP: %s\n", 00788 ast_inet_ntoa(rtp->them.sin_addr)); 00789 ast_set_flag(rtp, FLAG_3389_WARNING); 00790 } 00791 00792 /* Must have at least one byte */ 00793 if (!len) 00794 return NULL; 00795 if (len < 24) { 00796 rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET; 00797 rtp->f.datalen = len - 1; 00798 rtp->f.offset = AST_FRIENDLY_OFFSET; 00799 memcpy(rtp->f.data, data + 1, len - 1); 00800 } else { 00801 rtp->f.data = NULL; 00802 rtp->f.offset = 0; 00803 rtp->f.datalen = 0; 00804 } 00805 rtp->f.frametype = AST_FRAME_CNG; 00806 rtp->f.subclass = data[0] & 0x7f; 00807 rtp->f.datalen = len - 1; 00808 rtp->f.samples = 0; 00809 rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0; 00810 f = &rtp->f; 00811 return f; 00812 }
static int rtcp_debug_test_addr | ( | struct sockaddr_in * | addr | ) | [inline, static] |
Definition at line 655 of file rtp.c.
References rtcpdebugaddr.
Referenced by ast_rtcp_read(), ast_rtcp_write_rr(), ast_rtcp_write_sr(), and ast_rtp_destroy().
00656 { 00657 if (rtcpdebug == 0) 00658 return 0; 00659 if (rtcpdebugaddr.sin_addr.s_addr) { 00660 if (((ntohs(rtcpdebugaddr.sin_port) != 0) 00661 && (rtcpdebugaddr.sin_port != addr->sin_port)) 00662 || (rtcpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 00663 return 0; 00664 } 00665 return 1; 00666 }
static int rtcp_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3515 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, rtcp_do_debug_ip(), and rtcpdebugaddr.
03515 { 03516 if (argc != 2) { 03517 if (argc != 4) 03518 return RESULT_SHOWUSAGE; 03519 return rtcp_do_debug_ip(fd, argc, argv); 03520 } 03521 rtcpdebug = 1; 03522 memset(&rtcpdebugaddr,0,sizeof(rtcpdebugaddr)); 03523 ast_cli(fd, "RTCP Debugging Enabled\n"); 03524 return RESULT_SUCCESS; 03525 }
static int rtcp_do_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3503 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, rtcp_do_debug_ip_deprecated(), and rtcpdebugaddr.
03503 { 03504 if (argc != 3) { 03505 if (argc != 5) 03506 return RESULT_SHOWUSAGE; 03507 return rtcp_do_debug_ip_deprecated(fd, argc, argv); 03508 } 03509 rtcpdebug = 1; 03510 memset(&rtcpdebugaddr,0,sizeof(rtcpdebugaddr)); 03511 ast_cli(fd, "RTCP Debugging Enabled\n"); 03512 return RESULT_SUCCESS; 03513 }
static int rtcp_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3460 of file rtp.c.
References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rtcpdebugaddr.
Referenced by rtcp_do_debug().
03461 { 03462 struct hostent *hp; 03463 struct ast_hostent ahp; 03464 int port = 0; 03465 char *p, *arg; 03466 if (argc != 4) 03467 return RESULT_SHOWUSAGE; 03468 03469 arg = argv[3]; 03470 p = strstr(arg, ":"); 03471 if (p) { 03472 *p = '\0'; 03473 p++; 03474 port = atoi(p); 03475 } 03476 hp = ast_gethostbyname(arg, &ahp); 03477 if (hp == NULL) 03478 return RESULT_SHOWUSAGE; 03479 rtcpdebugaddr.sin_family = AF_INET; 03480 memcpy(&rtcpdebugaddr.sin_addr, hp->h_addr, sizeof(rtcpdebugaddr.sin_addr)); 03481 rtcpdebugaddr.sin_port = htons(port); 03482 if (port == 0) 03483 ast_cli(fd, "RTCP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr)); 03484 else 03485 ast_cli(fd, "RTCP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr), port); 03486 rtcpdebug = 1; 03487 return RESULT_SUCCESS; 03488 }
static int rtcp_do_debug_ip_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3430 of file rtp.c.
References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rtcpdebugaddr.
Referenced by rtcp_do_debug_deprecated().
03431 { 03432 struct hostent *hp; 03433 struct ast_hostent ahp; 03434 int port = 0; 03435 char *p, *arg; 03436 if (argc != 5) 03437 return RESULT_SHOWUSAGE; 03438 03439 arg = argv[4]; 03440 p = strstr(arg, ":"); 03441 if (p) { 03442 *p = '\0'; 03443 p++; 03444 port = atoi(p); 03445 } 03446 hp = ast_gethostbyname(arg, &ahp); 03447 if (hp == NULL) 03448 return RESULT_SHOWUSAGE; 03449 rtcpdebugaddr.sin_family = AF_INET; 03450 memcpy(&rtcpdebugaddr.sin_addr, hp->h_addr, sizeof(rtcpdebugaddr.sin_addr)); 03451 rtcpdebugaddr.sin_port = htons(port); 03452 if (port == 0) 03453 ast_cli(fd, "RTCP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr)); 03454 else 03455 ast_cli(fd, "RTCP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtcpdebugaddr.sin_addr), port); 03456 rtcpdebug = 1; 03457 return RESULT_SUCCESS; 03458 }
static int rtcp_do_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3536 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03536 { 03537 if (argc != 2) { 03538 return RESULT_SHOWUSAGE; 03539 } 03540 rtcpstats = 1; 03541 ast_cli(fd, "RTCP Stats Enabled\n"); 03542 return RESULT_SUCCESS; 03543 }
static int rtcp_do_stats_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3527 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03527 { 03528 if (argc != 3) { 03529 return RESULT_SHOWUSAGE; 03530 } 03531 rtcpstats = 1; 03532 ast_cli(fd, "RTCP Stats Enabled\n"); 03533 return RESULT_SUCCESS; 03534 }
static int rtcp_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3563 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03564 { 03565 if (argc != 3) 03566 return RESULT_SHOWUSAGE; 03567 rtcpdebug = 0; 03568 ast_cli(fd,"RTCP Debugging Disabled\n"); 03569 return RESULT_SUCCESS; 03570 }
static int rtcp_no_debug_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3554 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03555 { 03556 if (argc != 4) 03557 return RESULT_SHOWUSAGE; 03558 rtcpdebug = 0; 03559 ast_cli(fd,"RTCP Debugging Disabled\n"); 03560 return RESULT_SUCCESS; 03561 }
static int rtcp_no_stats | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3581 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03582 { 03583 if (argc != 3) 03584 return RESULT_SHOWUSAGE; 03585 rtcpstats = 0; 03586 ast_cli(fd,"RTCP Stats Disabled\n"); 03587 return RESULT_SUCCESS; 03588 }
static int rtcp_no_stats_deprecated | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3572 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03573 { 03574 if (argc != 4) 03575 return RESULT_SHOWUSAGE; 03576 rtcpstats = 0; 03577 ast_cli(fd,"RTCP Stats Disabled\n"); 03578 return RESULT_SUCCESS; 03579 }
static int rtp_debug_test_addr | ( | struct sockaddr_in * | addr | ) | [inline, static] |
Definition at line 642 of file rtp.c.
References rtpdebugaddr.
Referenced by ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), ast_rtp_senddigit_begin(), ast_rtp_senddigit_continuation(), ast_rtp_senddigit_end(), and bridge_p2p_rtp_write().
00643 { 00644 if (rtpdebug == 0) 00645 return 0; 00646 if (rtpdebugaddr.sin_addr.s_addr) { 00647 if (((ntohs(rtpdebugaddr.sin_port) != 0) 00648 && (rtpdebugaddr.sin_port != addr->sin_port)) 00649 || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 00650 return 0; 00651 } 00652 return 1; 00653 }
static int rtp_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3490 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, rtp_do_debug_ip(), and rtpdebugaddr.
03491 { 03492 if (argc != 2) { 03493 if (argc != 4) 03494 return RESULT_SHOWUSAGE; 03495 return rtp_do_debug_ip(fd, argc, argv); 03496 } 03497 rtpdebug = 1; 03498 memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr)); 03499 ast_cli(fd, "RTP Debugging Enabled\n"); 03500 return RESULT_SUCCESS; 03501 }
static int rtp_do_debug_ip | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3400 of file rtp.c.
References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, and rtpdebugaddr.
Referenced by rtp_do_debug().
03401 { 03402 struct hostent *hp; 03403 struct ast_hostent ahp; 03404 int port = 0; 03405 char *p, *arg; 03406 03407 if (argc != 4) 03408 return RESULT_SHOWUSAGE; 03409 arg = argv[3]; 03410 p = strstr(arg, ":"); 03411 if (p) { 03412 *p = '\0'; 03413 p++; 03414 port = atoi(p); 03415 } 03416 hp = ast_gethostbyname(arg, &ahp); 03417 if (hp == NULL) 03418 return RESULT_SHOWUSAGE; 03419 rtpdebugaddr.sin_family = AF_INET; 03420 memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr)); 03421 rtpdebugaddr.sin_port = htons(port); 03422 if (port == 0) 03423 ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(rtpdebugaddr.sin_addr)); 03424 else 03425 ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(rtpdebugaddr.sin_addr), port); 03426 rtpdebug = 1; 03427 return RESULT_SUCCESS; 03428 }
static int rtp_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3545 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03546 { 03547 if (argc != 3) 03548 return RESULT_SHOWUSAGE; 03549 rtpdebug = 0; 03550 ast_cli(fd,"RTP Debugging Disabled\n"); 03551 return RESULT_SUCCESS; 03552 }
static int rtp_socket | ( | void | ) | [static] |
Definition at line 1833 of file rtp.c.
References s.
Referenced by ast_rtcp_new(), and ast_rtp_new_with_bindaddr().
01834 { 01835 int s; 01836 long flags; 01837 s = socket(AF_INET, SOCK_DGRAM, 0); 01838 if (s > -1) { 01839 flags = fcntl(s, F_GETFL); 01840 fcntl(s, F_SETFL, flags | O_NONBLOCK); 01841 #ifdef SO_NO_CHECK 01842 if (nochecksums) 01843 setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 01844 #endif 01845 } 01846 return s; 01847 }
static int rtpread | ( | int * | id, | |
int | fd, | |||
short | events, | |||
void * | cbdata | |||
) | [static] |
Definition at line 814 of file rtp.c.
References ast_rtp_read(), ast_rtp::callback, ast_rtp::data, and f.
Referenced by ast_rtp_new_with_bindaddr(), and p2p_callback_disable().
00815 { 00816 struct ast_rtp *rtp = cbdata; 00817 struct ast_frame *f; 00818 f = ast_rtp_read(rtp); 00819 if (f) { 00820 if (rtp->callback) 00821 rtp->callback(rtp, f, rtp->data); 00822 } 00823 return 1; 00824 }
static struct ast_frame* send_dtmf | ( | struct ast_rtp * | rtp, | |
enum ast_frame_type | type | |||
) | [static, read] |
Definition at line 615 of file rtp.c.
References AST_CONTROL_FLASH, AST_FRAME_CONTROL, AST_FRAME_DTMF_BEGIN, AST_FRAME_DTMF_END, ast_inet_ntoa(), ast_log(), ast_null_frame, ast_test_flag, ast_frame::datalen, ast_rtp::dtmfmute, ast_rtp::dtmfsamples, ast_rtp::f, FLAG_DTMF_COMPENSATE, ast_frame::frametype, LOG_DEBUG, ast_frame::mallocd, option_debug, ast_rtp::resp, ast_frame::samples, ast_frame::src, ast_frame::subclass, and ast_rtp::them.
Referenced by process_cisco_dtmf(), and process_rfc2833().
00616 { 00617 if (((ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && type == AST_FRAME_DTMF_END) || 00618 (type == AST_FRAME_DTMF_BEGIN)) && ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) { 00619 if (option_debug) 00620 ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(rtp->them.sin_addr)); 00621 rtp->resp = 0; 00622 rtp->dtmfsamples = 0; 00623 return &ast_null_frame; 00624 } 00625 if (option_debug) 00626 ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(rtp->them.sin_addr)); 00627 if (rtp->resp == 'X') { 00628 rtp->f.frametype = AST_FRAME_CONTROL; 00629 rtp->f.subclass = AST_CONTROL_FLASH; 00630 } else { 00631 rtp->f.frametype = type; 00632 rtp->f.subclass = rtp->resp; 00633 } 00634 rtp->f.datalen = 0; 00635 rtp->f.samples = 0; 00636 rtp->f.mallocd = 0; 00637 rtp->f.src = "RTP"; 00638 return &rtp->f; 00639 00640 }
static const char* stun_attr2str | ( | int | msg | ) | [static] |
Definition at line 299 of file rtp.c.
References STUN_CHANGE_REQUEST, STUN_CHANGED_ADDRESS, STUN_ERROR_CODE, STUN_MAPPED_ADDRESS, STUN_MESSAGE_INTEGRITY, STUN_PASSWORD, STUN_REFLECTED_FROM, STUN_RESPONSE_ADDRESS, STUN_SOURCE_ADDRESS, STUN_UNKNOWN_ATTRIBUTES, and STUN_USERNAME.
Referenced by stun_handle_packet(), and stun_process_attr().
00300 { 00301 switch(msg) { 00302 case STUN_MAPPED_ADDRESS: 00303 return "Mapped Address"; 00304 case STUN_RESPONSE_ADDRESS: 00305 return "Response Address"; 00306 case STUN_CHANGE_REQUEST: 00307 return "Change Request"; 00308 case STUN_SOURCE_ADDRESS: 00309 return "Source Address"; 00310 case STUN_CHANGED_ADDRESS: 00311 return "Changed Address"; 00312 case STUN_USERNAME: 00313 return "Username"; 00314 case STUN_PASSWORD: 00315 return "Password"; 00316 case STUN_MESSAGE_INTEGRITY: 00317 return "Message Integrity"; 00318 case STUN_ERROR_CODE: 00319 return "Error Code"; 00320 case STUN_UNKNOWN_ATTRIBUTES: 00321 return "Unknown Attributes"; 00322 case STUN_REFLECTED_FROM: 00323 return "Reflected From"; 00324 } 00325 return "Non-RFC3489 Attribute"; 00326 }
static int stun_do_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3590 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03591 { 03592 if (argc != 2) { 03593 return RESULT_SHOWUSAGE; 03594 } 03595 stundebug = 1; 03596 ast_cli(fd, "STUN Debugging Enabled\n"); 03597 return RESULT_SUCCESS; 03598 }
static int stun_handle_packet | ( | int | s, | |
struct sockaddr_in * | src, | |||
unsigned char * | data, | |||
size_t | len | |||
) | [static] |
Definition at line 423 of file rtp.c.
References append_attr_address(), append_attr_string(), ast_log(), ast_verbose(), stun_attr::attr, stun_header::id, stun_header::ies, stun_attr::len, LOG_DEBUG, stun_header::msglen, stun_header::msgtype, option_debug, STUN_ACCEPT, stun_attr2str(), STUN_BINDREQ, STUN_BINDRESP, STUN_IGNORE, STUN_MAPPED_ADDRESS, stun_msg2str(), stun_process_attr(), stun_send(), STUN_USERNAME, and stun_state::username.
Referenced by ast_rtp_read().
00424 { 00425 struct stun_header *resp, *hdr = (struct stun_header *)data; 00426 struct stun_attr *attr; 00427 struct stun_state st; 00428 int ret = STUN_IGNORE; 00429 unsigned char respdata[1024]; 00430 int resplen, respleft; 00431 00432 if (len < sizeof(struct stun_header)) { 00433 if (option_debug) 00434 ast_log(LOG_DEBUG, "Runt STUN packet (only %zd, wanting at least %zd)\n", len, sizeof(struct stun_header)); 00435 return -1; 00436 } 00437 if (stundebug) 00438 ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), ntohs(hdr->msglen)); 00439 if (ntohs(hdr->msglen) > len - sizeof(struct stun_header)) { 00440 if (option_debug) 00441 ast_log(LOG_DEBUG, "Scrambled STUN packet length (got %d, expecting %zd)\n", ntohs(hdr->msglen), len - sizeof(struct stun_header)); 00442 } else 00443 len = ntohs(hdr->msglen); 00444 data += sizeof(struct stun_header); 00445 memset(&st, 0, sizeof(st)); 00446 while(len) { 00447 if (len < sizeof(struct stun_attr)) { 00448 if (option_debug) 00449 ast_log(LOG_DEBUG, "Runt Attribute (got %zd, expecting %zd)\n", len, sizeof(struct stun_attr)); 00450 break; 00451 } 00452 attr = (struct stun_attr *)data; 00453 if ((ntohs(attr->len) + sizeof(struct stun_attr)) > len) { 00454 if (option_debug) 00455 ast_log(LOG_DEBUG, "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n", (int) (ntohs(attr->len) + sizeof(struct stun_attr)), (int) len); 00456 break; 00457 } 00458 if (stun_process_attr(&st, attr)) { 00459 if (option_debug) 00460 ast_log(LOG_DEBUG, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr)); 00461 break; 00462 } 00463 /* Clear attribute in case previous entry was a string */ 00464 attr->attr = 0; 00465 data += ntohs(attr->len) + sizeof(struct stun_attr); 00466 len -= ntohs(attr->len) + sizeof(struct stun_attr); 00467 } 00468 /* Null terminate any string */ 00469 *data = '\0'; 00470 resp = (struct stun_header *)respdata; 00471 resplen = 0; 00472 respleft = sizeof(respdata) - sizeof(struct stun_header); 00473 resp->id = hdr->id; 00474 resp->msgtype = 0; 00475 resp->msglen = 0; 00476 attr = (struct stun_attr *)resp->ies; 00477 if (!len) { 00478 switch(ntohs(hdr->msgtype)) { 00479 case STUN_BINDREQ: 00480 if (stundebug) 00481 ast_verbose("STUN Bind Request, username: %s\n", 00482 st.username ? st.username : "<none>"); 00483 if (st.username) 00484 append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, &respleft); 00485 append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft); 00486 resp->msglen = htons(resplen); 00487 resp->msgtype = htons(STUN_BINDRESP); 00488 stun_send(s, src, resp); 00489 ret = STUN_ACCEPT; 00490 break; 00491 default: 00492 if (stundebug) 00493 ast_verbose("Dunno what to do with STUN message %04x (%s)\n", ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype))); 00494 } 00495 } 00496 return ret; 00497 }
static const char* stun_msg2str | ( | int | msg | ) | [static] |
Definition at line 280 of file rtp.c.
References STUN_BINDERR, STUN_BINDREQ, STUN_BINDRESP, STUN_SECERR, STUN_SECREQ, and STUN_SECRESP.
Referenced by stun_handle_packet().
00281 { 00282 switch(msg) { 00283 case STUN_BINDREQ: 00284 return "Binding Request"; 00285 case STUN_BINDRESP: 00286 return "Binding Response"; 00287 case STUN_BINDERR: 00288 return "Binding Error Response"; 00289 case STUN_SECREQ: 00290 return "Shared Secret Request"; 00291 case STUN_SECRESP: 00292 return "Shared Secret Response"; 00293 case STUN_SECERR: 00294 return "Shared Secret Error Response"; 00295 } 00296 return "Non-RFC3489 Message"; 00297 }
static int stun_no_debug | ( | int | fd, | |
int | argc, | |||
char * | argv[] | |||
) | [static] |
Definition at line 3600 of file rtp.c.
References ast_cli(), RESULT_SHOWUSAGE, and RESULT_SUCCESS.
03601 { 03602 if (argc != 3) 03603 return RESULT_SHOWUSAGE; 03604 stundebug = 0; 03605 ast_cli(fd, "STUN Debugging Disabled\n"); 03606 return RESULT_SUCCESS; 03607 }
static int stun_process_attr | ( | struct stun_state * | state, | |
struct stun_attr * | attr | |||
) | [static] |
Definition at line 333 of file rtp.c.
References ast_verbose(), stun_attr::attr, stun_attr::len, stun_state::password, stun_attr2str(), STUN_PASSWORD, STUN_USERNAME, stun_state::username, and stun_attr::value.
Referenced by stun_handle_packet().
00334 { 00335 if (stundebug) 00336 ast_verbose("Found STUN Attribute %s (%04x), length %d\n", 00337 stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len)); 00338 switch(ntohs(attr->attr)) { 00339 case STUN_USERNAME: 00340 state->username = (const char *) (attr->value); 00341 break; 00342 case STUN_PASSWORD: 00343 state->password = (const char *) (attr->value); 00344 break; 00345 default: 00346 if (stundebug) 00347 ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n", 00348 stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len)); 00349 } 00350 return 0; 00351 }
static void stun_req_id | ( | struct stun_header * | req | ) | [static] |
Definition at line 390 of file rtp.c.
References ast_random(), and stun_header::id.
Referenced by ast_rtp_stun_request().
00391 { 00392 int x; 00393 for (x=0;x<4;x++) 00394 req->id.id[x] = ast_random(); 00395 }
static int stun_send | ( | int | s, | |
struct sockaddr_in * | dst, | |||
struct stun_header * | resp | |||
) | [static] |
Definition at line 384 of file rtp.c.
References stun_header::msglen.
Referenced by ast_rtp_stun_request(), and stun_handle_packet().
00385 { 00386 return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0, 00387 (struct sockaddr *)dst, sizeof(*dst)); 00388 }
static void timeval2ntp | ( | struct timeval | tv, | |
unsigned int * | msw, | |||
unsigned int * | lsw | |||
) | [static] |
Definition at line 502 of file rtp.c.
Referenced by ast_rtcp_read(), and ast_rtcp_write_sr().
00503 { 00504 unsigned int sec, usec, frac; 00505 sec = tv.tv_sec + 2208988800u; /* Sec between 1900 and 1970 */ 00506 usec = tv.tv_usec; 00507 frac = (usec << 12) + (usec << 8) - ((usec * 3650) >> 6); 00508 *msw = sec; 00509 *lsw = frac; 00510 }
struct ast_cli_entry cli_rtp[] [static] |
struct ast_cli_entry cli_rtp_no_debug_deprecated [static] |
Initial value:
{ { "rtp", "no", "debug", NULL }, rtp_no_debug, NULL, NULL }
struct ast_cli_entry cli_rtp_rtcp_debug_deprecated [static] |
Initial value:
{ { "rtp", "rtcp", "debug", NULL }, rtcp_do_debug_deprecated, NULL, NULL }
struct ast_cli_entry cli_rtp_rtcp_debug_ip_deprecated [static] |
Initial value:
{ { "rtp", "rtcp", "debug", "ip", NULL }, rtcp_do_debug_deprecated, NULL, NULL }
struct ast_cli_entry cli_rtp_rtcp_no_debug_deprecated [static] |
Initial value:
{ { "rtp", "rtcp", "no", "debug", NULL }, rtcp_no_debug_deprecated, NULL, NULL }
struct ast_cli_entry cli_rtp_rtcp_no_stats_deprecated [static] |
Initial value:
{ { "rtp", "rtcp", "no", "stats", NULL }, rtcp_no_stats_deprecated, NULL, NULL }
struct ast_cli_entry cli_rtp_rtcp_stats_deprecated [static] |
Initial value:
{ { "rtp", "rtcp", "stats", NULL }, rtcp_do_stats_deprecated, NULL, NULL }
struct ast_cli_entry cli_stun_no_debug_deprecated [static] |
Initial value:
{ { "stun", "no", "debug", NULL }, stun_no_debug, NULL, NULL }
char debug_usage[] [static] |
int dtmftimeout = DEFAULT_DTMF_TIMEOUT [static] |
struct { ... } mimeTypes[] [static] |
Referenced by ast_rtp_lookup_mime_subtype(), and ast_rtp_set_rtpmap_type().
char no_debug_usage[] [static] |
Referenced by get_unaligned_uint16(), get_unaligned_uint32(), put_unaligned_uint16(), and put_unaligned_uint32().
struct rtpPayloadType payloadType |
Definition at line 1331 of file rtp.c.
Referenced by ast_rtp_lookup_mime_subtype(), and ast_rtp_set_rtpmap_type().
char rtcp_debug_usage[] [static] |
char rtcp_no_debug_usage[] [static] |
char rtcp_no_stats_usage[] [static] |
char rtcp_stats_usage[] [static] |
struct sockaddr_in rtcpdebugaddr [static] |
Debug RTCP packets to/from this host
Definition at line 88 of file rtp.c.
Referenced by rtcp_debug_test_addr(), rtcp_do_debug(), rtcp_do_debug_deprecated(), rtcp_do_debug_ip(), and rtcp_do_debug_ip_deprecated().
int rtcpinterval = RTCP_DEFAULT_INTERVALMS [static] |
struct sockaddr_in rtpdebugaddr [static] |
Debug packets to/from this host
Definition at line 87 of file rtp.c.
Referenced by rtp_debug_test_addr(), rtp_do_debug(), and rtp_do_debug_ip().
int rtpend [static] |
int rtpstart [static] |
struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] [static] |
char stun_debug_usage[] [static] |
char stun_no_debug_usage[] [static] |
char* subtype |
char* type |
Definition at line 1332 of file rtp.c.
Referenced by _build_port_config(), _fill_defaults(), _free_port_cfg(), acf_channel_read(), aji_handle_presence(), ast_rtp_set_rtpmap_type(), ast_writestream(), build_connect(), build_setup(), check_header(), find_subscription_type(), g723_len(), load_module(), misdn_cfg_get(), misdn_cfg_get_config_string(), parse_information(), parse_setup(), sla_load_config(), subscription_type2str(), and yyparse().