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