~davewalker/ubuntu/maverick/asterisk/lp_705014

« back to all changes in this revision

Viewing changes to rtp.c

  • Committer: Bazaar Package Importer
  • Author(s): Kilian Krause
  • Date: 2005-03-09 22:09:05 UTC
  • mto: (1.2.1 upstream) (8.2.1 experimental)
  • mto: This revision was merged to the branch mainline in revision 4.
  • Revision ID: james.westby@ubuntu.com-20050309220905-9afy6hcpw96xbr6j
Tags: upstream-1.0.6
ImportĀ upstreamĀ versionĀ 1.0.6

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
 * Asterisk -- A telephony toolkit for Linux.
3
3
 *
4
4
 * Real-time Protocol Support
 
5
 *      Supports RTP and RTCP with Symmetric RTP support for NAT
 
6
 *      traversal
5
7
 * 
6
 
 * Copyright (C) 1999, Mark Spencer
 
8
 * Copyright (C) 1999-2004, Digium, Inc.
7
9
 *
8
 
 * Mark Spencer <markster@linux-support.net>
 
10
 * Mark Spencer <markster@digium.com>
9
11
 *
10
12
 * This program is free software, distributed under the terms of
11
13
 * the GNU General Public License
13
15
 
14
16
#include <stdio.h>
15
17
#include <stdlib.h>
16
 
#include <pthread.h>
17
18
#include <string.h>
18
19
#include <sys/time.h>
19
20
#include <signal.h>
34
35
#include <asterisk/channel.h>
35
36
#include <asterisk/channel_pvt.h>
36
37
#include <asterisk/config.h>
 
38
#include <asterisk/lock.h>
 
39
#include <asterisk/utils.h>
 
40
 
 
41
#define MAX_TIMESTAMP_SKEW      640
37
42
 
38
43
#define RTP_MTU         1200
39
44
 
43
48
#define TYPE_DONTSEND    0x3
44
49
#define TYPE_MASK        0x3
45
50
 
46
 
static int dtmftimeout = 300;   /* 300 samples */
 
51
static int dtmftimeout = 3000;  /* 3000 samples */
47
52
 
48
53
static int rtpstart = 0;
49
54
static int rtpend = 0;
 
55
#ifdef SO_NO_CHECK
 
56
static int checksums = 1;
 
57
#endif
50
58
 
51
 
// The value of each payload format mapping:
 
59
/* The value of each payload format mapping: */
52
60
struct rtpPayloadType {
53
 
  int isAstFormat; // whether the following code is an AST_FORMAT
 
61
  int isAstFormat;      /* whether the following code is an AST_FORMAT */
54
62
  int code;
55
63
};
56
64
 
57
65
#define MAX_RTP_PT 256
58
66
 
 
67
#define FLAG_3389_WARNING (1 << 0)
 
68
 
59
69
struct ast_rtp {
60
70
        int s;
61
71
        char resp;
66
76
        unsigned int lastrxts;
67
77
        unsigned int lastividtimestamp;
68
78
        unsigned int lastovidtimestamp;
 
79
        unsigned int lasteventseqn;
69
80
        int lasttxformat;
70
81
        int lastrxformat;
71
82
        int dtmfcount;
72
83
        unsigned int dtmfduration;
73
84
        int nat;
 
85
        int flags;
74
86
        struct sockaddr_in us;
75
87
        struct sockaddr_in them;
76
88
        struct timeval rxcore;
84
96
        void *data;
85
97
        ast_rtp_callback callback;
86
98
    struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
87
 
    // a cache for the result of rtp_lookup_code():
88
 
    int rtp_lookup_code_cache_isAstFormat;
 
99
    int rtp_lookup_code_cache_isAstFormat;      /* a cache for the result of rtp_lookup_code(): */
89
100
    int rtp_lookup_code_cache_code;
90
101
    int rtp_lookup_code_cache_result;
 
102
    int rtp_offered_from_local;
91
103
        struct ast_rtcp *rtcp;
92
104
};
93
105
 
166
178
{
167
179
        struct timeval tv;
168
180
        static struct ast_frame null_frame = { AST_FRAME_NULL, };
 
181
        char iabuf[INET_ADDRSTRLEN];
169
182
        gettimeofday(&tv, NULL);
170
183
        if ((tv.tv_sec < rtp->dtmfmute.tv_sec) ||
171
184
            ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < rtp->dtmfmute.tv_usec))) {
172
 
                ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", inet_ntoa(rtp->them.sin_addr));
 
185
                ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr));
173
186
                rtp->resp = 0;
174
187
                rtp->dtmfduration = 0;
175
188
                return &null_frame;
176
189
        }
177
 
        ast_log(LOG_DEBUG, "Sending dtmf: %d (%c), at %s\n", rtp->resp, rtp->resp, inet_ntoa(rtp->them.sin_addr));
178
 
        rtp->f.frametype = AST_FRAME_DTMF;
179
 
        rtp->f.subclass = rtp->resp;
 
190
        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));
 
191
        if (rtp->resp == 'X') {
 
192
                rtp->f.frametype = AST_FRAME_CONTROL;
 
193
                rtp->f.subclass = AST_CONTROL_FLASH;
 
194
        } else {
 
195
                rtp->f.frametype = AST_FRAME_DTMF;
 
196
                rtp->f.subclass = rtp->resp;
 
197
        }
180
198
        rtp->f.datalen = 0;
181
199
        rtp->f.samples = 0;
182
200
        rtp->f.mallocd = 0;
205
223
                resp = '#';
206
224
        } else if (event < 16) {
207
225
                resp = 'A' + (event - 12);
 
226
        } else if (event < 17) {
 
227
                resp = 'X';
208
228
        }
209
229
        if (rtp->resp && (rtp->resp != resp)) {
210
230
                f = send_dtmf(rtp);
239
259
                resp = '#';
240
260
        } else if (event < 16) {
241
261
                resp = 'A' + (event - 12);
 
262
        } else if (event < 17) {
 
263
                resp = 'X';
242
264
        }
