2 * Asterisk -- A telephony toolkit for Linux.
4 * Real-time Protocol Support
5 * Supports RTP and RTCP with Symmetric RTP support for NAT
8 * Copyright (C) 1999-2004, Digium, Inc.
10 * Mark Spencer <markster@digium.com>
12 * This program is free software, distributed under the terms of
13 * the GNU General Public License
23 #include <netinet/in.h>
25 #include <sys/socket.h>
26 #include <arpa/inet.h>
29 #include <asterisk/rtp.h>
30 #include <asterisk/frame.h>
31 #include <asterisk/logger.h>
32 #include <asterisk/options.h>
33 #include <asterisk/channel.h>
34 #include <asterisk/acl.h>
35 #include <asterisk/channel.h>
36 #include <asterisk/channel_pvt.h>
37 #include <asterisk/config.h>
38 #include <asterisk/lock.h>
39 #include <asterisk/utils.h>
41 #define MAX_TIMESTAMP_SKEW 640
47 #define TYPE_SILENCE 0x2
48 #define TYPE_DONTSEND 0x3
51 static int dtmftimeout = 3000; /* 3000 samples */
53 static int rtpstart = 0;
54 static int rtpend = 0;
56 static int checksums = 1;
59 /* The value of each payload format mapping: */
60 struct rtpPayloadType {
61 int isAstFormat; /* whether the following code is an AST_FORMAT */
65 #define MAX_RTP_PT 256
67 #define FLAG_3389_WARNING (1 << 0)
73 unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
76 unsigned int lastrxts;
77 unsigned int lastividtimestamp;
78 unsigned int lastovidtimestamp;
79 unsigned int lasteventseqn;
83 unsigned int dtmfduration;
86 struct sockaddr_in us;
87 struct sockaddr_in them;
88 struct timeval rxcore;
89 struct timeval txcore;
90 struct timeval dtmfmute;
91 struct ast_smoother *smoother;
94 struct sched_context *sched;
95 struct io_context *io;
97 ast_rtp_callback callback;
98 struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
99 int rtp_lookup_code_cache_isAstFormat; /* a cache for the result of rtp_lookup_code(): */
100 int rtp_lookup_code_cache_code;
101 int rtp_lookup_code_cache_result;
102 int rtp_offered_from_local;
103 struct ast_rtcp *rtcp;
108 struct sockaddr_in us;
109 struct sockaddr_in them;
112 static struct ast_rtp_protocol *protos = NULL;
114 int ast_rtp_fd(struct ast_rtp *rtp)
119 int ast_rtcp_fd(struct ast_rtp *rtp)
126 static int g723_len(unsigned char buf)
128 switch(buf & TYPE_MASK) {
142 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
147 static int g723_samples(unsigned char *buf, int maxlen)
152 while(pos < maxlen) {
153 res = g723_len(buf[pos]);
162 void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
167 void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
169 rtp->callback = callback;
172 void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
177 static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
180 static struct ast_frame null_frame = { AST_FRAME_NULL, };
181 char iabuf[INET_ADDRSTRLEN];
182 gettimeofday(&tv, NULL);
183 if ((tv.tv_sec < rtp->dtmfmute.tv_sec) ||
184 ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < rtp->dtmfmute.tv_usec))) {
185 ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr));
187 rtp->dtmfduration = 0;
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 rtp->f.frametype = AST_FRAME_DTMF;
192 rtp->f.subclass = rtp->resp;
198 rtp->dtmfduration = 0;
203 static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, int len)
207 struct ast_frame *f = NULL;
208 event = ntohl(*((unsigned int *)(data)));
211 printf("Cisco Digit: %08x (len = %d)\n", event, len);
215 } else if (event < 11) {
217 } else if (event < 12) {
219 } else if (event < 16) {
220 resp = 'A' + (event - 12);
222 if (rtp->resp && (rtp->resp != resp)) {
226 rtp->dtmfcount = dtmftimeout;
230 static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
233 unsigned int event_end;
234 unsigned int duration;
236 struct ast_frame *f = NULL;
237 event = ntohl(*((unsigned int *)(data)));
239 event_end = ntohl(*((unsigned int *)(data)));
242 duration = ntohl(*((unsigned int *)(data)));
245 printf("Event: %08x (len = %d)\n", event, len);
249 } else if (event < 11) {
251 } else if (event < 12) {
253 } else if (event < 16) {
254 resp = 'A' + (event - 12);
256 if (rtp->resp && (rtp->resp != resp)) {
259 else if(event_end & 0x80)
268 else if(rtp->dtmfduration && (duration < rtp->dtmfduration))
272 if (!(event_end & 0x80))
274 rtp->dtmfcount = dtmftimeout;
275 rtp->dtmfduration = duration;
279 static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
281 struct ast_frame *f = NULL;
282 /* Convert comfort noise into audio with various codecs. Unfortunately this doesn't
283 totally help us out becuase we don't have an engine to keep it going and we are not
284 guaranteed to have it every 20ms or anything */
286 printf("RFC3389: %d bytes, level %d...\n", len, rtp->lastrxformat);
288 if (!(rtp->flags & FLAG_3389_WARNING)) {
289 ast_log(LOG_NOTICE, "RFC3389 support incomplete. Turn off on client if possible\n");
290 rtp->flags |= FLAG_3389_WARNING;
292 /* Must have at least one byte */
296 rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET;
297 rtp->f.datalen = len - 1;
298 rtp->f.offset = AST_FRIENDLY_OFFSET;
299 memcpy(rtp->f.data, data + 1, len - 1);
305 rtp->f.frametype = AST_FRAME_CNG;
306 rtp->f.subclass = data[0] & 0x7f;
307 rtp->f.datalen = len - 1;
309 rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
314 static int rtpread(int *id, int fd, short events, void *cbdata)
316 struct ast_rtp *rtp = cbdata;
318 f = ast_rtp_read(rtp);
321 rtp->callback(rtp, f, rtp->data);
326 struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
328 static struct ast_frame null_frame = { AST_FRAME_NULL, };
332 struct sockaddr_in sin;
333 unsigned int rtcpdata[1024];
334 char iabuf[INET_ADDRSTRLEN];
341 res = recvfrom(rtp->rtcp->s, rtcpdata, sizeof(rtcpdata),
342 0, (struct sockaddr *)&sin, &len);
346 ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
348 ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
355 ast_log(LOG_WARNING, "RTP Read too short\n");
360 /* Send to whoever sent to us */
361 if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
362 (rtp->rtcp->them.sin_port != sin.sin_port)) {
363 memcpy(&rtp->them, &sin, sizeof(rtp->them));
364 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));
368 ast_log(LOG_DEBUG, "Got RTCP report of %d bytes\n", res);
372 static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
374 if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
375 gettimeofday(&rtp->rxcore, NULL);
376 rtp->rxcore.tv_sec -= timestamp / 8000;
377 rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
378 /* Round to 20ms for nice, pretty timestamps */
379 rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
380 if (rtp->rxcore.tv_usec < 0) {
381 /* Adjust appropriately if necessary */
382 rtp->rxcore.tv_usec += 1000000;
383 rtp->rxcore.tv_sec -= 1;
386 tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
387 tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
388 if (tv->tv_usec >= 1000000) {
389 tv->tv_usec -= 1000000;
394 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
397 struct sockaddr_in sin;
404 char iabuf[INET_ADDRSTRLEN];
405 unsigned int timestamp;
406 unsigned int *rtpheader;
407 static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
408 struct rtpPayloadType rtpPT;
412 /* Cache where the header will go */
413 res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
414 0, (struct sockaddr *)&sin, &len);
417 rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
420 ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
422 ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
428 ast_log(LOG_WARNING, "RTP Read too short\n");
432 /* Ignore if the other side hasn't been given an address
434 if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
438 /* Send to whoever sent to us */
439 if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
440 (rtp->them.sin_port != sin.sin_port)) {
441 memcpy(&rtp->them, &sin, sizeof(rtp->them));
442 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));
447 seqno = ntohl(rtpheader[0]);
448 payloadtype = (seqno & 0x7f0000) >> 16;
449 mark = seqno & (1 << 23);
450 ext = seqno & (1 << 28);
452 timestamp = ntohl(rtpheader[1]);
454 /* RTP Extension present */
456 hdrlen += (ntohl(rtpheader[3]) & 0xffff) << 2;
460 ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen);
465 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);
467 rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
468 if (!rtpPT.isAstFormat) {
469 /* This is special in-band data that's not one of our codecs */
470 if (rtpPT.code == AST_RTP_DTMF) {
471 /* It's special -- rfc2833 process it */
472 if (rtp->lasteventseqn <= seqno) {
473 f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
474 rtp->lasteventseqn = seqno;
476 if (f) return f; else return &null_frame;
477 } else if (rtpPT.code == AST_RTP_CISCO_DTMF) {
478 /* It's really special -- process it the Cisco way */
479 if (rtp->lasteventseqn <= seqno) {
480 f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
481 rtp->lasteventseqn = seqno;
483 if (f) return f; else return &null_frame;
484 } else if (rtpPT.code == AST_RTP_CN) {
486 f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
487 if (f) return f; else return &null_frame;
489 ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype);
493 rtp->f.subclass = rtpPT.code;
494 if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO)
495 rtp->f.frametype = AST_FRAME_VOICE;
497 rtp->f.frametype = AST_FRAME_VIDEO;
498 rtp->lastrxformat = rtp->f.subclass;
501 rtp->lastrxts = timestamp;
503 if (rtp->dtmfcount) {
505 printf("dtmfcount was %d\n", rtp->dtmfcount);
507 rtp->dtmfcount -= (timestamp - rtp->lastrxts);
508 if (rtp->dtmfcount < 0)
511 if (dtmftimeout != rtp->dtmfcount)
512 printf("dtmfcount is %d\n", rtp->dtmfcount);
515 rtp->lastrxts = timestamp;
517 /* Send any pending DTMF */
518 if (rtp->resp && !rtp->dtmfcount) {
519 ast_log(LOG_DEBUG, "Sending pending DTMF\n");
520 return send_dtmf(rtp);
523 rtp->f.datalen = res - hdrlen;
524 rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
525 rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
526 if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) {
527 switch(rtp->f.subclass) {
528 case AST_FORMAT_ULAW:
529 case AST_FORMAT_ALAW:
530 rtp->f.samples = rtp->f.datalen;
532 case AST_FORMAT_SLINEAR:
533 rtp->f.samples = rtp->f.datalen / 2;
536 rtp->f.samples = 160 * (rtp->f.datalen / 33);
538 case AST_FORMAT_ILBC:
539 rtp->f.samples = 240 * (rtp->f.datalen / 50);
541 case AST_FORMAT_ADPCM:
542 case AST_FORMAT_G726:
543 rtp->f.samples = rtp->f.datalen * 2;
545 case AST_FORMAT_G729A:
546 rtp->f.samples = rtp->f.datalen * 8;
548 case AST_FORMAT_G723_1:
549 rtp->f.samples = g723_samples(rtp->f.data, rtp->f.datalen);
551 case AST_FORMAT_SPEEX:
552 rtp->f.samples = 160;
553 /* assumes that the RTP packet contained one Speex frame */
556 ast_log(LOG_NOTICE, "Unable to calculate samples for format %s\n", ast_getformatname(rtp->f.subclass));
559 calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
561 /* Video -- samples is # of samples vs. 90000 */
562 if (!rtp->lastividtimestamp)
563 rtp->lastividtimestamp = timestamp;
564 rtp->f.samples = timestamp - rtp->lastividtimestamp;
565 rtp->lastividtimestamp = timestamp;
566 rtp->f.delivery.tv_sec = 0;
567 rtp->f.delivery.tv_usec = 0;
569 rtp->f.subclass |= 0x1;
576 /* The following array defines the MIME Media type (and subtype) for each
577 of our codecs, or RTP-specific data type. */
579 struct rtpPayloadType payloadType;
583 {{1, AST_FORMAT_G723_1}, "audio", "G723"},
584 {{1, AST_FORMAT_GSM}, "audio", "GSM"},
585 {{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
586 {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
587 {{1, AST_FORMAT_G726}, "audio", "G726-32"},
588 {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
589 {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
590 {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
591 {{1, AST_FORMAT_G729A}, "audio", "G729"},
592 {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
593 {{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
594 {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
595 {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
596 {{0, AST_RTP_CN}, "audio", "CN"},
597 {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
598 {{1, AST_FORMAT_PNG}, "video", "PNG"},
599 {{1, AST_FORMAT_H261}, "video", "H261"},
600 {{1, AST_FORMAT_H263}, "video", "H263"},
603 /* Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
604 also, our own choices for dynamic payload types. This is our master
605 table for transmission */
606 static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
607 [0] = {1, AST_FORMAT_ULAW},
608 [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
609 [3] = {1, AST_FORMAT_GSM},
610 [4] = {1, AST_FORMAT_G723_1},
611 [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
612 [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
613 [7] = {1, AST_FORMAT_LPC10},
614 [8] = {1, AST_FORMAT_ALAW},
615 [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
616 [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
617 [13] = {0, AST_RTP_CN},
618 [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
619 [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
620 [18] = {1, AST_FORMAT_G729A},
621 [19] = {0, AST_RTP_CN}, /* Also used for CN */
622 [26] = {1, AST_FORMAT_JPEG},
623 [31] = {1, AST_FORMAT_H261},
624 [34] = {1, AST_FORMAT_H263},
625 [97] = {1, AST_FORMAT_ILBC},
626 [101] = {0, AST_RTP_DTMF},
627 [110] = {1, AST_FORMAT_SPEEX},
628 [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
631 void ast_rtp_pt_clear(struct ast_rtp* rtp)
635 for (i = 0; i < MAX_RTP_PT; ++i) {
636 rtp->current_RTP_PT[i].isAstFormat = 0;
637 rtp->current_RTP_PT[i].code = 0;
640 rtp->rtp_lookup_code_cache_isAstFormat = 0;
641 rtp->rtp_lookup_code_cache_code = 0;
642 rtp->rtp_lookup_code_cache_result = 0;
645 void ast_rtp_pt_default(struct ast_rtp* rtp)
648 /* Initialize to default payload types */
649 for (i = 0; i < MAX_RTP_PT; ++i) {
650 rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat;
651 rtp->current_RTP_PT[i].code = static_RTP_PT[i].code;
654 rtp->rtp_lookup_code_cache_isAstFormat = 0;
655 rtp->rtp_lookup_code_cache_code = 0;
656 rtp->rtp_lookup_code_cache_result = 0;
659 /* Make a note of a RTP payload type that was seen in a SDP "m=" line. */
660 /* By default, use the well-known value for this type (although it may */
661 /* still be set to a different value by a subsequent "a=rtpmap:" line): */
662 void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
663 if (pt < 0 || pt > MAX_RTP_PT) return; /* bogus payload type */
665 if (static_RTP_PT[pt].code != 0) {
666 rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
670 /* Make a note of a RTP payload type (with MIME type) that was seen in */
671 /* a SDP "a=rtpmap:" line. */
672 void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
673 char* mimeType, char* mimeSubtype) {
676 if (pt < 0 || pt > MAX_RTP_PT) return; /* bogus payload type */
678 for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
679 if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
680 strcasecmp(mimeType, mimeTypes[i].type) == 0) {
681 rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
687 /* Return the union of all of the codecs that were set by rtp_set...() calls */
688 /* They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
689 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
690 int* astFormats, int* nonAstFormats) {
693 *astFormats = *nonAstFormats = 0;
694 for (pt = 0; pt < MAX_RTP_PT; ++pt) {
695 if (rtp->current_RTP_PT[pt].isAstFormat) {
696 *astFormats |= rtp->current_RTP_PT[pt].code;
698 *nonAstFormats |= rtp->current_RTP_PT[pt].code;
703 void ast_rtp_offered_from_local(struct ast_rtp* rtp, int local) {
705 rtp->rtp_offered_from_local = local;
707 ast_log(LOG_WARNING, "rtp structure is null\n");
710 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt)
712 struct rtpPayloadType result;
714 result.isAstFormat = result.code = 0;
715 if (pt < 0 || pt > MAX_RTP_PT) {
716 return result; /* bogus payload type */
718 /* Start with the negotiated codecs */
719 if (!rtp->rtp_offered_from_local)
720 result = rtp->current_RTP_PT[pt];
721 /* If it doesn't exist, check our static RTP type list, just in case */
723 result = static_RTP_PT[pt];
727 /* Looks up an RTP code out of our *static* outbound list */
728 int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) {
732 if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
733 code == rtp->rtp_lookup_code_cache_code) {
734 /* Use our cached mapping, to avoid the overhead of the loop below */
735 return rtp->rtp_lookup_code_cache_result;
738 /* Check the dynamic list first */
739 for (pt = 0; pt < MAX_RTP_PT; ++pt) {
740 if (rtp->current_RTP_PT[pt].code == code &&
741 rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) {
742 rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
743 rtp->rtp_lookup_code_cache_code = code;
744 rtp->rtp_lookup_code_cache_result = pt;
749 /* Then the static list */
750 for (pt = 0; pt < MAX_RTP_PT; ++pt) {
751 if (static_RTP_PT[pt].code == code &&
752 static_RTP_PT[pt].isAstFormat == isAstFormat) {
753 rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
754 rtp->rtp_lookup_code_cache_code = code;
755 rtp->rtp_lookup_code_cache_result = pt;
762 char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code) {
765 for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
766 if (mimeTypes[i].payloadType.code == code &&
767 mimeTypes[i].payloadType.isAstFormat == isAstFormat) {
768 return mimeTypes[i].subtype;
774 static int rtp_socket(void)
778 s = socket(AF_INET, SOCK_DGRAM, 0);
780 flags = fcntl(s, F_GETFL);
781 fcntl(s, F_SETFL, flags | O_NONBLOCK);
784 setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &checksums, sizeof(checksums));
791 static struct ast_rtcp *ast_rtcp_new(void)
793 struct ast_rtcp *rtcp;
794 rtcp = malloc(sizeof(struct ast_rtcp));
797 memset(rtcp, 0, sizeof(struct ast_rtcp));
798 rtcp->s = rtp_socket();
799 rtcp->us.sin_family = AF_INET;
802 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
808 struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
814 rtp = malloc(sizeof(struct ast_rtp));
817 memset(rtp, 0, sizeof(struct ast_rtp));
818 rtp->them.sin_family = AF_INET;
819 rtp->us.sin_family = AF_INET;
820 rtp->s = rtp_socket();
822 rtp->seqno = rand() & 0xffff;
825 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
828 if (sched && rtcpenable) {
830 rtp->rtcp = ast_rtcp_new();
832 /* Find us a place */
833 x = (rand() % (rtpend-rtpstart)) + rtpstart;
837 /* Must be an even port number by RTP spec */
838 rtp->us.sin_port = htons(x);
839 rtp->us.sin_addr = addr;
841 rtp->rtcp->us.sin_port = htons(x + 1);
842 if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) &&
843 (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us))))
846 /* Primary bind succeeded! Gotta recreate it */
848 rtp->s = rtp_socket();
850 if (errno != EADDRINUSE) {
851 ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
862 x = (rtpstart + 1) & ~1;
863 if (x == startplace) {
864 ast_log(LOG_WARNING, "No RTP ports remaining\n");
874 if (io && sched && callbackmode) {
875 /* Operate this one in a callback mode */
878 rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
880 ast_rtp_pt_default(rtp);
884 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
887 memset(&ia, 0, sizeof(ia));
888 return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
891 int ast_rtp_settos(struct ast_rtp *rtp, int tos)
894 if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos))))
895 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
899 void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
901 rtp->them.sin_port = them->sin_port;
902 rtp->them.sin_addr = them->sin_addr;
904 rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1);
905 rtp->rtcp->them.sin_addr = them->sin_addr;
909 void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
911 them->sin_family = AF_INET;
912 them->sin_port = rtp->them.sin_port;
913 them->sin_addr = rtp->them.sin_addr;
916 void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us)
918 memcpy(us, &rtp->us, sizeof(rtp->us));
921 void ast_rtp_stop(struct ast_rtp *rtp)
923 memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
924 memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port));
926 memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
927 memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->them.sin_port));
931 void ast_rtp_destroy(struct ast_rtp *rtp)
934 ast_smoother_free(rtp->smoother);
936 ast_io_remove(rtp->io, rtp->ioid);
946 static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
950 if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
951 gettimeofday(&rtp->txcore, NULL);
952 /* Round to 20ms for nice, pretty timestamps */
953 rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
955 if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
956 /* Use previous txcore */
957 ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
958 ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
959 rtp->txcore.tv_sec = delivery->tv_sec;
960 rtp->txcore.tv_usec = delivery->tv_usec;
962 gettimeofday(&now, NULL);
963 ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
964 ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
965 /* Use what we just got for next time */
966 rtp->txcore.tv_sec = now.tv_sec;
967 rtp->txcore.tv_usec = now.tv_usec;
972 int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
974 unsigned int *rtpheader;
981 char iabuf[INET_ADDRSTRLEN];
983 if ((digit <= '9') && (digit >= '0'))
985 else if (digit == '*')
987 else if (digit == '#')
989 else if ((digit >= 'A') && (digit <= 'D'))
990 digit = digit - 'A' + 12;
991 else if ((digit >= 'a') && (digit <= 'd'))
992 digit = digit - 'a' + 12;
994 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
997 payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF);
999 /* If we have no peer, return immediately */
1000 if (!rtp->them.sin_addr.s_addr)
1003 gettimeofday(&rtp->dtmfmute, NULL);
1004 rtp->dtmfmute.tv_usec += (500 * 1000);
1005 if (rtp->dtmfmute.tv_usec > 1000000) {
1006 rtp->dtmfmute.tv_usec -= 1000000;
1007 rtp->dtmfmute.tv_sec += 1;
1010 ms = calc_txstamp(rtp, NULL);
1011 /* Default prediction */
1012 rtp->lastts = rtp->lastts + ms * 8;
1014 /* Get a pointer to the header */
1015 rtpheader = (unsigned int *)data;
1016 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
1017 rtpheader[1] = htonl(rtp->lastts);
1018 rtpheader[2] = htonl(rtp->ssrc);
1019 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
1021 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
1022 res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
1024 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));
1026 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));
1030 /* Clear marker bit and increment seqno */
1031 rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno++));
1032 /* Make duration 800 (100ms) */
1033 rtpheader[3] |= htonl((800));
1034 /* Set the End bit for the last 3 */
1035 rtpheader[3] |= htonl((1 << 23));
1041 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
1043 unsigned int *rtpheader;
1044 char iabuf[INET_ADDRSTRLEN];
1051 ms = calc_txstamp(rtp, &f->delivery);
1052 /* Default prediction */
1053 if (f->subclass < AST_FORMAT_MAX_AUDIO) {
1054 pred = rtp->lastts + ms * 8;
1056 switch(f->subclass) {
1057 case AST_FORMAT_ULAW:
1058 case AST_FORMAT_ALAW:
1059 /* If we're within +/- 20ms from when where we
1060 predict we should be, use that */
1061 pred = rtp->lastts + f->datalen;
1063 case AST_FORMAT_ADPCM:
1064 case AST_FORMAT_G726:
1065 /* If we're within +/- 20ms from when where we
1066 predict we should be, use that */
1067 pred = rtp->lastts + f->datalen * 2;
1069 case AST_FORMAT_G729A:
1070 pred = rtp->lastts + f->datalen * 8;
1072 case AST_FORMAT_GSM:
1073 pred = rtp->lastts + (f->datalen * 160 / 33);
1075 case AST_FORMAT_ILBC:
1076 pred = rtp->lastts + (f->datalen * 240 / 50);
1078 case AST_FORMAT_G723_1:
1079 pred = rtp->lastts + g723_samples(f->data, f->datalen);
1081 case AST_FORMAT_SPEEX:
1082 pred = rtp->lastts + 160;
1083 /* assumes that the RTP packet contains one Speex frame */
1086 ast_log(LOG_WARNING, "Not sure about timestamp format for codec format %s\n", ast_getformatname(f->subclass));
1088 /* Re-calculate last TS */
1089 rtp->lastts = rtp->lastts + ms * 8;
1090 if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
1091 /* If this isn't an absolute delivery time, Check if it is close to our prediction,
1092 and if so, go with our prediction */
1093 if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
1096 ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
1101 mark = f->subclass & 0x1;
1102 pred = rtp->lastovidtimestamp + f->samples;
1103 /* Re-calculate last TS */
1104 rtp->lastts = rtp->lastts + ms * 90;
1105 /* If it's close to our prediction, go for it */
1106 if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
1107 if (abs(rtp->lastts - pred) < 7200) {
1109 rtp->lastovidtimestamp += f->samples;
1111 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);
1112 rtp->lastovidtimestamp = rtp->lastts;
1116 /* Get a pointer to the header */
1117 rtpheader = (unsigned int *)(f->data - hdrlen);
1118 rtpheader[0] = htonl((2 << 30) | (codec << 16) | (rtp->seqno++) | (mark << 23));
1119 rtpheader[1] = htonl(rtp->lastts);
1120 rtpheader[2] = htonl(rtp->ssrc);
1121 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
1122 res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
1124 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));
1126 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));
1132 int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
1134 struct ast_frame *f;
1140 /* If we have no peer, return immediately */
1141 if (!rtp->them.sin_addr.s_addr)
1144 /* If there is no data length, return immediately */
1148 /* Make sure we have enough space for RTP header */
1149 if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) {
1150 ast_log(LOG_WARNING, "RTP can only send voice\n");
1154 subclass = _f->subclass;
1155 if (_f->frametype == AST_FRAME_VIDEO)
1158 codec = ast_rtp_lookup_code(rtp, 1, subclass);
1160 ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass));
1164 if (rtp->lasttxformat != subclass) {
1165 /* New format, reset the smoother */
1166 ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
1167 rtp->lasttxformat = subclass;
1169 ast_smoother_free(rtp->smoother);
1170 rtp->smoother = NULL;
1175 case AST_FORMAT_ULAW:
1176 case AST_FORMAT_ALAW:
1177 if (!rtp->smoother) {
1178 rtp->smoother = ast_smoother_new(160);
1180 if (!rtp->smoother) {
1181 ast_log(LOG_WARNING, "Unable to create smoother :(\n");
1184 ast_smoother_feed(rtp->smoother, _f);
1186 while((f = ast_smoother_read(rtp->smoother)))
1187 ast_rtp_raw_write(rtp, f, codec);
1189 case AST_FORMAT_ADPCM:
1190 case AST_FORMAT_G726:
1191 if (!rtp->smoother) {
1192 rtp->smoother = ast_smoother_new(80);
1194 if (!rtp->smoother) {
1195 ast_log(LOG_WARNING, "Unable to create smoother :(\n");
1198 ast_smoother_feed(rtp->smoother, _f);
1200 while((f = ast_smoother_read(rtp->smoother)))
1201 ast_rtp_raw_write(rtp, f, codec);
1203 case AST_FORMAT_G729A:
1204 if (!rtp->smoother) {
1205 rtp->smoother = ast_smoother_new(20);
1207 ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_G729);
1209 if (!rtp->smoother) {
1210 ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n");
1213 ast_smoother_feed(rtp->smoother, _f);
1215 while((f = ast_smoother_read(rtp->smoother)))
1216 ast_rtp_raw_write(rtp, f, codec);
1218 case AST_FORMAT_GSM:
1219 if (!rtp->smoother) {
1220 rtp->smoother = ast_smoother_new(33);
1222 if (!rtp->smoother) {
1223 ast_log(LOG_WARNING, "Unable to create GSM smoother :(\n");
1226 ast_smoother_feed(rtp->smoother, _f);
1227 while((f = ast_smoother_read(rtp->smoother)))
1228 ast_rtp_raw_write(rtp, f, codec);
1230 case AST_FORMAT_ILBC:
1231 if (!rtp->smoother) {
1232 rtp->smoother = ast_smoother_new(50);
1234 if (!rtp->smoother) {
1235 ast_log(LOG_WARNING, "Unable to create ILBC smoother :(\n");
1238 ast_smoother_feed(rtp->smoother, _f);
1239 while((f = ast_smoother_read(rtp->smoother)))
1240 ast_rtp_raw_write(rtp, f, codec);
1243 ast_log(LOG_WARNING, "Not sure about sending format %s packets\n", ast_getformatname(subclass));
1244 /* fall through to... */
1245 case AST_FORMAT_H261:
1246 case AST_FORMAT_H263:
1247 case AST_FORMAT_G723_1:
1248 case AST_FORMAT_SPEEX:
1249 /* Don't buffer outgoing frames; send them one-per-packet: */
1250 if (_f->offset < hdrlen) {
1255 ast_rtp_raw_write(rtp, f, codec);
1261 void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto)
1263 struct ast_rtp_protocol *cur, *prev;
1269 prev->next = proto->next;
1271 protos = proto->next;
1279 int ast_rtp_proto_register(struct ast_rtp_protocol *proto)
1281 struct ast_rtp_protocol *cur;
1284 if (cur->type == proto->type) {
1285 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
1290 proto->next = protos;
1295 static struct ast_rtp_protocol *get_proto(struct ast_channel *chan)
1297 struct ast_rtp_protocol *cur;
1300 if (cur->type == chan->type) {
1308 int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
1310 struct ast_frame *f;
1311 struct ast_channel *who, *cs[3];
1312 struct ast_rtp *p0, *p1;
1313 struct ast_rtp *vp0, *vp1;
1314 struct ast_rtp_protocol *pr0, *pr1;
1315 struct sockaddr_in ac0, ac1;
1316 struct sockaddr_in vac0, vac1;
1317 struct sockaddr_in t0, t1;
1318 struct sockaddr_in vt0, vt1;
1319 char iabuf[INET_ADDRSTRLEN];
1323 int codec0,codec1, oldcodec0, oldcodec1;
1325 memset(&vt0, 0, sizeof(vt0));
1326 memset(&vt1, 0, sizeof(vt1));
1327 memset(&vac0, 0, sizeof(vac0));
1328 memset(&vac1, 0, sizeof(vac1));
1330 /* if need DTMF, cant native bridge */
1331 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
1333 ast_mutex_lock(&c0->lock);
1334 while(ast_mutex_trylock(&c1->lock)) {
1335 ast_mutex_unlock(&c0->lock);
1337 ast_mutex_lock(&c0->lock);
1339 pr0 = get_proto(c0);
1340 pr1 = get_proto(c1);
1342 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
1343 ast_mutex_unlock(&c0->lock);
1344 ast_mutex_unlock(&c1->lock);
1348 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
1349 ast_mutex_unlock(&c0->lock);
1350 ast_mutex_unlock(&c1->lock);
1353 pvt0 = c0->pvt->pvt;
1354 pvt1 = c1->pvt->pvt;
1355 p0 = pr0->get_rtp_info(c0);
1356 if (pr0->get_vrtp_info)
1357 vp0 = pr0->get_vrtp_info(c0);
1360 p1 = pr1->get_rtp_info(c1);
1361 if (pr1->get_vrtp_info)
1362 vp1 = pr1->get_vrtp_info(c1);
1366 /* Somebody doesn't want to play... */
1367 ast_mutex_unlock(&c0->lock);
1368 ast_mutex_unlock(&c1->lock);
1372 codec0 = pr0->get_codec(c0);
1376 codec1 = pr1->get_codec(c1);
1379 if (pr0->get_codec && pr1->get_codec) {
1380 /* Hey, we can't do reinvite if both parties speak diffrent codecs */
1381 if (!(codec0 & codec1)) {
1382 ast_log(LOG_WARNING, "codec0 = %d is not codec1 = %d, cannot native bridge.\n",codec0,codec1);
1383 ast_mutex_unlock(&c0->lock);
1384 ast_mutex_unlock(&c1->lock);
1388 if (pr0->set_rtp_peer(c0, p1, vp1, codec1))
1389 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
1391 /* Store RTP peer */
1392 ast_rtp_get_peer(p1, &ac1);
1394 ast_rtp_get_peer(vp1, &vac1);
1396 if (pr1->set_rtp_peer(c1, p0, vp0, codec0))
1397 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
1399 /* Store RTP peer */
1400 ast_rtp_get_peer(p0, &ac0);
1402 ast_rtp_get_peer(vp0, &vac0);
1404 ast_mutex_unlock(&c0->lock);
1405 ast_mutex_unlock(&c1->lock);
1412 if ((c0->pvt->pvt != pvt0) ||
1413 (c1->pvt->pvt != pvt1) ||
1414 (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
1415 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
1416 if (c0->pvt->pvt == pvt0) {
1417 if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
1418 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1420 if (c1->pvt->pvt == pvt1) {
1421 if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
1422 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1424 /* Tell it to try again later */
1428 ast_rtp_get_peer(p1, &t1);
1429 ast_rtp_get_peer(p0, &t0);
1431 codec0 = pr0->get_codec(c0);
1433 codec1 = pr1->get_codec(c1);
1435 ast_rtp_get_peer(vp1, &vt1);
1437 ast_rtp_get_peer(vp0, &vt0);
1438 if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) {
1439 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
1440 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1);
1441 ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n",
1442 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1);
1443 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n",
1444 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
1445 ast_log(LOG_DEBUG, "Oooh, '%s' wasv %s:%d/(format %d)\n",
1446 c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
1447 if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1))
1448 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
1449 memcpy(&ac1, &t1, sizeof(ac1));
1450 memcpy(&vac1, &vt1, sizeof(vac1));
1453 if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) {
1454 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n",
1455 c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0);
1456 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n",
1457 c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
1458 if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0))
1459 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
1460 memcpy(&ac0, &t0, sizeof(ac0));
1461 memcpy(&vac0, &vt0, sizeof(vac0));
1464 who = ast_waitfor_n(cs, 2, &to);
1466 ast_log(LOG_DEBUG, "Ooh, empty read...\n");
1467 /* check for hagnup / whentohangup */
1468 if (ast_check_hangup(c0) || ast_check_hangup(c1))
1473 if (!f || ((f->frametype == AST_FRAME_DTMF) &&
1474 (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) ||
1475 ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
1478 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
1479 if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
1480 if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
1481 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1483 if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
1484 if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
1485 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1487 /* That's all we needed */
1490 if ((f->frametype == AST_FRAME_DTMF) ||
1491 (f->frametype == AST_FRAME_VOICE) ||
1492 (f->frametype == AST_FRAME_VIDEO)) {
1493 /* Forward voice or DTMF frames if they happen upon us */
1496 } else if (who == c1) {
1502 /* Swap priority not that it's a big deal at this point */
1511 void ast_rtp_reload(void)
1513 struct ast_config *cfg;
1520 cfg = ast_load("rtp.conf");
1522 if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
1524 if (rtpstart < 1024)
1526 if (rtpstart > 65535)
1529 if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) {
1536 if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
1544 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
1549 if (rtpstart >= rtpend) {
1550 ast_log(LOG_WARNING, "Unreasonable values for RTP start/end\n");
1554 if (option_verbose > 1)
1555 ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
1558 void ast_rtp_init(void)