#include <netinet/in.h>
#include "asterisk/frame.h"
#include "asterisk/io.h"
#include "asterisk/sched.h"
#include "asterisk/channel.h"
#include "asterisk/linkedlists.h"
Include dependency graph for rtp.h:

This graph shows which files directly or indirectly include this file:

Go to the source code of this file.
Data Structures | |
| struct | ast_rtp_protocol |
| struct | ast_rtp_quality |
Defines | |
| #define | AST_RTP_CISCO_DTMF (1 << 2) |
| #define | AST_RTP_CN (1 << 1) |
| #define | AST_RTP_DTMF (1 << 0) |
| #define | AST_RTP_MAX AST_RTP_CISCO_DTMF |
| #define | FLAG_3389_WARNING (1 << 0) |
| #define | MAX_RTP_PT 256 |
Typedefs | |
| typedef int(*) | ast_rtp_callback (struct ast_rtp *rtp, struct ast_frame *f, void *data) |
Enumerations | |
| enum | ast_rtp_get_result { AST_RTP_GET_FAILED = 0, AST_RTP_TRY_PARTIAL, AST_RTP_TRY_NATIVE } |
| enum | ast_rtp_options { AST_RTP_OPT_G726_NONSTANDARD = (1 << 0) } |
Functions | |
| int | ast_rtcp_fd (struct ast_rtp *rtp) |
| ast_frame * | ast_rtcp_read (struct ast_rtp *rtp) |
| int | ast_rtcp_send_h261fur (void *data) |
| Send an H.261 fast update request. Some devices need this rather than the XML message in SIP. | |
| size_t | ast_rtp_alloc_size (void) |
| Get the amount of space required to hold an RTP session. | |
| int | 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) |
| 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) |
| 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, int isAstFormat, 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 (int isAstFormat, int code, enum ast_rtp_options options) |
| Mapping an Asterisk code into a MIME subtype (string):. | |
| 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) |
| 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. | |
| void | ast_rtp_new_source (struct ast_rtp *rtp) |
| ast_rtp * | ast_rtp_new_with_bindaddr (struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr in) |
| 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. | |
| 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. | |
| int | ast_rtp_senddigit_end (struct ast_rtp *rtp, char digit) |
| 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) |
| Activate payload type. | |
| 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) |
| Initiate payload type to a known MIME media type for a codec. | |
| 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) |
| clear payload type | |
| int | ast_rtp_write (struct ast_rtp *rtp, struct ast_frame *f) |
RTP is defined in RFC 3550.
Definition in file rtp.h.
| #define AST_RTP_CISCO_DTMF (1 << 2) |
| #define AST_RTP_CN (1 << 1) |
'Comfort Noise' (RFC3389)
Definition at line 45 of file rtp.h.
Referenced by ast_rtp_read(), and ast_rtp_sendcng().
| #define AST_RTP_DTMF (1 << 0) |
DTMF (RFC2833)
Definition at line 43 of file rtp.h.
Referenced by add_noncodec_to_sdp(), ast_rtp_read(), ast_rtp_senddigit_begin(), bridge_p2p_rtp_write(), check_user_full(), create_addr(), create_addr_from_peer(), oh323_alloc(), oh323_request(), process_sdp(), sip_alloc(), and sip_dtmfmode().
| #define AST_RTP_MAX AST_RTP_CISCO_DTMF |
Maximum RTP-specific code
Definition at line 49 of file rtp.h.
Referenced by add_sdp(), and ast_rtp_lookup_mime_multiple().
| #define MAX_RTP_PT 256 |
Definition at line 51 of file rtp.h.
Referenced by ast_rtp_get_current_formats(), ast_rtp_lookup_code(), ast_rtp_lookup_pt(), ast_rtp_pt_clear(), ast_rtp_pt_copy(), ast_rtp_pt_default(), ast_rtp_set_m_type(), ast_rtp_set_rtpmap_type(), ast_rtp_unset_m_type(), and process_sdp().
| typedef int(*) ast_rtp_callback(struct ast_rtp *rtp, struct ast_frame *f, void *data) |
| enum ast_rtp_get_result |
Definition at line 57 of file rtp.h.
00057 { 00058 /*! Failed to find the RTP structure */ 00059 AST_RTP_GET_FAILED = 0, 00060 /*! RTP structure exists but true native bridge can not occur so try partial */ 00061 AST_RTP_TRY_PARTIAL, 00062 /*! RTP structure exists and native bridge can occur */ 00063 AST_RTP_TRY_NATIVE, 00064 };
| enum ast_rtp_options |
| int ast_rtcp_fd | ( | struct ast_rtp * | rtp | ) |
Definition at line 518 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().
Definition at line 827 of file rtp.c.
References ast_rtcp::accumulated_transit, ast_assert, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_null_frame, ast_verbose(), 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().
00828 { 00829 socklen_t len; 00830 int position, i, packetwords; 00831 int res; 00832 struct sockaddr_in sin; 00833 unsigned int rtcpdata[8192 + AST_FRIENDLY_OFFSET]; 00834 unsigned int *rtcpheader; 00835 int pt; 00836 struct timeval now; 00837 unsigned int length; 00838 int rc; 00839 double rttsec; 00840 uint64_t rtt = 0; 00841 unsigned int dlsr; 00842 unsigned int lsr; 00843 unsigned int msw; 00844 unsigned int lsw; 00845 unsigned int comp; 00846 struct ast_frame *f = &ast_null_frame; 00847 00848 if (!rtp || !rtp->rtcp) 00849 return &ast_null_frame; 00850 00851 len = sizeof(sin); 00852 00853 res = recvfrom(rtp->rtcp->s, rtcpdata + AST_FRIENDLY_OFFSET, sizeof(rtcpdata) - sizeof(unsigned int) * AST_FRIENDLY_OFFSET, 00854 0, (struct sockaddr *)&sin, &len); 00855 rtcpheader = (unsigned int *)(rtcpdata + AST_FRIENDLY_OFFSET); 00856 00857 if (res < 0) { 00858 ast_assert(errno != EBADF); 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 | ) |
Send an H.261 fast update request. Some devices need this rather than the XML message in SIP.
Definition at line 2347 of file rtp.c.
References ast_rtcp_write(), ast_rtp::rtcp, and ast_rtcp::sendfur.
02348 { 02349 struct ast_rtp *rtp = data; 02350 int res; 02351 02352 rtp->rtcp->sendfur = 1; 02353 res = ast_rtcp_write(data); 02354 02355 return res; 02356 }
| size_t ast_rtp_alloc_size | ( | void | ) |
Get the amount of space required to hold an RTP session.
Definition at line 398 of file rtp.c.
Referenced by process_sdp().
00399 { 00400 return sizeof(struct ast_rtp); 00401 }
| int 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 3285 of file rtp.c.
References AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, ast_channel_lock, ast_channel_trylock, ast_channel_unlock, ast_check_hangup(), 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_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_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.
03286 { 03287 struct ast_rtp *p0 = NULL, *p1 = NULL; /* Audio RTP Channels */ 03288 struct ast_rtp *vp0 = NULL, *vp1 = NULL; /* Video RTP channels */ 03289 struct ast_rtp_protocol *pr0 = NULL, *pr1 = NULL; 03290 enum ast_rtp_get_result audio_p0_res = AST_RTP_GET_FAILED, video_p0_res = AST_RTP_GET_FAILED; 03291 enum ast_rtp_get_result audio_p1_res = AST_RTP_GET_FAILED, video_p1_res = AST_RTP_GET_FAILED; 03292 enum ast_bridge_result res = AST_BRIDGE_FAILED; 03293 int codec0 = 0, codec1 = 0; 03294 void *pvt0 = NULL, *pvt1 = NULL; 03295 03296 /* Lock channels */ 03297 ast_channel_lock(c0); 03298 while(ast_channel_trylock(c1)) { 03299 ast_channel_unlock(c0); 03300 usleep(1); 03301 ast_channel_lock(c0); 03302 } 03303 03304 /* Ensure neither channel got hungup during lock avoidance */ 03305 if (ast_check_hangup(c0) || ast_check_hangup(c1)) { 03306 ast_log(LOG_WARNING, "Got hangup while attempting to bridge '%s' and '%s'\n", c0->name, c1->name); 03307 ast_channel_unlock(c0); 03308 ast_channel_unlock(c1); 03309 return AST_BRIDGE_FAILED; 03310 } 03311 03312 /* Find channel driver interfaces */ 03313 if (!(pr0 = get_proto(c0))) { 03314 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name); 03315 ast_channel_unlock(c0); 03316 ast_channel_unlock(c1); 03317 return AST_BRIDGE_FAILED; 03318 } 03319 if (!(pr1 = get_proto(c1))) { 03320 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name); 03321 ast_channel_unlock(c0); 03322 ast_channel_unlock(c1); 03323 return AST_BRIDGE_FAILED; 03324 } 03325 03326 /* Get channel specific interface structures */ 03327 pvt0 = c0->tech_pvt; 03328 pvt1 = c1->tech_pvt; 03329 03330 /* Get audio and video interface (if native bridge is possible) */ 03331 audio_p0_res = pr0->get_rtp_info(c0, &p0); 03332 video_p0_res = pr0->get_vrtp_info ? pr0->get_vrtp_info(c0, &vp0) : AST_RTP_GET_FAILED; 03333 audio_p1_res = pr1->get_rtp_info(c1, &p1); 03334 video_p1_res = pr1->get_vrtp_info ? pr1->get_vrtp_info(c1, &vp1) : AST_RTP_GET_FAILED; 03335 03336 /* If we are carrying video, and both sides are not reinviting... then fail the native bridge */ 03337 if (video_p0_res != AST_RTP_GET_FAILED && (audio_p0_res != AST_RTP_TRY_NATIVE || video_p0_res != AST_RTP_TRY_NATIVE)) 03338 audio_p0_res = AST_RTP_GET_FAILED; 03339 if (video_p1_res != AST_RTP_GET_FAILED && (audio_p1_res != AST_RTP_TRY_NATIVE || video_p1_res != AST_RTP_TRY_NATIVE)) 03340 audio_p1_res = AST_RTP_GET_FAILED; 03341 03342 /* Check if a bridge is possible (partial/native) */ 03343 if (audio_p0_res == AST_RTP_GET_FAILED || audio_p1_res == AST_RTP_GET_FAILED) { 03344 /* Somebody doesn't want to play... */ 03345 ast_channel_unlock(c0); 03346 ast_channel_unlock(c1); 03347 return AST_BRIDGE_FAILED_NOWARN; 03348 } 03349 03350 /* If we need to feed DTMF frames into the core then only do a partial native bridge */ 03351 if (ast_test_flag(p0, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) { 03352 ast_set_flag(p0, FLAG_P2P_NEED_DTMF); 03353 audio_p0_res = AST_RTP_TRY_PARTIAL; 03354 } 03355 03356 if (ast_test_flag(p1, FLAG_HAS_DTMF) && (flags & AST_BRIDGE_DTMF_CHANNEL_1)) { 03357 ast_set_flag(p1, FLAG_P2P_NEED_DTMF); 03358 audio_p1_res = AST_RTP_TRY_PARTIAL; 03359 } 03360 03361 /* If both sides are not using the same method of DTMF transmission 03362 * (ie: one is RFC2833, other is INFO... then we can not do direct media. 03363 * -------------------------------------------------- 03364 * | DTMF Mode | HAS_DTMF | Accepts Begin Frames | 03365 * |-----------|------------|-----------------------| 03366 * | Inband | False | True | 03367 * | RFC2833 | True | True | 03368 * | SIP INFO | False | False | 03369 * -------------------------------------------------- 03370 * However, if DTMF from both channels is being monitored by the core, then 03371 * we can still do packet-to-packet bridging, because passing through the 03372 * core will handle DTMF mode translation. 03373 */ 03374 if ( (ast_test_flag(p0, FLAG_HAS_DTMF) != ast_test_flag(p1, FLAG_HAS_DTMF)) || 03375 (!c0->tech->send_digit_begin != !c1->tech->send_digit_begin)) { 03376 if (!ast_test_flag(p0, FLAG_P2P_NEED_DTMF) || !ast_test_flag(p1, FLAG_P2P_NEED_DTMF)) { 03377 ast_channel_unlock(c0); 03378 ast_channel_unlock(c1); 03379 return AST_BRIDGE_FAILED_NOWARN; 03380 } 03381 audio_p0_res = AST_RTP_TRY_PARTIAL; 03382 audio_p1_res = AST_RTP_TRY_PARTIAL; 03383 } 03384 03385 /* If we need to feed frames into the core don't do a P2P bridge */ 03386 if ((audio_p0_res == AST_RTP_TRY_PARTIAL && ast_test_flag(p0, FLAG_P2P_NEED_DTMF)) || 03387 (audio_p1_res == AST_RTP_TRY_PARTIAL && ast_test_flag(p1, FLAG_P2P_NEED_DTMF))) { 03388 ast_channel_unlock(c0); 03389 ast_channel_unlock(c1); 03390 return AST_BRIDGE_FAILED_NOWARN; 03391 } 03392 03393 /* Get codecs from both sides */ 03394 codec0 = pr0->get_codec ? pr0->get_codec(c0) : 0; 03395 codec1 = pr1->get_codec ? pr1->get_codec(c1) : 0; 03396 if (codec0 && codec1 && !(codec0 & codec1)) { 03397 /* Hey, we can't do native bridging if both parties speak different codecs */ 03398 if (option_debug) 03399 ast_log(LOG_DEBUG, "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", codec0, codec1); 03400 ast_channel_unlock(c0); 03401 ast_channel_unlock(c1); 03402 return AST_BRIDGE_FAILED_NOWARN; 03403 } 03404 03405 /* If either side can only do a partial bridge, then don't try for a true native bridge */ 03406 if (audio_p0_res == AST_RTP_TRY_PARTIAL || audio_p1_res == AST_RTP_TRY_PARTIAL) { 03407 struct ast_format_list fmt0, fmt1; 03408 03409 /* In order to do Packet2Packet bridging both sides must be in the same rawread/rawwrite */ 03410 if (c0->rawreadformat != c1->rawwriteformat || c1->rawreadformat != c0->rawwriteformat) { 03411 if (option_debug) 03412 ast_log(LOG_DEBUG, "Cannot packet2packet bridge - raw formats are incompatible\n"); 03413 ast_channel_unlock(c0); 03414 ast_channel_unlock(c1); 03415 return AST_BRIDGE_FAILED_NOWARN; 03416 } 03417 /* They must also be using the same packetization */ 03418 fmt0 = ast_codec_pref_getsize(&p0->pref, c0->rawreadformat); 03419 fmt1 = ast_codec_pref_getsize(&p1->pref, c1->rawreadformat); 03420 if (fmt0.cur_ms != fmt1.cur_ms) { 03421 if (option_debug) 03422 ast_log(LOG_DEBUG, "Cannot packet2packet bridge - packetization settings prevent it\n"); 03423 ast_channel_unlock(c0); 03424 ast_channel_unlock(c1); 03425 return AST_BRIDGE_FAILED_NOWARN; 03426 } 03427 03428 if (option_verbose > 2) 03429 ast_verbose(VERBOSE_PREFIX_3 "Packet2Packet bridging %s and %s\n", c0->name, c1->name); 03430 res = bridge_p2p_loop(c0, c1, p0, p1, timeoutms, flags, fo, rc, pvt0, pvt1); 03431 } else { 03432 if (option_verbose > 2) 03433 ast_verbose(VERBOSE_PREFIX_3 "Native bridging %s and %s\n", c0->name, c1->name); 03434 res = bridge_native_loop(c0, c1, p0, p1, vp0, vp1, pr0, pr1, codec0, codec1, timeoutms, flags, fo, rc, pvt0, pvt1); 03435 } 03436 03437 return res; 03438 }
| int ast_rtp_codec_getformat | ( | int | pt | ) |
Definition at line 2729 of file rtp.c.
References rtpPayloadType::code, and static_RTP_PT.
Referenced by process_sdp().
02730 { 02731 if (pt < 0 || pt > MAX_RTP_PT) 02732 return 0; /* bogus payload type */ 02733 02734 if (static_RTP_PT[pt].isAstFormat) 02735 return static_RTP_PT[pt].code; 02736 else 02737 return 0; 02738 }
| struct ast_codec_pref* ast_rtp_codec_getpref | ( | struct ast_rtp * | rtp | ) |
Definition at line 2724 of file rtp.c.
References ast_rtp::pref.
Referenced by add_codec_to_sdp(), and process_sdp().
02725 { 02726 return &rtp->pref; 02727 }
| int ast_rtp_codec_setpref | ( | struct ast_rtp * | rtp, | |
| struct ast_codec_pref * | prefs | |||
| ) |
Definition at line 2711 of file rtp.c.
References ast_smoother_free(), ast_codec_pref::framing, ast_codec_pref::order, ast_rtp::pref, prefs, and ast_rtp::smoother.
Referenced by __oh323_rtp_create(), check_user_full(), create_addr_from_peer(), process_sdp(), register_verify(), set_peer_capabilities(), sip_alloc(), start_rtp(), and transmit_response_with_sdp().
02712 { 02713 int x; 02714 for (x = 0; x < 32; x++) { /* Ugly way */ 02715 rtp->pref.order[x] = prefs->order[x]; 02716 rtp->pref.framing[x] = prefs->framing[x]; 02717 } 02718 if (rtp->smoother) 02719 ast_smoother_free(rtp->smoother); 02720 rtp->smoother = NULL; 02721 return 0; 02722 }
| void ast_rtp_destroy | ( | struct ast_rtp * | rtp | ) |
Definition at line 2130 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().
02131 { 02132 if (rtcp_debug_test_addr(&rtp->them) || rtcpstats) { 02133 /*Print some info on the call here */ 02134 ast_verbose(" RTP-stats\n"); 02135 ast_verbose("* Our Receiver:\n"); 02136 ast_verbose(" SSRC: %u\n", rtp->themssrc); 02137 ast_verbose(" Received packets: %u\n", rtp->rxcount); 02138 ast_verbose(" Lost packets: %u\n", rtp->rtcp->expected_prior - rtp->rtcp->received_prior); 02139 ast_verbose(" Jitter: %.4f\n", rtp->rxjitter); 02140 ast_verbose(" Transit: %.4f\n", rtp->rxtransit); 02141 ast_verbose(" RR-count: %u\n", rtp->rtcp->rr_count); 02142 ast_verbose("* Our Sender:\n"); 02143 ast_verbose(" SSRC: %u\n", rtp->ssrc); 02144 ast_verbose(" Sent packets: %u\n", rtp->txcount); 02145 ast_verbose(" Lost packets: %u\n", rtp->rtcp->reported_lost); 02146 ast_verbose(" Jitter: %u\n", rtp->rtcp->reported_jitter / (unsigned int)65536.0); 02147 ast_verbose(" SR-count: %u\n", rtp->rtcp->sr_count); 02148 ast_verbose(" RTT: %f\n", rtp->rtcp->rtt); 02149 } 02150 02151 if (rtp->smoother) 02152 ast_smoother_free(rtp->smoother); 02153 if (rtp->ioid) 02154 ast_io_remove(rtp->io, rtp->ioid); 02155 if (rtp->s > -1) 02156 close(rtp->s); 02157 if (rtp->rtcp) { 02158 AST_SCHED_DEL(rtp->sched, rtp->rtcp->schedid); 02159 close(rtp->rtcp->s); 02160 free(rtp->rtcp); 02161 rtp->rtcp=NULL; 02162 } 02163 02164 ast_mutex_destroy(&rtp->bridge_lock); 02165 02166 free(rtp); 02167 }
| int ast_rtp_early_bridge | ( | struct ast_channel * | dest, | |
| struct ast_channel * | src | |||
| ) |