243
265
        if (rtp->resp && (rtp->resp != resp)) {
244
266
                f = send_dtmf(rtp);
269
291
        /* Convert comfort noise into audio with various codecs.  Unfortunately this doesn't
270
292
           totally help us out becuase we don't have an engine to keep it going and we are not
271
293
           guaranteed to have it every 20ms or anything */
272
 
#if 0
273
 
        printf("RFC3389: %d bytes, format is %d\n", len, rtp->lastrxformat);
 
294
#if 1
 
295
        printf("RFC3389: %d bytes, level %d...\n", len, rtp->lastrxformat);
274
296
#endif  
275
 
        ast_log(LOG_NOTICE, "RFC3389 support incomplete.  Turn off on client if possible\n");
276
 
        if (!rtp->lastrxformat)
277
 
                return  NULL;
278
 
        switch(rtp->lastrxformat) {
279
 
        case AST_FORMAT_ULAW:
280
 
                rtp->f.frametype = AST_FRAME_VOICE;
281
 
                rtp->f.subclass = AST_FORMAT_ULAW;
282
 
                rtp->f.datalen = 160;
283
 
                rtp->f.samples = 160;
284
 
                memset(rtp->f.data, 0x7f, rtp->f.datalen);
285
 
                f = &rtp->f;
286
 
                break;
287
 
        case AST_FORMAT_ALAW:
288
 
                rtp->f.frametype = AST_FRAME_VOICE;
289
 
                rtp->f.subclass = AST_FORMAT_ALAW;
290
 
                rtp->f.datalen = 160;
291
 
                rtp->f.samples = 160;
292
 
                memset(rtp->f.data, 0x7e, rtp->f.datalen); /* XXX Is this right? XXX */
293
 
                f = &rtp->f;
294
 
                break;
295
 
        case AST_FORMAT_SLINEAR:
296
 
                rtp->f.frametype = AST_FRAME_VOICE;
297
 
                rtp->f.subclass = AST_FORMAT_SLINEAR;
298
 
                rtp->f.datalen = 320;
299
 
                rtp->f.samples = 160;
300
 
                memset(rtp->f.data, 0x00, rtp->f.datalen);
301
 
                f = &rtp->f;
302
 
                break;
303
 
        default:
304
 
                ast_log(LOG_NOTICE, "Don't know how to handle RFC3389 for receive codec %d\n", rtp->lastrxformat);
305
 
        }
 
297
        if (!(rtp->flags & FLAG_3389_WARNING)) {
 
298
                ast_log(LOG_NOTICE, "RFC3389 support incomplete.  Turn off on client if possible\n");
 
299
                rtp->flags |= FLAG_3389_WARNING;
 
300
        }
 
301
        /* Must have at least one byte */
 
302
        if (!len)
 
303
                return NULL;
 
304
        if (len < 24) {
 
305
                rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET;
 
306
                rtp->f.datalen = len - 1;
 
307
                rtp->f.offset = AST_FRIENDLY_OFFSET;
 
308
                memcpy(rtp->f.data, data + 1, len - 1);
 
309
        } else {
 
310
                rtp->f.data = NULL;
 
311
                rtp->f.offset = 0;
 
312
                rtp->f.datalen = 0;
 
313
        }
 
314
        rtp->f.frametype = AST_FRAME_CNG;
 
315
        rtp->f.subclass = data[0] & 0x7f;
 
316
        rtp->f.datalen = len - 1;
 
317
        rtp->f.samples = 0;
 
318
        rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
 
319
        f = &rtp->f;
306
320
        return f;
307
321
}
308
322
 
326
340
        int res;
327
341
        struct sockaddr_in sin;
328
342
        unsigned int rtcpdata[1024];
 
343
        char iabuf[INET_ADDRSTRLEN];
329
344
        
330
345
        if (!rtp->rtcp)
331
346
                return &null_frame;
336
351
                                        0, (struct sockaddr *)&sin, &len);
337
352
        
338
353
        if (res < 0) {
339
 
                ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
 
354
                if (errno == EAGAIN)
 
355
                        ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
 
356
                else
 
357
                        ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
340
358
                if (errno == EBADF)
341
359
                        CRASH;
342
360
                return &null_frame;
352
370
                if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
353
371
                    (rtp->rtcp->them.sin_port != sin.sin_port)) {
354
372
                        memcpy(&rtp->them, &sin, sizeof(rtp->them));
355
 
                        ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", inet_ntoa(rtp->rtcp->them.sin_addr), ntohs(rtp->rtcp->them.sin_port));
 
373
                        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));
356
374
                }
357
375
        }
358
376
        if (option_debug)
360
378
        return &null_frame;
361
379
}
362
380
 
 
381
static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
 
382
{
 
383
        if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
 
384
                gettimeofday(&rtp->rxcore, NULL);
 
385
                rtp->rxcore.tv_sec -= timestamp / 8000;
 
386
                rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
 
387
                /* Round to 20ms for nice, pretty timestamps */
 
388
                rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
 
389
                if (rtp->rxcore.tv_usec < 0) {
 
390
                        /* Adjust appropriately if necessary */
 
391
                        rtp->rxcore.tv_usec += 1000000;
 
392
                        rtp->rxcore.tv_sec -= 1;
 
393
                }
 
394
        }
 
395
        tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
 
396
        tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
 
397
        if (tv->tv_usec >= 1000000) {
 
398
                tv->tv_usec -= 1000000;
 
399
                tv->tv_sec += 1;
 
400
        }
 
401
}
 
402
 
