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

Generated on Wed Aug 10 11:36:32 2005 for Asterisk by  doxygen 1.4.4