Fri Sep 25 19:28:15 2009

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

Generated on Fri Sep 25 19:28:15 2009 for Asterisk - the Open Source PBX by  doxygen 1.5.5