363
403
struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
364
404
{
365
405
        int res;
366
406
        struct sockaddr_in sin;
367
407
        int len;
368
408
        unsigned int seqno;
 
409
        int version;
369
410
        int payloadtype;
370
411
        int hdrlen = 12;
371
412
        int mark;
 
413
        int ext;
 
414
        char iabuf[INET_ADDRSTRLEN];
372
415
        unsigned int timestamp;
373
416
        unsigned int *rtpheader;
374
417
        static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
383
426
 
384
427
        rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
385
428
        if (res < 0) {
386
 
                ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
 
429
                if (errno == EAGAIN)
 
430
                        ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
 
431
                else
 
432
                        ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
387
433
                if (errno == EBADF)
388
434
                        CRASH;
389
435
                return &null_frame;
392
438
                ast_log(LOG_WARNING, "RTP Read too short\n");
393
439
                return &null_frame;
394
440
        }
395
 
        if (rtp->nat) {
396
 
                /* Send to whoever sent to us */
397
 
                if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
398
 
                    (rtp->them.sin_port != sin.sin_port)) {
399
 
                        memcpy(&rtp->them, &sin, sizeof(rtp->them));
400
 
                        ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
401
 
                }
402
 
        }
 
441
 
403
442
        /* Ignore if the other side hasn't been given an address
404
443
           yet.  */
405
444
        if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
406
445
                return &null_frame;
407
446
 
 
447
        if (rtp->nat) {
 
448
                /* Send to whoever sent to us */
 
449
                if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
 
450
                    (rtp->them.sin_port != sin.sin_port)) {
 
451
                        memcpy(&rtp->them, &sin, sizeof(rtp->them));
 
452
                        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));
 
453
                }
 
454
        }
 
455
 
408
456
        /* Get fields */
409
457
        seqno = ntohl(rtpheader[0]);
 
458
 
 
459
        /* Check RTP version */
 
460
        version = (seqno & 0xC0000000) >> 30;
 
461
        if (version != 2)
 
462
                return &null_frame;
 
463
        
410
464
        payloadtype = (seqno & 0x7f0000) >> 16;
411
465
        mark = seqno & (1 << 23);
 
466
        ext = seqno & (1 << 28);
412
467
        seqno &= 0xffff;
413
468
        timestamp = ntohl(rtpheader[1]);
 
469
        if (ext) {
 
470
                /* RTP Extension present */
 
471
                hdrlen += 4;
 
472
                hdrlen += (ntohl(rtpheader[3]) & 0xffff) << 2;
 
473
        }
 
474
 
 
475
        if (res < hdrlen) {
 
476
                ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen);
 
477
                return &null_frame;
 
478
        }
414
479
 
415
480
#if 0
416
 
        printf("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len = %d)\n", inet_ntoa(sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
 
481
        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);
417
482
#endif  
418
483
        rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
419
484
        if (!rtpPT.isAstFormat) {
420
 
          // This is special in-band data that's not one of our codecs
 
485
          /* This is special in-band data that's not one of our codecs */
421
486
          if (rtpPT.code == AST_RTP_DTMF) {
422
487
            /* It's special -- rfc2833 process it */
423
 
            f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
 
488
            if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
 
489
              f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
 
490
              rtp->lasteventseqn = seqno;
 
491
            } else f = NULL;
424
492
            if (f) return f; else return &null_frame;
425
493
          } else if (rtpPT.code == AST_RTP_CISCO_DTMF) {
426
494
            /* It's really special -- process it the Cisco way */
427
 
            f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
 
495
            if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
 
496
              f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
 
497
              rtp->lasteventseqn = seqno;
 
498
            } else f = NULL;
428
499
            if (f) return f; else return &null_frame;
429
500
          } else if (rtpPT.code == AST_RTP_CN) {
430
501
            /* Comfort Noise */
484
555
                        rtp->f.samples = 240 * (rtp->f.datalen / 50);
485
556
                        break;
486
557
                case AST_FORMAT_ADPCM:
 
558
                case AST_FORMAT_G726:
487
559
                        rtp->f.samples = rtp->f.datalen * 2;
488
560
                        break;
489
561
                case AST_FORMAT_G729A:
493
565
                        rtp->f.samples = g723_samples(rtp->f.data, rtp->f.datalen);
494
566
                        break;
495
567
                case AST_FORMAT_SPEEX:
496
 
                        rtp->f.samples = 160;
497
 
                        // assumes that the RTP packet contained one Speex frame
 
568
                        /* assumes that the RTP packet contained one Speex frame */
 
569
                rtp->f.samples = 160;
 
570
                        break;
 
571
                case AST_FORMAT_LPC10:
 
572
                    rtp->f.samples = 22 * 8;
 
573
                        rtp->f.samples += (((char *)(rtp->f.data))[7] & 0x1) * 8;
498
574
                        break;
499
575
                default:
500
576
                        ast_log(LOG_NOTICE, "Unable to calculate samples for format %s\n", ast_getformatname(rtp->f.subclass));
501
577
                        break;
502
578
                }
 
579
                calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
503
580
        } else {
504
581
                /* Video -- samples is # of samples vs. 90000 */
505
582
                if (!rtp->lastividtimestamp)
506
583
                        rtp->lastividtimestamp = timestamp;
507
584
                rtp->f.samples = timestamp - rtp->lastividtimestamp;
508
585
                rtp->lastividtimestamp = timestamp;
 
586
                rtp->f.delivery.tv_sec = 0;
 
587
                rtp->f.delivery.tv_usec = 0;
509
588
                if (mark)
510
589
                        rtp->f.subclass |= 0x1;
511
590
                
514
593
        return &rtp->f;
515
594
}
516
595
 
517
 
// The following array defines the MIME type (and subtype) for each
518
 
// of our codecs, or RTP-specific data type.
 
596
/* The following array defines the MIME Media type (and subtype) for each
 
597
   of our codecs, or RTP-specific data type. */
