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

Generated on Wed Mar 16 20:08:35 2005 for Asterisk by  doxygen 1.4.0