#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.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"
Include dependency graph for rtp.c:
Go to the source code of this file.
Defines | |
#define | DEFAULT_DTMF_TIMEOUT 3000 |
#define | FLAG_3389_WARNING (1 << 0) |
#define | FLAG_NAT_ACTIVE (3 << 1) |
#define | FLAG_NAT_INACTIVE (0 << 1) |
#define | FLAG_NAT_INACTIVE_NOWARN (1 << 1) |
#define | MAX_RTP_PT 256 |
#define | MAX_TIMESTAMP_SKEW 640 |
#define | RTP_MTU 1200 |
Functions | |
int | ast_rtcp_fd (struct ast_rtp *rtp) |
static struct ast_rtcp * | ast_rtcp_new (void) |
Initialize a new RTCP session. | |
ast_frame * | ast_rtcp_read (struct ast_rtp *rtp) |
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) |
void | ast_rtp_destroy (struct ast_rtp *rtp) |
int | ast_rtp_fd (struct ast_rtp *rtp) |
void | ast_rtp_get_current_formats (struct ast_rtp *rtp, int *astFormats, int *nonAstFormats) |
void | ast_rtp_get_peer (struct ast_rtp *rtp, struct sockaddr_in *them) |
void | ast_rtp_get_us (struct ast_rtp *rtp, struct sockaddr_in *us) |
void | ast_rtp_init (void) |
int | ast_rtp_lookup_code (struct ast_rtp *rtp, const int isAstFormat, const int code) |
char * | ast_rtp_lookup_mime_multiple (char *buf, int size, const int capability, const int isAstFormat) |
char * | ast_rtp_lookup_mime_subtype (const int isAstFormat, const int code) |
rtpPayloadType | ast_rtp_lookup_pt (struct ast_rtp *rtp, int pt) |
ast_rtp * | ast_rtp_new (struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode) |
Initializate a RTP session. | |
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. | |
void | ast_rtp_offered_from_local (struct ast_rtp *rtp, int local) |
int | ast_rtp_proto_register (struct ast_rtp_protocol *proto) |
void | ast_rtp_proto_unregister (struct ast_rtp_protocol *proto) |
void | ast_rtp_pt_clear (struct ast_rtp *rtp) |
void | ast_rtp_pt_default (struct ast_rtp *rtp) |
static int | ast_rtp_raw_write (struct ast_rtp *rtp, struct ast_frame *f, int codec) |
ast_frame * | ast_rtp_read (struct ast_rtp *rtp) |
void | ast_rtp_reload (void) |
void | ast_rtp_reset (struct ast_rtp *rtp) |
int | ast_rtp_sendcng (struct ast_rtp *rtp, int level) |
int | ast_rtp_senddigit (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) |
void | ast_rtp_set_peer (struct ast_rtp *rtp, struct sockaddr_in *them) |
void | ast_rtp_set_rtpmap_type (struct ast_rtp *rtp, int pt, char *mimeType, char *mimeSubtype) |
void | ast_rtp_setnat (struct ast_rtp *rtp, int nat) |
int | ast_rtp_settos (struct ast_rtp *rtp, int tos) |
void | ast_rtp_stop (struct ast_rtp *rtp) |
int | ast_rtp_write (struct ast_rtp *rtp, struct ast_frame *_f) |
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) |
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) |
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 | 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) |
Variables | |
static struct ast_cli_entry | cli_debug |
static struct ast_cli_entry | cli_debug_ip |
static struct ast_cli_entry | cli_no_debug |
static char | debug_usage [] |
static int | dtmftimeout = DEFAULT_DTMF_TIMEOUT |
struct { | |
rtpPayloadType payloadType | |
char * subtype | |
char * type | |
} | mimeTypes [] |
static char | no_debug_usage [] |
static struct ast_rtp_protocol * | protos = NULL |
static int | rtpdebug = 0 |
static struct sockaddr_in | rtpdebugaddr |
static int | rtpend = 0 |
static int | rtpstart = 0 |
static struct rtpPayloadType | static_RTP_PT [MAX_RTP_PT] |
RTP is deffined in RFC 3550.
Definition in file rtp.c.
|
Definition at line 61 of file rtp.c. Referenced by ast_rtp_reload(). |
|
Definition at line 81 of file rtp.c. Referenced by process_rfc3389(). |
|
Definition at line 82 of file rtp.c. Referenced by ast_rtp_bridge(), ast_rtp_raw_write(), and ast_rtp_read(). |
|
Definition at line 83 of file rtp.c. Referenced by ast_rtp_raw_write(). |
|
Definition at line 84 of file rtp.c. Referenced by ast_rtp_raw_write(). |
|
|
|
Definition at line 57 of file rtp.c. Referenced by ast_rtp_raw_write(), calc_timestamp(), and calc_txpeerstamp(). |
|
|
|
Definition at line 158 of file rtp.c. References ast_rtp::rtcp, and ast_rtcp::s. Referenced by sip_new().
|
|
Initialize a new RTCP session.
Definition at line 912 of file rtp.c. References ast_log(), free, LOG_WARNING, malloc, and rtp_socket(). Referenced by ast_rtp_new_with_bindaddr(). 00913 { 00914 struct ast_rtcp *rtcp; 00915 rtcp = malloc(sizeof(struct ast_rtcp)); 00916 if (!rtcp) 00917 return NULL; 00918 memset(rtcp, 0, sizeof(struct ast_rtcp)); 00919 rtcp->s = rtp_socket(); 00920 rtcp->us.sin_family = AF_INET; 00921 if (rtcp->s < 0) { 00922 free(rtcp); 00923 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno)); 00924 return NULL; 00925 } 00926 return rtcp; 00927 }
|
|
Definition at line 370 of file rtp.c. References AST_FRAME_NULL, ast_inet_ntoa(), ast_log(), CRASH, LOG_DEBUG, LOG_WARNING, ast_rtp::nat, option_debug, ast_rtp::rtcp, rtpdebug, ast_rtcp::s, and ast_rtcp::them. Referenced by sip_rtp_read(). 00371 { 00372 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 00373 socklen_t len; 00374 int hdrlen = 8; 00375 int res; 00376 struct sockaddr_in sin; 00377 unsigned int rtcpdata[1024]; 00378 char iabuf[INET_ADDRSTRLEN]; 00379 00380 if (!rtp || !rtp->rtcp) 00381 return &null_frame; 00382 00383 len = sizeof(sin); 00384 00385 res = recvfrom(rtp->rtcp->s, rtcpdata, sizeof(rtcpdata), 00386 0, (struct sockaddr *)&sin, &len); 00387 00388 if (res < 0) { 00389 if (errno != EAGAIN) 00390 ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno)); 00391 if (errno == EBADF) 00392 CRASH; 00393 return &null_frame; 00394 } 00395 00396 if (res < hdrlen) { 00397 ast_log(LOG_WARNING, "RTP Read too short\n"); 00398 return &null_frame; 00399 } 00400 00401 if (rtp->nat) { 00402 /* Send to whoever sent to us */ 00403 if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || 00404 (rtp->rtcp->them.sin_port != sin.sin_port)) { 00405 memcpy(&rtp->rtcp->them, &sin, sizeof(rtp->rtcp->them)); 00406 if (option_debug || rtpdebug) 00407 ast_log(LOG_DEBUG, "RTCP NAT: Got RTCP from other end. Now sending to address %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port)); 00408 } 00409 } 00410 if (option_debug) 00411 ast_log(LOG_DEBUG, "Got RTCP report of %d bytes\n", res); 00412 return &null_frame; 00413 }
|
|
Definition at line 1518 of file rtp.c. References AST_BRIDGE_COMPLETE, AST_BRIDGE_DTMF_CHANNEL_0, AST_BRIDGE_DTMF_CHANNEL_1, AST_BRIDGE_FAILED, AST_BRIDGE_FAILED_NOWARN, AST_BRIDGE_IGNORE_SIGS, AST_BRIDGE_RETRY, ast_check_hangup(), AST_CONTROL_HOLD, AST_CONTROL_UNHOLD, AST_CONTROL_VIDUPDATE, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frfree(), ast_indicate(), ast_inet_ntoa(), ast_log(), ast_mutex_lock(), ast_mutex_trylock(), ast_mutex_unlock(), ast_read(), ast_rtp_get_peer(), ast_test_flag, ast_waitfor_n(), ast_write(), FLAG_NAT_ACTIVE, ast_frame::frametype, ast_rtp_protocol::get_codec, get_proto(), ast_rtp_protocol::get_rtp_info, ast_rtp_protocol::get_vrtp_info, inaddrcmp(), ast_channel::lock, LOG_DEBUG, LOG_WARNING, ast_channel::name, option_debug, ast_rtp_protocol::set_rtp_peer, ast_frame::subclass, and ast_channel::tech_pvt. 01519 { 01520 struct ast_frame *f; 01521 struct ast_channel *who, *cs[3]; 01522 struct ast_rtp *p0, *p1; /* Audio RTP Channels */ 01523 struct ast_rtp *vp0, *vp1; /* Video RTP channels */ 01524 struct ast_rtp_protocol *pr0, *pr1; 01525 struct sockaddr_in ac0, ac1; 01526 struct sockaddr_in vac0, vac1; 01527 struct sockaddr_in t0, t1; 01528 struct sockaddr_in vt0, vt1; 01529 char iabuf[INET_ADDRSTRLEN]; 01530 01531 void *pvt0, *pvt1; 01532 int codec0,codec1, oldcodec0, oldcodec1; 01533 01534 memset(&vt0, 0, sizeof(vt0)); 01535 memset(&vt1, 0, sizeof(vt1)); 01536 memset(&vac0, 0, sizeof(vac0)); 01537 memset(&vac1, 0, sizeof(vac1)); 01538 01539 /* if need DTMF, cant native bridge */ 01540 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1)) 01541 return AST_BRIDGE_FAILED_NOWARN; 01542 01543 /* Lock channels */ 01544 ast_mutex_lock(&c0->lock); 01545 while(ast_mutex_trylock(&c1->lock)) { 01546 ast_mutex_unlock(&c0->lock); 01547 usleep(1); 01548 ast_mutex_lock(&c0->lock); 01549 } 01550 01551 /* Find channel driver interfaces */ 01552 pr0 = get_proto(c0); 01553 pr1 = get_proto(c1); 01554 if (!pr0) { 01555 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name); 01556 ast_mutex_unlock(&c0->lock); 01557 ast_mutex_unlock(&c1->lock); 01558 return AST_BRIDGE_FAILED; 01559 } 01560 if (!pr1) { 01561 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name); 01562 ast_mutex_unlock(&c0->lock); 01563 ast_mutex_unlock(&c1->lock); 01564 return AST_BRIDGE_FAILED; 01565 } 01566 01567 /* Get channel specific interface structures */ 01568 pvt0 = c0->tech_pvt; 01569 pvt1 = c1->tech_pvt; 01570 01571 /* Get audio and video interface (if native bridge is possible) */ 01572 p0 = pr0->get_rtp_info(c0); 01573 if (pr0->get_vrtp_info) 01574 vp0 = pr0->get_vrtp_info(c0); 01575 else 01576 vp0 = NULL; 01577 p1 = pr1->get_rtp_info(c1); 01578 if (pr1->get_vrtp_info) 01579 vp1 = pr1->get_vrtp_info(c1); 01580 else 01581 vp1 = NULL; 01582 01583 /* Check if bridge is still possible (In SIP canreinvite=no stops this, like NAT) */ 01584 if (!p0 || !p1) { 01585 /* Somebody doesn't want to play... */ 01586 ast_mutex_unlock(&c0->lock); 01587 ast_mutex_unlock(&c1->lock); 01588 return AST_BRIDGE_FAILED_NOWARN; 01589 } 01590 /* Get codecs from both sides */ 01591 if (pr0->get_codec) 01592 codec0 = pr0->get_codec(c0); 01593 else 01594 codec0 = 0; 01595 if (pr1->get_codec) 01596 codec1 = pr1->get_codec(c1); 01597 else 01598 codec1 = 0; 01599 if (pr0->get_codec && pr1->get_codec) { 01600 /* Hey, we can't do reinvite if both parties speak different codecs */ 01601 if (!(codec0 & codec1)) { 01602 if (option_debug) 01603 ast_log(LOG_DEBUG, "Channel codec0 = %d is not codec1 = %d, cannot native bridge in RTP.\n", codec0, codec1); 01604 ast_mutex_unlock(&c0->lock); 01605 ast_mutex_unlock(&c1->lock); 01606 return AST_BRIDGE_FAILED_NOWARN; 01607 } 01608 } 01609 01610 /* Ok, we should be able to redirect the media. Start with one channel */ 01611 if (pr0->set_rtp_peer(c0, p1, vp1, codec1, ast_test_flag(p1, FLAG_NAT_ACTIVE))) 01612 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name); 01613 else { 01614 /* Store RTP peer */ 01615 ast_rtp_get_peer(p1, &ac1); 01616 if (vp1) 01617 ast_rtp_get_peer(vp1, &vac1); 01618 } 01619 /* Then test the other channel */ 01620 if (pr1->set_rtp_peer(c1, p0, vp0, codec0, ast_test_flag(p0, FLAG_NAT_ACTIVE))) 01621 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name); 01622 else { 01623 /* Store RTP peer */ 01624 ast_rtp_get_peer(p0, &ac0); 01625 if (vp0) 01626 ast_rtp_get_peer(vp0, &vac0); 01627 } 01628 ast_mutex_unlock(&c0->lock); 01629 ast_mutex_unlock(&c1->lock); 01630 /* External RTP Bridge up, now loop and see if something happes that force us to take the 01631 media back to Asterisk */ 01632 cs[0] = c0; 01633 cs[1] = c1; 01634 cs[2] = NULL; 01635 oldcodec0 = codec0; 01636 oldcodec1 = codec1; 01637 for (;;) { 01638 /* Check if something changed... */ 01639 if ((c0->tech_pvt != pvt0) || 01640 (c1->tech_pvt != pvt1) || 01641 (c0->masq || c0->masqr || c1->masq || c1->masqr)) { 01642 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n"); 01643 if (c0->tech_pvt == pvt0) { 01644 if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) 01645 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); 01646 } 01647 if (c1->tech_pvt == pvt1) { 01648 if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) 01649 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); 01650 } 01651 return AST_BRIDGE_RETRY; 01652 } 01653 /* Now check if they have changed address */ 01654 ast_rtp_get_peer(p1, &t1); 01655 ast_rtp_get_peer(p0, &t0); 01656 if (pr0->get_codec) 01657 codec0 = pr0->get_codec(c0); 01658 if (pr1->get_codec) 01659 codec1 = pr1->get_codec(c1); 01660 if (vp1) 01661 ast_rtp_get_peer(vp1, &vt1); 01662 if (vp0) 01663 ast_rtp_get_peer(vp0, &vt0); 01664 if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) { 01665 if (option_debug > 1) { 01666 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 01667 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1); 01668 ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", 01669 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1); 01670 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 01671 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1); 01672 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 01673 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1); 01674 } 01675 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))) 01676 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name); 01677 memcpy(&ac1, &t1, sizeof(ac1)); 01678 memcpy(&vac1, &vt1, sizeof(vac1)); 01679 oldcodec1 = codec1; 01680 } 01681 if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) { 01682 if (option_debug) { 01683 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 01684 c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0); 01685 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 01686 c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0); 01687 } 01688 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))) 01689 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name); 01690 memcpy(&ac0, &t0, sizeof(ac0)); 01691 memcpy(&vac0, &vt0, sizeof(vac0)); 01692 oldcodec0 = codec0; 01693 } 01694 who = ast_waitfor_n(cs, 2, &timeoutms); 01695 if (!who) { 01696 if (!timeoutms) 01697 return AST_BRIDGE_RETRY; 01698 if (option_debug) 01699 ast_log(LOG_DEBUG, "Ooh, empty read...\n"); 01700 /* check for hangup / whentohangup */ 01701 if (ast_check_hangup(c0) || ast_check_hangup(c1)) 01702 break; 01703 continue; 01704 } 01705 f = ast_read(who); 01706 if (!f || ((f->frametype == AST_FRAME_DTMF) && 01707 (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || 01708 ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) { 01709 *fo = f; 01710 *rc = who; 01711 if (option_debug) 01712 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup"); 01713 if ((c0->tech_pvt == pvt0) && (!c0->_softhangup)) { 01714 if (pr0->set_rtp_peer(c0, NULL, NULL, 0, 0)) 01715 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c0->name); 01716 } 01717 if ((c1->tech_pvt == pvt1) && (!c1->_softhangup)) { 01718 if (pr1->set_rtp_peer(c1, NULL, NULL, 0, 0)) 01719 ast_log(LOG_WARNING, "Channel '%s' failed to break RTP bridge\n", c1->name); 01720 } 01721 return AST_BRIDGE_COMPLETE; 01722 } else if ((f->frametype == AST_FRAME_CONTROL) && !(flags & AST_BRIDGE_IGNORE_SIGS)) { 01723 if ((f->subclass == AST_CONTROL_HOLD) || (f->subclass == AST_CONTROL_UNHOLD) || 01724 (f->subclass == AST_CONTROL_VIDUPDATE)) { 01725 ast_indicate(who == c0 ? c1 : c0, f->subclass); 01726 ast_frfree(f); 01727 } else { 01728 *fo = f; 01729 *rc = who; 01730 ast_log(LOG_DEBUG, "Got a FRAME_CONTROL (%d) frame on channel %s\n", f->subclass, who->name); 01731 return AST_BRIDGE_COMPLETE; 01732 } 01733 } else { 01734 if ((f->frametype == AST_FRAME_DTMF) || 01735 (f->frametype == AST_FRAME_VOICE) || 01736 (f->frametype == AST_FRAME_VIDEO)) { 01737 /* Forward voice or DTMF frames if they happen upon us */ 01738 if (who == c0) { 01739 ast_write(c1, f); 01740 } else if (who == c1) { 01741 ast_write(c0, f); 01742 } 01743 } 01744 ast_frfree(f); 01745 } 01746 /* Swap priority not that it's a big deal at this point */ 01747 cs[2] = cs[0]; 01748 cs[0] = cs[1]; 01749 cs[1] = cs[2]; 01750 01751 } 01752 return AST_BRIDGE_FAILED; 01753 }
|
|
Definition at line 1086 of file rtp.c. References ast_io_remove(), ast_smoother_free(), free, ast_rtp::io, ast_rtp::ioid, ast_rtp::rtcp, ast_rtp::s, ast_rtcp::s, and ast_rtp::smoother. Referenced by __oh323_destroy(), __sip_destroy(), cleanup_connection(), destroy_endpoint(), mgcp_hangup(), skinny_hangup(), start_rtp(), and unalloc_sub(). 01087 { 01088 if (rtp->smoother) 01089 ast_smoother_free(rtp->smoother); 01090 if (rtp->ioid) 01091 ast_io_remove(rtp->io, rtp->ioid); 01092 if (rtp->s > -1) 01093 close(rtp->s); 01094 if (rtp->rtcp) { 01095 close(rtp->rtcp->s); 01096 free(rtp->rtcp); 01097 } 01098 free(rtp); 01099 }
|
|
Definition at line 153 of file rtp.c. References ast_rtp::s. Referenced by __oh323_new(), mgcp_new(), sip_new(), skinny_new(), and start_rtp(). 00154 { 00155 return rtp->s; 00156 }
|
|
Definition at line 771 of file rtp.c. References rtpPayloadType::code, ast_rtp::current_RTP_PT, and rtpPayloadType::isAstFormat. Referenced by process_sdp(). 00772 { 00773 int pt; 00774 00775 *astFormats = *nonAstFormats = 0; 00776 for (pt = 0; pt < MAX_RTP_PT; ++pt) { 00777 if (rtp->current_RTP_PT[pt].isAstFormat) { 00778 *astFormats |= rtp->current_RTP_PT[pt].code; 00779 } else { 00780 *nonAstFormats |= rtp->current_RTP_PT[pt].code; 00781 } 00782 } 00783 }
|
|
Definition at line 1044 of file rtp.c. References ast_rtp::them. Referenced by add_sdp(), ast_rtp_bridge(), do_monitor(), oh323_set_rtp_peer(), sip_set_rtp_peer(), and transmit_modify_with_sdp(). 01045 { 01046 them->sin_family = AF_INET; 01047 them->sin_port = rtp->them.sin_port; 01048 them->sin_addr = rtp->them.sin_addr; 01049 }
|
|
Definition at line 1051 of file rtp.c. References ast_rtp::us. Referenced by add_sdp(), external_rtp_create(), handle_message(), and oh323_set_rtp_peer().
|
|
Definition at line 1881 of file rtp.c. References ast_cli_register(), and ast_rtp_reload(). Referenced by main(). 01882 { 01883 ast_cli_register(&cli_debug); 01884 ast_cli_register(&cli_debug_ip); 01885 ast_cli_register(&cli_no_debug); 01886 ast_rtp_reload(); 01887 }
|
|
Definition at line 811 of file rtp.c. References rtpPayloadType::code, ast_rtp::current_RTP_PT, rtpPayloadType::isAstFormat, 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_sdp(), add_noncodec_to_sdp(), add_sdp(), ast_rtp_sendcng(), ast_rtp_senddigit(), and ast_rtp_write(). 00811 { 00812 00813 int pt; 00814 00815 if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat && 00816 code == rtp->rtp_lookup_code_cache_code) { 00817 00818 /* Use our cached mapping, to avoid the overhead of the loop below */ 00819 return rtp->rtp_lookup_code_cache_result; 00820 } 00821 00822 /* Check the dynamic list first */ 00823 for (pt = 0; pt < MAX_RTP_PT; ++pt) { 00824 if (rtp->current_RTP_PT[pt].code == code && rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) { 00825 rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat; 00826 rtp->rtp_lookup_code_cache_code = code; 00827 rtp->rtp_lookup_code_cache_result = pt; 00828 return pt; 00829 } 00830 } 00831 00832 /* Then the static list */ 00833 for (pt = 0; pt < MAX_RTP_PT; ++pt) { 00834 if (static_RTP_PT[pt].code == code && static_RTP_PT[pt].isAstFormat == isAstFormat) { 00835 rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat; 00836 rtp->rtp_lookup_code_cache_code = code; 00837 rtp->rtp_lookup_code_cache_result = pt; 00838 return pt; 00839 } 00840 } 00841 return -1; 00842 }
|
|
Definition at line 856 of file rtp.c. References ast_rtp_lookup_mime_subtype(), AST_RTP_MAX, format, and name. Referenced by process_sdp(). 00857 { 00858 int format; 00859 unsigned len; 00860 char *end = buf; 00861 char *start = buf; 00862 00863 if (!buf || !size) 00864 return NULL; 00865 00866 snprintf(end, size, "0x%x (", capability); 00867 00868 len = strlen(end); 00869 end += len; 00870 size -= len; 00871 start = end; 00872 00873 for (format = 1; format < AST_RTP_MAX; format <<= 1) { 00874 if (capability & format) { 00875 const char *name = ast_rtp_lookup_mime_subtype(isAstFormat, format); 00876 snprintf(end, size, "%s|", name); 00877 len = strlen(end); 00878 end += len; 00879 size -= len; 00880 } 00881 } 00882 00883 if (start == end) 00884 snprintf(start, size, "nothing)"); 00885 else if (size > 1) 00886 *(end -1) = ')'; 00887 00888 return buf; 00889 }
|
|
Definition at line 844 of file rtp.c. References 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(). 00844 { 00845 00846 int i; 00847 00848 for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) { 00849 if (mimeTypes[i].payloadType.code == code && mimeTypes[i].payloadType.isAstFormat == isAstFormat) { 00850 return mimeTypes[i].subtype; 00851 } 00852 } 00853 return ""; 00854 }
|
|
Definition at line 792 of file rtp.c. References rtpPayloadType::code, and rtpPayloadType::isAstFormat. Referenced by ast_rtp_read(), and setup_rtp_connection(). 00793 { 00794 struct rtpPayloadType result; 00795 00796 result.isAstFormat = result.code = 0; 00797 if (pt < 0 || pt > MAX_RTP_PT) 00798 return result; /* bogus payload type */ 00799 00800 /* Start with the negotiated codecs */ 00801 if (!rtp->rtp_offered_from_local) 00802 result = rtp->current_RTP_PT[pt]; 00803 00804 /* If it doesn't exist, check our static RTP type list, just in case */ 00805 if (!result.code) 00806 result = static_RTP_PT[pt]; 00807 return result; 00808 }
|
|
Initializate a RTP session.
Definition at line 1016 of file rtp.c. References ast_rtp_new_with_bindaddr(). Referenced by start_rtp(). 01017 { 01018 struct in_addr ia; 01019 01020 memset(&ia, 0, sizeof(ia)); 01021 return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia); 01022 }
|
|
Initializate a RTP session using an in_addr structure. This fuction gets called by ast_rtp_new().
Definition at line 929 of file rtp.c. References ast_io_add(), AST_IO_IN, ast_log(), ast_rtcp_new(), ast_rtp_pt_default(), free, LOG_ERROR, malloc, rtp_socket(), rtpend, rtpread(), and rtpstart. Referenced by ast_rtp_new(), oh323_alloc(), sip_alloc(), and start_rtp(). 00930 { 00931 struct ast_rtp *rtp; 00932 int x; 00933 int first; 00934 int startplace; 00935 rtp = malloc(sizeof(struct ast_rtp)); 00936 if (!rtp) 00937 return NULL; 00938 memset(rtp, 0, sizeof(struct ast_rtp)); 00939 rtp->them.sin_family = AF_INET; 00940 rtp->us.sin_family = AF_INET; 00941 rtp->s = rtp_socket(); 00942 rtp->ssrc = rand(); 00943 rtp->seqno = rand() & 0xffff; 00944 if (rtp->s < 0) { 00945 free(rtp); 00946 ast_log(LOG_ERROR, "Unable to allocate socket: %s\n", strerror(errno)); 00947 return NULL; 00948 } 00949 if (sched && rtcpenable) { 00950 rtp->sched = sched; 00951 rtp->rtcp = ast_rtcp_new(); 00952 } 00953 00954 /* Select a random port number in the range of possible RTP */ 00955 x = (rand() % (rtpend-rtpstart)) + rtpstart; 00956 x = x & ~1; 00957 /* Save it for future references. */ 00958 startplace = x; 00959 /* Iterate tring to bind that port and incrementing it otherwise untill a port was found or no ports are available. */ 00960 for (;;) { 00961 /* Must be an even port number by RTP spec */ 00962 rtp->us.sin_port = htons(x); 00963 rtp->us.sin_addr = addr; 00964 /* If there's rtcp, initialize it as well. */ 00965 if (rtp->rtcp) 00966 rtp->rtcp->us.sin_port = htons(x + 1); 00967 /* Try to bind it/them. */ 00968 if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) && 00969 (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us)))) 00970 break; 00971 if (!first) { 00972 /* Primary bind succeeded! Gotta recreate it */ 00973 close(rtp->s); 00974 rtp->s = rtp_socket(); 00975 } 00976 if (errno != EADDRINUSE) { 00977 /* We got an error that wasn't expected, abort! */ 00978 ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno)); 00979 close(rtp->s); 00980 if (rtp->rtcp) { 00981 close(rtp->rtcp->s); 00982 free(rtp->rtcp); 00983 } 00984 free(rtp); 00985 return NULL; 00986 } 00987 /* The port was used, increment it (by two). */ 00988 x += 2; 00989 /* Did we go over the limit ? */ 00990 if (x > rtpend) 00991 /* then, start from the begingig. */ 00992 x = (rtpstart + 1) & ~1; 00993 /* Check if we reached the place were we started. */ 00994 if (x == startplace) { 00995 /* If so, there's no ports available. */ 00996 ast_log(LOG_ERROR, "No RTP ports remaining. Can't setup media stream for this call.\n"); 00997 close(rtp->s); 00998 if (rtp->rtcp) { 00999 close(rtp->rtcp->s); 01000 free(rtp->rtcp); 01001 } 01002 free(rtp); 01003 return NULL; 01004 } 01005 } 01006 if (io && sched && callbackmode) { 01007 /* Operate this one in a callback mode */ 01008 rtp->sched = sched; 01009 rtp->io = io; 01010 rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp); 01011 } 01012 ast_rtp_pt_default(rtp); 01013 return rtp; 01014 }
|
|
Definition at line 785 of file rtp.c. References ast_log(), and LOG_WARNING. Referenced by transmit_connect_with_sdp(), transmit_invite(), transmit_modify_with_sdp(), transmit_reinvite_with_sdp(), and transmit_response_with_sdp(). 00785 { 00786 if (rtp) 00787 rtp->rtp_offered_from_local = local; 00788 else 00789 ast_log(LOG_WARNING, "rtp structure is null\n"); 00790 }
|
|
Definition at line 1484 of file rtp.c. References ast_log(), LOG_WARNING, ast_rtp_protocol::next, and ast_rtp_protocol::type. Referenced by load_module(), and unload_module(). 01485 { 01486 struct ast_rtp_protocol *cur; 01487 cur = protos; 01488 while(cur) { 01489 if (cur->type == proto->type) { 01490 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type); 01491 return -1; 01492 } 01493 cur = cur->next; 01494 } 01495 proto->next = protos; 01496 protos = proto; 01497 return 0; 01498 }
|
|
Definition at line 1464 of file rtp.c. References ast_rtp_protocol::next. Referenced by unload_module(). 01465 { 01466 struct ast_rtp_protocol *cur, *prev; 01467 01468 cur = protos; 01469 prev = NULL; 01470 while(cur) { 01471 if (cur == proto) { 01472 if (prev) 01473 prev->next = proto->next; 01474 else 01475 protos = proto->next; 01476 return; 01477 } 01478 prev = cur; 01479 cur = cur->next; 01480 } 01481 }
|
|
Definition at line 708 of file rtp.c. Referenced by process_sdp(). 00709 { 00710 int i; 00711 if (!rtp) 00712 return; 00713 00714 for (i = 0; i < MAX_RTP_PT; ++i) { 00715 rtp->current_RTP_PT[i].isAstFormat = 0; 00716 rtp->current_RTP_PT[i].code = 0; 00717 } 00718 00719 rtp->rtp_lookup_code_cache_isAstFormat = 0; 00720 rtp->rtp_lookup_code_cache_code = 0; 00721 rtp->rtp_lookup_code_cache_result = 0; 00722 }
|
|
Definition at line 724 of file rtp.c. References rtpPayloadType::code, and rtpPayloadType::isAstFormat. Referenced by ast_rtp_new_with_bindaddr(). 00725 { 00726 int i; 00727 00728 /* Initialize to default payload types */ 00729 for (i = 0; i < MAX_RTP_PT; ++i) { 00730 rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat; 00731 rtp->current_RTP_PT[i].code = static_RTP_PT[i].code; 00732 } 00733 00734 rtp->rtp_lookup_code_cache_isAstFormat = 0; 00735 rtp->rtp_lookup_code_cache_code = 0; 00736 rtp->rtp_lookup_code_cache_result = 0; 00737 }
|
|
Definition at line 1237 of file rtp.c. References AST_FORMAT_MAX_AUDIO, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, ast_verbose(), calc_txstamp(), ast_frame::data, ast_frame::datalen, ast_frame::delivery, FLAG_NAT_ACTIVE, FLAG_NAT_INACTIVE, FLAG_NAT_INACTIVE_NOWARN, ast_rtp::lastdigitts, ast_rtp::lastovidtimestamp, ast_rtp::lastts, LOG_DEBUG, MAX_TIMESTAMP_SKEW, ast_rtp::nat, option_debug, put_unaligned_uint32(), rtp_debug_test_addr(), rtpdebug, ast_rtp::s, ast_frame::samples, ast_rtp::seqno, ast_rtp::ssrc, ast_frame::subclass, and ast_rtp::them. Referenced by ast_rtp_write(). 01238 { 01239 unsigned char *rtpheader; 01240 char iabuf[INET_ADDRSTRLEN]; 01241 int hdrlen = 12; 01242 int res; 01243 unsigned int ms; 01244 int pred; 01245 int mark = 0; 01246 01247 ms = calc_txstamp(rtp, &f->delivery); 01248 /* Default prediction */ 01249 if (f->subclass < AST_FORMAT_MAX_AUDIO) { 01250 pred = rtp->lastts + f->samples; 01251 01252 /* Re-calculate last TS */ 01253 rtp->lastts = rtp->lastts + ms * 8; 01254 if (ast_tvzero(f->delivery)) { 01255 /* If this isn't an absolute delivery time, Check if it is close to our prediction, 01256 and if so, go with our prediction */ 01257 if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW) 01258 rtp->lastts = pred; 01259 else { 01260 if (option_debug > 2) 01261 ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms); 01262 mark = 1; 01263 } 01264 } 01265 } else { 01266 mark = f->subclass & 0x1; 01267 pred = rtp->lastovidtimestamp + f->samples; 01268 /* Re-calculate last TS */ 01269 rtp->lastts = rtp->lastts + ms * 90; 01270 /* If it's close to our prediction, go for it */ 01271 if (ast_tvzero(f->delivery)) { 01272 if (abs(rtp->lastts - pred) < 7200) { 01273 rtp->lastts = pred; 01274 rtp->lastovidtimestamp += f->samples; 01275 } else { 01276 if (option_debug > 2) 01277 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); 01278 rtp->lastovidtimestamp = rtp->lastts; 01279 } 01280 } 01281 } 01282 /* If the timestamp for non-digit packets has moved beyond the timestamp 01283 for digits, update the digit timestamp. 01284 */ 01285 if (rtp->lastts > rtp->lastdigitts) 01286 rtp->lastdigitts = rtp->lastts; 01287 01288 /* Get a pointer to the header */ 01289 rtpheader = (unsigned char *)(f->data - hdrlen); 01290 01291 put_unaligned_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23))); 01292 put_unaligned_uint32(rtpheader + 4, htonl(rtp->lastts)); 01293 put_unaligned_uint32(rtpheader + 8, htonl(rtp->ssrc)); 01294 01295 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { 01296 res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); 01297 if (res <0) { 01298 if (!rtp->nat || (rtp->nat && (ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_ACTIVE))) { 01299 ast_log(LOG_DEBUG, "RTP Transmission error of packet %d to %s:%d: %s\n", rtp->seqno, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); 01300 } else if ((ast_test_flag(rtp, FLAG_NAT_ACTIVE) == FLAG_NAT_INACTIVE) || rtpdebug) { 01301 /* Only give this error message once if we are not RTP debugging */ 01302 if (option_debug || rtpdebug) 01303 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(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port)); 01304 ast_set_flag(rtp, FLAG_NAT_INACTIVE_NOWARN); 01305 } 01306 } 01307 01308 if(rtp_debug_test_addr(&rtp->them)) 01309 ast_verbose("Sent RTP packet to %s:%d (type %d, seq %u, ts %u, len %u)\n" 01310 , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen); 01311 } 01312 01313 rtp->seqno++; 01314 01315 return 0; 01316 }
|
|
Definition at line 426 of file rtp.c. References ast_codec_get_samples(), AST_FORMAT_MAX_AUDIO, AST_FORMAT_SLINEAR, ast_frame_byteswap_be, AST_FRAME_NULL, AST_FRAME_VIDEO, AST_FRAME_VOICE, AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), AST_RTP_CISCO_DTMF, AST_RTP_CN, AST_RTP_DTMF, ast_rtp_lookup_pt(), ast_set_flag, ast_verbose(), calc_rxstamp(), rtpPayloadType::code, CRASH, ast_frame::data, ast_frame::datalen, ast_frame::delivery, ast_rtp::dtmfcount, dtmftimeout, ast_rtp::f, FLAG_NAT_ACTIVE, ast_frame::frametype, rtpPayloadType::isAstFormat, ast_rtp::lasteventseqn, ast_rtp::lastividtimestamp, ast_rtp::lastrxformat, ast_rtp::lastrxts, 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::resp, rtp_debug_test_addr(), rtpdebug, ast_rtp::rxseqno, ast_rtp::rxssrc, ast_rtp::s, ast_frame::samples, send_dtmf(), ast_frame::src, ast_frame::subclass, and ast_rtp::them. Referenced by mgcp_rtp_read(), oh323_rtp_read(), rtpread(), sip_rtp_read(), and skinny_rtp_read(). 00427 { 00428 int res; 00429 struct sockaddr_in sin; 00430 socklen_t len; 00431 unsigned int seqno; 00432 int version; 00433 int payloadtype; 00434 int hdrlen = 12; 00435 int padding; 00436 int mark; 00437 int ext; 00438 int x; 00439 char iabuf[INET_ADDRSTRLEN]; 00440 unsigned int ssrc; 00441 unsigned int timestamp; 00442 unsigned int *rtpheader; 00443 struct ast_frame *f; 00444 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 00445 struct rtpPayloadType rtpPT; 00446 00447 len = sizeof(sin); 00448 00449 /* Cache where the header will go */ 00450 res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET, 00451 0, (struct sockaddr *)&sin, &len); 00452 00453 00454 rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET); 00455 if (res < 0) { 00456 if (errno != EAGAIN) 00457 ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno)); 00458 if (errno == EBADF) 00459 CRASH; 00460 return &null_frame; 00461 } 00462 if (res < hdrlen) { 00463 ast_log(LOG_WARNING, "RTP Read too short\n"); 00464 return &null_frame; 00465 } 00466 00467 /* Ignore if the other side hasn't been given an address 00468 yet. */ 00469 if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port) 00470 return &null_frame; 00471 00472 if (rtp->nat) { 00473 /* Send to whoever sent to us */ 00474 if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) || 00475 (rtp->them.sin_port != sin.sin_port)) { 00476 memcpy(&rtp->them, &sin, sizeof(rtp->them)); 00477 rtp->rxseqno = 0; 00478 ast_set_flag(rtp, FLAG_NAT_ACTIVE); 00479 if (option_debug || rtpdebug) 00480 ast_log(LOG_DEBUG, "RTP NAT: Got audio from other end. Now sending to address %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port)); 00481 } 00482 } 00483 00484 /* Get fields */ 00485 seqno = ntohl(rtpheader[0]); 00486 00487 /* Check RTP version */ 00488 version = (seqno & 0xC0000000) >> 30; 00489 if (version != 2) 00490 return &null_frame; 00491 00492 payloadtype = (seqno & 0x7f0000) >> 16; 00493 padding = seqno & (1 << 29); 00494 mark = seqno & (1 << 23); 00495 ext = seqno & (1 << 28); 00496 seqno &= 0xffff; 00497 timestamp = ntohl(rtpheader[1]); 00498 ssrc = ntohl(rtpheader[2]); 00499 00500 if (!mark && rtp->rxssrc && rtp->rxssrc != ssrc) { 00501 if (option_debug || rtpdebug) 00502 ast_log(LOG_DEBUG, "Forcing Marker bit, because SSRC has changed\n"); 00503 mark = 1; 00504 } 00505 00506 rtp->rxssrc = ssrc; 00507 00508 if (padding) { 00509 /* Remove padding bytes */ 00510 res -= rtp->rawdata[AST_FRIENDLY_OFFSET + res - 1]; 00511 } 00512 00513 if (ext) { 00514 /* RTP Extension present */ 00515 hdrlen += 4; 00516 hdrlen += (ntohl(rtpheader[3]) & 0xffff) << 2; 00517 } 00518 00519 if (res < hdrlen) { 00520 ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen); 00521 return &null_frame; 00522 } 00523 00524 if(rtp_debug_test_addr(&sin)) 00525 ast_verbose("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len %d)\n" 00526 , ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen); 00527 00528 rtpPT = ast_rtp_lookup_pt(rtp, payloadtype); 00529 if (!rtpPT.isAstFormat) { 00530 /* This is special in-band data that's not one of our codecs */ 00531 if (rtpPT.code == AST_RTP_DTMF) { 00532 /* It's special -- rfc2833 process it */ 00533 if(rtp_debug_test_addr(&sin)) { 00534 unsigned char *data; 00535 unsigned int event; 00536 unsigned int event_end; 00537 unsigned int duration; 00538 data = rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen; 00539 event = ntohl(*((unsigned int *)(data))); 00540 event >>= 24; 00541 event_end = ntohl(*((unsigned int *)(data))); 00542 event_end <<= 8; 00543 event_end >>= 24; 00544 duration = ntohl(*((unsigned int *)(data))); 00545 duration &= 0xFFFF; 00546 ast_verbose("Got rfc2833 RTP packet from %s:%d (type %d, seq %d, ts %d, len %d, mark %d, event %08x, end %d, duration %d) \n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp, res - hdrlen, (mark?1:0), event, ((event_end & 0x80)?1:0), duration); 00547 } 00548 if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) { 00549 f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen, seqno); 00550 rtp->lasteventseqn = seqno; 00551 } else 00552 f = NULL; 00553 if (f) 00554 return f; 00555 else 00556 return &null_frame; 00557 } else if (rtpPT.code == AST_RTP_CISCO_DTMF) { 00558 /* It's really special -- process it the Cisco way */ 00559 if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) { 00560 f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); 00561 rtp->lasteventseqn = seqno; 00562 } else 00563 f = NULL; 00564 if (f) 00565 return f; 00566 else 00567 return &null_frame; 00568 } else if (rtpPT.code == AST_RTP_CN) { 00569 /* Comfort Noise */ 00570 f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen); 00571 if (f) 00572 return f; 00573 else 00574 return &null_frame; 00575 } else { 00576 ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype); 00577 return &null_frame; 00578 } 00579 } 00580 rtp->f.subclass = rtpPT.code; 00581 if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) 00582 rtp->f.frametype = AST_FRAME_VOICE; 00583 else 00584 rtp->f.frametype = AST_FRAME_VIDEO; 00585 rtp->lastrxformat = rtp->f.subclass; 00586 00587 if (!rtp->lastrxts) 00588 rtp->lastrxts = timestamp; 00589 00590 if (rtp->rxseqno) { 00591 for (x=rtp->rxseqno + 1; x < seqno; x++) { 00592 /* Queue empty frames */ 00593 rtp->f.mallocd = 0; 00594 rtp->f.datalen = 0; 00595 rtp->f.data = NULL; 00596 rtp->f.offset = 0; 00597 rtp->f.samples = 0; 00598 rtp->f.src = "RTPMissedFrame"; 00599 } 00600 } 00601 rtp->rxseqno = seqno; 00602 00603 if (rtp->dtmfcount) { 00604 #if 0 00605 printf("dtmfcount was %d\n", rtp->dtmfcount); 00606 #endif 00607 rtp->dtmfcount -= (timestamp - rtp->lastrxts); 00608 if (rtp->dtmfcount < 0) 00609 rtp->dtmfcount = 0; 00610 #if 0 00611 if (dtmftimeout != rtp->dtmfcount) 00612 printf("dtmfcount is %d\n", rtp->dtmfcount); 00613 #endif 00614 } 00615 rtp->lastrxts = timestamp; 00616 00617 /* Send any pending DTMF */ 00618 if (rtp->resp && !rtp->dtmfcount) { 00619 if (option_debug) 00620 ast_log(LOG_DEBUG, "Sending pending DTMF\n"); 00621 return send_dtmf(rtp); 00622 } 00623 rtp->f.mallocd = 0; 00624 rtp->f.datalen = res - hdrlen; 00625 rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET; 00626 rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET; 00627 if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) { 00628 rtp->f.samples = ast_codec_get_samples(&rtp->f); 00629 if (rtp->f.subclass == AST_FORMAT_SLINEAR) 00630 ast_frame_byteswap_be(&rtp->f); 00631 calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark); 00632 } else { 00633 /* Video -- samples is # of samples vs. 90000 */ 00634 if (!rtp->lastividtimestamp) 00635 rtp->lastividtimestamp = timestamp; 00636 rtp->f.samples = timestamp - rtp->lastividtimestamp; 00637 rtp->lastividtimestamp = timestamp; 00638 rtp->f.delivery.tv_sec = 0; 00639 rtp->f.delivery.tv_usec = 0; 00640 if (mark) 00641 rtp->f.subclass |= 0x1; 00642 00643 } 00644 rtp->f.src = "RTP"; 00645 return &rtp->f; 00646 }
|
|
Definition at line 1825 of file rtp.c. References ast_config_destroy(), ast_config_load(), ast_false(), ast_log(), ast_variable_retrieve(), ast_verbose(), cfg, DEFAULT_DTMF_TIMEOUT, dtmftimeout, LOG_WARNING, option_verbose, rtpend, rtpstart, s, and VERBOSE_PREFIX_2. Referenced by ast_module_reload(), ast_rtp_init(), and main(). 01826 { 01827 struct ast_config *cfg; 01828 char *s; 01829 01830 rtpstart = 5000; 01831 rtpend = 31000; 01832 dtmftimeout = DEFAULT_DTMF_TIMEOUT; 01833 cfg = ast_config_load("rtp.conf"); 01834 if (cfg) { 01835 if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) { 01836 rtpstart = atoi(s); 01837 if (rtpstart < 1024) 01838 rtpstart = 1024; 01839 if (rtpstart > 65535) 01840 rtpstart = 65535; 01841 } 01842 if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) { 01843 rtpend = atoi(s); 01844 if (rtpend < 1024) 01845 rtpend = 1024; 01846 if (rtpend > 65535) 01847 rtpend = 65535; 01848 } 01849 if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) { 01850 #ifdef SO_NO_CHECK 01851 if (ast_false(s)) 01852 nochecksums = 1; 01853 else 01854 nochecksums = 0; 01855 #else 01856 if (ast_false(s)) 01857 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n"); 01858 #endif 01859 } 01860 if ((s = ast_variable_retrieve(cfg, "general", "dtmftimeout"))) { 01861 dtmftimeout = atoi(s); 01862 if ((dtmftimeout < 0) || (dtmftimeout > 20000)) { 01863 ast_log(LOG_WARNING, "DTMF timeout of '%d' outside range, using default of '%d' instead\n", 01864 dtmftimeout, DEFAULT_DTMF_TIMEOUT); 01865 dtmftimeout = DEFAULT_DTMF_TIMEOUT; 01866 }; 01867 } 01868 ast_config_destroy(cfg); 01869 } 01870 if (rtpstart >= rtpend) { 01871 ast_log(LOG_WARNING, "Unreasonable values for RTP start/end port in rtp.conf\n"); 01872 rtpstart = 5000; 01873 rtpend = 31000; 01874 } 01875 if (option_verbose > 1) 01876 ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend); 01877 01878 }
|
|
Definition at line 1066 of file rtp.c. References ast_rtp::dtmfcount, ast_rtp::dtmfduration, ast_rtp::dtmfmute, ast_rtp::lastdigitts, ast_rtp::lasteventendseqn, 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. 01067 { 01068 memset(&rtp->rxcore, 0, sizeof(rtp->rxcore)); 01069 memset(&rtp->txcore, 0, sizeof(rtp->txcore)); 01070 memset(&rtp->dtmfmute, 0, sizeof(rtp->dtmfmute)); 01071 rtp->lastts = 0; 01072 rtp->lastdigitts = 0; 01073 rtp->lastrxts = 0; 01074 rtp->lastividtimestamp = 0; 01075 rtp->lastovidtimestamp = 0; 01076 rtp->lasteventseqn = 0; 01077 rtp->lasteventendseqn = 0; 01078 rtp->lasttxformat = 0; 01079 rtp->lastrxformat = 0; 01080 rtp->dtmfcount = 0; 01081 rtp->dtmfduration = 0; 01082 rtp->seqno = 0; 01083 rtp->rxseqno = 0; 01084 }
|
|
Definition at line 1202 of file rtp.c. References ast_inet_ntoa(), ast_log(), AST_RTP_CN, ast_rtp_lookup_code(), ast_tvadd(), ast_verbose(), ast_rtp::dtmfmute, 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(). 01203 { 01204 unsigned int *rtpheader; 01205 int hdrlen = 12; 01206 int res; 01207 int payload; 01208 char data[256]; 01209 char iabuf[INET_ADDRSTRLEN]; 01210 level = 127 - (level & 0x7f); 01211 payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN); 01212 01213 /* If we have no peer, return immediately */ 01214 if (!rtp->them.sin_addr.s_addr) 01215 return 0; 01216 01217 rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); 01218 01219 /* Get a pointer to the header */ 01220 rtpheader = (unsigned int *)data; 01221 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++)); 01222 rtpheader[1] = htonl(rtp->lastts); 01223 rtpheader[2] = htonl(rtp->ssrc); 01224 data[12] = level; 01225 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { 01226 res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them)); 01227 if (res <0) 01228 ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno)); 01229 if(rtp_debug_test_addr(&rtp->them)) 01230 ast_verbose("Sent Comfort Noise RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n" 01231 , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen); 01232 01233 } 01234 return 0; 01235 }
|
|
Definition at line 1120 of file rtp.c. References ast_inet_ntoa(), ast_log(), AST_RTP_DTMF, ast_rtp_lookup_code(), ast_tvadd(), ast_verbose(), LOG_ERROR, LOG_WARNING, and rtp_debug_test_addr(). Referenced by oh323_digit(), and sip_senddigit(). 01121 { 01122 unsigned int *rtpheader; 01123 int hdrlen = 12; 01124 int res; 01125 int x; 01126 int payload; 01127 char data[256]; 01128 char iabuf[INET_ADDRSTRLEN]; 01129 01130 if ((digit <= '9') && (digit >= '0')) 01131 digit -= '0'; 01132 else if (digit == '*') 01133 digit = 10; 01134 else if (digit == '#') 01135 digit = 11; 01136 else if ((digit >= 'A') && (digit <= 'D')) 01137 digit = digit - 'A' + 12; 01138 else if ((digit >= 'a') && (digit <= 'd')) 01139 digit = digit - 'a' + 12; 01140 else { 01141 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit); 01142 return -1; 01143 } 01144 payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF); 01145 01146 /* If we have no peer, return immediately */ 01147 if (!rtp->them.sin_addr.s_addr) 01148 return 0; 01149 01150 rtp->dtmfmute = ast_tvadd(ast_tvnow(), ast_tv(0, 500000)); 01151 01152 /* Get a pointer to the header */ 01153 rtpheader = (unsigned int *)data; 01154 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno)); 01155 rtpheader[1] = htonl(rtp->lastdigitts); 01156 rtpheader[2] = htonl(rtp->ssrc); 01157 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0)); 01158 for (x = 0; x < 6; x++) { 01159 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) { 01160 res = sendto(rtp->s, (void *) rtpheader, hdrlen + 4, 0, (struct sockaddr *) &rtp->them, sizeof(rtp->them)); 01161 if (res < 0) 01162 ast_log(LOG_ERROR, "RTP Transmission error to %s:%d: %s\n", 01163 ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), 01164 ntohs(rtp->them.sin_port), strerror(errno)); 01165 if (rtp_debug_test_addr(&rtp->them)) 01166 ast_verbose("Sent RTP packet to %s:%d (type %d, seq %u, ts %u, len %u)\n", 01167 ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), 01168 ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastdigitts, res - hdrlen); 01169 } 01170 /* Sequence number of last two end packets does not get incremented */ 01171 if (x < 3) 01172 rtp->seqno++; 01173 /* Clear marker bit and set seqno */ 01174 rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno)); 01175 /* For the last three packets, set the duration and the end bit */ 01176 if (x == 2) { 01177 #if 0 01178 /* No, this is wrong... Do not increment lastdigitts, that's not according 01179 to the RFC, as best we can determine */ 01180 rtp->lastdigitts++; /* or else the SPA3000 will click instead of beeping... */ 01181 rtpheader[1] = htonl(rtp->lastdigitts); 01182 #endif 01183 /* Make duration 800 (100ms) */ 01184 rtpheader[3] |= htonl((800)); 01185 /* Set the End bit */ 01186 rtpheader[3] |= htonl((1 << 23)); 01187 } 01188 } 01189 /* Increment the digit timestamp by 120ms, to ensure that digits 01190 sent sequentially with no intervening non-digit packets do not 01191 get sent with the same timestamp, and that sequential digits 01192 have some 'dead air' in between them 01193 */ 01194 rtp->lastdigitts += 960; 01195 /* Increment the sequence number to reflect the last packet 01196 that was sent 01197 */ 01198 rtp->seqno++; 01199 return 0; 01200 }
|
|
Definition at line 170 of file rtp.c. References ast_rtp::callback. Referenced by start_rtp(). 00171 { 00172 rtp->callback = callback; 00173 }
|
|
Definition at line 165 of file rtp.c. References ast_rtp::data. Referenced by start_rtp(). 00166 { 00167 rtp->data = data; 00168 }
|
|
Definition at line 742 of file rtp.c. References rtpPayloadType::code. Referenced by process_sdp(). 00742 { 00743 if (pt < 0 || pt > MAX_RTP_PT) 00744 return; /* bogus payload type */ 00745 00746 if (static_RTP_PT[pt].code != 0) { 00747 rtp->current_RTP_PT[pt] = static_RTP_PT[pt]; 00748 } 00749 }
|
|
Definition at line 1033 of file rtp.c. References ast_rtp::rtcp, ast_rtp::rxseqno, ast_rtp::them, and ast_rtcp::them. Referenced by handle_message(), process_sdp(), and setup_rtp_connection(). 01034 { 01035 rtp->them.sin_port = them->sin_port; 01036 rtp->them.sin_addr = them->sin_addr; 01037 if (rtp->rtcp) { 01038 rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1); 01039 rtp->rtcp->them.sin_addr = them->sin_addr; 01040 } 01041 rtp->rxseqno = 0; 01042 }
|
|
Definition at line 753 of file rtp.c. References ast_rtp::current_RTP_PT, mimeTypes, subtype, and type. Referenced by process_sdp(), and set_dtmf_payload(). 00754 { 00755 int i; 00756 00757 if (pt < 0 || pt > MAX_RTP_PT) 00758 return; /* bogus payload type */ 00759 00760 for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) { 00761 if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 && 00762 strcasecmp(mimeType, mimeTypes[i].type) == 0) { 00763 rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType; 00764 return; 00765 } 00766 } 00767 }
|
|
Definition at line 175 of file rtp.c. References ast_rtp::nat. Referenced by check_user_full(), create_addr(), create_addr_from_peer(), oh323_request(), oh323_rtp_read(), sip_alloc(), and start_rtp().
|
|
Definition at line 1024 of file rtp.c. References ast_log(), LOG_WARNING, and ast_rtp::s. Referenced by oh323_alloc(), and sip_alloc(). 01025 { 01026 int res; 01027 01028 if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) 01029 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos); 01030 return res; 01031 }
|
|
Definition at line 1056 of file rtp.c. References ast_rtp::rtcp, ast_rtp::them, and ast_rtcp::them. Referenced by handle_request_bye(), handle_request_cancel(), handle_response(), and process_sdp(). 01057 { 01058 memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr)); 01059 memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port)); 01060 if (rtp->rtcp) { 01061 memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->them.sin_addr)); 01062 memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->them.sin_port)); 01063 } 01064 }
|
|
Definition at line 1318 of file rtp.c. References AST_FORMAT_ADPCM, AST_FORMAT_ALAW, AST_FORMAT_G723_1, AST_FORMAT_G726, AST_FORMAT_G729A, AST_FORMAT_GSM, AST_FORMAT_H261, AST_FORMAT_H263, AST_FORMAT_H263_PLUS, AST_FORMAT_ILBC, AST_FORMAT_LPC10, AST_FORMAT_SLINEAR, AST_FORMAT_SPEEX, AST_FORMAT_ULAW, AST_FRAME_VIDEO, AST_FRAME_VOICE, ast_frdup(), ast_getformatname(), ast_log(), ast_rtp_lookup_code(), ast_rtp_raw_write(), ast_smoother_feed, ast_smoother_feed_be, AST_SMOOTHER_FLAG_G729, ast_smoother_free(), ast_smoother_new(), ast_smoother_read(), ast_smoother_set_flags(), ast_frame::datalen, ast_frame::frametype, LOG_DEBUG, LOG_WARNING, ast_frame::offset, option_debug, ast_frame::subclass, and ast_rtp::them. Referenced by mgcp_write(), oh323_write(), sip_write(), and skinny_write(). 01319 { 01320 struct ast_frame *f; 01321 int codec; 01322 int hdrlen = 12; 01323 int subclass; 01324 01325 01326 /* If we have no peer, return immediately */ 01327 if (!rtp->them.sin_addr.s_addr) 01328 return 0; 01329 01330 /* If there is no data length, return immediately */ 01331 if (!_f->datalen) 01332 return 0; 01333 01334 /* Make sure we have enough space for RTP header */ 01335 if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) { 01336 ast_log(LOG_WARNING, "RTP can only send voice\n"); 01337 return -1; 01338 } 01339 01340 subclass = _f->subclass; 01341 if (_f->frametype == AST_FRAME_VIDEO) 01342 subclass &= ~0x1; 01343 01344 codec = ast_rtp_lookup_code(rtp, 1, subclass); 01345 if (codec < 0) { 01346 ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass)); 01347 return -1; 01348 } 01349 01350 if (rtp->lasttxformat != subclass) { 01351 /* New format, reset the smoother */ 01352 if (option_debug) 01353 ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass)); 01354 rtp->lasttxformat = subclass; 01355 if (rtp->smoother) 01356 ast_smoother_free(rtp->smoother); 01357 rtp->smoother = NULL; 01358 } 01359 01360 01361 switch(subclass) { 01362 case AST_FORMAT_SLINEAR: 01363 if (!rtp->smoother) { 01364 rtp->smoother = ast_smoother_new(320); 01365 } 01366 if (!rtp->smoother) { 01367 ast_log(LOG_WARNING, "Unable to create smoother :(\n"); 01368 return -1; 01369 } 01370 ast_smoother_feed_be(rtp->smoother, _f); 01371 01372 while((f = ast_smoother_read(rtp->smoother))) 01373 ast_rtp_raw_write(rtp, f, codec); 01374 break; 01375 case AST_FORMAT_ULAW: 01376 case AST_FORMAT_ALAW: 01377 if (!rtp->smoother) { 01378 rtp->smoother = ast_smoother_new(160); 01379 } 01380 if (!rtp->smoother) { 01381 ast_log(LOG_WARNING, "Unable to create smoother :(\n"); 01382 return -1; 01383 } 01384 ast_smoother_feed(rtp->smoother, _f); 01385 01386 while((f = ast_smoother_read(rtp->smoother))) 01387 ast_rtp_raw_write(rtp, f, codec); 01388 break; 01389 case AST_FORMAT_ADPCM: 01390 case AST_FORMAT_G726: 01391 if (!rtp->smoother) { 01392 rtp->smoother = ast_smoother_new(80); 01393 } 01394 if (!rtp->smoother) { 01395 ast_log(LOG_WARNING, "Unable to create smoother :(\n"); 01396 return -1; 01397 } 01398 ast_smoother_feed(rtp->smoother, _f); 01399 01400 while((f = ast_smoother_read(rtp->smoother))) 01401 ast_rtp_raw_write(rtp, f, codec); 01402 break; 01403 case AST_FORMAT_G729A: 01404 if (!rtp->smoother) { 01405 rtp->smoother = ast_smoother_new(20); 01406 if (rtp->smoother) 01407 ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_G729); 01408 } 01409 if (!rtp->smoother) { 01410 ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n"); 01411 return -1; 01412 } 01413 ast_smoother_feed(rtp->smoother, _f); 01414 01415 while((f = ast_smoother_read(rtp->smoother))) 01416 ast_rtp_raw_write(rtp, f, codec); 01417 break; 01418 case AST_FORMAT_GSM: 01419 if (!rtp->smoother) { 01420 rtp->smoother = ast_smoother_new(33); 01421 } 01422 if (!rtp->smoother) { 01423 ast_log(LOG_WARNING, "Unable to create GSM smoother :(\n"); 01424 return -1; 01425 } 01426 ast_smoother_feed(rtp->smoother, _f); 01427 while((f = ast_smoother_read(rtp->smoother))) 01428 ast_rtp_raw_write(rtp, f, codec); 01429 break; 01430 case AST_FORMAT_ILBC: 01431 if (!rtp->smoother) { 01432 rtp->smoother = ast_smoother_new(50); 01433 } 01434 if (!rtp->smoother) { 01435 ast_log(LOG_WARNING, "Unable to create ILBC smoother :(\n"); 01436 return -1; 01437 } 01438 ast_smoother_feed(rtp->smoother, _f); 01439 while((f = ast_smoother_read(rtp->smoother))) 01440 ast_rtp_raw_write(rtp, f, codec); 01441 break; 01442 default: 01443 ast_log(LOG_WARNING, "Not sure about sending format %s packets\n", ast_getformatname(subclass)); 01444 /* fall through to... */ 01445 case AST_FORMAT_H261: 01446 case AST_FORMAT_H263: 01447 case AST_FORMAT_H263_PLUS: 01448 case AST_FORMAT_G723_1: 01449 case AST_FORMAT_LPC10: 01450 case AST_FORMAT_SPEEX: 01451 /* Don't buffer outgoing frames; send them one-per-packet: */ 01452 if (_f->offset < hdrlen) { 01453 f = ast_frdup(_f); 01454 } else { 01455 f = _f; 01456 } 01457 ast_rtp_raw_write(rtp, f, codec); 01458 } 01459 01460 return 0; 01461 }
|
|
Definition at line 415 of file rtp.c. References ast_tvadd(), ast_tvsub(), and ast_rtp::rxcore. Referenced by ast_rtp_read(), and schedule_delivery(). 00416 { 00417 struct timeval ts = ast_samp2tv( timestamp, 8000); 00418 if (ast_tvzero(rtp->rxcore) || mark) { 00419 rtp->rxcore = ast_tvsub(ast_tvnow(), ts); 00420 /* Round to 20ms for nice, pretty timestamps */ 00421 rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000; 00422 } 00423 *tv = ast_tvadd(rtp->rxcore, ts); 00424 }
|
|
Definition at line 1101 of file rtp.c. References ast_rtp::txcore. Referenced by ast_rtp_raw_write(). 01102 { 01103 struct timeval t; 01104 long ms; 01105 if (ast_tvzero(rtp->txcore)) { 01106 rtp->txcore = ast_tvnow(); 01107 /* Round to 20ms for nice, pretty timestamps */ 01108 rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000; 01109 } 01110 /* Use previous txcore if available */ 01111 t = (delivery && !ast_tvzero(*delivery)) ? *delivery : ast_tvnow(); 01112 ms = ast_tvdiff_ms(t, rtp->txcore); 01113 if (ms < 0) 01114 ms = 0; 01115 /* Use what we just got for next time */ 01116 rtp->txcore = t; 01117 return (unsigned int) ms; 01118 }
|
|
Definition at line 1501 of file rtp.c. References ast_rtp_protocol::next, ast_channel::type, and ast_rtp_protocol::type. Referenced by ast_rtp_bridge(). 01502 { 01503 struct ast_rtp_protocol *cur; 01504 01505 cur = protos; 01506 while(cur) { 01507 if (cur->type == chan->type) { 01508 return cur; 01509 } 01510 cur = cur->next; 01511 } 01512 return NULL; 01513 }
|
|
Definition at line 224 of file rtp.c. References ast_rtp::dtmfcount, dtmftimeout, ast_rtp::resp, and send_dtmf(). Referenced by ast_rtp_read(). 00225 { 00226 unsigned int event; 00227 char resp = 0; 00228 struct ast_frame *f = NULL; 00229 event = ntohl(*((unsigned int *)(data))); 00230 event &= 0x001F; 00231 #if 0 00232 printf("Cisco Digit: %08x (len = %d)\n", event, len); 00233 #endif 00234 if (event < 10) { 00235 resp = '0' + event; 00236 } else if (event < 11) { 00237 resp = '*'; 00238 } else if (event < 12) { 00239 resp = '#'; 00240 } else if (event < 16) { 00241 resp = 'A' + (event - 12); 00242 } else if (event < 17) { 00243 resp = 'X'; 00244 } 00245 if (rtp->resp && (rtp->resp != resp)) { 00246 f = send_dtmf(rtp); 00247 } 00248 rtp->resp = resp; 00249 rtp->dtmfcount = dtmftimeout; 00250 return f; 00251 }
|
|
Process RTP DTMF and events according to RFC 2833. RFC 2833 is "RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals".
Definition at line 264 of file rtp.c. References ast_log(), ast_rtp::dtmfcount, ast_rtp::dtmfduration, dtmftimeout, ast_rtp::lasteventendseqn, LOG_DEBUG, ast_rtp::resp, rtpdebug, and send_dtmf(). Referenced by ast_rtp_read(). 00265 { 00266 unsigned int event; 00267 unsigned int event_end; 00268 unsigned int duration; 00269 char resp = 0; 00270 struct ast_frame *f = NULL; 00271 event = ntohl(*((unsigned int *)(data))); 00272 event >>= 24; 00273 event_end = ntohl(*((unsigned int *)(data))); 00274 event_end <<= 8; 00275 event_end >>= 24; 00276 duration = ntohl(*((unsigned int *)(data))); 00277 duration &= 0xFFFF; 00278 if (rtpdebug) 00279 ast_log(LOG_DEBUG, "- RTP 2833 Event: %08x (len = %d)\n", event, len); 00280 if (event < 10) { 00281 resp = '0' + event; 00282 } else if (event < 11) { 00283 resp = '*'; 00284 } else if (event < 12) { 00285 resp = '#'; 00286 } else if (event < 16) { 00287 resp = 'A' + (event - 12); 00288 } else if (event < 17) { /* Event 16: Hook flash */ 00289 resp = 'X'; 00290 } 00291 if (rtp->resp && (rtp->resp != resp)) { 00292 f = send_dtmf(rtp); 00293 } else if(event_end & 0x80) { 00294 if (rtp->resp) { 00295 if(rtp->lasteventendseqn != seqno) { 00296 f = send_dtmf(rtp); 00297 rtp->lasteventendseqn = seqno; 00298 } 00299 rtp->resp = 0; 00300 } 00301 resp = 0; 00302 duration = 0; 00303 } else if (rtp->resp && rtp->dtmfduration && (duration < rtp->dtmfduration)) { 00304 f = send_dtmf(rtp); 00305 } 00306 if (!(event_end & 0x80)) 00307 rtp->resp = resp; 00308 rtp->dtmfcount = dtmftimeout; 00309 rtp->dtmfduration = duration; 00310 return f; 00311 }
|
|
Process Comfort Noise RTP. This is incomplete at the moment. Definition at line 319 of file rtp.c. References AST_FRAME_CNG, AST_FRIENDLY_OFFSET, ast_inet_ntoa(), ast_log(), ast_set_flag, ast_test_flag, FLAG_3389_WARNING, LOG_DEBUG, LOG_NOTICE, and rtpdebug. Referenced by ast_rtp_read(). 00320 { 00321 struct ast_frame *f = NULL; 00322 /* Convert comfort noise into audio with various codecs. Unfortunately this doesn't 00323 totally help us out becuase we don't have an engine to keep it going and we are not 00324 guaranteed to have it every 20ms or anything */ 00325 if (rtpdebug) 00326 ast_log(LOG_DEBUG, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", rtp->lastrxformat, len); 00327 00328 if (!(ast_test_flag(rtp, FLAG_3389_WARNING))) { 00329 char iabuf[INET_ADDRSTRLEN]; 00330 00331 ast_log(LOG_NOTICE, "Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client IP: %s\n", 00332 ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr)); 00333 ast_set_flag(rtp, FLAG_3389_WARNING); 00334 } 00335 00336 /* Must have at least one byte */ 00337 if (!len) 00338 return NULL; 00339 if (len < 24) { 00340 rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET; 00341 rtp->f.datalen = len - 1; 00342 rtp->f.offset = AST_FRIENDLY_OFFSET; 00343 memcpy(rtp->f.data, data + 1, len - 1); 00344 } else { 00345 rtp->f.data = NULL; 00346 rtp->f.offset = 0; 00347 rtp->f.datalen = 0; 00348 } 00349 rtp->f.frametype = AST_FRAME_CNG; 00350 rtp->f.subclass = data[0] & 0x7f; 00351 rtp->f.datalen = len - 1; 00352 rtp->f.samples = 0; 00353 rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0; 00354 f = &rtp->f; 00355 return f; 00356 }
|
|
Definition at line 211 of file rtp.c. References rtpdebug, and rtpdebugaddr. Referenced by ast_rtp_raw_write(), ast_rtp_read(), ast_rtp_sendcng(), and ast_rtp_senddigit(). 00212 { 00213 if (rtpdebug == 0) 00214 return 0; 00215 if (rtpdebugaddr.sin_addr.s_addr) { 00216 if (((ntohs(rtpdebugaddr.sin_port) != 0) 00217 && (rtpdebugaddr.sin_port != addr->sin_port)) 00218 || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr)) 00219 return 0; 00220 } 00221 return 1; 00222 }
|
|
Definition at line 1786 of file rtp.c. References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, rtp_do_debug_ip(), rtpdebug, and rtpdebugaddr. 01787 { 01788 if(argc != 2) { 01789 if(argc != 4) 01790 return RESULT_SHOWUSAGE; 01791 return rtp_do_debug_ip(fd, argc, argv); 01792 } 01793 rtpdebug = 1; 01794 memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr)); 01795 ast_cli(fd, "RTP Debugging Enabled\n"); 01796 return RESULT_SUCCESS; 01797 }
|
|
Definition at line 1755 of file rtp.c. References ast_cli(), ast_gethostbyname(), ast_inet_ntoa(), hp, RESULT_SHOWUSAGE, RESULT_SUCCESS, rtpdebug, and rtpdebugaddr. Referenced by rtp_do_debug(). 01756 { 01757 struct hostent *hp; 01758 struct ast_hostent ahp; 01759 char iabuf[INET_ADDRSTRLEN]; 01760 int port = 0; 01761 char *p, *arg; 01762 01763 if (argc != 4) 01764 return RESULT_SHOWUSAGE; 01765 arg = argv[3]; 01766 p = strstr(arg, ":"); 01767 if (p) { 01768 *p = '\0'; 01769 p++; 01770 port = atoi(p); 01771 } 01772 hp = ast_gethostbyname(arg, &ahp); 01773 if (hp == NULL) 01774 return RESULT_SHOWUSAGE; 01775 rtpdebugaddr.sin_family = AF_INET; 01776 memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr)); 01777 rtpdebugaddr.sin_port = htons(port); 01778 if (port == 0) 01779 ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr)); 01780 else 01781 ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr), port); 01782 rtpdebug = 1; 01783 return RESULT_SUCCESS; 01784 }
|
|
Definition at line 1799 of file rtp.c. References ast_cli(), RESULT_SHOWUSAGE, RESULT_SUCCESS, and rtpdebug. 01800 { 01801 if(argc !=3) 01802 return RESULT_SHOWUSAGE; 01803 rtpdebug = 0; 01804 ast_cli(fd,"RTP Debugging Disabled\n"); 01805 return RESULT_SUCCESS; 01806 }
|
|
Definition at line 891 of file rtp.c. References s. Referenced by ast_rtcp_new(), and ast_rtp_new_with_bindaddr(). 00892 { 00893 int s; 00894 long flags; 00895 s = socket(AF_INET, SOCK_DGRAM, 0); 00896 if (s > -1) { 00897 flags = fcntl(s, F_GETFL); 00898 fcntl(s, F_SETFL, flags | O_NONBLOCK); 00899 #ifdef SO_NO_CHECK 00900 if (nochecksums) 00901 setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &nochecksums, sizeof(nochecksums)); 00902 #endif 00903 } 00904 return s; 00905 }
|
|
Definition at line 358 of file rtp.c. References ast_rtp_read(), ast_rtp::callback, and ast_frame::data. Referenced by ast_rtp_new_with_bindaddr(). 00359 { 00360 struct ast_rtp *rtp = cbdata; 00361 struct ast_frame *f; 00362 f = ast_rtp_read(rtp); 00363 if (f) { 00364 if (rtp->callback) 00365 rtp->callback(rtp, f, rtp->data); 00366 } 00367 return 1; 00368 }
|
|
Definition at line 180 of file rtp.c. References AST_CONTROL_FLASH, AST_FRAME_CONTROL, AST_FRAME_DTMF, AST_FRAME_NULL, ast_inet_ntoa(), ast_log(), ast_frame::datalen, ast_rtp::dtmfduration, ast_rtp::dtmfmute, ast_rtp::f, 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 ast_rtp_read(), process_cisco_dtmf(), and process_rfc2833(). 00181 { 00182 static struct ast_frame null_frame = { AST_FRAME_NULL, }; 00183 char iabuf[INET_ADDRSTRLEN]; 00184 00185 if (ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) { 00186 if (option_debug) 00187 ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr)); 00188 rtp->resp = 0; 00189 rtp->dtmfduration = 0; 00190 return &null_frame; 00191 } 00192 if (option_debug) 00193 ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr)); 00194 if (rtp->resp == 'X') { 00195 rtp->f.frametype = AST_FRAME_CONTROL; 00196 rtp->f.subclass = AST_CONTROL_FLASH; 00197 } else { 00198 rtp->f.frametype = AST_FRAME_DTMF; 00199 rtp->f.subclass = rtp->resp; 00200 } 00201 rtp->f.datalen = 0; 00202 rtp->f.samples = 0; 00203 rtp->f.mallocd = 0; 00204 rtp->f.src = "RTP"; 00205 rtp->resp = 0; 00206 rtp->dtmfduration = 0; 00207 return &rtp->f; 00208 00209 }
|
|
Initial value: {{ "rtp", "debug", NULL } , rtp_do_debug, "Enable RTP debugging", debug_usage } |
|
Initial value: {{ "rtp", "debug", "ip", NULL } , rtp_do_debug, "Enable RTP debugging on IP", debug_usage } |
|
Initial value: {{ "rtp", "no", "debug", NULL } , rtp_no_debug, "Disable RTP debugging", no_debug_usage } |
|
Initial value: "Usage: rtp debug [ip host[:port]]\n" " Enable dumping of all RTP packets to and from host.\n" |
|
Definition at line 63 of file rtp.c. Referenced by ast_rtp_read(), ast_rtp_reload(), process_cisco_dtmf(), and process_rfc2833(). |
|
Referenced by ast_rtp_lookup_mime_subtype(), and ast_rtp_set_rtpmap_type(). |
|
Initial value: "Usage: rtp no debug\n" " Disable all RTP debugging\n" |
|
Definition at line 651 of file rtp.c. Referenced by ast_rtp_lookup_mime_subtype(). |
|
|
|
Definition at line 67 of file rtp.c. Referenced by ast_rtcp_read(), ast_rtp_raw_write(), ast_rtp_read(), process_rfc2833(), process_rfc3389(), rtp_debug_test_addr(), rtp_do_debug(), rtp_do_debug_ip(), and rtp_no_debug(). |
|
Definition at line 68 of file rtp.c. Referenced by rtp_debug_test_addr(), rtp_do_debug(), and rtp_do_debug_ip(). |
|
Definition at line 66 of file rtp.c. Referenced by ast_rtp_new_with_bindaddr(), and ast_rtp_reload(). |
|
Definition at line 65 of file rtp.c. Referenced by ast_rtp_new_with_bindaddr(), and ast_rtp_reload(). |
|
|
|
Definition at line 653 of file rtp.c. Referenced by ast_rtp_set_rtpmap_type(). |
|
Definition at line 652 of file rtp.c. Referenced by __oh323_new(), alsa_new(), alsa_read(), ast_modem_new(), ast_rtp_set_rtpmap_type(), ast_writestream(), build_filename(), check_header(), features_new(), find_subscription_type(), load_module(), local_new(), mgcp_new(), misdn_new(), nbs_new(), nbs_xread(), oss_new(), oss_read(), phone_exception(), phone_new(), phone_read(), schedule_delivery(), skinny_new(), ss_thread(), subscription_type2str(), and zt_new(). |