519
598
static struct {
520
599
  struct rtpPayloadType payloadType;
521
600
  char* type;
530
609
  {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
531
610
  {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
532
611
  {{1, AST_FORMAT_G729A}, "audio", "G729"},
533
 
  {{1, AST_FORMAT_SPEEX}, "audio", "SPEEX"},
 
612
  {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
534
613
  {{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
535
614
  {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
536
615
  {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
546
625
   table for transmission */
547
626
static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
548
627
  [0] = {1, AST_FORMAT_ULAW},
549
 
  [2] = {1, AST_FORMAT_G726}, // Technically this is G.721, but if Cisco can do it, so can we...
 
628
  [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
550
629
  [3] = {1, AST_FORMAT_GSM},
551
630
  [4] = {1, AST_FORMAT_G723_1},
552
 
  [5] = {1, AST_FORMAT_ADPCM}, // 8 kHz
553
 
  [6] = {1, AST_FORMAT_ADPCM}, // 16 kHz
 
631
  [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
 
632
  [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
554
633
  [7] = {1, AST_FORMAT_LPC10},
555
634
  [8] = {1, AST_FORMAT_ALAW},
556
 
  [10] = {1, AST_FORMAT_SLINEAR}, // 2 channels
557
 
  [11] = {1, AST_FORMAT_SLINEAR}, // 1 channel
 
635
  [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
 
636
  [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
558
637
  [13] = {0, AST_RTP_CN},
559
 
  [16] = {1, AST_FORMAT_ADPCM}, // 11.025 kHz
560
 
  [17] = {1, AST_FORMAT_ADPCM}, // 22.050 kHz
 
638
  [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
 
639
  [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
561
640
  [18] = {1, AST_FORMAT_G729A},
 
641
  [19] = {0, AST_RTP_CN},               /* Also used for CN */
562
642
  [26] = {1, AST_FORMAT_JPEG},
563
643
  [31] = {1, AST_FORMAT_H261},
564
644
  [34] = {1, AST_FORMAT_H263},
565
645
  [97] = {1, AST_FORMAT_ILBC},
566
646
  [101] = {0, AST_RTP_DTMF},
567
647
  [110] = {1, AST_FORMAT_SPEEX},
568
 
  [121] = {0, AST_RTP_CISCO_DTMF}, // Must be type 121
 
648
  [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
569
649
};
570
650
 
571
651
void ast_rtp_pt_clear(struct ast_rtp* rtp) 
596
676
  rtp->rtp_lookup_code_cache_result = 0;
597
677
}
598
678
 
599
 
// Make a note of a RTP payload type that was seen in a SDP "m=" line.
600
 
// By default, use the well-known value for this type (although it may
601
 
// still be set to a different value by a subsequent "a=rtpmap:" line):
 
679
/* Make a note of a RTP payload type that was seen in a SDP "m=" line. */
 
680
/* By default, use the well-known value for this type (although it may */
 
681
/* still be set to a different value by a subsequent "a=rtpmap:" line): */
602
682
void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
603
 
  if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type
 
683
  if (pt < 0 || pt > MAX_RTP_PT) return; /* bogus payload type */
604
684
 
605
685
  if (static_RTP_PT[pt].code != 0) {
606
686
    rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
607
687
  }
608
688
609
689
 
610
 
// Make a note of a RTP payload type (with MIME type) that was seen in
611
 
// a SDP "a=rtpmap:" line.
 
690
/* Make a note of a RTP payload type (with MIME type) that was seen in */
 
691
/* a SDP "a=rtpmap:" line. */
612
692
void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
613
693
                         char* mimeType, char* mimeSubtype) {
614
694
  int i;
615
695
 
616
 
  if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type
 
696
  if (pt < 0 || pt > MAX_RTP_PT) return; /* bogus payload type */
617
697
 
618
698
  for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
619
699
    if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
624
704
  }
625
705
626
706
 
627
 
// Return the union of all of the codecs that were set by rtp_set...() calls
628
 
// They're returned as two distinct sets: AST_FORMATs, and AST_RTPs
 
707
/* Return the union of all of the codecs that were set by rtp_set...() calls */
 
708
/* They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
629
709
void ast_rtp_get_current_formats(struct ast_rtp* rtp,
630
710
                             int* astFormats, int* nonAstFormats) {
631
711
  int pt;
640
720
  }
641
721
}
642
722
 
643
 
struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) {
 
723
void ast_rtp_offered_from_local(struct ast_rtp* rtp, int local) {
 
724
  if (rtp)
 
725
    rtp->rtp_offered_from_local = local;
 
726
  else
 
727
    ast_log(LOG_WARNING, "rtp structure is null\n");
 
728
}
 
729
 
 
730
struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) 
 
731
{
 
732
  struct rtpPayloadType result;
 
733
 
 
734
  result.isAstFormat = result.code = 0;
644
735
  if (pt < 0 || pt > MAX_RTP_PT) {
645
 
    struct rtpPayloadType result;
646
 
    result.isAstFormat = result.code = 0;
647
 
    return result; // bogus payload type
 
736
    return result; /* bogus payload type */
648
737
  }
649
 
  /* Gotta use our static one, since that's what we sent against */
650
 
  return static_RTP_PT[pt];
 
738
  /* Start with the negotiated codecs */
 
739
  if (!rtp->rtp_offered_from_local)
 
740
    result = rtp->current_RTP_PT[pt];
 
741
  /* If it doesn't exist, check our static RTP type list, just in case */
 
742
  if (!result.code) 
 
743
    result = static_RTP_PT[pt];
 
744
  return result;
651
745
}
652
746
 
 
747
/* Looks up an RTP code out of our *static* outbound list */
653
748
int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) {
654
749
  int pt;
655
750
 
656
 
  /* Looks up an RTP code out of our *static* outbound list */
657
751
 
658
752
  if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
659
753
      code == rtp->rtp_lookup_code_cache_code) {
660
 
    // Use our cached mapping, to avoid the overhead of the loop below
 
754
    /* Use our cached mapping, to avoid the overhead of the loop below */
661
755
    return rtp->rtp_lookup_code_cache_result;
662
756
  }
663
757
 
 
758
        /* Check the dynamic list first */
 
759
  for (pt = 0; pt < MAX_RTP_PT; ++pt) {
 
760
    if (rtp->current_RTP_PT[pt].code == code &&
 
761
                rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) {
 
762
      rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
 
763
      rtp->rtp_lookup_code_cache_code = code;
 
764
      rtp->rtp_lookup_code_cache_result = pt;
 
765
      return pt;
 
766
    }
 
767
  }
 
768
 
 
769
        /* Then the static list */
664
770
  for (pt = 0; pt < MAX_RTP_PT; ++pt) {
665
771
    if (static_RTP_PT[pt].code == code &&
666
772
                static_RTP_PT[pt].isAstFormat == isAstFormat) {
685
791
  return "";
686
792
}
687
793
 
 
794
static int rtp_socket(void)
 
795
{
 
796
        int s;
 
797
        long flags;
 
798
        s = socket(AF_INET, SOCK_DGRAM, 0);
 
799
        if (s > -1) {
 
800
                flags = fcntl(s, F_GETFL);
 
801
                fcntl(s, F_SETFL, flags | O_NONBLOCK);
 
802
#ifdef SO_NO_CHECK
 
803
                if (checksums) {
 
804
                        setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &checksums, sizeof(checksums));
 
805
                }
 
806
#endif
 
807
        }
 
808
        return s;
 
809
}
 
810
 
688
811
static struct ast_rtcp *ast_rtcp_new(void)
689
812
{
690
813
        struct ast_rtcp *rtcp;
691
 
        long flags;
692
814
        rtcp = malloc(sizeof(struct ast_rtcp));
693
815
        if (!rtcp)
694
816
                return NULL;
695
817
        memset(rtcp, 0, sizeof(struct ast_rtcp));
696
 
        rtcp->s = socket(AF_INET, SOCK_DGRAM, 0);
 
818
        rtcp->s = rtp_socket();
697
819
        rtcp->us.sin_family = AF_INET;
698
820
        if (rtcp->s < 0) {
699
821
                free(rtcp);
700
822
                ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
701
823
                return NULL;
702
824
        }
703
 
        flags = fcntl(rtcp->s, F_GETFL);
704
 
        fcntl(rtcp->s, F_SETFL, flags | O_NONBLOCK);
705
825
        return rtcp;
706
826
}
707
827
 
708
 
struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
 
828
struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
709
829
{
710
830
        struct ast_rtp *rtp;
711
831
        int x;
712
 
        int flags;
 
832
        int first;
713
833
        int startplace;
714
834
        rtp = malloc(sizeof(struct ast_rtp));
715
835
        if (!rtp)
717
837
        memset(rtp, 0, sizeof(struct ast_rtp));
718
838
        rtp->them.sin_family = AF_INET;
719
839
        rtp->us.sin_family = AF_INET;
720
 
        rtp->s = socket(AF_INET, SOCK_DGRAM, 0);
 
840
        rtp->s = rtp_socket();
721
841
        rtp->ssrc = rand();
722
842
        rtp->seqno = rand() & 0xffff;
723
843
        if (rtp->s < 0) {
729
849
                rtp->sched = sched;
730
850
                rtp->rtcp = ast_rtcp_new();
731
851
        }
732
 
        flags = fcntl(rtp->s, F_GETFL);
733
 
        fcntl(rtp->s, F_SETFL, flags | O_NONBLOCK);
734
852
        /* Find us a place */
735
853
        x = (rand() % (rtpend-rtpstart)) + rtpstart;
736
854
        x = x & ~1;
738
856
        for (;;) {
739
857
                /* Must be an even port number by RTP spec */
740
858
                rtp->us.sin_port = htons(x);
 
859
                rtp->us.sin_addr = addr;
741
860
                if (rtp->rtcp)
742
861
                        rtp->rtcp->us.sin_port = htons(x + 1);
743
 
                if (!bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us)) &&
 
862
                if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) &&
744
863
                        (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us))))
745
864
                        break;
 
865
                if (!first) {
 
866
                        /* Primary bind succeeded! Gotta recreate it */
 
867
                        close(rtp->s);
 
868
                        rtp->s = rtp_socket();
 
869
                }
746
870
                if (errno != EADDRINUSE) {
747
871
                        ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
748
872
                        close(rtp->s);
777
901
        return rtp;
778
902
}
779
903
 
 
904
struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
 
905
{
 
906
        struct in_addr ia;
 
907
        memset(&ia, 0, sizeof(ia));
 
908
        return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
 
909
}
 
910
 
780
911
int ast_rtp_settos(struct ast_rtp *rtp, int tos)
781
912
{
782
913
        int res;
832
963
        free(rtp);
833
964
}
834
965
 
835
 
static unsigned int calc_txstamp(struct ast_rtp *rtp)
 
966
static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
836
967
{
837
968
        struct timeval now;
838
969
        unsigned int ms;
839
970
        if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
840
971
                gettimeofday(&rtp->txcore, NULL);
841
 
        }
842
 
        gettimeofday(&now, NULL);
843
 
        ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
844
 
        ms += (now.tv_usec - rtp->txcore.tv_usec) / 1000;
845
 
        /* Use what we just got for next time */
846
 
        rtp->txcore.tv_sec = now.tv_sec;
847
 
        rtp->txcore.tv_usec = now.tv_usec;
 
972
                /* Round to 20ms for nice, pretty timestamps */
 
973
                rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
 
974
        }
 
975
        if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
 
976
                /* Use previous txcore */
 
977
                ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
 
978
                ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
 
979
                rtp->txcore.tv_sec = delivery->tv_sec;
 
980
                rtp->txcore.tv_usec = delivery->tv_usec;
 
981
        } else {
 
982
                gettimeofday(&now, NULL);
 
983
                ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
 
984
                ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
 
985
                /* Use what we just got for next time */
 
986
                rtp->txcore.tv_sec = now.tv_sec;
 
987
                rtp->txcore.tv_usec = now.tv_usec;
 
988
        }
848
989
        return ms;
849
990
}
850
991
 
853
994
        unsigned int *rtpheader;
854
995
        int hdrlen = 12;
855
996
        int res;
856
 
        int ms;
857
 
        int pred;
858
997
        int x;
 
998
        int payload;
859
999
        char data[256];
 
1000
        char iabuf[INET_ADDRSTRLEN];
860
1001
 
861
1002
        if ((digit <= '9') && (digit >= '0'))
862
1003
                digit -= '0';
872
1013
                ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
873
1014
                return -1;
874
1015
        }
875
 
        
 
1016
        payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF);
876
1017
 
877
1018
        /* If we have no peer, return immediately */    
878
1019
        if (!rtp->them.sin_addr.s_addr)
884
1025
                rtp->dtmfmute.tv_usec -= 1000000;
885
1026
                rtp->dtmfmute.tv_sec += 1;
886
1027
        }
887
 
 
888
 
