2 * Asterisk -- A telephony toolkit for Linux.
4 * Real-time Protocol Support
6 * Copyright (C) 1999, Mark Spencer
8 * Mark Spencer <markster@linux-support.net>
10 * This program is free software, distributed under the terms of
11 * the GNU General Public License
22 #include <netinet/in.h>
24 #include <sys/socket.h>
25 #include <arpa/inet.h>
28 #include <asterisk/rtp.h>
29 #include <asterisk/frame.h>
30 #include <asterisk/logger.h>
31 #include <asterisk/options.h>
32 #include <asterisk/channel.h>
33 #include <asterisk/channel_pvt.h>
35 #define TYPE_SILENCE 0x2
40 static int dtmftimeout = 300; /* 300 samples */
42 // The value of each payload format mapping:
43 struct rtpPayloadType {
44 int isAstFormat; // whether the following code is an AST_FORMAT
48 #define MAX_RTP_PT 256
54 unsigned char rawdata[1024 + AST_FRIENDLY_OFFSET];
57 unsigned int lastrxts;
62 struct sockaddr_in us;
63 struct sockaddr_in them;
64 struct timeval rxcore;
65 struct timeval txcore;
66 struct ast_smoother *smoother;
69 struct sched_context *sched;
70 struct io_context *io;
72 ast_rtp_callback callback;
73 struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
74 // a cache for the result of rtp_lookup_code():
75 int rtp_lookup_code_cache_isAstFormat;
76 int rtp_lookup_code_cache_code;
77 int rtp_lookup_code_cache_result;
80 static struct ast_rtp_protocol *protos = NULL;
82 int ast_rtp_fd(struct ast_rtp *rtp)
87 static int g723_len(unsigned char buf)
89 switch(buf & TYPE_MASK) {
101 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
106 static int g723_samples(unsigned char *buf, int maxlen)
111 while(pos < maxlen) {
112 res = g723_len(buf[pos]);
121 void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
126 void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
128 rtp->callback = callback;
131 void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
136 static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
138 ast_log(LOG_DEBUG, "Sending dtmf: %d (%c)\n", rtp->resp, rtp->resp);
139 rtp->f.frametype = AST_FRAME_DTMF;
140 rtp->f.subclass = rtp->resp;
150 static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
154 struct ast_frame *f = NULL;
155 event = ntohl(*((unsigned int *)(data)));
158 printf("Event: %08x (len = %d)\n", event, len);
162 } else if (event < 11) {
164 } else if (event < 12) {
166 } else if (event < 16) {
167 resp = 'A' + (event - 12);
169 if (rtp->resp && (rtp->resp != resp)) {
173 rtp->dtmfcount = dtmftimeout;
177 static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
179 struct ast_frame *f = NULL;
180 /* Convert comfort noise into audio with various codecs. Unfortunately this doesn't
181 totally help us out becuase we don't have an engine to keep it going and we are not
182 guaranteed to have it every 20ms or anything */
184 printf("RFC3389: %d bytes, format is %d\n", len, rtp->lastrxformat);
186 ast_log(LOG_NOTICE, "RFC3389 support incomplete. Turn off on client if possible\n");
187 if (!rtp->lastrxformat)
189 switch(rtp->lastrxformat) {
190 case AST_FORMAT_ULAW:
191 rtp->f.frametype = AST_FRAME_VOICE;
192 rtp->f.subclass = AST_FORMAT_ULAW;
193 rtp->f.datalen = 160;
194 rtp->f.samples = 160;
195 memset(rtp->f.data, 0x7f, rtp->f.datalen);
198 case AST_FORMAT_ALAW:
199 rtp->f.frametype = AST_FRAME_VOICE;
200 rtp->f.subclass = AST_FORMAT_ALAW;
201 rtp->f.datalen = 160;
202 rtp->f.samples = 160;
203 memset(rtp->f.data, 0x7e, rtp->f.datalen); /* XXX Is this right? XXX */
206 case AST_FORMAT_SLINEAR:
207 rtp->f.frametype = AST_FRAME_VOICE;
208 rtp->f.subclass = AST_FORMAT_SLINEAR;
209 rtp->f.datalen = 320;
210 rtp->f.samples = 160;
211 memset(rtp->f.data, 0x00, rtp->f.datalen);
215 ast_log(LOG_NOTICE, "Don't know how to handle RFC3389 for receive codec %d\n", rtp->lastrxformat);
220 static int rtpread(int *id, int fd, short events, void *cbdata)
222 struct ast_rtp *rtp = cbdata;
224 f = ast_rtp_read(rtp);
227 rtp->callback(rtp, f, rtp->data);
232 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
235 struct sockaddr_in sin;
240 unsigned int timestamp;
241 unsigned int *rtpheader;
242 static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
243 struct rtpPayloadType rtpPT;
247 res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
248 0, (struct sockaddr *)&sin, &len);
251 rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
253 ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
259 ast_log(LOG_WARNING, "RTP Read too short\n");
263 /* Send to whoever sent to us */
264 if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
265 (rtp->them.sin_port != sin.sin_port)) {
266 memcpy(&rtp->them, &sin, sizeof(rtp->them));
267 ast_log(LOG_DEBUG, "RTP NAT: Using address %s:%d\n", inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
271 seqno = ntohl(rtpheader[0]);
272 payloadtype = (seqno & 0x7f0000) >> 16;
274 timestamp = ntohl(rtpheader[1]);
276 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);
278 rtp->f.frametype = AST_FRAME_VOICE;
279 rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
280 if (!rtpPT.isAstFormat) {
281 // This is special in-band data that's not one of our codecs
282 if (rtpPT.code == AST_RTP_DTMF) {
283 /* It's special -- rfc2833 process it */
284 f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
285 if (f) return f; else return &null_frame;
286 } else if (rtpPT.code == AST_RTP_CN) {
288 f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
289 if (f) return f; else return &null_frame;
291 ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype);
295 rtp->f.subclass = rtpPT.code;
296 rtp->lastrxformat = rtp->f.subclass;
299 rtp->lastrxts = timestamp;
301 if (rtp->dtmfcount) {
303 printf("dtmfcount was %d\n", rtp->dtmfcount);
305 rtp->dtmfcount -= (timestamp - rtp->lastrxts);
306 if (rtp->dtmfcount < 0)
309 if (dtmftimeout != rtp->dtmfcount)
310 printf("dtmfcount is %d\n", rtp->dtmfcount);
313 rtp->lastrxts = timestamp;
315 /* Send any pending DTMF */
316 if (rtp->resp && !rtp->dtmfcount) {
317 ast_log(LOG_DEBUG, "Sending pending DTMF\n");
318 return send_dtmf(rtp);
321 rtp->f.datalen = res - hdrlen;
322 rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
323 rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
324 switch(rtp->f.subclass) {
325 case AST_FORMAT_ULAW:
326 case AST_FORMAT_ALAW:
327 rtp->f.samples = rtp->f.datalen;
329 case AST_FORMAT_SLINEAR:
330 rtp->f.samples = rtp->f.datalen / 2;
333 rtp->f.samples = 160 * (rtp->f.datalen / 33);
335 case AST_FORMAT_ADPCM:
336 rtp->f.samples = rtp->f.datalen * 2;
338 case AST_FORMAT_G729A:
339 rtp->f.samples = rtp->f.datalen * 8;
341 case AST_FORMAT_G723_1:
342 rtp->f.samples = g723_samples(rtp->f.data, rtp->f.datalen);
344 case AST_FORMAT_SPEEX:
345 rtp->f.samples = 160;
346 // assumes that the RTP packet contained one Speex frame
349 ast_log(LOG_NOTICE, "Unable to calculate samples for format %d\n", rtp->f.subclass);
356 // The following array defines the MIME type (and subtype) for each
357 // of our codecs, or RTP-specific data type.
359 struct rtpPayloadType payloadType;
363 {{1, AST_FORMAT_G723_1}, "audio", "G723"},
364 {{1, AST_FORMAT_GSM}, "audio", "GSM"},
365 {{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
366 {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
367 {{1, AST_FORMAT_MP3}, "audio", "MPA"},
368 {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
369 {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
370 {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
371 {{1, AST_FORMAT_G729A}, "audio", "G729"},
372 {{1, AST_FORMAT_SPEEX}, "audio", "SPEEX"},
373 {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
374 {{0, AST_RTP_CN}, "audio", "CN"},
375 {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
376 {{1, AST_FORMAT_PNG}, "video", "PNG"},
377 {{1, AST_FORMAT_H261}, "video", "H261"},
378 {{1, AST_FORMAT_H263}, "video", "H263"},
381 // Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
382 static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
383 [0] = {1, AST_FORMAT_ULAW},
384 [3] = {1, AST_FORMAT_GSM},
385 [4] = {1, AST_FORMAT_G723_1},
386 [5] = {1, AST_FORMAT_ADPCM}, // 8 kHz
387 [6] = {1, AST_FORMAT_ADPCM}, // 16 kHz
388 [7] = {1, AST_FORMAT_LPC10},
389 [8] = {1, AST_FORMAT_ALAW},
390 [10] = {1, AST_FORMAT_SLINEAR}, // 2 channels
391 [11] = {1, AST_FORMAT_SLINEAR}, // 1 channel
392 [13] = {0, AST_RTP_CN},
393 [14] = {1, AST_FORMAT_MP3},
394 [16] = {1, AST_FORMAT_ADPCM}, // 11.025 kHz
395 [17] = {1, AST_FORMAT_ADPCM}, // 22.050 kHz
396 [18] = {1, AST_FORMAT_G729A},
397 [26] = {1, AST_FORMAT_JPEG},
398 [31] = {1, AST_FORMAT_H261},
399 [34] = {1, AST_FORMAT_H263},
400 [101] = {0, AST_RTP_DTMF},
403 void ast_rtp_pt_clear(struct ast_rtp* rtp)
407 for (i = 0; i < MAX_RTP_PT; ++i) {
408 rtp->current_RTP_PT[i].isAstFormat = 0;
409 rtp->current_RTP_PT[i].code = 0;
412 rtp->rtp_lookup_code_cache_isAstFormat = 0;
413 rtp->rtp_lookup_code_cache_code = 0;
414 rtp->rtp_lookup_code_cache_result = 0;
417 void ast_rtp_pt_default(struct ast_rtp* rtp)
420 /* Initialize to default payload types */
421 for (i = 0; i < MAX_RTP_PT; ++i) {
422 rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat;
423 rtp->current_RTP_PT[i].code = static_RTP_PT[i].code;
426 rtp->rtp_lookup_code_cache_isAstFormat = 0;
427 rtp->rtp_lookup_code_cache_code = 0;
428 rtp->rtp_lookup_code_cache_result = 0;
431 // Make a note of a RTP payload type that was seen in a SDP "m=" line.
432 // By default, use the well-known value for this type (although it may
433 // still be set to a different value by a subsequent "a=rtpmap:" line):
434 void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
435 if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type
437 if (static_RTP_PT[pt].code != 0) {
438 rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
442 // Make a note of a RTP payload type (with MIME type) that was seen in
443 // a SDP "a=rtpmap:" line.
444 void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
445 char* mimeType, char* mimeSubtype) {
448 if (pt < 0 || pt > MAX_RTP_PT) return; // bogus payload type
450 for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
451 if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
452 strcasecmp(mimeType, mimeTypes[i].type) == 0) {
453 rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
459 // Return the union of all of the codecs that were set by rtp_set...() calls
460 // They're returned as two distinct sets: AST_FORMATs, and AST_RTPs
461 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
462 int* astFormats, int* nonAstFormats) {
465 *astFormats = *nonAstFormats = 0;
466 for (pt = 0; pt < MAX_RTP_PT; ++pt) {
467 if (rtp->current_RTP_PT[pt].isAstFormat) {
468 *astFormats |= rtp->current_RTP_PT[pt].code;
470 *nonAstFormats |= rtp->current_RTP_PT[pt].code;
475 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) {
476 if (pt < 0 || pt > MAX_RTP_PT) {
477 struct rtpPayloadType result;
478 result.isAstFormat = result.code = 0;
479 return result; // bogus payload type
481 return rtp->current_RTP_PT[pt];
484 int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) {
487 if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
488 code == rtp->rtp_lookup_code_cache_code) {
489 // Use our cached mapping, to avoid the overhead of the loop below
490 return rtp->rtp_lookup_code_cache_result;
493 for (pt = 0; pt < MAX_RTP_PT; ++pt) {
494 if (rtp->current_RTP_PT[pt].code == code &&
495 rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) {
496 rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
497 rtp->rtp_lookup_code_cache_code = code;
498 rtp->rtp_lookup_code_cache_result = pt;
505 char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code) {
508 for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
509 if (mimeTypes[i].payloadType.code == code &&
510 mimeTypes[i].payloadType.isAstFormat == isAstFormat) {
511 return mimeTypes[i].subtype;
517 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io)
522 rtp = malloc(sizeof(struct ast_rtp));
525 memset(rtp, 0, sizeof(struct ast_rtp));
526 rtp->them.sin_family = AF_INET;
527 rtp->us.sin_family = AF_INET;
528 rtp->s = socket(AF_INET, SOCK_DGRAM, 0);
530 rtp->seqno = rand() & 0xffff;
533 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
536 flags = fcntl(rtp->s, F_GETFL);
537 fcntl(rtp->s, F_SETFL, flags | O_NONBLOCK);
539 /* Find us a place */
540 x = (rand() % (65000-1025)) + 1025;
541 /* Must be an even port number by RTP spec */
543 rtp->us.sin_port = htons(x);
544 if (!bind(rtp->s, &rtp->us, sizeof(rtp->us)))
546 if (errno != EADDRINUSE) {
547 ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
554 /* Operate this one in a callback mode */
557 rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
559 ast_rtp_pt_default(rtp);
563 int ast_rtp_settos(struct ast_rtp *rtp, int tos)
566 if ((res = setsockopt(rtp->s, SOL_IP, IP_TOS, &tos, sizeof(tos))))
567 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
571 void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
573 rtp->them.sin_port = them->sin_port;
574 rtp->them.sin_addr = them->sin_addr;
577 void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
579 them->sin_family = AF_INET;
580 them->sin_port = rtp->them.sin_port;
581 them->sin_addr = rtp->them.sin_addr;
584 void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us)
586 memcpy(us, &rtp->us, sizeof(rtp->us));
589 void ast_rtp_destroy(struct ast_rtp *rtp)
592 ast_smoother_free(rtp->smoother);
594 ast_io_remove(rtp->io, rtp->ioid);
600 static unsigned int calc_txstamp(struct ast_rtp *rtp)
604 if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
605 gettimeofday(&rtp->txcore, NULL);
607 gettimeofday(&now, NULL);
608 ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
609 ms += (now.tv_usec - rtp->txcore.tv_usec) / 1000;
610 /* Use what we just got for next time */
611 rtp->txcore.tv_sec = now.tv_sec;
612 rtp->txcore.tv_usec = now.tv_usec;
616 int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
618 unsigned int *rtpheader;
626 if ((digit <= '9') && (digit >= '0'))
628 else if (digit == '*')
630 else if (digit == '#')
632 else if ((digit >= 'A') && (digit <= 'D'))
633 digit = digit - 'A' + 12;
634 else if ((digit >= 'a') && (digit <= 'd'))
635 digit = digit - 'a' + 12;
637 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
642 /* If we have no peer, return immediately */
643 if (!rtp->them.sin_addr.s_addr)
646 ms = calc_txstamp(rtp);
647 /* Default prediction */
648 pred = rtp->lastts + ms * 8;
650 /* Get a pointer to the header */
651 rtpheader = (unsigned int *)data;
652 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (101 << 16) | (rtp->seqno++));
653 rtpheader[1] = htonl(rtp->lastts);
654 rtpheader[2] = htonl(rtp->ssrc);
655 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
657 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
658 res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, &rtp->them, sizeof(rtp->them));
660 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));
662 printf("Sent %d bytes of RTP data to %s:%d\n", res, inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
666 /* Clear marker bit and increment seqno */
667 rtpheader[0] = htonl((2 << 30) | (101 << 16) | (rtp->seqno++));
668 /* Make duration 240 */
669 rtpheader[3] |= htonl((240));
670 /* Set the End bit for the last 3 */
671 rtpheader[3] |= htonl((1 << 23));
677 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
679 unsigned int *rtpheader;
685 ms = calc_txstamp(rtp);
686 /* Default prediction */
687 pred = rtp->lastts + ms * 8;
689 switch(f->subclass) {
690 case AST_FORMAT_ULAW:
691 case AST_FORMAT_ALAW:
692 /* If we're within +/- 20ms from when where we
693 predict we should be, use that */
694 pred = rtp->lastts + f->datalen;
696 case AST_FORMAT_G729A:
697 pred = rtp->lastts + f->datalen * 8;
700 pred = rtp->lastts + (f->datalen * 160 / 33);
702 case AST_FORMAT_G723_1:
703 pred = rtp->lastts + g723_samples(f->data, f->datalen);
705 case AST_FORMAT_SPEEX:
706 pred = rtp->lastts + 160;
707 // assumes that the RTP packet contains one Speex frame
710 ast_log(LOG_WARNING, "Not sure about timestamp format for codec format %d\n", f->subclass);
713 /* Re-calculate last TS */
714 rtp->lastts = rtp->lastts + ms * 8;
715 /* If it's close to ou prediction, go for it */
716 if (abs(rtp->lastts - pred) < 640)
719 ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
720 /* Get a pointer to the header */
721 rtpheader = (unsigned int *)(f->data - hdrlen);
722 rtpheader[0] = htonl((2 << 30) | (codec << 16) | (rtp->seqno++));
723 rtpheader[1] = htonl(rtp->lastts);
724 rtpheader[2] = htonl(rtp->ssrc);
725 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
726 res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, &rtp->them, sizeof(rtp->them));
728 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));
730 printf("Sent %d bytes of RTP data to %s:%d\n", res, inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
736 int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
743 /* If we have no peer, return immediately */
744 if (!rtp->them.sin_addr.s_addr)
747 /* Make sure we have enough space for RTP header */
748 if (_f->frametype != AST_FRAME_VOICE) {
749 ast_log(LOG_WARNING, "RTP can only send voice\n");
753 codec = ast_rtp_lookup_code(rtp, 1, _f->subclass);
755 ast_log(LOG_WARNING, "Don't know how to send format %d packets with RTP\n", _f->subclass);
759 if (rtp->lasttxformat != _f->subclass) {
760 /* New format, reset the smoother */
761 ast_log(LOG_DEBUG, "Ooh, format changed from %d to %d\n", rtp->lasttxformat, _f->subclass);
762 rtp->lasttxformat = _f->subclass;
764 ast_smoother_free(rtp->smoother);
765 rtp->smoother = NULL;
769 switch(_f->subclass) {
770 case AST_FORMAT_ULAW:
771 case AST_FORMAT_ALAW:
772 if (!rtp->smoother) {
773 rtp->smoother = ast_smoother_new(160);
775 if (!rtp->smoother) {
776 ast_log(LOG_WARNING, "Unable to create smoother :(\n");
779 ast_smoother_feed(rtp->smoother, _f);
781 while((f = ast_smoother_read(rtp->smoother)))
782 ast_rtp_raw_write(rtp, f, codec);
784 case AST_FORMAT_G729A:
785 if (!rtp->smoother) {
786 rtp->smoother = ast_smoother_new(20);
788 if (!rtp->smoother) {
789 ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n");
792 ast_smoother_feed(rtp->smoother, _f);
794 while((f = ast_smoother_read(rtp->smoother)))
795 ast_rtp_raw_write(rtp, f, codec);
798 if (!rtp->smoother) {
799 rtp->smoother = ast_smoother_new(33);
801 if (!rtp->smoother) {
802 ast_log(LOG_WARNING, "Unable to create GSM smoother :(\n");
805 ast_smoother_feed(rtp->smoother, _f);
806 while((f = ast_smoother_read(rtp->smoother)))
807 ast_rtp_raw_write(rtp, f, codec);
810 ast_log(LOG_WARNING, "Not sure about sending format %d packets\n", _f->subclass);
811 // fall through to...
812 case AST_FORMAT_SPEEX:
813 // Don't buffer outgoing frames; send them one-per-packet:
814 if (_f->offset < hdrlen) {
819 ast_rtp_raw_write(rtp, f, codec);
825 void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto)
827 struct ast_rtp_protocol *cur, *prev;
833 prev->next = proto->next;
835 protos = proto->next;
843 int ast_rtp_proto_register(struct ast_rtp_protocol *proto)
845 struct ast_rtp_protocol *cur;
848 if (cur->type == proto->type) {
849 ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
854 proto->next = protos;
859 static struct ast_rtp_protocol *get_proto(struct ast_channel *chan)
861 struct ast_rtp_protocol *cur;
864 if (cur->type == chan->type) {
872 int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
875 struct ast_channel *who, *cs[3];
876 struct ast_rtp *p0, *p1;
877 struct ast_rtp_protocol *pr0, *pr1;
881 /* XXX Wait a half a second for things to settle up
882 this really should be fixed XXX */
883 ast_autoservice_start(c0);
884 ast_autoservice_start(c1);
886 ast_autoservice_stop(c0);
887 ast_autoservice_stop(c1);
889 /* if need DTMF, cant native bridge */
890 if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
892 ast_pthread_mutex_lock(&c0->lock);
893 ast_pthread_mutex_lock(&c1->lock);
897 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
898 ast_pthread_mutex_unlock(&c0->lock);
899 ast_pthread_mutex_unlock(&c1->lock);
903 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
904 ast_pthread_mutex_unlock(&c0->lock);
905 ast_pthread_mutex_unlock(&c1->lock);
910 p0 = pr0->get_rtp_info(c0);
911 p1 = pr1->get_rtp_info(c1);
913 /* Somebody doesn't want to play... */
914 ast_pthread_mutex_unlock(&c0->lock);
915 ast_pthread_mutex_unlock(&c1->lock);
918 if (pr0->set_rtp_peer(c0, p1))
919 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
920 if (pr1->set_rtp_peer(c1, p0))
921 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
922 ast_pthread_mutex_unlock(&c0->lock);
923 ast_pthread_mutex_unlock(&c1->lock);
928 if ((c0->pvt->pvt != pvt0) ||
929 (c1->pvt->pvt != pvt1) ||
930 (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
931 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
932 if (c0->pvt->pvt == pvt0) {
933 if (pr0->set_rtp_peer(c0, NULL))
934 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
936 if (c1->pvt->pvt == pvt1) {
937 if (pr1->set_rtp_peer(c1, NULL))
938 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
940 /* Tell it to try again later */
944 who = ast_waitfor_n(cs, 2, &to);
946 ast_log(LOG_DEBUG, "Ooh, empty read...\n");
950 if (!f || ((f->frametype == AST_FRAME_DTMF) &&
951 (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) ||
952 ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
955 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
956 if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
957 if (pr0->set_rtp_peer(c0, NULL))
958 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
960 if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
961 if (pr1->set_rtp_peer(c1, NULL))
962 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
964 /* That's all we needed */
967 if ((f->frametype == AST_FRAME_DTMF) || (f->frametype == AST_FRAME_VOICE)) {
968 /* Forward voice or DTMF frames if they happen upon us */
971 } else if (who == c1) {
977 /* Swap priority not that it's a big deal at this point */