Sat Nov 1 06:28:39 2008

Asterisk developer's documentation


rtp.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- An open source telephony toolkit.
00003  *
00004  * Copyright (C) 1999 - 2006, Digium, Inc.
00005  *
00006  * Mark Spencer <markster@digium.com>
00007  *
00008  * See http://www.asterisk.org for more information about
00009  * the Asterisk project. Please do not directly contact
00010  * any of the maintainers of this project for assistance;
00011  * the project provides a web site, mailing lists and IRC
00012  * channels for your use.
00013  *
00014  * This program is free software, distributed under the terms of
00015  * the GNU General Public License Version 2. See the LICENSE file
00016  * at the top of the source tree.
00017  */
00018 
00019 /*! 
00020  * \file 
00021  *
00022  * \brief Supports RTP and RTCP with Symmetric RTP support for NAT traversal.
00023  *
00024  * \author Mark Spencer <markster@digium.com>
00025  * 
00026  * \note RTP is defined in RFC 3550.
00027  */
00028 
00029 #include "asterisk.h"
00030 
00031 ASTERISK_FILE_VERSION(__FILE__, "$Revision: 143337 $")
00032 
00033 #include <stdio.h>
00034 #include <stdlib.h>
00035 #include <string.h>
00036 #include <sys/time.h>
00037 #include <signal.h>
00038 #include <errno.h>
00039 #include <unistd.h>
00040 #include <netinet/in.h>
00041 #include <sys/time.h>
00042 #include <sys/socket.h>
00043 #include <arpa/inet.h>
00044 #include <fcntl.h>
00045 
00046 #include "asterisk/rtp.h"
00047 #include "asterisk/frame.h"
00048 #include "asterisk/logger.h"
00049 #include "asterisk/options.h"
00050 #include "asterisk/channel.h"
00051 #include "asterisk/acl.h"
00052 #include "asterisk/channel.h"
00053 #include "asterisk/config.h"
00054 #include "asterisk/lock.h"
00055 #include "asterisk/utils.h"
00056 #include "asterisk/cli.h"
00057 #include "asterisk/unaligned.h"
00058 #include "asterisk/utils.h"
00059 
00060 #define MAX_TIMESTAMP_SKEW 640
00061 
00062 #define RTP_SEQ_MOD     (1<<16)  /*!< A sequence number can't be more than 16 bits */
00063 #define RTCP_DEFAULT_INTERVALMS   5000 /*!< Default milli-seconds between RTCP reports we send */
00064 #define RTCP_MIN_INTERVALMS       500  /*!< Min milli-seconds between RTCP reports we send */
00065 #define RTCP_MAX_INTERVALMS       60000   /*!< Max milli-seconds between RTCP reports we send */
00066 
00067 #define RTCP_PT_FUR     192
00068 #define RTCP_PT_SR      200
00069 #define RTCP_PT_RR      201
00070 #define RTCP_PT_SDES    202
00071 #define RTCP_PT_BYE     203
00072 #define RTCP_PT_APP     204
00073 
00074 #define RTP_MTU      1200
00075 
00076 #define DEFAULT_DTMF_TIMEOUT 3000   /*!< samples */
00077 
00078 static int dtmftimeout = DEFAULT_DTMF_TIMEOUT;
00079 
00080 static int rtpstart;       /*!< First port for RTP sessions (set in rtp.conf) */
00081 static int rtpend;         /*!< Last port for RTP sessions (set in rtp.conf) */
00082 static int rtpdebug;       /*!< Are we debugging? */
00083 static int rtcpdebug;         /*!< Are we debugging RTCP? */
00084 static int rtcpstats;         /*!< Are we debugging RTCP? */
00085 static int rtcpinterval = RTCP_DEFAULT_INTERVALMS; /*!< Time between rtcp reports in millisecs */
00086 static int stundebug;         /*!< Are we debugging stun? */
00087 static struct sockaddr_in rtpdebugaddr;   /*!< Debug packets to/from this host */
00088 static struct sockaddr_in rtcpdebugaddr;  /*!< Debug RTCP packets to/from this host */
00089 #ifdef SO_NO_CHECK
00090 static int nochecksums;
00091 #endif
00092 
00093 /* Uncomment this to enable more intense native bridging, but note: this is currently buggy */
00094 /* #define P2P_INTENSE */
00095 
00096 /*!
00097  * \brief Structure representing a RTP session.
00098  *
00099  * RTP session is defined on page 9 of RFC 3550: "An association among a set of participants communicating with RTP.  A participant may be involved in multiple RTP sessions at the same time [...]"
00100  *
00101  */
00102 /*! \brief The value of each payload format mapping: */
00103 struct rtpPayloadType {
00104    int isAstFormat;  /*!< whether the following code is an AST_FORMAT */
00105    int code;
00106 };
00107 
00108 
00109 /*! \brief RTP session description */
00110 struct ast_rtp {
00111    int s;
00112    struct ast_frame f;
00113    unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
00114    unsigned int ssrc;      /*!< Synchronization source, RFC 3550, page 10. */
00115    unsigned int themssrc;     /*!< Their SSRC */
00116    unsigned int rxssrc;
00117    unsigned int lastts;
00118    unsigned int lastrxts;
00119    unsigned int lastividtimestamp;
00120    unsigned int lastovidtimestamp;
00121    unsigned int lasteventseqn;
00122    int lastrxseqno;                /*!< Last received sequence number */
00123    unsigned short seedrxseqno;     /*!< What sequence number did they start with?*/
00124    unsigned int seedrxts;          /*!< What RTP timestamp did they start with? */
00125    unsigned int rxcount;           /*!< How many packets have we received? */
00126    unsigned int rxoctetcount;      /*!< How many octets have we received? should be rxcount *160*/
00127    unsigned int txcount;           /*!< How many packets have we sent? */
00128    unsigned int txoctetcount;      /*!< How many octets have we sent? (txcount*160)*/
00129    unsigned int cycles;            /*!< Shifted count of sequence number cycles */
00130    double rxjitter;                /*!< Interarrival jitter at the moment */
00131    double rxtransit;               /*!< Relative transit time for previous packet */
00132    int lasttxformat;
00133    int lastrxformat;
00134 
00135    int rtptimeout;         /*!< RTP timeout time (negative or zero means disabled, negative value means temporarily disabled) */
00136    int rtpholdtimeout;     /*!< RTP timeout when on hold (negative or zero means disabled, negative value means temporarily disabled). */
00137    int rtpkeepalive;    /*!< Send RTP comfort noice packets for keepalive */
00138 
00139    /* DTMF Reception Variables */
00140    char resp;
00141    unsigned int lastevent;
00142    int dtmfcount;
00143    unsigned int dtmfsamples;
00144    /* DTMF Transmission Variables */
00145    unsigned int lastdigitts;
00146    char sending_digit;  /*!< boolean - are we sending digits */
00147    char send_digit;  /*!< digit we are sending */
00148    int send_payload;
00149    int send_duration;
00150    int nat;
00151    unsigned int flags;
00152    struct sockaddr_in us;     /*!< Socket representation of the local endpoint. */
00153    struct sockaddr_in them;   /*!< Socket representation of the remote endpoint. */
00154    struct timeval rxcore;
00155    struct timeval txcore;
00156    double drxcore;                 /*!< The double representation of the first received packet */
00157    struct timeval lastrx;          /*!< timeval when we last received a packet */
00158    struct timeval dtmfmute;
00159    struct ast_smoother *smoother;
00160    int *ioid;
00161    unsigned short seqno;      /*!< Sequence number, RFC 3550, page 13. */
00162    unsigned short rxseqno;
00163    struct sched_context *sched;
00164    struct io_context *io;
00165    void *data;
00166    ast_rtp_callback callback;
00167    ast_mutex_t bridge_lock;
00168    struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
00169    int rtp_lookup_code_cache_isAstFormat; /*!< a cache for the result of rtp_lookup_code(): */
00170    int rtp_lookup_code_cache_code;
00171    int rtp_lookup_code_cache_result;
00172    struct ast_rtcp *rtcp;
00173    struct ast_codec_pref pref;
00174    struct ast_rtp *bridged;        /*!< Who we are Packet bridged to */
00175    int set_marker_bit:1;           /*!< Whether to set the marker bit or not */
00176 };
00177 
00178 /* Forward declarations */
00179 static int ast_rtcp_write(const void *data);
00180 static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw);
00181 static int ast_rtcp_write_sr(const void *data);
00182 static int ast_rtcp_write_rr(const void *data);
00183 static unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp);
00184 static int ast_rtp_senddigit_continuation(struct ast_rtp *rtp);
00185 int ast_rtp_senddigit_end(struct ast_rtp *rtp, char digit);
00186 
00187 #define FLAG_3389_WARNING     (1 << 0)
00188 #define FLAG_NAT_ACTIVE       (3 << 1)
00189 #define FLAG_NAT_INACTIVE     (0 << 1)
00190 #define FLAG_NAT_INACTIVE_NOWARN (1 << 1)
00191 #define FLAG_HAS_DTMF         (1 << 3)
00192 #define FLAG_P2P_SENT_MARK              (1 << 4)
00193 #define FLAG_P2P_NEED_DTMF              (1 << 5)
00194 #define FLAG_CALLBACK_MODE              (1 << 6)
00195 #define FLAG_DTMF_COMPENSATE            (1 << 7)
00196 #define FLAG_HAS_STUN                   (1 << 8)
00197 
00198 /*!
00199  * \brief Structure defining an RTCP session.
00200  * 
00201  * The concept "RTCP session" is not defined in RFC 3550, but since 
00202  * this structure is analogous to ast_rtp, which tracks a RTP session, 
00203  * it is logical to think of this as a RTCP session.
00204  *
00205  * RTCP packet is defined on page 9 of RFC 3550.
00206  * 
00207  */
00208 struct ast_rtcp {
00209    int s;            /*!< Socket */
00210    struct sockaddr_in us;     /*!< Socket representation of the local endpoint. */
00211    struct sockaddr_in them;   /*!< Socket representation of the remote endpoint. */
00212    unsigned int soc;    /*!< What they told us */
00213    unsigned int spc;    /*!< What they told us */
00214    unsigned int themrxlsr;    /*!< The middle 32 bits of the NTP timestamp in the last received SR*/
00215    struct timeval rxlsr;      /*!< Time when we got their last SR */
00216    struct timeval txlsr;      /*!< Time when we sent or last SR*/
00217    unsigned int expected_prior;  /*!< no. packets in previous interval */
00218    unsigned int received_prior;  /*!< no. packets received in previous interval */
00219    int schedid;         /*!< Schedid returned from ast_sched_add() to schedule RTCP-transmissions*/
00220    unsigned int rr_count;     /*!< number of RRs we've sent, not including report blocks in SR's */
00221    unsigned int sr_count;     /*!< number of SRs we've sent */
00222    unsigned int lastsrtxcount;     /*!< Transmit packet count when last SR sent */
00223    double accumulated_transit;   /*!< accumulated a-dlsr-lsr */
00224    double rtt;       /*!< Last reported rtt */
00225    unsigned int reported_jitter; /*!< The contents of their last jitter entry in the RR */
00226    unsigned int reported_lost;   /*!< Reported lost packets in their RR */
00227    char quality[AST_MAX_USER_FIELD];
00228    double maxrxjitter;
00229    double minrxjitter;
00230    double maxrtt;
00231    double minrtt;
00232    int sendfur;
00233 };
00234 
00235 
00236 typedef struct { unsigned int id[4]; } __attribute__((packed)) stun_trans_id;
00237 
00238 /* XXX Maybe stun belongs in another file if it ever has use outside of RTP */
00239 struct stun_header {
00240    unsigned short msgtype;
00241    unsigned short msglen;
00242    stun_trans_id  id;
00243    unsigned char ies[0];
00244 } __attribute__((packed));
00245 
00246 struct stun_attr {
00247    unsigned short attr;
00248    unsigned short len;
00249    unsigned char value[0];
00250 } __attribute__((packed));
00251 
00252 struct stun_addr {
00253    unsigned char unused;
00254    unsigned char family;
00255    unsigned short port;
00256    unsigned int addr;
00257 } __attribute__((packed));
00258 
00259 #define STUN_IGNORE     (0)
00260 #define STUN_ACCEPT     (1)
00261 
00262 #define STUN_BINDREQ 0x0001
00263 #define STUN_BINDRESP   0x0101
00264 #define STUN_BINDERR 0x0111
00265 #define STUN_SECREQ  0x0002
00266 #define STUN_SECRESP 0x0102
00267 #define STUN_SECERR  0x0112
00268 
00269 #define STUN_MAPPED_ADDRESS   0x0001
00270 #define STUN_RESPONSE_ADDRESS 0x0002
00271 #define STUN_CHANGE_REQUEST   0x0003
00272 #define STUN_SOURCE_ADDRESS   0x0004
00273 #define STUN_CHANGED_ADDRESS  0x0005
00274 #define STUN_USERNAME      0x0006
00275 #define STUN_PASSWORD      0x0007
00276 #define STUN_MESSAGE_INTEGRITY   0x0008
00277 #define STUN_ERROR_CODE    0x0009
00278 #define STUN_UNKNOWN_ATTRIBUTES  0x000a
00279 #define STUN_REFLECTED_FROM   0x000b
00280 
00281 static const char *stun_msg2str(int msg)
00282 {
00283    switch(msg) {
00284    case STUN_BINDREQ:
00285       return "Binding Request";
00286    case STUN_BINDRESP:
00287       return "Binding Response";
00288    case STUN_BINDERR:
00289       return "Binding Error Response";
00290    case STUN_SECREQ:
00291       return "Shared Secret Request";
00292    case STUN_SECRESP:
00293       return "Shared Secret Response";
00294    case STUN_SECERR:
00295       return "Shared Secret Error Response";
00296    }
00297    return "Non-RFC3489 Message";
00298 }
00299 
00300 static const char *stun_attr2str(int msg)
00301 {
00302    switch(msg) {
00303    case STUN_MAPPED_ADDRESS:
00304       return "Mapped Address";
00305    case STUN_RESPONSE_ADDRESS:
00306       return "Response Address";
00307    case STUN_CHANGE_REQUEST:
00308       return "Change Request";
00309    case STUN_SOURCE_ADDRESS:
00310       return "Source Address";
00311    case STUN_CHANGED_ADDRESS:
00312       return "Changed Address";
00313    case STUN_USERNAME:
00314       return "Username";
00315    case STUN_PASSWORD:
00316       return "Password";
00317    case STUN_MESSAGE_INTEGRITY:
00318       return "Message Integrity";
00319    case STUN_ERROR_CODE:
00320       return "Error Code";
00321    case STUN_UNKNOWN_ATTRIBUTES:
00322       return "Unknown Attributes";
00323    case STUN_REFLECTED_FROM:
00324       return "Reflected From";
00325    }
00326    return "Non-RFC3489 Attribute";
00327 }
00328 
00329 struct stun_state {
00330    const char *username;
00331    const char *password;
00332 };
00333 
00334 static int stun_process_attr(struct stun_state *state, struct stun_attr *attr)
00335 {
00336    if (stundebug)
00337       ast_verbose("Found STUN Attribute %s (%04x), length %d\n",
00338          stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
00339    switch(ntohs(attr->attr)) {
00340    case STUN_USERNAME:
00341       state->username = (const char *) (attr->value);
00342       break;
00343    case STUN_PASSWORD:
00344       state->password = (const char *) (attr->value);
00345       break;
00346    default:
00347       if (stundebug)
00348          ast_verbose("Ignoring STUN attribute %s (%04x), length %d\n", 
00349             stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr), ntohs(attr->len));
00350    }
00351    return 0;
00352 }
00353 
00354 static void append_attr_string(struct stun_attr **attr, int attrval, const char *s, int *len, int *left)
00355 {
00356    int size = sizeof(**attr) + strlen(s);
00357    if (*left > size) {
00358       (*attr)->attr = htons(attrval);
00359       (*attr)->len = htons(strlen(s));
00360       memcpy((*attr)->value, s, strlen(s));
00361       (*attr) = (struct stun_attr *)((*attr)->value + strlen(s));
00362       *len += size;
00363       *left -= size;
00364    }
00365 }
00366 
00367 static void append_attr_address(struct stun_attr **attr, int attrval, struct sockaddr_in *sin, int *len, int *left)
00368 {
00369    int size = sizeof(**attr) + 8;
00370    struct stun_addr *addr;
00371    if (*left > size) {
00372       (*attr)->attr = htons(attrval);
00373       (*attr)->len = htons(8);
00374       addr = (struct stun_addr *)((*attr)->value);
00375       addr->unused = 0;
00376       addr->family = 0x01;
00377       addr->port = sin->sin_port;
00378       addr->addr = sin->sin_addr.s_addr;
00379       (*attr) = (struct stun_attr *)((*attr)->value + 8);
00380       *len += size;
00381       *left -= size;
00382    }
00383 }
00384 
00385 static int stun_send(int s, struct sockaddr_in *dst, struct stun_header *resp)
00386 {
00387    return sendto(s, resp, ntohs(resp->msglen) + sizeof(*resp), 0,
00388       (struct sockaddr *)dst, sizeof(*dst));
00389 }
00390 
00391 static void stun_req_id(struct stun_header *req)
00392 {
00393    int x;
00394    for (x=0;x<4;x++)
00395       req->id.id[x] = ast_random();
00396 }
00397 
00398 size_t ast_rtp_alloc_size(void)
00399 {
00400    return sizeof(struct ast_rtp);
00401 }
00402 
00403 void ast_rtp_stun_request(struct ast_rtp *rtp, struct sockaddr_in *suggestion, const char *username)
00404 {
00405    struct stun_header *req;
00406    unsigned char reqdata[1024];
00407    int reqlen, reqleft;
00408    struct stun_attr *attr;
00409 
00410    req = (struct stun_header *)reqdata;
00411    stun_req_id(req);
00412    reqlen = 0;
00413    reqleft = sizeof(reqdata) - sizeof(struct stun_header);
00414    req->msgtype = 0;
00415    req->msglen = 0;
00416    attr = (struct stun_attr *)req->ies;
00417    if (username)
00418       append_attr_string(&attr, STUN_USERNAME, username, &reqlen, &reqleft);
00419    req->msglen = htons(reqlen);
00420    req->msgtype = htons(STUN_BINDREQ);
00421    stun_send(rtp->s, suggestion, req);
00422 }
00423 
00424 static int stun_handle_packet(int s, struct sockaddr_in *src, unsigned char *data, size_t len)
00425 {
00426    struct stun_header *resp, *hdr = (struct stun_header *)data;
00427    struct stun_attr *attr;
00428    struct stun_state st;
00429    int ret = STUN_IGNORE;  
00430    unsigned char respdata[1024];
00431    int resplen, respleft;
00432    
00433    if (len < sizeof(struct stun_header)) {
00434       if (option_debug)
00435          ast_log(LOG_DEBUG, "Runt STUN packet (only %zd, wanting at least %zd)\n", len, sizeof(struct stun_header));
00436       return -1;
00437    }
00438    if (stundebug)
00439       ast_verbose("STUN Packet, msg %s (%04x), length: %d\n", stun_msg2str(ntohs(hdr->msgtype)), ntohs(hdr->msgtype), ntohs(hdr->msglen));
00440    if (ntohs(hdr->msglen) > len - sizeof(struct stun_header)) {
00441       if (option_debug)
00442          ast_log(LOG_DEBUG, "Scrambled STUN packet length (got %d, expecting %zd)\n", ntohs(hdr->msglen), len - sizeof(struct stun_header));
00443    } else
00444       len = ntohs(hdr->msglen);
00445    data += sizeof(struct stun_header);
00446    memset(&st, 0, sizeof(st));
00447    while(len) {
00448       if (len < sizeof(struct stun_attr)) {
00449          if (option_debug)
00450             ast_log(LOG_DEBUG, "Runt Attribute (got %zd, expecting %zd)\n", len, sizeof(struct stun_attr));
00451          break;
00452       }
00453       attr = (struct stun_attr *)data;
00454       if ((ntohs(attr->len) + sizeof(struct stun_attr)) > len) {
00455          if (option_debug)
00456             ast_log(LOG_DEBUG, "Inconsistent Attribute (length %d exceeds remaining msg len %d)\n", (int) (ntohs(attr->len) + sizeof(struct stun_attr)), (int) len);
00457          break;
00458       }
00459       if (stun_process_attr(&st, attr)) {
00460          if (option_debug)
00461             ast_log(LOG_DEBUG, "Failed to handle attribute %s (%04x)\n", stun_attr2str(ntohs(attr->attr)), ntohs(attr->attr));
00462          break;
00463       }
00464       /* Clear attribute in case previous entry was a string */
00465       attr->attr = 0;
00466       data += ntohs(attr->len) + sizeof(struct stun_attr);
00467       len -= ntohs(attr->len) + sizeof(struct stun_attr);
00468    }
00469    /* Null terminate any string */
00470    *data = '\0';
00471    resp = (struct stun_header *)respdata;
00472    resplen = 0;
00473    respleft = sizeof(respdata) - sizeof(struct stun_header);
00474    resp->id = hdr->id;
00475    resp->msgtype = 0;
00476    resp->msglen = 0;
00477    attr = (struct stun_attr *)resp->ies;
00478    if (!len) {
00479       switch(ntohs(hdr->msgtype)) {
00480       case STUN_BINDREQ:
00481          if (stundebug)
00482             ast_verbose("STUN Bind Request, username: %s\n", 
00483                st.username ? st.username : "<none>");
00484          if (st.username)
00485             append_attr_string(&attr, STUN_USERNAME, st.username, &resplen, &respleft);
00486          append_attr_address(&attr, STUN_MAPPED_ADDRESS, src, &resplen, &respleft);
00487          resp->msglen = htons(resplen);
00488          resp->msgtype = htons(STUN_BINDRESP);
00489          stun_send(s, src, resp);
00490          ret = STUN_ACCEPT;
00491          break;
00492       default:
00493          if (stundebug)
00494             ast_verbose("Dunno what to do with STUN message %04x (%s)\n", ntohs(hdr->msgtype), stun_msg2str(ntohs(hdr->msgtype)));
00495       }
00496    }
00497    return ret;
00498 }
00499 
00500 /*! \brief List of current sessions */
00501 static AST_LIST_HEAD_STATIC(protos, ast_rtp_protocol);
00502 
00503 static void timeval2ntp(struct timeval tv, unsigned int *msw, unsigned int *lsw)
00504 {
00505    unsigned int sec, usec, frac;
00506    sec = tv.tv_sec + 2208988800u; /* Sec between 1900 and 1970 */
00507    usec = tv.tv_usec;
00508    frac = (usec << 12) + (usec << 8) - ((usec * 3650) >> 6);
00509    *msw = sec;
00510    *lsw = frac;
00511 }
00512 
00513 int ast_rtp_fd(struct ast_rtp *rtp)
00514 {
00515    return rtp->s;
00516 }
00517 
00518 int ast_rtcp_fd(struct ast_rtp *rtp)
00519 {
00520    if (rtp->rtcp)
00521       return rtp->rtcp->s;
00522    return -1;
00523 }
00524 
00525 unsigned int ast_rtcp_calc_interval(struct ast_rtp *rtp)
00526 {
00527    unsigned int interval;
00528    /*! \todo XXX Do a more reasonable calculation on this one
00529    * Look in RFC 3550 Section A.7 for an example*/
00530    interval = rtcpinterval;
00531    return interval;
00532 }
00533 
00534 /* \brief Put RTP timeout timers on hold during another transaction, like T.38 */
00535 void ast_rtp_set_rtptimers_onhold(struct ast_rtp *rtp)
00536 {
00537    rtp->rtptimeout = (-1) * rtp->rtptimeout;
00538    rtp->rtpholdtimeout = (-1) * rtp->rtpholdtimeout;
00539 }
00540 
00541 /*! \brief Set rtp timeout */
00542 void ast_rtp_set_rtptimeout(struct ast_rtp *rtp, int timeout)
00543 {
00544    rtp->rtptimeout = timeout;
00545 }
00546 
00547 /*! \brief Set rtp hold timeout */
00548 void ast_rtp_set_rtpholdtimeout(struct ast_rtp *rtp, int timeout)
00549 {
00550    rtp->rtpholdtimeout = timeout;
00551 }
00552 
00553 /*! \brief set RTP keepalive interval */
00554 void ast_rtp_set_rtpkeepalive(struct ast_rtp *rtp, int period)
00555 {
00556    rtp->rtpkeepalive = period;
00557 }
00558 
00559 /*! \brief Get rtp timeout */
00560 int ast_rtp_get_rtptimeout(struct ast_rtp *rtp)
00561 {
00562    if (rtp->rtptimeout < 0)   /* We're not checking, but remembering the setting (during T.38 transmission) */
00563       return 0;
00564    return rtp->rtptimeout;
00565 }
00566 
00567 /*! \brief Get rtp hold timeout */
00568 int ast_rtp_get_rtpholdtimeout(struct ast_rtp *rtp)
00569 {
00570    if (rtp->rtptimeout < 0)   /* We're not checking, but remembering the setting (during T.38 transmission) */
00571       return 0;
00572    return rtp->rtpholdtimeout;
00573 }
00574 
00575 /*! \brief Get RTP keepalive interval */
00576 int ast_rtp_get_rtpkeepalive(struct ast_rtp *rtp)
00577 {
00578    return rtp->rtpkeepalive;
00579 }
00580 
00581 void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
00582 {
00583    rtp->data = data;
00584 }
00585 
00586 void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
00587 {
00588    rtp->callback = callback;
00589 }
00590 
00591 void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
00592 {
00593    rtp->nat = nat;
00594 }
00595 
00596 int ast_rtp_getnat(struct ast_rtp *rtp)
00597 {
00598    return ast_test_flag(rtp, FLAG_NAT_ACTIVE);
00599 }
00600 
00601 void ast_rtp_setdtmf(struct ast_rtp *rtp, int dtmf)
00602 {
00603    ast_set2_flag(rtp, dtmf ? 1 : 0, FLAG_HAS_DTMF);
00604 }
00605 
00606 void ast_rtp_setdtmfcompensate(struct ast_rtp *rtp, int compensate)
00607 {
00608    ast_set2_flag(rtp, compensate ? 1 : 0, FLAG_DTMF_COMPENSATE);
00609 }
00610 
00611 void ast_rtp_setstun(struct ast_rtp *rtp, int stun_enable)
00612 {
00613    ast_set2_flag(rtp, stun_enable ? 1 : 0, FLAG_HAS_STUN);
00614 }
00615 
00616 static struct ast_frame *send_dtmf(struct ast_rtp *rtp, enum ast_frame_type type)
00617 {
00618    if (((ast_test_flag(rtp, FLAG_DTMF_COMPENSATE) && type == AST_FRAME_DTMF_END) ||
00619         (type == AST_FRAME_DTMF_BEGIN)) && ast_tvcmp(ast_tvnow(), rtp->dtmfmute) < 0) {
00620       if (option_debug)
00621          ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(rtp->them.sin_addr));
00622       rtp->resp = 0;
00623       rtp->dtmfsamples = 0;
00624       return &ast_null_frame;
00625    }
00626    if (option_debug)
00627       ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(rtp->them.sin_addr));
00628    if (rtp->resp == 'X') {
00629       rtp->f.frametype = AST_FRAME_CONTROL;
00630       rtp->f.subclass = AST_CONTROL_FLASH;
00631    } else {
00632       rtp->f.frametype = type;
00633       rtp->f.subclass = rtp->resp;
00634    }
00635    rtp->f.datalen = 0;
00636    rtp->f.samples = 0;
00637    rtp->f.mallocd = 0;
00638    rtp->f.src = "RTP";
00639    return &rtp->f;
00640    
00641 }
00642 
00643 static inline int rtp_debug_test_addr(struct sockaddr_in *addr)
00644 {
00645    if (rtpdebug == 0)
00646       return 0;
00647    if (rtpdebugaddr.sin_addr.s_addr) {
00648       if (((ntohs(rtpdebugaddr.sin_port) != 0)
00649          && (rtpdebugaddr.sin_port != addr->sin_port))
00650          || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
00651       return 0;
00652    }
00653    return 1;
00654 }
00655 
00656 static inline int rtcp_debug_test_addr(struct sockaddr_in *addr)
00657 {
00658    if (rtcpdebug == 0)
00659       return 0;
00660    if (rtcpdebugaddr.sin_addr.s_addr) {
00661       if (((ntohs(rtcpdebugaddr.sin_port) != 0)
00662          && (rtcpdebugaddr.sin_port != addr->sin_port))
00663          || (rtcpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
00664       return 0;
00665    }
00666    return 1;
00667 }
00668 
00669 
00670 static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, int len)
00671 {
00672    unsigned int event;
00673    char resp = 0;
00674    struct ast_frame *f = NULL;
00675    event = ntohl(*((unsigned int *)(data)));
00676    event &= 0x001F;
00677    if (option_debug > 2 || rtpdebug)
00678       ast_log(LOG_DEBUG, "Cisco DTMF Digit: %08x (len = %d)\n", event, len);
00679    if (event < 10) {
00680       resp = '0' + event;
00681    } else if (event < 11) {
00682       resp = '*';
00683    } else if (event < 12) {
00684       resp = '#';
00685    } else if (event < 16) {
00686       resp = 'A' + (event - 12);
00687    } else if (event < 17) {
00688       resp = 'X';
00689    }
00690    if (rtp->resp && (rtp->resp != resp)) {
00691       f = send_dtmf(rtp, AST_FRAME_DTMF_END);
00692    }
00693    rtp->resp = resp;
00694    rtp->dtmfcount = dtmftimeout;
00695    return f;
00696 }
00697 
00698 /*! 
00699  * \brief Process RTP DTMF and events according to RFC 2833.
00700  * 
00701  * RFC 2833 is "RTP Payload for DTMF Digits, Telephony Tones and Telephony Signals".
00702  * 
00703  * \param rtp
00704  * \param data
00705  * \param len
00706  * \param seqno
00707  * \returns
00708  */
00709 static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len, unsigned int seqno, unsigned int timestamp)
00710 {
00711    unsigned int event;
00712    unsigned int event_end;
00713    unsigned int samples;
00714    char resp = 0;
00715    struct ast_frame *f = NULL;
00716 
00717    /* Figure out event, event end, and samples */
00718    event = ntohl(*((unsigned int *)(data)));
00719    event >>= 24;
00720    event_end = ntohl(*((unsigned int *)(data)));
00721    event_end <<= 8;
00722    event_end >>= 24;
00723    samples = ntohl(*((unsigned int *)(data)));
00724    samples &= 0xFFFF;
00725 
00726    /* Print out debug if turned on */
00727    if (rtpdebug || option_debug > 2)
00728       ast_log(LOG_DEBUG, "- RTP 2833 Event: %08x (len = %d)\n", event, len);
00729 
00730    /* Figure out what digit was pressed */
00731    if (event < 10) {
00732       resp = '0' + event;
00733    } else if (event < 11) {
00734       resp = '*';
00735    } else if (event < 12) {
00736       resp = '#';
00737    } else if (event < 16) {
00738       resp = 'A' + (event - 12);
00739    } else if (event < 17) {   /* Event 16: Hook flash */
00740       resp = 'X'; 
00741    } else {
00742       /* Not a supported event */
00743       ast_log(LOG_DEBUG, "Ignoring RTP 2833 Event: %08x. Not a DTMF Digit.\n", event);
00744       return &ast_null_frame;
00745    }
00746 
00747    if (ast_test_flag(rtp, FLAG_DTMF_COMPENSATE)) {
00748       if ((rtp->lastevent != timestamp) || (rtp->resp && rtp->resp != resp)) {
00749          rtp->resp = resp;
00750          f = send_dtmf(rtp, AST_FRAME_DTMF_END);
00751          f->len = 0;
00752          rtp->lastevent = timestamp;
00753       }
00754    } else {
00755       if ((!(rtp->resp) && (!(event_end & 0x80))) || (rtp->resp && rtp->resp != resp)) {
00756          rtp->resp = resp;
00757          f = send_dtmf(rtp, AST_FRAME_DTMF_BEGIN);
00758       } else if ((event_end & 0x80) && (rtp->lastevent != seqno) && rtp->resp) {
00759          f = send_dtmf(rtp, AST_FRAME_DTMF_END);
00760          f->len = ast_tvdiff_ms(ast_samp2tv(samples, 8000), ast_tv(0, 0)); /* XXX hard coded 8kHz */
00761          rtp->resp = 0;
00762          rtp->lastevent = seqno;
00763       }
00764    }
00765 
00766    rtp->dtmfcount = dtmftimeout;
00767    rtp->dtmfsamples = samples;
00768 
00769    return f;
00770 }
00771 
00772 /*!
00773  * \brief Process Comfort Noise RTP.
00774  * 
00775  * This is incomplete at the moment.
00776  * 
00777 */
00778 static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
00779 {
00780    struct ast_frame *f = NULL;
00781    /* Convert comfort noise into audio with various codecs.  Unfortunately this doesn't
00782       totally help us out becuase we don't have an engine to keep it going and we are not
00783       guaranteed to have it every 20ms or anything */
00784    if (rtpdebug)
00785       ast_log(LOG_DEBUG, "- RTP 3389 Comfort noise event: Level %d (len = %d)\n", rtp->lastrxformat, len);
00786 
00787    if (!(ast_test_flag(rtp, FLAG_3389_WARNING))) {
00788       ast_log(LOG_NOTICE, "Comfort noise support incomplete in Asterisk (RFC 3389). Please turn off on client if possible. Client IP: %s\n",
00789          ast_inet_ntoa(rtp->them.sin_addr));
00790       ast_set_flag(rtp, FLAG_3389_WARNING);
00791    }
00792 
00793    /* Must have at least one byte */
00794    if (!len)
00795       return NULL;
00796    if (len < 24) {
00797       rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET;
00798       rtp->f.datalen = len - 1;
00799       rtp->f.offset = AST_FRIENDLY_OFFSET;
00800       memcpy(rtp->f.data, data + 1, len - 1);
00801    } else {
00802       rtp->f.data = NULL;