        ms = calc_txstamp(rtp);
889
 
        /* Default prediction */
890
 
        pred = rtp->lastts + ms * 8;
891
1028
        
892
1029
        /* Get a pointer to the header */
893
1030
        rtpheader = (unsigned int *)data;
894
 
        rtpheader[0] = htonl((2 << 30) | (1 << 23) | (101 << 16) | (rtp->seqno++));
 
1031
        rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
895
1032
        rtpheader[1] = htonl(rtp->lastts);
896
1033
        rtpheader[2] = htonl(rtp->ssrc); 
897
1034
        rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
898
 
        for (x=0;x<4;x++) {
 
1035
        for (x=0;x<6;x++) {
899
1036
                if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
900
1037
                        res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
901
1038
                        if (res <0) 
902
 
                                ast_log(LOG_NOTICE, "RTP Transmission error to %s:%d: %s\n", inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
 
1039
                                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));
903
1040
        #if 0
904
 
                printf("Sent %d bytes of RTP data to %s:%d\n", res, inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
 
1041
                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));
905
1042
        #endif          
906
1043
                }
907
 
                if (x ==0) {
 
1044
                if (x == 2) {
908
1045
                        /* Clear marker bit and increment seqno */
909
 
                        rtpheader[0] = htonl((2 << 30)  | (101 << 16) | (rtp->seqno++));
 
1046
                        rtpheader[0] = htonl((2 << 30)  | (payload << 16) | (rtp->seqno++));
910
1047
                        /* Make duration 800 (100ms) */
911
1048
                        rtpheader[3] |= htonl((800));
912
1049
                        /* Set the End bit for the last 3 */
913
1050
                        rtpheader[3] |= htonl((1 << 23));
 
1051
                } else if ( x < 5) {
 
1052
                        rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno++));
