Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals  

rtp.c

Go to the documentation of this file.
00001 /*
00002  * Asterisk -- A telephony toolkit for Linux.
00003  *
00004  * Real-time Protocol Support
00005  *    Supports RTP and RTCP with Symmetric RTP support for NAT
00006  *    traversal
00007  * 
00008  * Copyright (C) 1999-2004, Digium, Inc.
00009  *
00010  * Mark Spencer <markster@digium.com>
00011  *
00012  * This program is free software, distributed under the terms of
00013  * the GNU General Public License
00014  */
00015 
00016 #include <stdio.h>
00017 #include <stdlib.h>
00018 #include <string.h>
00019 #include <sys/time.h>
00020 #include <signal.h>
00021 #include <errno.h>
00022 #include <unistd.h>
00023 #include <netinet/in.h>
00024 #include <sys/time.h>
00025 #include <sys/socket.h>
00026 #include <arpa/inet.h>
00027 #include <fcntl.h>
00028 
00029 #include <asterisk/rtp.h>
00030 #include <asterisk/frame.h>
00031 #include <asterisk/logger.h>
00032 #include <asterisk/options.h>
00033 #include <asterisk/channel.h>
00034 #include <asterisk/acl.h>
00035 #include <asterisk/channel.h>
00036 #include <asterisk/channel_pvt.h>
00037 #include <asterisk/config.h>
00038 #include <asterisk/lock.h>
00039 #include <asterisk/utils.h>
00040 
00041 #define MAX_TIMESTAMP_SKEW 640
00042 
00043 #define RTP_MTU      1200
00044 
00045 #define TYPE_HIGH  0x0
00046 #define TYPE_LOW   0x1
00047 #define TYPE_SILENCE  0x2
00048 #define TYPE_DONTSEND    0x3
00049 #define TYPE_MASK  0x3
00050 
00051 static int dtmftimeout = 3000;   /* 3000 samples */
00052 
00053 static int rtpstart = 0;
00054 static int rtpend = 0;
00055 #ifdef SO_NO_CHECK
00056 static int checksums = 1;
00057 #endif
00058 
00059 /* The value of each payload format mapping: */
00060 struct rtpPayloadType {
00061   int isAstFormat;   /* whether the following code is an AST_FORMAT */
00062   int code;
00063 };
00064 
00065 #define MAX_RTP_PT 256
00066 
00067 #define FLAG_3389_WARNING (1 << 0)
00068 
00069 struct ast_rtp {
00070    int s;
00071    char resp;
00072    struct ast_frame f;
00073    unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
00074    unsigned int ssrc;
00075    unsigned int lastts;
00076    unsigned int lastrxts;
00077    unsigned int lastividtimestamp;
00078    unsigned int lastovidtimestamp;
00079    unsigned int lasteventseqn;
00080    int lasttxformat;
00081    int lastrxformat;
00082    int dtmfcount;
00083    unsigned int dtmfduration;
00084    int nat;
00085    int flags;
00086    struct sockaddr_in us;
00087    struct sockaddr_in them;
00088    struct timeval rxcore;
00089    struct timeval txcore;
00090    struct timeval dtmfmute;
00091    struct ast_smoother *smoother;
00092    int *ioid;
00093    unsigned short seqno;
00094    struct sched_context *sched;
00095    struct io_context *io;
00096    void *data;
00097    ast_rtp_callback callback;
00098     struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
00099     int rtp_lookup_code_cache_isAstFormat;   /* a cache for the result of rtp_lookup_code(): */
00100     int rtp_lookup_code_cache_code;
00101     int rtp_lookup_code_cache_result;
00102     int rtp_offered_from_local;
00103    struct ast_rtcp *rtcp;
00104 };
00105 
00106 struct ast_rtcp {
00107    int s;      /* Socket */
00108    struct sockaddr_in us;
00109    struct sockaddr_in them;
00110 };
00111 
00112 static struct ast_rtp_protocol *protos = NULL;
00113 
00114 int ast_rtp_fd(struct ast_rtp *rtp)
00115 {
00116    return rtp->s;
00117 }
00118 
00119 int ast_rtcp_fd(struct ast_rtp *rtp)
00120 {
00121    if (rtp->rtcp)
00122       return rtp->rtcp->s;
00123    return -1;
00124 }
00125 
00126 static int g723_len(unsigned char buf)
00127 {
00128    switch(buf & TYPE_MASK) {
00129    case TYPE_DONTSEND:
00130       return 0;
00131       break;
00132    case TYPE_SILENCE:
00133       return 4;
00134       break;
00135    case TYPE_HIGH:
00136       return 24;
00137       break;
00138    case TYPE_LOW:
00139       return 20;
00140       break;
00141    default:
00142       ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
00143    }
00144    return -1;
00145 }
00146 
00147 static int g723_samples(unsigned char *buf, int maxlen)
00148 {
00149    int pos = 0;
00150    int samples = 0;
00151    int res;
00152    while(pos < maxlen) {
00153       res = g723_len(buf[pos]);
00154       if (res <= 0)
00155          break;
00156       samples += 240;
00157       pos += res;
00158    }
00159    return samples;
00160 }
00161 
00162 void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
00163 {
00164    rtp->data = data;
00165 }
00166 
00167 void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
00168 {
00169    rtp->callback = callback;
00170 }
00171 
00172 void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
00173 {
00174    rtp->nat = nat;
00175 }
00176 
00177 static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
00178 {
00179    struct timeval tv;
00180    static struct ast_frame null_frame = { AST_FRAME_NULL, };
00181    char iabuf[INET_ADDRSTRLEN];
00182    gettimeofday(&tv, NULL);
00183    if ((tv.tv_sec < rtp->dtmfmute.tv_sec) ||
00184        ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < rtp->dtmfmute.tv_usec))) {
00185       ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr));
00186       rtp->resp = 0;
00187       rtp->dtmfduration = 0;
00188       return &null_frame;
00189    }
00190    ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr));
00191    rtp->f.frametype = AST_FRAME_DTMF;
00192    rtp->f.subclass = rtp->resp;
00193    rtp->f.datalen = 0;
00194    rtp->f.samples = 0;
00195    rtp->f.mallocd = 0;
00196    rtp->f.src = "RTP";
00197    rtp->resp = 0;
00198    rtp->dtmfduration = 0;
00199    return &rtp->f;
00200    
00201 }
00202 
00203 static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, int len)
00204 {
00205    unsigned int event;
00206    char resp = 0;
00207    struct ast_frame *f = NULL;
00208    event = ntohl(*((unsigned int *)(data)));
00209    event &= 0x001F;
00210 #if 0
00211    printf("Cisco Digit: %08x (len = %d)\n", event, len);
00212 #endif   
00213    if (event < 10) {
00214       resp = '0' + event;
00215    } else if (event < 11) {
00216       resp = '*';
00217    } else if (event < 12) {
00218       resp = '#';
00219    } else if (event < 16) {
00220       resp = 'A' + (event - 12);
00221    }
00222    if (rtp->resp && (rtp->resp != resp)) {
00223       f = send_dtmf(rtp);
00224    }
00225    rtp->resp = resp;
00226    rtp->dtmfcount = dtmftimeout;
00227    return f;
00228 }
00229 
00230 static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
00231 {
00232    unsigned int event;
00233    unsigned int event_end;
00234    unsigned int duration;
00235    char resp = 0;
00236    struct ast_frame *f = NULL;
00237    event = ntohl(*((unsigned int *)(data)));
00238    event >>= 24;
00239    event_end = ntohl(*((unsigned int *)(data)));
00240    event_end <<= 8;
00241    event_end >>= 24;
00242    duration = ntohl(*((unsigned int *)(data)));
00243    duration &= 0xFFFF;
00244 #if 0
00245    printf("Event: %08x (len = %d)\n", event, len);
00246 #endif   
00247    if (event < 10) {
00248       resp = '0' + event;
00249    } else if (event < 11) {
00250       resp = '*';
00251    } else if (event < 12) {
00252       resp = '#';
00253    } else if (event < 16) {
00254       resp = 'A' + (event - 12);
00255    }
00256    if (rtp->resp && (rtp->resp != resp)) {
00257       f = send_dtmf(rtp);
00258    }
00259    else if(event_end & 0x80)
00260    {
00261       if (rtp->resp) {
00262          f = send_dtmf(rtp);
00263          rtp->resp = 0;
00264       }
00265       resp = 0;
00266       duration = 0;
00267    }
00268    else if(rtp->dtmfduration && (duration < rtp->dtmfduration))
00269    {
00270       f = send_dtmf(rtp);
00271    }
00272    if (!(event_end & 0x80))
00273       rtp->resp = resp;
00274    rtp->dtmfcount = dtmftimeout;
00275    rtp->dtmfduration = duration;
00276    return f;
00277 }
00278 
00279 static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
00280 {
00281    struct ast_frame *f = NULL;
00282    /* Convert comfort noise into audio with various codecs.  Unfortunately this doesn't
00283       totally help us out becuase we don't have an engine to keep it going and we are not
00284       guaranteed to have it every 20ms or anything */
00285 #if 1
00286    printf("RFC3389: %d bytes, level %d...\n", len, rtp->lastrxformat);
00287 #endif   
00288    if (!(rtp->flags & FLAG_3389_WARNING)) {
00289       ast_log(LOG_NOTICE, "RFC3389 support incomplete.  Turn off on client if possible\n");
00290       rtp->flags |= FLAG_3389_WARNING;
00291    }
00292    /* Must have at least one byte */
00293    if (!len)
00294       return NULL;
00295    if (len < 24) {
00296       rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET;
00297       rtp->f.datalen = len - 1;
00298       rtp->f.offset = AST_FRIENDLY_OFFSET;
00299       memcpy(rtp->f.data, data + 1, len - 1);
00300    } else {
00301       rtp->f.data = NULL;
00302       rtp->f.offset = 0;
00303       rtp->f.datalen = 0;
00304    }
00305    rtp->f.frametype = AST_FRAME_CNG;
00306    rtp->f.subclass = data[0] & 0x7f;
00307    rtp->f.datalen = len - 1;
00308    rtp->f.samples = 0;
00309    rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
00310    f = &rtp->f;
00311    return f;
00312 }
00313 
00314 static int rtpread(int *id, int fd, short events, void *cbdata)
00315 {
00316    struct ast_rtp *rtp = cbdata;
00317    struct ast_frame *f;
00318    f = ast_rtp_read(rtp);
00319    if (f) {
00320       if (rtp->callback)
00321          rtp->callback(rtp, f, rtp->data);
00322    }
00323    return 1;
00324 }
00325 
00326 struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
00327 {
00328    static struct ast_frame null_frame = { AST_FRAME_NULL, };
00329    int len;
00330    int hdrlen = 8;
00331    int res;
00332    struct sockaddr_in sin;
00333    unsigned int rtcpdata[1024];
00334    char iabuf[INET_ADDRSTRLEN];
00335    
00336    if (!rtp->rtcp)
00337       return &null_frame;
00338 
00339    len = sizeof(sin);
00340    
00341    res = recvfrom(rtp->rtcp->s, rtcpdata, sizeof(rtcpdata),
00342                0, (struct sockaddr *)&sin, &len);
00343    
00344    if (res < 0) {
00345       if (errno == EAGAIN)
00346          ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
00347       else
00348          ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
00349       if (errno == EBADF)
00350          CRASH;
00351       return &null_frame;
00352    }
00353 
00354    if (res < hdrlen) {
00355       ast_log(LOG_WARNING, "RTP Read too short\n");
00356       return &null_frame;
00357    }
00358 
00359    if (rtp->nat) {
00360       /* Send to whoever sent to us */
00361       if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
00362           (rtp->rtcp->them.sin_port != sin.sin_port)) {
00363          memcpy(&rtp->them, &sin, sizeof(rtp->them));
00364          ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
00365       }
00366    }
00367    if (option_debug)
00368       ast_log(LOG_DEBUG, "Got RTCP report of %d bytes\n", res);
00369    return &null_frame;
00370 }
00371 
00372 static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
00373 {
00374    if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
00375       gettimeofday(&rtp->rxcore, NULL);
00376       rtp->rxcore.tv_sec -= timestamp / 8000;
00377       rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
00378       /* Round to 20ms for nice, pretty timestamps */
00379       rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
00380       if (rtp->rxcore.tv_usec < 0) {
00381          /* Adjust appropriately if necessary */
00382          rtp->rxcore.tv_usec += 1000000;
00383          rtp->rxcore.tv_sec -= 1;
00384       }
00385    }
00386    tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
00387    tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
00388    if (tv->tv_usec >= 1000000) {
00389       tv->tv_usec -= 1000000;
00390       tv->tv_sec += 1;
00391    }
00392 }
00393 
00394 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
00395 {
00396    int res;
00397    struct sockaddr_in sin;
00398    int len;
00399    unsigned int seqno;
00400    int payloadtype;
00401    int hdrlen = 12;
00402    int mark;
00403    int ext;
00404    char iabuf[INET_ADDRSTRLEN];
00405    unsigned int timestamp;
00406    unsigned int *rtpheader;
00407    static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
00408    struct rtpPayloadType rtpPT;
00409    
00410    len = sizeof(sin);
00411    
00412    /* Cache where the header will go */
00413    res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
00414                0, (struct sockaddr *)&sin, &len);
00415 
00416 
00417    rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
00418    if (res < 0) {
00419       if (errno == EAGAIN)
00420          ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
00421       else
00422          ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
00423       if (errno == EBADF)
00424          CRASH;
00425       return &null_frame;
00426    }
00427    if (res < hdrlen) {
00428       ast_log(LOG_WARNING, "RTP Read too short\n");
00429       return &null_frame;
00430    }
00431 
00432    /* Ignore if the other side hasn't been given an address
00433       yet.  */
00434    if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
00435       return &null_frame;
00436 
00437    if (rtp->nat) {
00438       /* Send to whoever sent to us */
00439       if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
00440           (rtp->them.sin_port != sin.sin_port)) {
00441          memcpy(&rtp->them, &sin, sizeof(rtp->them));
00442          ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port));
00443       }
00444    }
00445 
00446    /* Get fields */
00447    seqno = ntohl(rtpheader[0]);
00448    payloadtype = (seqno & 0x7f0000) >> 16;
00449    mark = seqno & (1 << 23);
00450    ext = seqno & (1 << 28);
00451    seqno &= 0xffff;
00452    timestamp = ntohl(rtpheader[1]);
00453    if (ext) {
00454       /* RTP Extension present */
00455       hdrlen += 4;
00456       hdrlen += (ntohl(rtpheader[3]) & 0xffff) << 2;
00457    }
00458 
00459    if (res < hdrlen) {
00460       ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen);
00461       return &null_frame;
00462    }
00463 
00464 #if 0
00465    printf("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len = %d)\n", ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
00466 #endif   
00467    rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
00468    if (!rtpPT.isAstFormat) {
00469      /* This is special in-band data that's not one of our codecs */
00470      if (rtpPT.code == AST_RTP_DTMF) {
00471        /* It's special -- rfc2833 process it */
00472        if (rtp->lasteventseqn <= seqno) {
00473          f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
00474          rtp->lasteventseqn = seqno;
00475        }
00476        if (f) return f; else return &null_frame;
00477      } else if (rtpPT.code == AST_RTP_CISCO_DTMF) {
00478        /* It's really special -- process it the Cisco way */
00479        if (rtp->lasteventseqn <= seqno) {
00480          f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
00481          rtp->lasteventseqn = seqno;
00482        }
00483        if (f) return f; else return &null_frame;
00484      } else if (rtpPT.code == AST_RTP_CN) {
00485        /* Comfort Noise */
00486        f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
00487        if (f) return f; else return &null_frame;
00488      } else {
00489        ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype);
00490        return &null_frame;
00491      }
00492    }
00493    rtp->f.subclass = rtpPT.code;
00494    if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO)
00495       rtp->f.frametype = AST_FRAME_VOICE;
00496    else
00497       rtp->f.frametype = AST_FRAME_VIDEO;
00498    rtp->lastrxformat = rtp->f.subclass;
00499 
00500    if (!rtp->lastrxts)
00501       rtp->lastrxts = timestamp;
00502 
00503    if (rtp->dtmfcount) {
00504 #if 0
00505       printf("dtmfcount was %d\n", rtp->dtmfcount);
00506 #endif      
00507       rtp->dtmfcount -= (timestamp - rtp->lastrxts);
00508       if (rtp->dtmfcount < 0)
00509          rtp->dtmfcount = 0;
00510 #if 0
00511       if (dtmftimeout != rtp->dtmfcount)
00512          printf("dtmfcount is %d\n", rtp->dtmfcount);
00513 #endif
00514    }
00515    rtp->lastrxts = timestamp;
00516 
00517    /* Send any pending DTMF */
00518    if (rtp->resp && !rtp->dtmfcount) {
00519       ast_log(LOG_DEBUG, "Sending pending DTMF\n");
00520       return send_dtmf(rtp);
00521    }
00522    rtp->f.mallocd = 0;
00523    rtp->f.datalen = res - hdrlen;
00524    rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
00525    rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
00526    if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) {
00527       switch(rtp->f.subclass) {
00528       case AST_FORMAT_ULAW:
00529       case AST_FORMAT_ALAW:
00530          rtp->f.samples = rtp->f.datalen;
00531          break;
00532       case AST_FORMAT_SLINEAR:
00533          rtp->f.samples = rtp->f.datalen / 2;
00534          break;
00535       case AST_FORMAT_GSM:
00536          rtp->f.samples = 160 * (rtp->f.datalen / 33);
00537          break;
00538       case AST_FORMAT_ILBC:
00539          rtp->f.samples = 240 * (rtp->f.datalen / 50);
00540          break;
00541       case AST_FORMAT_ADPCM:
00542       case AST_FORMAT_G726:
00543          rtp->f.samples = rtp->f.datalen * 2;
00544          break;
00545       case AST_FORMAT_G729A:
00546          rtp->f.samples = rtp->f.datalen * 8;
00547          break;
00548       case AST_FORMAT_G723_1:
00549          rtp->f.samples = g723_samples(rtp->f.data, rtp->f.datalen);
00550          break;
00551       case AST_FORMAT_SPEEX:
00552          /* assumes that the RTP packet contained one Speex frame */
00553            rtp->f.samples = 160;
00554          break;
00555       case AST_FORMAT_LPC10:
00556           rtp->f.samples = 22 * 8;
00557          rtp->f.samples += (((char *)(rtp->f.data))[7] & 0x1) * 8;
00558          break;
00559       default:
00560          ast_log(LOG_NOTICE, "Unable to calculate samples for format %s\n", ast_getformatname(rtp->f.subclass));
00561          break;
00562       }
00563       calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
00564    } else {
00565       /* Video -- samples is # of samples vs. 90000 */
00566       if (!rtp->lastividtimestamp)
00567          rtp->lastividtimestamp = timestamp;
00568       rtp->f.samples = timestamp - rtp->lastividtimestamp;
00569       rtp->lastividtimestamp = timestamp;
00570       rtp->f.delivery.tv_sec = 0;
00571       rtp->f.delivery.tv_usec = 0;
00572       if (mark)
00573          rtp->f.subclass |= 0x1;
00574       
00575    }
00576    rtp->f.src = "RTP";
00577    return &rtp->f;
00578 }
00579 
00580 /* The following array defines the MIME Media type (and subtype) for each
00581    of our codecs, or RTP-specific data type. */
00582 static struct {
00583   struct rtpPayloadType payloadType;
00584   char* type;
00585   char* subtype;
00586 } mimeTypes[] = {
00587   {{1, AST_FORMAT_G723_1}, "audio", "G723"},
00588   {{1, AST_FORMAT_GSM}, "audio", "GSM"},
00589   {{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
00590   {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
00591   {{1, AST_FORMAT_G726}, "audio", "G726-32"},
00592   {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
00593   {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
00594   {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
00595   {{1, AST_FORMAT_G729A}, "audio", "G729"},
00596   {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
00597   {{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
00598   {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
00599   {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
00600   {{0, AST_RTP_CN}, "audio", "CN"},
00601   {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
00602   {{1, AST_FORMAT_PNG}, "video", "PNG"},
00603   {{1, AST_FORMAT_H261}, "video", "H261"},
00604   {{1, AST_FORMAT_H263}, "video", "H263"},
00605 };
00606 
00607 /* Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
00608    also, our own choices for dynamic payload types.  This is our master
00609    table for transmission */
00610 static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
00611   [0] = {1, AST_FORMAT_ULAW},
00612   [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
00613   [3] = {1, AST_FORMAT_GSM},
00614   [4] = {1, AST_FORMAT_G723_1},
00615   [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
00616   [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
00617   [7] = {1, AST_FORMAT_LPC10},
00618   [8] = {1, AST_FORMAT_ALAW},
00619   [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
00620   [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
00621   [13] = {0, AST_RTP_CN},
00622   [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
00623   [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
00624   [18] = {1, AST_FORMAT_G729A},
00625   [19] = {0, AST_RTP_CN},     /* Also used for CN */
00626   [26] = {1, AST_FORMAT_JPEG},
00627   [31] = {1, AST_FORMAT_H261},
00628   [34] = {1, AST_FORMAT_H263},
00629   [97] = {1, AST_FORMAT_ILBC},
00630   [101] = {0, AST_RTP_DTMF},
00631   [110] = {1, AST_FORMAT_SPEEX},
00632   [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
00633 };
00634 
00635 void ast_rtp_pt_clear(struct ast_rtp* rtp) 
00636 {
00637   int i;
00638 
00639   for (i = 0; i < MAX_RTP_PT; ++i) {
00640     rtp->current_RTP_PT[i].isAstFormat = 0;
00641     rtp->current_RTP_PT[i].code = 0;
00642   }
00643 
00644   rtp->rtp_lookup_code_cache_isAstFormat = 0;
00645   rtp->rtp_lookup_code_cache_code = 0;
00646   rtp->rtp_lookup_code_cache_result = 0;
00647 }
00648 
00649 void ast_rtp_pt_default(struct ast_rtp* rtp) 
00650 {
00651   int i;
00652   /* Initialize to default payload types */
00653   for (i = 0; i < MAX_RTP_PT; ++i) {
00654     rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat;
00655     rtp->current_RTP_PT[i].code = static_RTP_PT[i].code;
00656   }
00657 
00658   rtp->rtp_lookup_code_cache_isAstFormat = 0;
00659   rtp->rtp_lookup_code_cache_code = 0;
00660   rtp->rtp_lookup_code_cache_result = 0;
00661 }
00662 
00663 /* Make a note of a RTP payload type that was seen in a SDP "m=" line. */
00664 /* By default, use the well-known value for this type (although it may */
00665 /* still be set to a different value by a subsequent "a=rtpmap:" line): */
00666 void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
00667   if (pt < 0 || pt > MAX_RTP_PT) return; /* bogus payload type */
00668 
00669   if (static_RTP_PT[pt].code != 0) {
00670     rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
00671   }
00672 } 
00673 
00674 /* Make a note of a RTP payload type (with MIME type) that was seen in */
00675 /* a SDP "a=rtpmap:" line. */
00676 void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
00677           char* mimeType, char* mimeSubtype) {
00678   int i;
00679 
00680   if (pt < 0 || pt > MAX_RTP_PT) return; /* bogus payload type */
00681 
00682   for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
00683     if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
00684    strcasecmp(mimeType, mimeTypes[i].type) == 0) {
00685       rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
00686       return;
00687     }
00688   }
00689 } 
00690 
00691 /* Return the union of all of the codecs that were set by rtp_set...() calls */
00692 /* They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
00693 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
00694               int* astFormats, int* nonAstFormats) {
00695   int pt;
00696 
00697   *astFormats = *nonAstFormats = 0;
00698   for (pt = 0; pt < MAX_RTP_PT; ++pt) {
00699     if (rtp->current_RTP_PT[pt].isAstFormat) {
00700       *astFormats |= rtp->current_RTP_PT[pt].code;
00701     } else {
00702       *nonAstFormats |= rtp->current_RTP_PT[pt].code;
00703     }
00704   }
00705 }
00706 
00707 void ast_rtp_offered_from_local(struct ast_rtp* rtp, int local) {
00708   if (rtp)
00709     rtp->rtp_offered_from_local = local;
00710   else
00711     ast_log(LOG_WARNING, "rtp structure is null\n");
00712 }
00713 
00714 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) 
00715 {
00716   struct rtpPayloadType result;
00717 
00718   result.isAstFormat = result.code = 0;
00719   if (pt < 0 || pt > MAX_RTP_PT) {
00720     return result; /* bogus payload type */
00721   }
00722   /* Start with the negotiated codecs */
00723   if (!rtp->rtp_offered_from_local)
00724     result = rtp->current_RTP_PT[pt];
00725   /* If it doesn't exist, check our static RTP type list, just in case */
00726   if (!result.code) 
00727     result = static_RTP_PT[pt];
00728   return result;
00729 }
00730 
00731 /* Looks up an RTP code out of our *static* outbound list */
00732 int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) {
00733   int pt;
00734 
00735 
00736   if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
00737       code == rtp->rtp_lookup_code_cache_code) {
00738     /* Use our cached mapping, to avoid the overhead of the loop below */
00739     return rtp->rtp_lookup_code_cache_result;
00740   }
00741 
00742    /* Check the dynamic list first */
00743   for (pt = 0; pt < MAX_RTP_PT; ++pt) {
00744     if (rtp->current_RTP_PT[pt].code == code &&
00745       rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) {
00746       rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
00747       rtp->rtp_lookup_code_cache_code = code;
00748       rtp->rtp_lookup_code_cache_result = pt;
00749       return pt;
00750     }
00751   }
00752 
00753    /* Then the static list */
00754   for (pt = 0; pt < MAX_RTP_PT; ++pt) {
00755     if (static_RTP_PT[pt].code == code &&
00756       static_RTP_PT[pt].isAstFormat == isAstFormat) {
00757       rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
00758       rtp->rtp_lookup_code_cache_code = code;
00759       rtp->rtp_lookup_code_cache_result = pt;
00760       return pt;
00761     }
00762   }
00763   return -1;
00764 }
00765 
00766 char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code) {
00767   int i;
00768 
00769   for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
00770     if (mimeTypes[i].payloadType.code == code &&
00771    mimeTypes[i].payloadType.isAstFormat == isAstFormat) {
00772       return mimeTypes[i].subtype;
00773     }
00774   }
00775   return "";
00776 }
00777 
00778 static int rtp_socket(void)
00779 {
00780    int s;
00781    long flags;
00782    s = socket(AF_INET, SOCK_DGRAM, 0);
00783    if (s > -1) {
00784       flags = fcntl(s, F_GETFL);
00785       fcntl(s, F_SETFL, flags | O_NONBLOCK);
00786 #ifdef SO_NO_CHECK
00787       if (checksums) {
00788          setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &checksums, sizeof(checksums));
00789       }
00790 #endif
00791    }
00792    return s;
00793 }
00794 
00795 static struct ast_rtcp *ast_rtcp_new(void)
00796 {
00797    struct ast_rtcp *rtcp;
00798    rtcp = malloc(sizeof(struct ast_rtcp));
00799    if (!rtcp)
00800       return NULL;
00801    memset(rtcp, 0, sizeof(struct ast_rtcp));
00802    rtcp->s = rtp_socket();
00803    rtcp->us.sin_family = AF_INET;
00804    if (rtcp->s < 0) {
00805       free(rtcp);
00806       ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
00807       return NULL;
00808    }
00809    return rtcp;
00810 }
00811 
00812 struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
00813 {
00814    struct ast_rtp *rtp;
00815    int x;
00816    int first;
00817    int startplace;
00818    rtp = malloc(sizeof(struct ast_rtp));
00819    if (!rtp)
00820       return NULL;
00821    memset(rtp, 0, sizeof(struct ast_rtp));
00822    rtp->them.sin_family = AF_INET;
00823    rtp->us.sin_family = AF_INET;
00824    rtp->s = rtp_socket();
00825    rtp->ssrc = rand();
00826    rtp->seqno = rand() & 0xffff;
00827    if (rtp->s < 0) {
00828       free(rtp);
00829       ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
00830       return NULL;
00831    }
00832    if (sched && rtcpenable) {
00833       rtp->sched = sched;
00834       rtp->rtcp = ast_rtcp_new();
00835    }
00836    /* Find us a place */
00837    x = (rand() % (rtpend-rtpstart)) + rtpstart;
00838    x = x & ~1;
00839    startplace = x;
00840    for (;;) {
00841       /* Must be an even port number by RTP spec */
00842       rtp->us.sin_port = htons(x);
00843       rtp->us.sin_addr = addr;
00844       if (rtp->rtcp)
00845          rtp->rtcp->us.sin_port = htons(x + 1);
00846       if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) &&
00847          (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us))))
00848          break;
00849       if (!first) {
00850          /* Primary bind succeeded! Gotta recreate it */
00851          close(rtp->s);
00852          rtp->s = rtp_socket();
00853       }
00854       if (errno != EADDRINUSE) {
00855          ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
00856          close(rtp->s);
00857          if (rtp->rtcp) {
00858             close(rtp->rtcp->s);
00859             free(rtp->rtcp);
00860          }
00861          free(rtp);
00862          return NULL;
00863       }
00864       x += 2;
00865       if (x > rtpend)
00866          x = (rtpstart + 1) & ~1;
00867       if (x == startplace) {
00868          ast_log(LOG_WARNING, "No RTP ports remaining\n");
00869          close(rtp->s);
00870          if (rtp->rtcp) {
00871             close(rtp->rtcp->s);
00872             free(rtp->rtcp);
00873          }
00874          free(rtp);
00875          return NULL;
00876       }
00877    }
00878    if (io && sched && callbackmode) {
00879       /* Operate this one in a callback mode */
00880       rtp->sched = sched;
00881       rtp->io = io;
00882       rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
00883    }
00884    ast_rtp_pt_default(rtp);
00885    return rtp;
00886 }
00887 
00888 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
00889 {
00890    struct in_addr ia;
00891    memset(&ia, 0, sizeof(ia));
00892    return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
00893 }
00894 
00895 int ast_rtp_settos(struct ast_rtp *rtp, int tos)
00896 {
00897    int res;
00898    if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) 
00899       ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
00900    return res;
00901 }
00902 
00903 void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
00904 {
00905    rtp->them.sin_port = them->sin_port;
00906    rtp->them.sin_addr = them->sin_addr;
00907    if (rtp->rtcp) {
00908       rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1);
00909       rtp->rtcp->them.sin_addr = them->sin_addr;
00910    }
00911 }
00912 
00913 void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
00914 {
00915    them->sin_family = AF_INET;
00916    them->sin_port = rtp->them.sin_port;
00917    them->sin_addr = rtp->them.sin_addr;
00918 }
00919 
00920 void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us)
00921 {
00922    memcpy(us, &rtp->us, sizeof(rtp->us));
00923 }
00924 
00925 void ast_rtp_stop(struct ast_rtp *rtp)
00926 {
00927    memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
00928    memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port));
00929    if (rtp->rtcp) {
00930       memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
00931       memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->them.sin_port));
00932    }
00933 }
00934 
00935 void ast_rtp_destroy(struct ast_rtp *rtp)
00936 {
00937    if (rtp->smoother)
00938       ast_smoother_free(rtp->smoother);
00939    if (rtp->ioid)
00940       ast_io_remove(rtp->io, rtp->ioid);
00941    if (rtp->s > -1)
00942       close(rtp->s);
00943    if (rtp->rtcp) {
00944       close(rtp->rtcp->s);
00945       free(rtp->rtcp);
00946    }
00947    free(rtp);
00948 }
00949 
00950 static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
00951 {
00952    struct timeval now;
00953    unsigned int ms;
00954    if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
00955       gettimeofday(&rtp->txcore, NULL);
00956       /* Round to 20ms for nice, pretty timestamps */
00957       rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
00958    }
00959    if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
00960       /* Use previous txcore */
00961       ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
00962       ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
00963       rtp->txcore.tv_sec = delivery->tv_sec;
00964       rtp->txcore.tv_usec = delivery->tv_usec;
00965    } else {
00966       gettimeofday(&now, NULL);
00967       ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
00968       ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
00969       /* Use what we just got for next time */
00970       rtp->txcore.tv_sec = now.tv_sec;
00971       rtp->txcore.tv_usec = now.tv_usec;
00972    }
00973    return ms;
00974 }
00975 
00976 int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
00977 {
00978    unsigned int *rtpheader;
00979    int hdrlen = 12;
00980    int res;
00981    int ms;
00982    int x;
00983    int payload;
00984    char data[256];
00985    char iabuf[INET_ADDRSTRLEN];
00986 
00987    if ((digit <= '9') && (digit >= '0'))
00988       digit -= '0';
00989    else if (digit == '*')
00990       digit = 10;
00991    else if (digit == '#')
00992       digit = 11;
00993    else if ((digit >= 'A') && (digit <= 'D')) 
00994       digit = digit - 'A' + 12;
00995    else if ((digit >= 'a') && (digit <= 'd')) 
00996       digit = digit - 'a' + 12;
00997    else {
00998       ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
00999       return -1;
01000    }
01001    payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF);
01002 
01003    /* If we have no peer, return immediately */ 
01004    if (!rtp->them.sin_addr.s_addr)
01005       return 0;
01006 
01007    gettimeofday(&rtp->dtmfmute, NULL);
01008    rtp->dtmfmute.tv_usec += (500 * 1000);
01009    if (rtp->dtmfmute.tv_usec > 1000000) {
01010       rtp->dtmfmute.tv_usec -= 1000000;
01011       rtp->dtmfmute.tv_sec += 1;
01012    }
01013 
01014    ms = calc_txstamp(rtp, NULL);
01015    /* Default prediction */
01016    rtp->lastts = rtp->lastts + ms * 8;
01017    
01018    /* Get a pointer to the header */
01019    rtpheader = (unsigned int *)data;
01020    rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
01021    rtpheader[1] = htonl(rtp->lastts);
01022    rtpheader[2] = htonl(rtp->ssrc); 
01023    rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
01024    for (x=0;x<4;x++) {
01025       if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
01026          res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
01027          if (res <0) 
01028             ast_log(LOG_NOTICE, "RTP Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
01029    #if 0
01030       printf("Sent %d bytes of RTP data to %s:%d\n", res, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port));
01031    #endif      
01032       }
01033       if (x ==0) {
01034          /* Clear marker bit and increment seqno */
01035          rtpheader[0] = htonl((2 << 30)  | (payload << 16) | (rtp->seqno++));
01036          /* Make duration 800 (100ms) */
01037          rtpheader[3] |= htonl((800));
01038          /* Set the End bit for the last 3 */
01039          rtpheader[3] |= htonl((1 << 23));
01040       }
01041    }
01042    return 0;
01043 }
01044 
01045 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
01046 {
01047    unsigned int *rtpheader;
01048    char iabuf[INET_ADDRSTRLEN];
01049    int hdrlen = 12;
01050    int res;
01051    int ms;
01052    int pred;
01053    int mark = 0;
01054 
01055    ms = calc_txstamp(rtp, &f->delivery);
01056    /* Default prediction */
01057    if (f->subclass < AST_FORMAT_MAX_AUDIO) {
01058       pred = rtp->lastts + ms * 8;
01059       
01060       switch(f->subclass) {
01061       case AST_FORMAT_ULAW:
01062       case AST_FORMAT_ALAW:
01063          /* If we're within +/- 20ms from when where we
01064             predict we should be, use that */
01065          pred = rtp->lastts + f->datalen;
01066          break;
01067       case AST_FORMAT_ADPCM:
01068       case AST_FORMAT_G726:
01069          /* If we're within +/- 20ms from when where we
01070             predict we should be, use that */
01071          pred = rtp->lastts + f->datalen * 2;
01072          break;
01073       case AST_FORMAT_G729A:
01074          pred = rtp->lastts + f->datalen * 8;
01075          break;
01076       case AST_FORMAT_GSM:
01077          pred = rtp->lastts + (f->datalen * 160 / 33);
01078          break;
01079       case AST_FORMAT_ILBC:
01080          pred = rtp->lastts + (f->datalen * 240 / 50);
01081          break;
01082       case AST_FORMAT_G723_1:
01083          pred = rtp->lastts + g723_samples(f->data, f->datalen);
01084          break;
01085       case AST_FORMAT_SPEEX:
01086           pred = rtp->lastts + 160;
01087          /* assumes that the RTP packet contains one Speex frame */
01088          break;
01089       case AST_FORMAT_LPC10:
01090          /* assumes that the RTP packet contains one LPC10 frame */
01091           pred = rtp->lastts + 22 * 8;
01092          pred += (((char *)(f->data))[7] & 0x1) * 8;
01093          break;
01094       default:
01095          ast_log(LOG_WARNING, "Not sure about timestamp format for codec format %s\n", ast_getformatname(f->subclass));
01096       }
01097       /* Re-calculate last TS */
01098       rtp->lastts = rtp->lastts + ms * 8;
01099       if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
01100          /* If this isn't an absolute delivery time, Check if it is close to our prediction, 
01101             and if so, go with our prediction */
01102          if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
01103             rtp->lastts = pred;
01104          else {
01105             ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
01106             mark = 1;
01107          }
01108       }
01109    } else {
01110       mark = f->subclass & 0x1;
01111       pred = rtp->lastovidtimestamp + f->samples;
01112       /* Re-calculate last TS */
01113       rtp->lastts = rtp->lastts + ms * 90;
01114       /* If it's close to our prediction, go for it */
01115       if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
01116          if (abs(rtp->lastts - pred) < 7200) {
01117             rtp->lastts = pred;
01118             rtp->lastovidtimestamp += f->samples;
01119          } else {
01120             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);
01121             rtp->lastovidtimestamp = rtp->lastts;
01122          }
01123       }
01124    }
01125    /* Get a pointer to the header */
01126    rtpheader = (unsigned int *)(f->data - hdrlen);
01127    rtpheader[0] = htonl((2 << 30) | (codec << 16) | (rtp->seqno++) | (mark << 23));
01128    rtpheader[1] = htonl(rtp->lastts);
01129    rtpheader[2] = htonl(rtp->ssrc); 
01130    if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
01131       res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
01132       if (res <0) 
01133          ast_log(LOG_NOTICE, "RTP Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
01134 #if 0
01135       printf("Sent %d bytes of RTP data to %s:%d\n", res, ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port));
01136 #endif      
01137    }
01138    return 0;
01139 }
01140 
01141 int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
01142 {
01143    struct ast_frame *f;
01144    int codec;
01145    int hdrlen = 12;
01146    int subclass;
01147    
01148 
01149    /* If we have no peer, return immediately */ 
01150    if (!rtp->them.sin_addr.s_addr)
01151       return 0;
01152 
01153    /* If there is no data length, return immediately */
01154    if (!_f->datalen) 
01155       return 0;
01156    
01157    /* Make sure we have enough space for RTP header */
01158    if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) {
01159       ast_log(LOG_WARNING, "RTP can only send voice\n");
01160       return -1;
01161    }
01162 
01163    subclass = _f->subclass;
01164    if (_f->frametype == AST_FRAME_VIDEO)
01165       subclass &= ~0x1;
01166 
01167    codec = ast_rtp_lookup_code(rtp, 1, subclass);
01168    if (codec < 0) {
01169       ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass));
01170       return -1;
01171    }
01172 
01173    if (rtp->lasttxformat != subclass) {
01174       /* New format, reset the smoother */
01175       ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
01176       rtp->lasttxformat = subclass;
01177       if (rtp->smoother)
01178          ast_smoother_free(rtp->smoother);
01179       rtp->smoother = NULL;
01180    }
01181 
01182 
01183    switch(subclass) {
01184    case AST_FORMAT_ULAW:
01185    case AST_FORMAT_ALAW:
01186       if (!rtp->smoother) {
01187          rtp->smoother = ast_smoother_new(160);
01188       }
01189       if (!rtp->smoother) {
01190          ast_log(LOG_WARNING, "Unable to create smoother :(\n");
01191          return -1;
01192       }
01193       ast_smoother_feed(rtp->smoother, _f);
01194       
01195       while((f = ast_smoother_read(rtp->smoother)))
01196          ast_rtp_raw_write(rtp, f, codec);
01197       break;
01198    case AST_FORMAT_ADPCM:
01199    case AST_FORMAT_G726:
01200       if (!rtp->smoother) {
01201          rtp->smoother = ast_smoother_new(80);
01202       }
01203       if (!rtp->smoother) {
01204          ast_log(LOG_WARNING, "Unable to create smoother :(\n");
01205          return -1;
01206       }
01207       ast_smoother_feed(rtp->smoother, _f);
01208       
01209       while((f = ast_smoother_read(rtp->smoother)))
01210          ast_rtp_raw_write(rtp, f, codec);
01211       break;
01212    case AST_FORMAT_G729A:
01213       if (!rtp->smoother) {
01214          rtp->smoother = ast_smoother_new(20);
01215          if (rtp->smoother)
01216             ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_G729);
01217       }
01218       if (!rtp->smoother) {
01219          ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n");
01220          return -1;
01221       }
01222       ast_smoother_feed(rtp->smoother, _f);
01223       
01224       while((f = ast_smoother_read(rtp->smoother)))
01225          ast_rtp_raw_write(rtp, f, codec);
01226       break;
01227    case AST_FORMAT_GSM:
01228       if (!rtp->smoother) {
01229          rtp->smoother = ast_smoother_new(33);
01230       }
01231       if (!rtp->smoother) {
01232          ast_log(LOG_WARNING, "Unable to create GSM smoother :(\n");
01233          return -1;
01234       }
01235       ast_smoother_feed(rtp->smoother, _f);
01236       while((f = ast_smoother_read(rtp->smoother)))
01237          ast_rtp_raw_write(rtp, f, codec);
01238       break;
01239    case AST_FORMAT_ILBC:
01240       if (!rtp->smoother) {
01241          rtp->smoother = ast_smoother_new(50);
01242       }
01243       if (!rtp->smoother) {
01244          ast_log(LOG_WARNING, "Unable to create ILBC smoother :(\n");
01245          return -1;
01246       }
01247       ast_smoother_feed(rtp->smoother, _f);
01248       while((f = ast_smoother_read(rtp->smoother)))
01249          ast_rtp_raw_write(rtp, f, codec);
01250       break;
01251    default: 
01252       ast_log(LOG_WARNING, "Not sure about sending format %s packets\n", ast_getformatname(subclass));
01253       /* fall through to... */
01254    case AST_FORMAT_H261:
01255    case AST_FORMAT_H263:
01256    case AST_FORMAT_G723_1:
01257    case AST_FORMAT_LPC10:
01258    case AST_FORMAT_SPEEX:
01259            /* Don't buffer outgoing frames; send them one-per-packet: */
01260       if (_f->offset < hdrlen) {
01261          f = ast_frdup(_f);
01262       } else {
01263          f = _f;
01264       }
01265       ast_rtp_raw_write(rtp, f, codec);
01266    }
01267       
01268    return 0;
01269 }
01270 
01271 void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto)
01272 {
01273    struct ast_rtp_protocol *cur, *prev;
01274    cur = protos;
01275    prev = NULL;
01276    while(cur) {
01277       if (cur == proto) {
01278          if (prev)
01279             prev->next = proto->next;
01280          else
01281             protos = proto->next;
01282          return;
01283       }
01284       prev = cur;
01285       cur = cur->next;
01286    }
01287 }
01288 
01289 int ast_rtp_proto_register(struct ast_rtp_protocol *proto)
01290 {
01291    struct ast_rtp_protocol *cur;
01292    cur = protos;
01293    while(cur) {
01294       if (cur->type == proto->type) {
01295          ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
01296          return -1;
01297       }
01298       cur = cur->next;
01299    }
01300    proto->next = protos;
01301    protos = proto;
01302    return 0;
01303 }
01304 
01305 static struct ast_rtp_protocol *get_proto(struct ast_channel *chan)
01306 {
01307    struct ast_rtp_protocol *cur;
01308    cur = protos;
01309    while(cur) {
01310       if (cur->type == chan->type) {
01311          return cur;
01312       }
01313       cur = cur->next;
01314    }
01315    return NULL;
01316 }
01317 
01318 int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
01319 {
01320    struct ast_frame *f;
01321    struct ast_channel *who, *cs[3];
01322    struct ast_rtp *p0, *p1;
01323    struct ast_rtp *vp0, *vp1;
01324    struct ast_rtp_protocol *pr0, *pr1;
01325    struct sockaddr_in ac0, ac1;
01326    struct sockaddr_in vac0, vac1;
01327    struct sockaddr_in t0, t1;
01328    struct sockaddr_in vt0, vt1;
01329    char iabuf[INET_ADDRSTRLEN];
01330    
01331    void *pvt0, *pvt1;
01332    int to;
01333    int codec0,codec1, oldcodec0, oldcodec1;
01334    
01335    memset(&vt0, 0, sizeof(vt0));
01336    memset(&vt1, 0, sizeof(vt1));
01337    memset(&vac0, 0, sizeof(vac0));
01338    memset(&vac1, 0, sizeof(vac1));
01339 
01340    /* if need DTMF, cant native bridge */
01341    if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
01342       return -2;
01343    ast_mutex_lock(&c0->lock);
01344    while(ast_mutex_trylock(&c1->lock)) {
01345       ast_mutex_unlock(&c0->lock);
01346       usleep(1);
01347       ast_mutex_lock(&c0->lock);
01348    }
01349    pr0 = get_proto(c0);
01350    pr1 = get_proto(c1);
01351    if (!pr0) {
01352       ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
01353       ast_mutex_unlock(&c0->lock);
01354       ast_mutex_unlock(&c1->lock);
01355       return -1;
01356    }
01357    if (!pr1) {
01358       ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
01359       ast_mutex_unlock(&c0->lock);
01360       ast_mutex_unlock(&c1->lock);
01361       return -1;
01362    }
01363    pvt0 = c0->pvt->pvt;
01364    pvt1 = c1->pvt->pvt;
01365    p0 = pr0->get_rtp_info(c0);
01366    if (pr0->get_vrtp_info)
01367       vp0 = pr0->get_vrtp_info(c0);
01368    else
01369       vp0 = NULL;
01370    p1 = pr1->get_rtp_info(c1);
01371    if (pr1->get_vrtp_info)
01372       vp1 = pr1->get_vrtp_info(c1);
01373    else
01374       vp1 = NULL;
01375    if (!p0 || !p1) {
01376       /* Somebody doesn't want to play... */
01377       ast_mutex_unlock(&c0->lock);
01378       ast_mutex_unlock(&c1->lock);
01379       return -2;
01380    }
01381    if (pr0->get_codec)
01382       codec0 = pr0->get_codec(c0);
01383    else
01384       codec0 = 0;
01385    if (pr1->get_codec)
01386       codec1 = pr1->get_codec(c1);
01387    else
01388       codec1 = 0;
01389    if (pr0->get_codec && pr1->get_codec) {
01390       /* Hey, we can't do reinvite if both parties speak diffrent codecs */
01391       if (!(codec0 & codec1)) {
01392          ast_log(LOG_WARNING, "codec0 = %d is not codec1 = %d, cannot native bridge.\n",codec0,codec1);
01393          ast_mutex_unlock(&c0->lock);
01394          ast_mutex_unlock(&c1->lock);
01395          return -2;
01396       }
01397    }
01398    if (pr0->set_rtp_peer(c0, p1, vp1, codec1)) 
01399       ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
01400    else {
01401       /* Store RTP peer */
01402       ast_rtp_get_peer(p1, &ac1);
01403       if (vp1)
01404          ast_rtp_get_peer(vp1, &vac1);
01405    }
01406    if (pr1->set_rtp_peer(c1, p0, vp0, codec0))
01407       ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
01408    else {
01409       /* Store RTP peer */
01410       ast_rtp_get_peer(p0, &ac0);
01411       if (vp0)
01412          ast_rtp_get_peer(vp0, &vac0);
01413    }
01414    ast_mutex_unlock(&c0->lock);
01415    ast_mutex_unlock(&c1->lock);
01416    cs[0] = c0;
01417    cs[1] = c1;
01418    cs[2] = NULL;
01419    oldcodec0 = codec0;
01420    oldcodec1 = codec1;
01421    for (;;) {
01422       if ((c0->pvt->pvt != pvt0)  ||
01423          (c1->pvt->pvt != pvt1) ||
01424          (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
01425             ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
01426             if (c0->pvt->pvt == pvt0) {
01427                if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
01428                   ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
01429             }
01430             if (c1->pvt->pvt == pvt1) {
01431                if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
01432                   ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
01433             }
01434             /* Tell it to try again later */
01435             return -3;
01436       }
01437       to = -1;
01438       ast_rtp_get_peer(p1, &t1);
01439       ast_rtp_get_peer(p0, &t0);
01440       if (pr0->get_codec)
01441          codec0 = pr0->get_codec(c0);
01442       if (pr1->get_codec)
01443          codec1 = pr1->get_codec(c1);
01444       if (vp1)
01445          ast_rtp_get_peer(vp1, &vt1);
01446       if (vp0)
01447          ast_rtp_get_peer(vp0, &vt0);
01448       if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) {
01449          ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
01450             c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1);
01451          ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", 
01452             c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1);
01453          ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
01454             c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
01455          ast_log(LOG_DEBUG, "Oooh, '%s' wasv %s:%d/(format %d)\n", 
01456             c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
01457          if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1)) 
01458             ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
01459          memcpy(&ac1, &t1, sizeof(ac1));
01460          memcpy(&vac1, &vt1, sizeof(vac1));
01461          oldcodec1 = codec1;
01462       }
01463       if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) {
01464          ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
01465             c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0);
01466          ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
01467             c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
01468          if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0))
01469             ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
01470          memcpy(&ac0, &t0, sizeof(ac0));
01471          memcpy(&vac0, &vt0, sizeof(vac0));
01472          oldcodec0 = codec0;
01473       }
01474       who = ast_waitfor_n(cs, 2, &to);
01475       if (!who) {
01476          ast_log(LOG_DEBUG, "Ooh, empty read...\n");
01477          /* check for hagnup / whentohangup */
01478          if (ast_check_hangup(c0) || ast_check_hangup(c1))
01479             break;
01480          continue;
01481       }
01482       f = ast_read(who);
01483       if (!f || ((f->frametype == AST_FRAME_DTMF) &&
01484                (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || 
01485                 ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
01486          *fo = f;
01487          *rc = who;
01488          ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
01489          if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
01490             if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
01491                ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
01492          }
01493          if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
01494             if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
01495                ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
01496          }
01497          /* That's all we needed */
01498          return 0;
01499       } else {
01500          if ((f->frametype == AST_FRAME_DTMF) || 
01501             (f->frametype == AST_FRAME_VOICE) || 
01502             (f->frametype == AST_FRAME_VIDEO)) {
01503             /* Forward voice or DTMF frames if they happen upon us */
01504             if (who == c0) {
01505                ast_write(c1, f);
01506             } else if (who == c1) {
01507                ast_write(c0, f);
01508             }
01509          }
01510          ast_frfree(f);
01511       }
01512       /* Swap priority not that it's a big deal at this point */
01513       cs[2] = cs[0];
01514       cs[0] = cs[1];
01515       cs[1] = cs[2];
01516       
01517    }
01518    return -1;
01519 }
01520 
01521 void ast_rtp_reload(void)
01522 {
01523    struct ast_config *cfg;
01524    char *s;
01525    rtpstart = 5000;
01526    rtpend = 31000;
01527 #ifdef SO_NO_CHECK
01528    checksums = 1;
01529 #endif
01530    cfg = ast_load("rtp.conf");
01531    if (cfg) {
01532       if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
01533          rtpstart = atoi(s);
01534          if (rtpstart < 1024)
01535             rtpstart = 1024;
01536          if (rtpstart > 65535)
01537             rtpstart = 65535;
01538       }
01539       if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) {
01540          rtpend = atoi(s);
01541          if (rtpend < 1024)
01542             rtpend = 1024;
01543          if (rtpend > 65535)
01544             rtpend = 65535;
01545       }
01546       if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
01547 #ifdef SO_NO_CHECK
01548          if (ast_true(s))
01549             checksums = 1;
01550          else
01551             checksums = 0;
01552 #else
01553          if (ast_true(s))
01554             ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
01555 #endif
01556       }
01557       ast_destroy(cfg);
01558    }
01559    if (rtpstart >= rtpend) {
01560       ast_log(LOG_WARNING, "Unreasonable values for RTP start/end\n");
01561       rtpstart = 5000;
01562       rtpend = 31000;
01563    }
01564    if (option_verbose > 1)
01565       ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
01566 }
01567 
01568 void ast_rtp_init(void)
01569 {
01570    ast_rtp_reload();
01571 }

Generated on Thu Oct 28 11:32:55 2004 for Asterisk by doxygen1.2.15