lun feb 24 22:10:09 CET 2003
[asterisk/asterisk.git] / rtp.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Real-time Protocol Support
5  * 
6  * Copyright (C) 1999, Mark Spencer
7  *
8  * Mark Spencer <markster@linux-support.net>
9  *
10  * This program is free software, distributed under the terms of
11  * the GNU General Public License
12  */
13
14 #include <stdio.h>
15 #include <stdlib.h>
16 #include <pthread.h>
17 #include <string.h>
18 #include <sys/time.h>
19 #include <signal.h>
20 #include <errno.h>
21 #include <unistd.h>
22 #include <netinet/in.h>
23 #include <sys/time.h>
24 #include <sys/socket.h>
25 #include <arpa/inet.h>
26 #include <fcntl.h>
27
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>
34
35 #define TYPE_SILENCE     0x2
36 #define TYPE_HIGH        0x0
37 #define TYPE_LOW         0x1
38 #define TYPE_MASK        0x3
39
40 static int dtmftimeout = 300;   /* 300 samples */
41
42 struct ast_rtp {
43         int s;
44         char resp;
45         struct ast_frame f;
46         unsigned char rawdata[1024 + AST_FRIENDLY_OFFSET];
47         unsigned int ssrc;
48         unsigned int lastts;
49         unsigned int lastrxts;
50         int lasttxformat;
51         int lastrxformat;
52         int dtmfcount;
53         struct sockaddr_in us;
54         struct sockaddr_in them;
55         struct timeval rxcore;
56         struct timeval txcore;
57         struct ast_smoother *smoother;
58         int *ioid;
59         unsigned short seqno;
60         struct sched_context *sched;
61         struct io_context *io;
62         void *data;
63         ast_rtp_callback callback;
64 };
65
66 static struct ast_rtp_protocol *protos = NULL;
67
68 int ast_rtp_fd(struct ast_rtp *rtp)
69 {
70         return rtp->s;
71 }
72
73 static int g723_len(unsigned char buf)
74 {
75         switch(buf & TYPE_MASK) {
76         case TYPE_MASK:
77         case TYPE_SILENCE:
78                 return 4;
79                 break;
80         case TYPE_HIGH:
81                 return 24;
82                 break;
83         case TYPE_LOW:
84                 return 20;
85                 break;
86         default:
87                 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
88         }
89         return -1;
90 }
91
92 static int g723_samples(unsigned char *buf, int maxlen)
93 {
94         int pos = 0;
95         int samples = 0;
96         int res;
97         while(pos < maxlen) {
98                 res = g723_len(buf[pos]);
99                 if (res < 0)
100                         break;
101                 samples += 240;
102                 pos += res;
103         }
104         return samples;
105 }
106
107 void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
108 {
109         rtp->data = data;
110 }
111
112 void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
113 {
114         rtp->callback = callback;
115 }
116
117 static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
118 {
119         ast_log(LOG_DEBUG, "Sending dtmf: %d (%c)\n", rtp->resp, rtp->resp);
120         rtp->f.frametype = AST_FRAME_DTMF;
121         rtp->f.subclass = rtp->resp;
122         rtp->f.datalen = 0;
123         rtp->f.samples = 0;
124         rtp->f.mallocd = 0;
125         rtp->f.src = "RTP";
126         rtp->resp = 0;
127         return &rtp->f;
128         
129 }
130
131 static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
132 {
133         unsigned int event;
134         char resp = 0;
135         struct ast_frame *f = NULL;
136         event = ntohl(*((unsigned int *)(data)));
137         event >>= 24;
138 #if 0
139         printf("Event: %08x (len = %d)\n", event, len);
140 #endif  
141         if (event < 10) {
142                 resp = '0' + event;
143         } else if (event < 11) {
144                 resp = '*';
145         } else if (event < 12) {
146                 resp = '#';
147         } else if (event < 16) {
148                 resp = 'A' + (event - 12);
149         }
150         if (rtp->resp && (rtp->resp != resp)) {
151                 f = send_dtmf(rtp);
152         }
153         rtp->resp = resp;
154         rtp->dtmfcount = dtmftimeout;
155         return f;
156 }
157
158 static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
159 {
160         struct ast_frame *f = NULL;
161         /* Convert comfort noise into audio with various codecs.  Unfortunately this doesn't
162            totally help us out becuase we don't have an engine to keep it going and we are not
163            guaranteed to have it every 20ms or anything */
164 #if 0
165         printf("RFC3389: %d bytes, format is %d\n", len, rtp->lastrxformat);
166 #endif  
167         ast_log(LOG_NOTICE, "RFC3389 support incomplete.  Turn off on client if possible\n");
168         if (!rtp->lastrxformat)
169                 return  NULL;
170         switch(rtp->lastrxformat) {
171         case AST_FORMAT_ULAW:
172                 rtp->f.frametype = AST_FRAME_VOICE;
173                 rtp->f.subclass = AST_FORMAT_ULAW;
174                 rtp->f.datalen = 160;
175                 rtp->f.samples = 160;
176                 memset(rtp->f.data, 0x7f, rtp->f.datalen);
177                 f = &rtp->f;
178                 break;
179         case AST_FORMAT_ALAW:
180                 rtp->f.frametype = AST_FRAME_VOICE;
181                 rtp->f.subclass = AST_FORMAT_ALAW;
182                 rtp->f.datalen = 160;
183                 rtp->f.samples = 160;
184                 memset(rtp->f.data, 0x7e, rtp->f.datalen); /* XXX Is this right? XXX */
185                 f = &rtp->f;
186                 break;
187         case AST_FORMAT_SLINEAR:
188                 rtp->f.frametype = AST_FRAME_VOICE;
189                 rtp->f.subclass = AST_FORMAT_SLINEAR;
190                 rtp->f.datalen = 320;
191                 rtp->f.samples = 160;
192                 memset(rtp->f.data, 0x00, rtp->f.datalen);
193                 f = &rtp->f;
194                 break;
195         default:
196                 ast_log(LOG_NOTICE, "Don't know how to handle RFC3389 for receive codec %d\n", rtp->lastrxformat);
197         }
198         return f;
199 }
200
201 static struct ast_frame *process_type121(struct ast_rtp *rtp, unsigned char *data, int len)
202 {
203         char resp = 0;
204         struct ast_frame *f = NULL;
205         unsigned char b0,b1,b2,b3,b4,b5,b6,b7;
206         
207         b0=*(data+0);b1=*(data+1);b2=*(data+2);b3=*(data+3);
208         b4=*(data+4);b5=*(data+5);b6=*(data+6);b7=*(data+7);
209 //      printf("%u %u %u %u %u %u %u %u\n",b0,b1,b2,b3,b4,b5,b6,b7);
210         if (b2==32) {
211 //              printf("Start %d\n",b3);
212                 if (b4==0) {
213 //                      printf("Detection point for DTMF %d\n",b3);
214                         if (b3<10) {
215                                 resp='0'+b3;
216                         } else if (b3<11) {
217                                 resp='*';
218                         } else if (b3<12) {
219                                 resp='#';
220                         } else if (b3<16) {
221                                 resp='A'+(b3-12);
222                         }
223                         rtp->resp=resp;
224                         f = send_dtmf(rtp);
225                 }
226         }
227         if (b2==3) {
228 //              printf("Stop(3) %d\n",b3);
229         }
230         if (b2==0) {
231 //              printf("Stop(0) %d\n",b3);
232         }
233         return f;
234 }
235
236 static int rtpread(int *id, int fd, short events, void *cbdata)
237 {
238         struct ast_rtp *rtp = cbdata;
239         struct ast_frame *f;
240         f = ast_rtp_read(rtp);
241         if (f) {
242                 if (rtp->callback)
243                         rtp->callback(rtp, f, rtp->data);
244         }
245         return 1;
246 }
247
248 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
249 {
250         int res;
251         struct sockaddr_in sin;
252         int len;
253         unsigned int seqno;
254         int payloadtype;
255         int hdrlen = 12;
256         unsigned int timestamp;
257         unsigned int *rtpheader;
258         static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
259         
260         len = sizeof(sin);
261         
262         res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
263                                         0, (struct sockaddr *)&sin, &len);
264
265         rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
266         if (res < 0) {
267                 ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
268                 if (errno == EBADF)
269                         CRASH;
270                 return &null_frame;
271         }
272         if (res < hdrlen) {
273                 ast_log(LOG_WARNING, "RTP Read too short\n");
274                 return &null_frame;
275         }
276         /* Get fields */
277         seqno = ntohl(rtpheader[0]);
278         payloadtype = (seqno & 0x7f0000) >> 16;
279         seqno &= 0xffff;
280         timestamp = ntohl(rtpheader[1]);
281 #if 0
282         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);
283 #endif  
284         rtp->f.frametype = AST_FRAME_VOICE;
285         rtp->f.subclass = rtp2ast(payloadtype);
286         if (rtp->f.subclass < 0) {
287                 f = NULL;
288                 if (payloadtype == 101) {
289                         /* It's special -- rfc2833 process it */
290                         f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
291                 } else if (payloadtype == 121) {
292                         /* CISCO proprietary DTMF bridge */
293                         f = process_type121(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
294                 } else if (payloadtype == 100) {
295                         /* CISCO's notso proprietary DTMF bridge */
296                         f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
297                 } else if (payloadtype == 13) {
298                         f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
299                 } else {
300                         ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype);
301                 }
302                 if (f)
303                         return f;
304                 else
305                         return &null_frame;
306         } else
307                 rtp->lastrxformat = rtp->f.subclass;
308
309         if (!rtp->lastrxts)
310                 rtp->lastrxts = timestamp;
311
312         if (rtp->dtmfcount) {
313 #if 0
314                 printf("dtmfcount was %d\n", rtp->dtmfcount);
315 #endif          
316                 rtp->dtmfcount -= (timestamp - rtp->lastrxts);
317                 if (rtp->dtmfcount < 0)
318                         rtp->dtmfcount = 0;
319 #if 0
320                 if (dtmftimeout != rtp->dtmfcount)
321                         printf("dtmfcount is %d\n", rtp->dtmfcount);
322 #endif
323         }
324         rtp->lastrxts = timestamp;
325
326         /* Send any pending DTMF */
327         if (rtp->resp && !rtp->dtmfcount) {
328                 ast_log(LOG_DEBUG, "Sending pending DTMF\n");
329                 return send_dtmf(rtp);
330         }
331         rtp->f.mallocd = 0;
332         rtp->f.datalen = res - hdrlen;
333         rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
334         rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
335         switch(rtp->f.subclass) {
336         case AST_FORMAT_ULAW:
337         case AST_FORMAT_ALAW:
338                 rtp->f.samples = rtp->f.datalen;
339                 break;
340         case AST_FORMAT_SLINEAR:
341                 rtp->f.samples = rtp->f.datalen / 2;
342                 break;
343         case AST_FORMAT_GSM:
344                 rtp->f.samples = 160 * (rtp->f.datalen / 33);
345                 break;
346         case AST_FORMAT_ADPCM:
347                 rtp->f.samples = rtp->f.datalen * 2;
348                 break;
349         case AST_FORMAT_G729A:
350                 rtp->f.samples = rtp->f.datalen * 8;
351                 break;
352         case AST_FORMAT_G723_1:
353                 rtp->f.samples = g723_samples(rtp->f.data, rtp->f.datalen);
354                 break;
355         default:
356                 ast_log(LOG_NOTICE, "Unable to calculate samples for format %d\n", rtp->f.subclass);
357                 break;
358         }
359         rtp->f.src = "RTP";
360         return &rtp->f;
361 }
362
363 static struct {
364         int rtp;
365         int ast;
366         char *label;
367 } cmap[] = {
368         { 0, AST_FORMAT_ULAW, "PCMU" },
369         { 3, AST_FORMAT_GSM, "GSM" },
370         { 4, AST_FORMAT_G723_1, "G723" },
371         { 5, AST_FORMAT_ADPCM, "ADPCM" },
372         { 8, AST_FORMAT_ALAW, "PCMA" },
373         { 18, AST_FORMAT_G729A, "G729" },
374 };
375
376 int rtp2ast(int id)
377 {
378         int x;
379         for (x=0;x<sizeof(cmap) / sizeof(cmap[0]); x++) {
380                 if (cmap[x].rtp == id)
381                         return cmap[x].ast;
382         }
383         return -1;
384 }
385
386 int ast2rtp(int id)
387 {
388         int x;
389         for (x=0;x<sizeof(cmap) / sizeof(cmap[0]); x++) {
390                 if (cmap[x].ast == id)
391                         return cmap[x].rtp;
392         }
393         return -1;
394 }
395
396 char *ast2rtpn(int id)
397 {
398         int x;
399         for (x=0;x<sizeof(cmap) / sizeof(cmap[0]); x++) {
400                 if (cmap[x].ast == id)
401                         return cmap[x].label;
402         }
403         return "";
404 }
405 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io)
406 {
407         struct ast_rtp *rtp;
408         int x;
409         int flags;
410         rtp = malloc(sizeof(struct ast_rtp));
411         if (!rtp)
412                 return NULL;
413         memset(rtp, 0, sizeof(struct ast_rtp));
414         rtp->them.sin_family = AF_INET;
415         rtp->us.sin_family = AF_INET;
416         rtp->s = socket(AF_INET, SOCK_DGRAM, 0);
417         rtp->ssrc = rand();
418         rtp->seqno = rand() & 0xffff;
419         if (rtp->s < 0) {
420                 free(rtp);
421                 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
422                 return NULL;
423         }
424         flags = fcntl(rtp->s, F_GETFL);
425         fcntl(rtp->s, F_SETFL, flags | O_NONBLOCK);
426         for (;;) {
427                 /* Find us a place */
428                 x = (rand() % (65000-1025)) + 1025;
429                 /* Must be an even port number by RTP spec */
430                 x = x & ~1;
431                 rtp->us.sin_port = htons(x);
432                 if (!bind(rtp->s, &rtp->us, sizeof(rtp->us)))
433                         break;
434                 if (errno != EADDRINUSE) {
435                         ast_log(LOG_WARNING, "Unexpected bind error: %s\n", strerror(errno));
436                         close(rtp->s);
437                         free(rtp);
438                         return NULL;
439                 }
440         }
441         if (io && sched) {
442                 /* Operate this one in a callback mode */
443                 rtp->sched = sched;
444                 rtp->io = io;
445                 rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
446         }
447         return rtp;
448 }
449
450 int ast_rtp_settos(struct ast_rtp *rtp, int tos)
451 {
452         int res;
453         if ((res = setsockopt(rtp->s, SOL_IP, IP_TOS, &tos, sizeof(tos)))) 
454                 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
455         return res;
456 }
457
458 void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
459 {
460         rtp->them.sin_port = them->sin_port;
461         rtp->them.sin_addr = them->sin_addr;
462 }
463
464 void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
465 {
466         them->sin_family = AF_INET;
467         them->sin_port = rtp->them.sin_port;
468         them->sin_addr = rtp->them.sin_addr;
469 }
470
471 void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us)
472 {
473         memcpy(us, &rtp->us, sizeof(rtp->us));
474 }
475
476 void ast_rtp_destroy(struct ast_rtp *rtp)
477 {
478         if (rtp->smoother)
479                 ast_smoother_free(rtp->smoother);
480         if (rtp->ioid)
481                 ast_io_remove(rtp->io, rtp->ioid);
482         if (rtp->s > -1)
483                 close(rtp->s);
484         free(rtp);
485 }
486
487 static unsigned int calc_txstamp(struct ast_rtp *rtp)
488 {
489         struct timeval now;
490         unsigned int ms;
491         if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
492                 gettimeofday(&rtp->txcore, NULL);
493         }
494         gettimeofday(&now, NULL);
495         ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
496         ms += (now.tv_usec - rtp->txcore.tv_usec) / 1000;
497         /* Use what we just got for next time */
498         rtp->txcore.tv_sec = now.tv_sec;
499         rtp->txcore.tv_usec = now.tv_usec;
500         return ms;
501 }
502
503 int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
504 {
505         unsigned int *rtpheader;
506         int hdrlen = 12;
507         int res;
508         int ms;
509         int pred;
510         int x;
511         char data[256];
512
513         if ((digit <= '9') && (digit >= '0'))
514                 digit -= '0';
515         else if (digit == '*')
516                 digit = 10;
517         else if (digit == '#')
518                 digit = 11;
519         else if ((digit >= 'A') && (digit <= 'D')) 
520                 digit = digit - 'A' + 12;
521         else if ((digit >= 'a') && (digit <= 'd')) 
522                 digit = digit - 'a' + 12;
523         else {
524                 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
525                 return -1;
526         }
527         
528
529         /* If we have no peer, return immediately */    
530         if (!rtp->them.sin_addr.s_addr)
531                 return 0;
532
533         ms = calc_txstamp(rtp);
534         /* Default prediction */
535         pred = rtp->lastts + ms * 8;
536         
537         /* Get a pointer to the header */
538         rtpheader = (unsigned int *)data;
539         rtpheader[0] = htonl((2 << 30) | (1 << 23) | (101 << 16) | (rtp->seqno++));
540         rtpheader[1] = htonl(rtp->lastts);
541         rtpheader[2] = htonl(rtp->ssrc); 
542         rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
543         for (x=0;x<4;x++) {
544                 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
545                         res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, &rtp->them, sizeof(rtp->them));
546                         if (res <0) 
547                                 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));
548         #if 0
549                 printf("Sent %d bytes of RTP data to %s:%d\n", res, inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
550         #endif          
551                 }
552                 if (x ==0) {
553                         /* Clear marker bit and increment seqno */
554                         rtpheader[0] = htonl((2 << 30)  | (101 << 16) | (rtp->seqno++));
555                         /* Make duration 240 */
556                         rtpheader[3] |= htonl((240));
557                         /* Set the End bit for the last 3 */
558                         rtpheader[3] |= htonl((1 << 23));
559                 }
560         }
561         return 0;
562 }
563
564 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
565 {
566         unsigned int *rtpheader;
567         int hdrlen = 12;
568         int res;
569         int ms;
570         int pred;
571
572         ms = calc_txstamp(rtp);
573         /* Default prediction */
574         pred = rtp->lastts + ms * 8;
575         
576         switch(f->subclass) {
577         case AST_FORMAT_ULAW:
578         case AST_FORMAT_ALAW:
579                 /* If we're within +/- 20ms from when where we
580                    predict we should be, use that */
581                 pred = rtp->lastts + f->datalen;
582                 break;
583         case AST_FORMAT_G729A:
584                 pred = rtp->lastts + f->datalen * 8;
585                 break;
586         case AST_FORMAT_GSM:
587                 pred = rtp->lastts + (f->datalen * 160 / 33);
588                 break;
589         case AST_FORMAT_G723_1:
590                 pred = rtp->lastts + g723_samples(f->data, f->datalen);
591                 break;
592         default:
593                 ast_log(LOG_WARNING, "Not sure about timestamp format for codec format %d\n", f->subclass);
594         }
595
596         /* Re-calculate last TS */
597         rtp->lastts = rtp->lastts + ms * 8;
598         /* If it's close to ou prediction, go for it */
599         if (abs(rtp->lastts - pred) < 640)
600                 rtp->lastts = pred;
601         else
602                 ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
603         /* Get a pointer to the header */
604         rtpheader = (unsigned int *)(f->data - hdrlen);
605         rtpheader[0] = htonl((2 << 30) | (codec << 16) | (rtp->seqno++));
606         rtpheader[1] = htonl(rtp->lastts);
607         rtpheader[2] = htonl(rtp->ssrc); 
608         if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
609                 res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, &rtp->them, sizeof(rtp->them));
610                 if (res <0) 
611                         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));
612 #if 0
613                 printf("Sent %d bytes of RTP data to %s:%d\n", res, inet_ntoa(rtp->them.sin_addr), ntohs(rtp->them.sin_port));
614 #endif          
615         }
616         return 0;
617 }
618
619 int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
620 {
621         struct ast_frame *f;
622         int codec;
623         int hdrlen = 12;
624         
625
626         /* If we have no peer, return immediately */    
627         if (!rtp->them.sin_addr.s_addr)
628                 return 0;
629         
630         /* Make sure we have enough space for RTP header */
631         if (_f->frametype != AST_FRAME_VOICE) {
632                 ast_log(LOG_WARNING, "RTP can only send voice\n");
633                 return -1;
634         }
635
636         codec = ast2rtp(_f->subclass);
637         if (codec < 0) {
638                 ast_log(LOG_WARNING, "Don't know how to send format %d packets with RTP\n", _f->subclass);
639                 return -1;
640         }
641
642         if (rtp->lasttxformat !=  _f->subclass) {
643                 /* New format, reset the smoother */
644                 ast_log(LOG_DEBUG, "Ooh, format changed from %d to %d\n", rtp->lasttxformat, _f->subclass);
645                 rtp->lasttxformat = _f->subclass;
646                 if (rtp->smoother)
647                         ast_smoother_free(rtp->smoother);
648                 rtp->smoother = NULL;
649         }
650
651
652         switch(_f->subclass) {
653         case AST_FORMAT_ULAW:
654         case AST_FORMAT_ALAW:
655                 if (!rtp->smoother) {
656                         rtp->smoother = ast_smoother_new(160);
657                 }
658                 if (!rtp->smoother) {
659                         ast_log(LOG_WARNING, "Unable to create smoother :(\n");
660                         return -1;
661                 }
662                 ast_smoother_feed(rtp->smoother, _f);
663                 
664                 while((f = ast_smoother_read(rtp->smoother)))
665                         ast_rtp_raw_write(rtp, f, codec);
666                 break;
667         case AST_FORMAT_G729A:
668                 if (!rtp->smoother) {
669                         rtp->smoother = ast_smoother_new(20);
670                 }
671                 if (!rtp->smoother) {
672                         ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n");
673                         return -1;
674                 }
675                 ast_smoother_feed(rtp->smoother, _f);
676                 
677                 while((f = ast_smoother_read(rtp->smoother)))
678                         ast_rtp_raw_write(rtp, f, codec);
679                 break;
680         case AST_FORMAT_GSM:
681                 if (!rtp->smoother) {
682                         rtp->smoother = ast_smoother_new(33);
683                 }
684                 if (!rtp->smoother) {
685                         ast_log(LOG_WARNING, "Unable to create GSM smoother :(\n");
686                         return -1;
687                 }
688                 ast_smoother_feed(rtp->smoother, _f);
689                 while((f = ast_smoother_read(rtp->smoother)))
690                         ast_rtp_raw_write(rtp, f, codec);
691                 break;
692         default:        
693                 ast_log(LOG_WARNING, "Not sure about sending format %d packets\n", _f->subclass);
694                 if (_f->offset < hdrlen) {
695                         f = ast_frdup(_f);
696                 } else {
697                         f = _f;
698                 }
699                 ast_rtp_raw_write(rtp, f, codec);
700         }
701                 
702         return 0;
703 }
704
705 void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto)
706 {
707         struct ast_rtp_protocol *cur, *prev;
708         cur = protos;
709         prev = NULL;
710         while(cur) {
711                 if (cur == proto) {
712                         if (prev)
713                                 prev->next = proto->next;
714                         else
715                                 protos = proto->next;
716                         return;
717                 }
718                 prev = cur;
719                 cur = cur->next;
720         }
721 }
722
723 int ast_rtp_proto_register(struct ast_rtp_protocol *proto)
724 {
725         struct ast_rtp_protocol *cur;
726         cur = protos;
727         while(cur) {
728                 if (cur->type == proto->type) {
729                         ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
730                         return -1;
731                 }
732                 cur = cur->next;
733         }
734         proto->next = protos;
735         protos = proto;
736         return 0;
737 }
738
739 static struct ast_rtp_protocol *get_proto(struct ast_channel *chan)
740 {
741         struct ast_rtp_protocol *cur;
742         cur = protos;
743         while(cur) {
744                 if (cur->type == chan->type) {
745                         return cur;
746                 }
747                 cur = cur->next;
748         }
749         return NULL;
750 }
751
752 int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
753 {
754         struct ast_frame *f;
755         struct ast_channel *who, *cs[3];
756         struct ast_rtp *p0, *p1;
757         struct ast_rtp_protocol *pr0, *pr1;
758         void *pvt0, *pvt1;
759         int to;
760
761         /* XXX Wait a half a second for things to settle up 
762                         this really should be fixed XXX */
763         ast_autoservice_start(c0);
764         ast_autoservice_start(c1);
765         usleep(500000);
766         ast_autoservice_stop(c0);
767         ast_autoservice_stop(c1);
768
769         /* if need DTMF, cant native bridge */
770         if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
771                 return -2;
772         ast_pthread_mutex_lock(&c0->lock);
773         ast_pthread_mutex_lock(&c1->lock);
774         pr0 = get_proto(c0);
775         pr1 = get_proto(c1);
776         if (!pr0) {
777                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
778                 ast_pthread_mutex_unlock(&c0->lock);
779                 ast_pthread_mutex_unlock(&c1->lock);
780                 return -1;
781         }
782         if (!pr1) {
783                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
784                 ast_pthread_mutex_unlock(&c0->lock);
785                 ast_pthread_mutex_unlock(&c1->lock);
786                 return -1;
787         }
788         pvt0 = c0->pvt->pvt;
789         pvt1 = c1->pvt->pvt;
790         p0 = pr0->get_rtp_info(c0);
791         p1 = pr1->get_rtp_info(c1);
792         if (!p0 || !p1) {
793                 /* Somebody doesn't want to play... */
794                 ast_pthread_mutex_unlock(&c0->lock);
795                 ast_pthread_mutex_unlock(&c1->lock);
796                 return -2;
797         }
798         if (pr0->set_rtp_peer(c0, p1)) 
799                 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
800         if (pr1->set_rtp_peer(c1, p0)) 
801                 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
802         ast_pthread_mutex_unlock(&c0->lock);
803         ast_pthread_mutex_unlock(&c1->lock);
804         cs[0] = c0;
805         cs[1] = c1;
806         cs[2] = NULL;
807         for (;;) {
808                 if ((c0->pvt->pvt != pvt0)  ||
809                         (c1->pvt->pvt != pvt1) ||
810                         (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
811                                 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
812                                 if (c0->pvt->pvt == pvt0) {
813                                         if (pr0->set_rtp_peer(c0, NULL)) 
814                                                 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
815                                 }
816                                 if (c1->pvt->pvt == pvt1) {
817                                         if (pr1->set_rtp_peer(c1, NULL)) 
818                                                 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
819                                 }
820                                 /* Tell it to try again later */
821                                 return -3;
822                 }
823                 to = -1;
824                 who = ast_waitfor_n(cs, 2, &to);
825                 if (!who) {
826                         ast_log(LOG_DEBUG, "Ooh, empty read...\n");
827                         continue;
828                 }
829                 f = ast_read(who);
830                 if (!f || ((f->frametype == AST_FRAME_DTMF) &&
831                                    (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || 
832                                ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
833                         *fo = f;
834                         *rc = who;
835                         ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
836                         if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
837                                 if (pr0->set_rtp_peer(c0, NULL)) 
838                                         ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
839                         }
840                         if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
841                                 if (pr1->set_rtp_peer(c1, NULL)) 
842                                         ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
843                         }
844                         /* That's all we needed */
845                         return 0;
846                 } else 
847                         ast_frfree(f);
848                 /* Swap priority not that it's a big deal at this point */
849                 cs[2] = cs[0];
850                 cs[0] = cs[1];
851                 cs[1] = cs[2];
852                 
853         }
854         return -1;
855 }