914
1053
                }
915
1054
        }
916
1055
        return 0;
919
1058
static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
920
1059
{
921
1060
        unsigned int *rtpheader;
 
1061
        char iabuf[INET_ADDRSTRLEN];
922
1062
        int hdrlen = 12;
923
1063
        int res;
924
1064
        int ms;
925
1065
        int pred;
926
1066
        int mark = 0;
927
1067
 
928
 
        ms = calc_txstamp(rtp);
 
1068
        ms = calc_txstamp(rtp, &f->delivery);
929
1069
        /* Default prediction */
930
1070
        if (f->subclass < AST_FORMAT_MAX_AUDIO) {
931
1071
                pred = rtp->lastts + ms * 8;
937
1077
                           predict we should be, use that */
938
1078
                        pred = rtp->lastts + f->datalen;
939
1079
                        break;
 
1080
                case AST_FORMAT_ADPCM:
 
1081
                case AST_FORMAT_G726:
 
1082
                        /* If we're within +/- 20ms from when where we
 
1083
                           predict we should be, use that */
 
1084
                        pred = rtp->lastts + f->datalen * 2;
 
1085
                        break;
940
1086
                case AST_FORMAT_G729A:
941
1087
                        pred = rtp->lastts + f->datalen * 8;
942
1088
                        break;
950
1096
                        pred = rtp->lastts + g723_samples(f->data, f->datalen);
951
1097
                        break;
952
1098
                case AST_FORMAT_SPEEX:
953
 
                        pred = rtp->lastts + 160;
954
 
                        // assumes that the RTP packet contains one Speex frame
 
1099
                    pred = rtp->lastts + 160;
 
1100
                        /* assumes that the RTP packet contains one Speex frame */
 
1101
                        break;
 
1102
                case AST_FORMAT_LPC10:
 
1103
                        /* assumes that the RTP packet contains one LPC10 frame */
 
1104
                    pred = rtp->lastts + 22 * 8;
 
1105
                        pred += (((char *)(f->data))[7] & 0x1) * 8;
955
1106
                        break;
956
1107
                default:
957
1108
                        ast_log(LOG_WARNING, "Not sure about timestamp format for codec format %s\n", ast_getformatname(f->subclass));
958
1109
                }
959
 
 
960
1110
                /* Re-calculate last TS */
961
1111
                rtp->lastts = rtp->lastts + ms * 8;
962
 
                /* If it's close to our prediction, go for it */
963
 
                if (abs(rtp->lastts - pred) < 640)
964
 
                        rtp->lastts = pred;
965
 
                else
966
 
                        ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
 
1112
                if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
 
1113
                        /* If this isn't an absolute delivery time, Check if it is close to our prediction, 
 
1114
                           and if so, go with our prediction */
 
1115
                        if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
 
1116
                                rtp->lastts = pred;
 
1117
                        else {
 
1118
                                ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
 
1119
                                mark = 1;
 
1120
                        }
 
1121
                }
