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

Generated on Fri Aug 24 02:22:17 2007 for Asterisk - the Open Source PBX by  doxygen 1.5.1