Wed Aug 15 01:24:24 2007

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

Generated on Wed Aug 15 01:24:24 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.3