967
1122
        } else {
968
1123
                mark = f->subclass & 0x1;
969
1124
                pred = rtp->lastovidtimestamp + f->samples;
970
1125
                /* Re-calculate last TS */
971
1126
                rtp->lastts = rtp->lastts + ms * 90;
972
1127
                /* If it's close to our prediction, go for it */
973
 
                if (abs(rtp->lastts - pred) < 7200) {
974
 
                        rtp->lastts = pred;
975
 
                        rtp->lastovidtimestamp += f->samples;
976
 
                } else {
977
 
                        ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
978
 
                        rtp->lastovidtimestamp = rtp->lastts;
 
1128
                if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
 
1129
                        if (abs(rtp->lastts - pred) < 7200) {
 
1130
                                rtp->lastts = pred;
 
1131
                                rtp->lastovidtimestamp += f->samples;
 
1132
                        } else {
 
1133
                                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);
 
1134
                                rtp->lastovidtimestamp = rtp->lastts;
 
1135
                        }
979
1136
                }
980
1137
        }
981
1138
        /* Get a pointer to the header */
986
1143
        if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
987
1144
                res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
988
1145
                if (res <0) 
989
 
                        ast_log(LOG_NOTICE, "RTP Transmission error to %s:%d: %s\n", inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
 
1146
                        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));
990
1147
#if 0
991
 
                printf("Sent %d bytes of RTP data to %s:%d\n", res, inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
 
1148
                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));
992
1149
#endif          
993
1150
        }
994
1151
        return 0;
1051
1208
                while((f = ast_smoother_read(rtp->smoother)))
1052
1209
                        ast_rtp_raw_write(rtp, f, codec);
1053
1210
                break;
 
1211
        case AST_FORMAT_ADPCM:
 
1212
        case AST_FORMAT_G726:
 
1213
                if (!rtp->smoother) {
 
1214
                        rtp->smoother = ast_smoother_new(80);
 
1215
                }
 
1216
                if (!rtp->smoother) {
 
1217
                        ast_log(LOG_WARNING, "Unable to create smoother :(\n");
 
1218
                        return -1;
 
1219
                }
 
1220
                ast_smoother_feed(rtp->smoother, _f);
 
1221
                
 
1222
                while((f = ast_smoother_read(rtp->smoother)))
 
1223
                        ast_rtp_raw_write(rtp, f, codec);
 
1224
                break;
1054
1225
        case AST_FORMAT_G729A:
1055
1226
                if (!rtp->smoother) {
1056
1227
                        rtp->smoother = ast_smoother_new(20);
 
1228
                        if (rtp->smoother)
 
1229
                                ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_G729);
1057
1230
                }
1058
1231
                if (!rtp->smoother) {
1059
1232
                        ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n");
1090
1263
                break;
1091
1264
        default:        
1092
1265
                ast_log(LOG_WARNING, "Not sure about sending format %s packets\n", ast_getformatname(subclass));
1093
 
                // fall through to...
 
1266
                /* fall through to... */
1094
1267
        case AST_FORMAT_H261:
1095
1268
        case AST_FORMAT_H263:
1096
1269
        case AST_FORMAT_G723_1:
 
1270
        case AST_FORMAT_LPC10:
1097
1271
        case AST_FORMAT_SPEEX:
1098
 
                // Don't buffer outgoing frames; send them one-per-packet:
 
1272
                /* Don't buffer outgoing frames; send them one-per-packet: */
1099
1273
                if (_f->offset < hdrlen) {
1100
1274
                        f = ast_frdup(_f);
1101
1275
                } else {
1165
1339
        struct sockaddr_in vac0, vac1;
1166
1340
        struct sockaddr_in t0, t1;
1167
1341
        struct sockaddr_in vt0, vt1;
 
1342
        char iabuf[INET_ADDRSTRLEN];
1168
1343
        
1169
1344
        void *pvt0, *pvt1;
1170
1345
        int to;
 
1346
        int codec0,codec1, oldcodec0, oldcodec1;
 
1347
        
1171
1348
        memset(&vt0, 0, sizeof(vt0));
1172
1349
        memset(&vt1, 0, sizeof(vt1));
1173
1350
        memset(&vac0, 0, sizeof(vac0));
1174
1351
        memset(&vac1, 0, sizeof(vac1));
1175
1352
 
1176
 
        /* XXX Wait a half a second for things to settle up 
1177
 
                        this really should be fixed XXX */
1178
 
        ast_autoservice_start(c0);
1179
 
        ast_autoservice_start(c1);
1180
 
        usleep(500000);
1181
 
        ast_autoservice_stop(c0);
1182
 
        ast_autoservice_stop(c1);
1183
 
 
1184
1353
        /* if need DTMF, cant native bridge */
1185
1354
        if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
1186
1355
                return -2;
1187
1356
        ast_mutex_lock(&c0->lock);
1188
 
        ast_mutex_lock(&c1->lock);
 
1357
        while(ast_mutex_trylock(&c1->lock)) {
 
1358
                ast_mutex_unlock(&c0->lock);
 
1359
                usleep(1);
 
1360
                ast_mutex_lock(&c0->lock);
 
1361
        }
1189
1362
        pr0 = get_proto(c0);
1190
1363
        pr1 = get_proto(c1);
1191
1364
        if (!pr0) {
1218
1391
                ast_mutex_unlock(&c1->lock);
1219
1392
                return -2;
1220
1393
        }
1221
 
        if (pr0->get_codec && pr1->get_codec) {
1222
 
                int codec0,codec1;
 
1394
        if (pr0->get_codec)
1223
1395
                codec0 = pr0->get_codec(c0);
 
1396
        else
 
1397
                codec0 = 0;
 
1398
        if (pr1->get_codec)
1224
1399
                codec1 = pr1->get_codec(c1);
 
1400
        else
 
1401
                codec1 = 0;
 
1402
        if (pr0->get_codec && pr1->get_codec) {
1225
1403
                /* Hey, we can't do reinvite if both parties speak diffrent codecs */
1226
1404
                if (!(codec0 & codec1)) {
1227
1405
                        ast_log(LOG_WARNING, "codec0 = %d is not codec1 = %d, cannot native bridge.\n",codec0,codec1);
1230
1408
                        return -2;
1231
1409
                }
1232
1410
        }
1233
 
        if (pr0->set_rtp_peer(c0, p1, vp1)) 
 
1411
        if (pr0->set_rtp_peer(c0, p1, vp1, codec1)) 
1234
1412
                ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
1235
1413
        else {
1236
1414
                /* Store RTP peer */
1237
1415
                ast_rtp_get_peer(p1, &ac1);
1238
1416
                if (vp1)
1239
 
                        ast_rtp_get_peer(p1, &vac1);
 
1417
                        ast_rtp_get_peer(vp1, &vac1);
1240
1418
        }
1241
 
        if (pr1->set_rtp_peer(c1, p0, vp0))
 
1419
        if (pr1->set_rtp_peer(c1, p0, vp0, codec0))
1242
1420
                ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
1243
1421
        else {
1244
1422
                /* Store RTP peer */
1245
1423
                ast_rtp_get_peer(p0, &ac0);
1246
1424
                if (vp0)
1247
 
                        ast_rtp_get_peer(p0, &vac0);
 
1425
                        ast_rtp_get_peer(vp0, &vac0);
1248
1426
        }
1249
1427
        ast_mutex_unlock(&c0->lock);
1250
1428
        ast_mutex_unlock(&c1->lock);
1251
1429
        cs[0] = c0;
1252
1430
        cs[1] = c1;
1253
1431
        cs[2] = NULL;
 
1432
        oldcodec0 = codec0;
 
1433
        oldcodec1 = codec1;
1254
1434
        for (;;) {
1255
1435
                if ((c0->pvt->pvt != pvt0)  ||
1256
1436
                        (c1->pvt->pvt != pvt1) ||
1257
1437
                        (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
1258
1438
                                ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
1259
1439
                                if (c0->pvt->pvt == pvt0) {
1260
 
                                        if (pr0->set_rtp_peer(c0, NULL, NULL)) 
 
1440
                                        if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
1261
1441
                                                ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1262
1442
                                }
1263
1443
                                if (c1->pvt->pvt == pvt1) {
1264
 
                                        if (pr1->set_rtp_peer(c1, NULL, NULL)) 
 
1444
                                        if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
1265
1445
                                                ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1266
1446
                                }
1267
1447
                                /* Tell it to try again later */
1270
1450
                to = -1;
1271
1451
                ast_rtp_get_peer(p1, &t1);
1272
1452
                ast_rtp_get_peer(p0, &t0);
 
1453
                if (pr0->get_codec)
 
1454
                        codec0 = pr0->get_codec(c0);
 
1455
                if (pr1->get_codec)
 
1456
                        codec1 = pr1->get_codec(c1);
1273
1457
                if (vp1)
1274
1458
                        ast_rtp_get_peer(vp1, &vt1);
1275
1459
                if (vp0)
1276
1460
                        ast_rtp_get_peer(vp0, &vt0);
1277
 
                if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1))) {
1278
 
                        ast_log(LOG_DEBUG, "Oooh, '%s' changed end address\n", c1->name);
1279
 
                        if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL)) 
 
1461
                if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) {
 
1462
                        ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
 
1463
                                c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1);
 
1464
                        ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", 
 
1465
                                c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1);
 
1466
                        ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
 
1467
                                c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
 
1468
                        ast_log(LOG_DEBUG, "Oooh, '%s' wasv %s:%d/(format %d)\n", 
 
1469
                                c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
 
1470
                        if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1)) 
1280
1471
                                ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
1281
1472
                        memcpy(&ac1, &t1, sizeof(ac1));
1282
1473
                        memcpy(&vac1, &vt1, sizeof(vac1));
 
1474
                        oldcodec1 = codec1;
1283
1475
                }
1284
1476
                if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) {
1285
 
                        ast_log(LOG_DEBUG, "Oooh, '%s' changed end address\n", c0->name);
1286
 
                        if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL))
 
1477
                        ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
 
1478
                                c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0);
 
1479
                        ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
 
1480
                                c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
 
1481
                        if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0))
1287
1482
                                ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
1288
1483
                        memcpy(&ac0, &t0, sizeof(ac0));
1289
1484
                        memcpy(&vac0, &vt0, sizeof(vac0));
 
1485
                        oldcodec0 = codec0;
1290
1486
                }
1291
1487
                who = ast_waitfor_n(cs, 2, &to);
1292
1488
                if (!who) {
1304
1500
                        *rc = who;
1305
1501
                        ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
1306
1502
                        if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
1307
 
                                if (pr0->set_rtp_peer(c0, NULL, NULL)) 
 
1503
                                if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
1308
1504
                                        ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1309
1505
                        }
1310
1506
                        if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
1311
 
                                if (pr1->set_rtp_peer(c1, NULL, NULL)) 
 
1507
                                if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
1312
1508
                                        ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1313
1509
                        }
1314
1510
                        /* That's all we needed */
1341
1537
        char *s;
1342
1538
        rtpstart = 5000;
1343
1539
        rtpend = 31000;
 
1540
#ifdef SO_NO_CHECK
 
1541
        checksums = 1;
 
1542
#endif
1344
1543
        cfg = ast_load("rtp.conf");
1345
1544
        if (cfg) {
1346
1545
                if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
1357
1556
                        if (rtpend > 65535)
1358
1557
                                rtpend = 65535;
1359
1558
                }
 
1559
                if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
 
1560
#ifdef SO_NO_CHECK
 
1561
                        if (ast_true(s))
 
1562
                                checksums = 1;
 
1563
                        else
 
1564
                                checksums = 0;
 
1565
#else
 
1566
                        if (ast_true(s))
 
1567
                                ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
 
1568
#endif
 
1569
                }
1360
1570
                ast_destroy(cfg);
1361
1571
        }
1362
1572
        if (rtpstart >= rtpend) {