Add Estonian tone zone (bug #3589)
[asterisk/asterisk.git] / rtp.c
1 /*
2  * Asterisk -- A telephony toolkit for Linux.
3  *
4  * Real-time Protocol Support
5  *      Supports RTP and RTCP with Symmetric RTP support for NAT
6  *      traversal
7  * 
8  * Copyright (C) 1999 - 2005, Digium, Inc.
9  *
10  * Mark Spencer <markster@digium.com>
11  *
12  * This program is free software, distributed under the terms of
13  * the GNU General Public License
14  */
15
16 #include <stdio.h>
17 #include <stdlib.h>
18 #include <string.h>
19 #include <sys/time.h>
20 #include <signal.h>
21 #include <errno.h>
22 #include <unistd.h>
23 #include <netinet/in.h>
24 #include <sys/time.h>
25 #include <sys/socket.h>
26 #include <arpa/inet.h>
27 #include <fcntl.h>
28
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>
40 #include <asterisk/cli.h>
41
42 #define MAX_TIMESTAMP_SKEW      640
43
44 #define RTP_MTU         1200
45
46 #define TYPE_HIGH        0x0
47 #define TYPE_LOW         0x1
48 #define TYPE_SILENCE     0x2
49 #define TYPE_DONTSEND    0x3
50 #define TYPE_MASK        0x3
51
52 static int dtmftimeout = 3000;  /* 3000 samples */
53
54 static int rtpstart = 0;
55 static int rtpend = 0;
56 static int rtpdebug = 0;                /* Are we debugging? */
57 static struct sockaddr_in rtpdebugaddr; /* Debug packets to/from this host */
58 #ifdef SO_NO_CHECK
59 static int checksums = 1;
60 #endif
61
62 /* The value of each payload format mapping: */
63 struct rtpPayloadType {
64         int isAstFormat;        /* whether the following code is an AST_FORMAT */
65         int code;
66 };
67
68 #define MAX_RTP_PT 256
69
70 #define FLAG_3389_WARNING (1 << 0)
71
72 struct ast_rtp {
73         int s;
74         char resp;
75         struct ast_frame f;
76         unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
77         unsigned int ssrc;
78         unsigned int lastts;
79         unsigned int lastrxts;
80         unsigned int lastividtimestamp;
81         unsigned int lastovidtimestamp;
82         unsigned int lasteventseqn;
83         int lasttxformat;
84         int lastrxformat;
85         int dtmfcount;
86         unsigned int dtmfduration;
87         int nat;
88         int flags;
89         struct sockaddr_in us;
90         struct sockaddr_in them;
91         struct timeval rxcore;
92         struct timeval txcore;
93         struct timeval dtmfmute;
94         struct ast_smoother *smoother;
95         int *ioid;
96         unsigned short seqno;
97         unsigned short rxseqno;
98         struct sched_context *sched;
99         struct io_context *io;
100         void *data;
101         ast_rtp_callback callback;
102         struct rtpPayloadType current_RTP_PT[MAX_RTP_PT];
103         int rtp_lookup_code_cache_isAstFormat;  /* a cache for the result of rtp_lookup_code(): */
104         int rtp_lookup_code_cache_code;
105         int rtp_lookup_code_cache_result;
106         int rtp_offered_from_local;
107         struct ast_rtcp *rtcp;
108 };
109
110 struct ast_rtcp {
111         int s;          /* Socket */
112         struct sockaddr_in us;
113         struct sockaddr_in them;
114 };
115
116 static struct ast_rtp_protocol *protos = NULL;
117
118 int ast_rtp_fd(struct ast_rtp *rtp)
119 {
120         return rtp->s;
121 }
122
123 int ast_rtcp_fd(struct ast_rtp *rtp)
124 {
125         if (rtp->rtcp)
126                 return rtp->rtcp->s;
127         return -1;
128 }
129
130 static int g723_len(unsigned char buf)
131 {
132         switch(buf & TYPE_MASK) {
133         case TYPE_DONTSEND:
134                 return 0;
135                 break;
136         case TYPE_SILENCE:
137                 return 4;
138                 break;
139         case TYPE_HIGH:
140                 return 24;
141                 break;
142         case TYPE_LOW:
143                 return 20;
144                 break;
145         default:
146                 ast_log(LOG_WARNING, "Badly encoded frame (%d)\n", buf & TYPE_MASK);
147         }
148         return -1;
149 }
150
151 static int g723_samples(unsigned char *buf, int maxlen)
152 {
153         int pos = 0;
154         int samples = 0;
155         int res;
156         while(pos < maxlen) {
157                 res = g723_len(buf[pos]);
158                 if (res <= 0)
159                         break;
160                 samples += 240;
161                 pos += res;
162         }
163         return samples;
164 }
165
166 void ast_rtp_set_data(struct ast_rtp *rtp, void *data)
167 {
168         rtp->data = data;
169 }
170
171 void ast_rtp_set_callback(struct ast_rtp *rtp, ast_rtp_callback callback)
172 {
173         rtp->callback = callback;
174 }
175
176 void ast_rtp_setnat(struct ast_rtp *rtp, int nat)
177 {
178         rtp->nat = nat;
179 }
180
181 static struct ast_frame *send_dtmf(struct ast_rtp *rtp)
182 {
183         struct timeval tv;
184         static struct ast_frame null_frame = { AST_FRAME_NULL, };
185         char iabuf[INET_ADDRSTRLEN];
186         gettimeofday(&tv, NULL);
187         if ((tv.tv_sec < rtp->dtmfmute.tv_sec) ||
188             ((tv.tv_sec == rtp->dtmfmute.tv_sec) && (tv.tv_usec < rtp->dtmfmute.tv_usec))) {
189                 if (option_debug)
190                         ast_log(LOG_DEBUG, "Ignore potential DTMF echo from '%s'\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr));
191                 rtp->resp = 0;
192                 rtp->dtmfduration = 0;
193                 return &null_frame;
194         }
195         if (option_debug)
196                 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));
197         if (rtp->resp == 'X') {
198                 rtp->f.frametype = AST_FRAME_CONTROL;
199                 rtp->f.subclass = AST_CONTROL_FLASH;
200         } else {
201                 rtp->f.frametype = AST_FRAME_DTMF;
202                 rtp->f.subclass = rtp->resp;
203         }
204         rtp->f.datalen = 0;
205         rtp->f.samples = 0;
206         rtp->f.mallocd = 0;
207         rtp->f.src = "RTP";
208         rtp->resp = 0;
209         rtp->dtmfduration = 0;
210         return &rtp->f;
211         
212 }
213
214 static inline int rtp_debug_test_addr(struct sockaddr_in *addr)
215 {
216         if (rtpdebug == 0)
217                 return 0;
218         if (rtpdebugaddr.sin_addr.s_addr) {
219                 if (((ntohs(rtpdebugaddr.sin_port) != 0)
220                         && (rtpdebugaddr.sin_port != addr->sin_port))
221                         || (rtpdebugaddr.sin_addr.s_addr != addr->sin_addr.s_addr))
222                 return 0;
223         }
224         return 1;
225 }
226
227 static struct ast_frame *process_cisco_dtmf(struct ast_rtp *rtp, unsigned char *data, int len)
228 {
229         unsigned int event;
230         char resp = 0;
231         struct ast_frame *f = NULL;
232         event = ntohl(*((unsigned int *)(data)));
233         event &= 0x001F;
234 #if 0
235         printf("Cisco Digit: %08x (len = %d)\n", event, len);
236 #endif  
237         if (event < 10) {
238                 resp = '0' + event;
239         } else if (event < 11) {
240                 resp = '*';
241         } else if (event < 12) {
242                 resp = '#';
243         } else if (event < 16) {
244                 resp = 'A' + (event - 12);
245         } else if (event < 17) {
246                 resp = 'X';
247         }
248         if (rtp->resp && (rtp->resp != resp)) {
249                 f = send_dtmf(rtp);
250         }
251         rtp->resp = resp;
252         rtp->dtmfcount = dtmftimeout;
253         return f;
254 }
255
256 static struct ast_frame *process_rfc2833(struct ast_rtp *rtp, unsigned char *data, int len)
257 {
258         unsigned int event;
259         unsigned int event_end;
260         unsigned int duration;
261         char resp = 0;
262         struct ast_frame *f = NULL;
263         event = ntohl(*((unsigned int *)(data)));
264         event >>= 24;
265         event_end = ntohl(*((unsigned int *)(data)));
266         event_end <<= 8;
267         event_end >>= 24;
268         duration = ntohl(*((unsigned int *)(data)));
269         duration &= 0xFFFF;
270 #if 0
271         printf("Event: %08x (len = %d)\n", event, len);
272 #endif
273         if (event < 10) {
274                 resp = '0' + event;
275         } else if (event < 11) {
276                 resp = '*';
277         } else if (event < 12) {
278                 resp = '#';
279         } else if (event < 16) {
280                 resp = 'A' + (event - 12);
281         } else if (event < 17) {
282                 resp = 'X';
283         }
284         if (rtp->resp && (rtp->resp != resp)) {
285                 f = send_dtmf(rtp);
286         }
287         else if(event_end & 0x80)
288         {
289                 if (rtp->resp) {
290                         f = send_dtmf(rtp);
291                         rtp->resp = 0;
292                 }
293                 resp = 0;
294                 duration = 0;
295         }
296         else if(rtp->dtmfduration && (duration < rtp->dtmfduration))
297         {
298                 f = send_dtmf(rtp);
299         }
300         if (!(event_end & 0x80))
301                 rtp->resp = resp;
302         rtp->dtmfcount = dtmftimeout;
303         rtp->dtmfduration = duration;
304         return f;
305 }
306
307 static struct ast_frame *process_rfc3389(struct ast_rtp *rtp, unsigned char *data, int len)
308 {
309         struct ast_frame *f = NULL;
310         /* Convert comfort noise into audio with various codecs.  Unfortunately this doesn't
311            totally help us out becuase we don't have an engine to keep it going and we are not
312            guaranteed to have it every 20ms or anything */
313 #if 1
314         printf("RFC3389: %d bytes, level %d...\n", len, rtp->lastrxformat);
315 #endif  
316         if (!(rtp->flags & FLAG_3389_WARNING)) {
317                 ast_log(LOG_NOTICE, "RFC3389 support incomplete.  Turn off on client if possible\n");
318                 rtp->flags |= FLAG_3389_WARNING;
319         }
320         /* Must have at least one byte */
321         if (!len)
322                 return NULL;
323         if (len < 24) {
324                 rtp->f.data = rtp->rawdata + AST_FRIENDLY_OFFSET;
325                 rtp->f.datalen = len - 1;
326                 rtp->f.offset = AST_FRIENDLY_OFFSET;
327                 memcpy(rtp->f.data, data + 1, len - 1);
328         } else {
329                 rtp->f.data = NULL;
330                 rtp->f.offset = 0;
331                 rtp->f.datalen = 0;
332         }
333         rtp->f.frametype = AST_FRAME_CNG;
334         rtp->f.subclass = data[0] & 0x7f;
335         rtp->f.datalen = len - 1;
336         rtp->f.samples = 0;
337         rtp->f.delivery.tv_usec = rtp->f.delivery.tv_sec = 0;
338         f = &rtp->f;
339         return f;
340 }
341
342 static int rtpread(int *id, int fd, short events, void *cbdata)
343 {
344         struct ast_rtp *rtp = cbdata;
345         struct ast_frame *f;
346         f = ast_rtp_read(rtp);
347         if (f) {
348                 if (rtp->callback)
349                         rtp->callback(rtp, f, rtp->data);
350         }
351         return 1;
352 }
353
354 struct ast_frame *ast_rtcp_read(struct ast_rtp *rtp)
355 {
356         static struct ast_frame null_frame = { AST_FRAME_NULL, };
357         int len;
358         int hdrlen = 8;
359         int res;
360         struct sockaddr_in sin;
361         unsigned int rtcpdata[1024];
362         char iabuf[INET_ADDRSTRLEN];
363         
364         if (!rtp->rtcp)
365                 return &null_frame;
366
367         len = sizeof(sin);
368         
369         res = recvfrom(rtp->rtcp->s, rtcpdata, sizeof(rtcpdata),
370                                         0, (struct sockaddr *)&sin, &len);
371         
372         if (res < 0) {
373                 if (errno == EAGAIN)
374                         ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
375                 else
376                         ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
377                 if (errno == EBADF)
378                         CRASH;
379                 return &null_frame;
380         }
381
382         if (res < hdrlen) {
383                 ast_log(LOG_WARNING, "RTP Read too short\n");
384                 return &null_frame;
385         }
386
387         if (rtp->nat) {
388                 /* Send to whoever sent to us */
389                 if ((rtp->rtcp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
390                     (rtp->rtcp->them.sin_port != sin.sin_port)) {
391                         memcpy(&rtp->them, &sin, sizeof(rtp->them));
392                         rtp->rxseqno = 0;
393                         if (option_debug)
394                                 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));
395                 }
396         }
397         if (option_debug)
398                 ast_log(LOG_DEBUG, "Got RTCP report of %d bytes\n", res);
399         return &null_frame;
400 }
401
402 static void calc_rxstamp(struct timeval *tv, struct ast_rtp *rtp, unsigned int timestamp, int mark)
403 {
404         if ((!rtp->rxcore.tv_sec && !rtp->rxcore.tv_usec) || mark) {
405                 gettimeofday(&rtp->rxcore, NULL);
406                 rtp->rxcore.tv_sec -= timestamp / 8000;
407                 rtp->rxcore.tv_usec -= (timestamp % 8000) * 125;
408                 /* Round to 20ms for nice, pretty timestamps */
409                 rtp->rxcore.tv_usec -= rtp->rxcore.tv_usec % 20000;
410                 if (rtp->rxcore.tv_usec < 0) {
411                         /* Adjust appropriately if necessary */
412                         rtp->rxcore.tv_usec += 1000000;
413                         rtp->rxcore.tv_sec -= 1;
414                 }
415         }
416         tv->tv_sec = rtp->rxcore.tv_sec + timestamp / 8000;
417         tv->tv_usec = rtp->rxcore.tv_usec + (timestamp % 8000) * 125;
418         if (tv->tv_usec >= 1000000) {
419                 tv->tv_usec -= 1000000;
420                 tv->tv_sec += 1;
421         }
422 }
423
424 struct ast_frame *ast_rtp_read(struct ast_rtp *rtp)
425 {
426         int res;
427         struct sockaddr_in sin;
428         int len;
429         unsigned int seqno;
430         int version;
431         int payloadtype;
432         int hdrlen = 12;
433         int mark;
434         int ext;
435         int x;
436         char iabuf[INET_ADDRSTRLEN];
437         unsigned int timestamp;
438         unsigned int *rtpheader;
439         static struct ast_frame *f, null_frame = { AST_FRAME_NULL, };
440         struct rtpPayloadType rtpPT;
441         
442         len = sizeof(sin);
443         
444         /* Cache where the header will go */
445         res = recvfrom(rtp->s, rtp->rawdata + AST_FRIENDLY_OFFSET, sizeof(rtp->rawdata) - AST_FRIENDLY_OFFSET,
446                                         0, (struct sockaddr *)&sin, &len);
447
448
449         rtpheader = (unsigned int *)(rtp->rawdata + AST_FRIENDLY_OFFSET);
450         if (res < 0) {
451                 if (errno == EAGAIN)
452                         ast_log(LOG_NOTICE, "RTP: Received packet with bad UDP checksum\n");
453                 else
454                         ast_log(LOG_WARNING, "RTP Read error: %s\n", strerror(errno));
455                 if (errno == EBADF)
456                         CRASH;
457                 return &null_frame;
458         }
459         if (res < hdrlen) {
460                 ast_log(LOG_WARNING, "RTP Read too short\n");
461                 return &null_frame;
462         }
463
464         /* Ignore if the other side hasn't been given an address
465            yet.  */
466         if (!rtp->them.sin_addr.s_addr || !rtp->them.sin_port)
467                 return &null_frame;
468
469         if (rtp->nat) {
470                 /* Send to whoever sent to us */
471                 if ((rtp->them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
472                     (rtp->them.sin_port != sin.sin_port)) {
473                         memcpy(&rtp->them, &sin, sizeof(rtp->them));
474                         rtp->rxseqno = 0;
475                         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));
476                 }
477         }
478
479         /* Get fields */
480         seqno = ntohl(rtpheader[0]);
481
482         /* Check RTP version */
483         version = (seqno & 0xC0000000) >> 30;
484         if (version != 2)
485                 return &null_frame;
486         
487         payloadtype = (seqno & 0x7f0000) >> 16;
488         mark = seqno & (1 << 23);
489         ext = seqno & (1 << 28);
490         seqno &= 0xffff;
491         timestamp = ntohl(rtpheader[1]);
492         if (ext) {
493                 /* RTP Extension present */
494                 hdrlen += 4;
495                 hdrlen += (ntohl(rtpheader[3]) & 0xffff) << 2;
496         }
497
498         if (res < hdrlen) {
499                 ast_log(LOG_WARNING, "RTP Read too short (%d, expecting %d)\n", res, hdrlen);
500                 return &null_frame;
501         }
502
503         if(rtp_debug_test_addr(&sin))
504                 ast_verbose("Got RTP packet from %s:%d (type %d, seq %d, ts %d, len %d)\n"
505                         , ast_inet_ntoa(iabuf, sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
506
507         rtpPT = ast_rtp_lookup_pt(rtp, payloadtype);
508         if (!rtpPT.isAstFormat) {
509                 /* This is special in-band data that's not one of our codecs */
510                 if (rtpPT.code == AST_RTP_DTMF) {
511                         /* It's special -- rfc2833 process it */
512                         if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
513                                 f = process_rfc2833(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
514                                 rtp->lasteventseqn = seqno;
515                         } else 
516                                 f = NULL;
517                         if (f) 
518                                 return f; 
519                         else 
520                                 return &null_frame;
521                 } else if (rtpPT.code == AST_RTP_CISCO_DTMF) {
522                         /* It's really special -- process it the Cisco way */
523                         if (rtp->lasteventseqn <= seqno || rtp->resp == 0 || (rtp->lasteventseqn >= 65530 && seqno <= 6)) {
524                                 f = process_cisco_dtmf(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
525                                 rtp->lasteventseqn = seqno;
526                         } else 
527                                 f = NULL;
528                         if (f) 
529                                 return f; 
530                         else 
531                                 return &null_frame;
532                 } else if (rtpPT.code == AST_RTP_CN) {
533                         /* Comfort Noise */
534                         f = process_rfc3389(rtp, rtp->rawdata + AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
535                         if (f) 
536                                 return f; 
537                         else 
538                                 return &null_frame;
539                 } else {
540                         ast_log(LOG_NOTICE, "Unknown RTP codec %d received\n", payloadtype);
541                         return &null_frame;
542                 }
543         }
544         rtp->f.subclass = rtpPT.code;
545         if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO)
546                 rtp->f.frametype = AST_FRAME_VOICE;
547         else
548                 rtp->f.frametype = AST_FRAME_VIDEO;
549         rtp->lastrxformat = rtp->f.subclass;
550
551         if (!rtp->lastrxts)
552                 rtp->lastrxts = timestamp;
553
554         if (rtp->rxseqno) {
555                 for (x=rtp->rxseqno + 1; x < seqno; x++) {
556                         /* Queue empty frames */
557                         rtp->f.mallocd = 0;
558                         rtp->f.datalen = 0;
559                         rtp->f.data = NULL;
560                         rtp->f.offset = 0;
561                         rtp->f.samples = 0;
562                         rtp->f.src = "RTPMissedFrame";
563                 }
564         }
565         rtp->rxseqno = seqno;
566
567         if (rtp->dtmfcount) {
568 #if 0
569                 printf("dtmfcount was %d\n", rtp->dtmfcount);
570 #endif          
571                 rtp->dtmfcount -= (timestamp - rtp->lastrxts);
572                 if (rtp->dtmfcount < 0)
573                         rtp->dtmfcount = 0;
574 #if 0
575                 if (dtmftimeout != rtp->dtmfcount)
576                         printf("dtmfcount is %d\n", rtp->dtmfcount);
577 #endif
578         }
579         rtp->lastrxts = timestamp;
580
581         /* Send any pending DTMF */
582         if (rtp->resp && !rtp->dtmfcount) {
583                 if (option_debug)
584                         ast_log(LOG_DEBUG, "Sending pending DTMF\n");
585                 return send_dtmf(rtp);
586         }
587         rtp->f.mallocd = 0;
588         rtp->f.datalen = res - hdrlen;
589         rtp->f.data = rtp->rawdata + hdrlen + AST_FRIENDLY_OFFSET;
590         rtp->f.offset = hdrlen + AST_FRIENDLY_OFFSET;
591         if (rtp->f.subclass < AST_FORMAT_MAX_AUDIO) {
592                 switch(rtp->f.subclass) {
593                 case AST_FORMAT_ULAW:
594                 case AST_FORMAT_ALAW:
595                         rtp->f.samples = rtp->f.datalen;
596                         break;
597                 case AST_FORMAT_SLINEAR:
598                         rtp->f.samples = rtp->f.datalen / 2;
599                         break;
600                 case AST_FORMAT_GSM:
601                         rtp->f.samples = 160 * (rtp->f.datalen / 33);
602                         break;
603                 case AST_FORMAT_ILBC:
604                         rtp->f.samples = 240 * (rtp->f.datalen / 50);
605                         break;
606                 case AST_FORMAT_ADPCM:
607                 case AST_FORMAT_G726:
608                         rtp->f.samples = rtp->f.datalen * 2;
609                         break;
610                 case AST_FORMAT_G729A:
611                         rtp->f.samples = rtp->f.datalen * 8;
612                         break;
613                 case AST_FORMAT_G723_1:
614                         rtp->f.samples = g723_samples(rtp->f.data, rtp->f.datalen);
615                         break;
616                 case AST_FORMAT_SPEEX:
617                         /* assumes that the RTP packet contained one Speex frame */
618                         rtp->f.samples = 160;
619                         break;
620                 case AST_FORMAT_LPC10:
621                         rtp->f.samples = 22 * 8;
622                         rtp->f.samples += (((char *)(rtp->f.data))[7] & 0x1) * 8;
623                         break;
624                 default:
625                         ast_log(LOG_NOTICE, "Unable to calculate samples for format %s\n", ast_getformatname(rtp->f.subclass));
626                         break;
627                 }
628                 calc_rxstamp(&rtp->f.delivery, rtp, timestamp, mark);
629         } else {
630                 /* Video -- samples is # of samples vs. 90000 */
631                 if (!rtp->lastividtimestamp)
632                         rtp->lastividtimestamp = timestamp;
633                 rtp->f.samples = timestamp - rtp->lastividtimestamp;
634                 rtp->lastividtimestamp = timestamp;
635                 rtp->f.delivery.tv_sec = 0;
636                 rtp->f.delivery.tv_usec = 0;
637                 if (mark)
638                         rtp->f.subclass |= 0x1;
639                 
640         }
641         rtp->f.src = "RTP";
642         return &rtp->f;
643 }
644
645 /* The following array defines the MIME Media type (and subtype) for each
646    of our codecs, or RTP-specific data type. */
647 static struct {
648   struct rtpPayloadType payloadType;
649   char* type;
650   char* subtype;
651 } mimeTypes[] = {
652   {{1, AST_FORMAT_G723_1}, "audio", "G723"},
653   {{1, AST_FORMAT_GSM}, "audio", "GSM"},
654   {{1, AST_FORMAT_ULAW}, "audio", "PCMU"},
655   {{1, AST_FORMAT_ALAW}, "audio", "PCMA"},
656   {{1, AST_FORMAT_G726}, "audio", "G726-32"},
657   {{1, AST_FORMAT_ADPCM}, "audio", "DVI4"},
658   {{1, AST_FORMAT_SLINEAR}, "audio", "L16"},
659   {{1, AST_FORMAT_LPC10}, "audio", "LPC"},
660   {{1, AST_FORMAT_G729A}, "audio", "G729"},
661   {{1, AST_FORMAT_SPEEX}, "audio", "speex"},
662   {{1, AST_FORMAT_ILBC}, "audio", "iLBC"},
663   {{0, AST_RTP_DTMF}, "audio", "telephone-event"},
664   {{0, AST_RTP_CISCO_DTMF}, "audio", "cisco-telephone-event"},
665   {{0, AST_RTP_CN}, "audio", "CN"},
666   {{1, AST_FORMAT_JPEG}, "video", "JPEG"},
667   {{1, AST_FORMAT_PNG}, "video", "PNG"},
668   {{1, AST_FORMAT_H261}, "video", "H261"},
669   {{1, AST_FORMAT_H263}, "video", "H263"},
670 };
671
672 /* Static (i.e., well-known) RTP payload types for our "AST_FORMAT..."s:
673    also, our own choices for dynamic payload types.  This is our master
674    table for transmission */
675 static struct rtpPayloadType static_RTP_PT[MAX_RTP_PT] = {
676   [0] = {1, AST_FORMAT_ULAW},
677   [2] = {1, AST_FORMAT_G726}, /* Technically this is G.721, but if Cisco can do it, so can we... */
678   [3] = {1, AST_FORMAT_GSM},
679   [4] = {1, AST_FORMAT_G723_1},
680   [5] = {1, AST_FORMAT_ADPCM}, /* 8 kHz */
681   [6] = {1, AST_FORMAT_ADPCM}, /* 16 kHz */
682   [7] = {1, AST_FORMAT_LPC10},
683   [8] = {1, AST_FORMAT_ALAW},
684   [10] = {1, AST_FORMAT_SLINEAR}, /* 2 channels */
685   [11] = {1, AST_FORMAT_SLINEAR}, /* 1 channel */
686   [13] = {0, AST_RTP_CN},
687   [16] = {1, AST_FORMAT_ADPCM}, /* 11.025 kHz */
688   [17] = {1, AST_FORMAT_ADPCM}, /* 22.050 kHz */
689   [18] = {1, AST_FORMAT_G729A},
690   [19] = {0, AST_RTP_CN},               /* Also used for CN */
691   [26] = {1, AST_FORMAT_JPEG},
692   [31] = {1, AST_FORMAT_H261},
693   [34] = {1, AST_FORMAT_H263},
694   [97] = {1, AST_FORMAT_ILBC},
695   [101] = {0, AST_RTP_DTMF},
696   [110] = {1, AST_FORMAT_SPEEX},
697   [121] = {0, AST_RTP_CISCO_DTMF}, /* Must be type 121 */
698 };
699
700 void ast_rtp_pt_clear(struct ast_rtp* rtp) 
701 {
702         int i;
703
704         for (i = 0; i < MAX_RTP_PT; ++i) {
705                 rtp->current_RTP_PT[i].isAstFormat = 0;
706                 rtp->current_RTP_PT[i].code = 0;
707         }
708
709         rtp->rtp_lookup_code_cache_isAstFormat = 0;
710         rtp->rtp_lookup_code_cache_code = 0;
711         rtp->rtp_lookup_code_cache_result = 0;
712 }
713
714 void ast_rtp_pt_default(struct ast_rtp* rtp) 
715 {
716         int i;
717
718         /* Initialize to default payload types */
719         for (i = 0; i < MAX_RTP_PT; ++i) {
720                 rtp->current_RTP_PT[i].isAstFormat = static_RTP_PT[i].isAstFormat;
721                 rtp->current_RTP_PT[i].code = static_RTP_PT[i].code;
722         }
723
724         rtp->rtp_lookup_code_cache_isAstFormat = 0;
725         rtp->rtp_lookup_code_cache_code = 0;
726         rtp->rtp_lookup_code_cache_result = 0;
727 }
728
729 /* Make a note of a RTP payload type that was seen in a SDP "m=" line. */
730 /* By default, use the well-known value for this type (although it may */
731 /* still be set to a different value by a subsequent "a=rtpmap:" line): */
732 void ast_rtp_set_m_type(struct ast_rtp* rtp, int pt) {
733         if (pt < 0 || pt > MAX_RTP_PT) 
734                 return; /* bogus payload type */
735
736         if (static_RTP_PT[pt].code != 0) {
737                 rtp->current_RTP_PT[pt] = static_RTP_PT[pt];
738         }
739
740
741 /* Make a note of a RTP payload type (with MIME type) that was seen in */
742 /* a SDP "a=rtpmap:" line. */
743 void ast_rtp_set_rtpmap_type(struct ast_rtp* rtp, int pt,
744                          char* mimeType, char* mimeSubtype) {
745         int i;
746
747         if (pt < 0 || pt > MAX_RTP_PT) 
748                         return; /* bogus payload type */
749
750         for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
751                 if (strcasecmp(mimeSubtype, mimeTypes[i].subtype) == 0 &&
752                      strcasecmp(mimeType, mimeTypes[i].type) == 0) {
753                         rtp->current_RTP_PT[pt] = mimeTypes[i].payloadType;
754                 return;
755                 }
756         }
757
758
759 /* Return the union of all of the codecs that were set by rtp_set...() calls */
760 /* They're returned as two distinct sets: AST_FORMATs, and AST_RTPs */
761 void ast_rtp_get_current_formats(struct ast_rtp* rtp,
762                              int* astFormats, int* nonAstFormats) {
763         int pt;
764
765         *astFormats = *nonAstFormats = 0;
766         for (pt = 0; pt < MAX_RTP_PT; ++pt) {
767                 if (rtp->current_RTP_PT[pt].isAstFormat) {
768                         *astFormats |= rtp->current_RTP_PT[pt].code;
769                 } else {
770                         *nonAstFormats |= rtp->current_RTP_PT[pt].code;
771                 }
772         }
773 }
774
775 void ast_rtp_offered_from_local(struct ast_rtp* rtp, int local) {
776         if (rtp)
777                 rtp->rtp_offered_from_local = local;
778         else
779                 ast_log(LOG_WARNING, "rtp structure is null\n");
780 }
781
782 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp, int pt) 
783 {
784         struct rtpPayloadType result;
785
786         result.isAstFormat = result.code = 0;
787         if (pt < 0 || pt > MAX_RTP_PT) 
788                 return result; /* bogus payload type */
789
790         /* Start with the negotiated codecs */
791         if (!rtp->rtp_offered_from_local)
792                 result = rtp->current_RTP_PT[pt];
793
794         /* If it doesn't exist, check our static RTP type list, just in case */
795         if (!result.code) 
796                 result = static_RTP_PT[pt];
797         return result;
798 }
799
800 /* Looks up an RTP code out of our *static* outbound list */
801 int ast_rtp_lookup_code(struct ast_rtp* rtp, int isAstFormat, int code) {
802
803         int pt;
804
805         if (isAstFormat == rtp->rtp_lookup_code_cache_isAstFormat &&
806                 code == rtp->rtp_lookup_code_cache_code) {
807
808                 /* Use our cached mapping, to avoid the overhead of the loop below */
809                 return rtp->rtp_lookup_code_cache_result;
810         }
811
812         /* Check the dynamic list first */
813         for (pt = 0; pt < MAX_RTP_PT; ++pt) {
814                 if (rtp->current_RTP_PT[pt].code == code && rtp->current_RTP_PT[pt].isAstFormat == isAstFormat) {
815                         rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
816                         rtp->rtp_lookup_code_cache_code = code;
817                         rtp->rtp_lookup_code_cache_result = pt;
818                         return pt;
819                 }
820         }
821
822         /* Then the static list */
823         for (pt = 0; pt < MAX_RTP_PT; ++pt) {
824                 if (static_RTP_PT[pt].code == code && static_RTP_PT[pt].isAstFormat == isAstFormat) {
825                         rtp->rtp_lookup_code_cache_isAstFormat = isAstFormat;
826                         rtp->rtp_lookup_code_cache_code = code;
827                         rtp->rtp_lookup_code_cache_result = pt;
828                         return pt;
829                 }
830         }
831         return -1;
832 }
833
834 char* ast_rtp_lookup_mime_subtype(int isAstFormat, int code) {
835
836         int i;
837
838         for (i = 0; i < sizeof mimeTypes/sizeof mimeTypes[0]; ++i) {
839         if (mimeTypes[i].payloadType.code == code && mimeTypes[i].payloadType.isAstFormat == isAstFormat) {
840                 return mimeTypes[i].subtype;
841                 }
842         }
843         return "";
844 }
845
846 static int rtp_socket(void)
847 {
848         int s;
849         long flags;
850         s = socket(AF_INET, SOCK_DGRAM, 0);
851         if (s > -1) {
852                 flags = fcntl(s, F_GETFL);
853                 fcntl(s, F_SETFL, flags | O_NONBLOCK);
854 #ifdef SO_NO_CHECK
855                 if (checksums) {
856                         setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &checksums, sizeof(checksums));
857                 }
858 #endif
859         }
860         return s;
861 }
862
863 static struct ast_rtcp *ast_rtcp_new(void)
864 {
865         struct ast_rtcp *rtcp;
866         rtcp = malloc(sizeof(struct ast_rtcp));
867         if (!rtcp)
868                 return NULL;
869         memset(rtcp, 0, sizeof(struct ast_rtcp));
870         rtcp->s = rtp_socket();
871         rtcp->us.sin_family = AF_INET;
872         if (rtcp->s < 0) {
873                 free(rtcp);
874                 ast_log(LOG_WARNING, "Unable to allocate socket: %s\n", strerror(errno));
875                 return NULL;
876         }
877         return rtcp;
878 }
879
880 struct ast_rtp *ast_rtp_new_with_bindaddr(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode, struct in_addr addr)
881 {
882         struct ast_rtp *rtp;
883         int x;
884         int first;
885         int startplace;
886         rtp = malloc(sizeof(struct ast_rtp));
887         if (!rtp)
888                 return NULL;
889         memset(rtp, 0, sizeof(struct ast_rtp));
890         rtp->them.sin_family = AF_INET;
891         rtp->us.sin_family = AF_INET;
892         rtp->s = rtp_socket();
893         rtp->ssrc = rand();
894         rtp->seqno = rand() & 0xffff;
895         if (rtp->s < 0) {
896                 free(rtp);
897                 ast_log(LOG_ERROR, "Unable to allocate socket: %s\n", strerror(errno));
898                 return NULL;
899         }
900         if (sched && rtcpenable) {
901                 rtp->sched = sched;
902                 rtp->rtcp = ast_rtcp_new();
903         }
904         /* Find us a place */
905         x = (rand() % (rtpend-rtpstart)) + rtpstart;
906         x = x & ~1;
907         startplace = x;
908         for (;;) {
909                 /* Must be an even port number by RTP spec */
910                 rtp->us.sin_port = htons(x);
911                 rtp->us.sin_addr = addr;
912                 if (rtp->rtcp)
913                         rtp->rtcp->us.sin_port = htons(x + 1);
914                 if (!(first = bind(rtp->s, (struct sockaddr *)&rtp->us, sizeof(rtp->us))) &&
915                         (!rtp->rtcp || !bind(rtp->rtcp->s, (struct sockaddr *)&rtp->rtcp->us, sizeof(rtp->rtcp->us))))
916                         break;
917                 if (!first) {
918                         /* Primary bind succeeded! Gotta recreate it */
919                         close(rtp->s);
920                         rtp->s = rtp_socket();
921                 }
922                 if (errno != EADDRINUSE) {
923                         ast_log(LOG_ERROR, "Unexpected bind error: %s\n", strerror(errno));
924                         close(rtp->s);
925                         if (rtp->rtcp) {
926                                 close(rtp->rtcp->s);
927                                 free(rtp->rtcp);
928                         }
929                         free(rtp);
930                         return NULL;
931                 }
932                 x += 2;
933                 if (x > rtpend)
934                         x = (rtpstart + 1) & ~1;
935                 if (x == startplace) {
936                         ast_log(LOG_ERROR, "No RTP ports remaining\n");
937                         close(rtp->s);
938                         if (rtp->rtcp) {
939                                 close(rtp->rtcp->s);
940                                 free(rtp->rtcp);
941                         }
942                         free(rtp);
943                         return NULL;
944                 }
945         }
946         if (io && sched && callbackmode) {
947                 /* Operate this one in a callback mode */
948                 rtp->sched = sched;
949                 rtp->io = io;
950                 rtp->ioid = ast_io_add(rtp->io, rtp->s, rtpread, AST_IO_IN, rtp);
951         }
952         ast_rtp_pt_default(rtp);
953         return rtp;
954 }
955
956 struct ast_rtp *ast_rtp_new(struct sched_context *sched, struct io_context *io, int rtcpenable, int callbackmode)
957 {
958         struct in_addr ia;
959
960         memset(&ia, 0, sizeof(ia));
961         return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
962 }
963
964 int ast_rtp_settos(struct ast_rtp *rtp, int tos)
965 {
966         int res;
967
968         if ((res = setsockopt(rtp->s, IPPROTO_IP, IP_TOS, &tos, sizeof(tos)))) 
969                 ast_log(LOG_WARNING, "Unable to set TOS to %d\n", tos);
970         return res;
971 }
972
973 void ast_rtp_set_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
974 {
975         rtp->them.sin_port = them->sin_port;
976         rtp->them.sin_addr = them->sin_addr;
977         if (rtp->rtcp) {
978                 rtp->rtcp->them.sin_port = htons(ntohs(them->sin_port) + 1);
979                 rtp->rtcp->them.sin_addr = them->sin_addr;
980         }
981         rtp->rxseqno = 0;
982 }
983
984 void ast_rtp_get_peer(struct ast_rtp *rtp, struct sockaddr_in *them)
985 {
986         them->sin_family = AF_INET;
987         them->sin_port = rtp->them.sin_port;
988         them->sin_addr = rtp->them.sin_addr;
989 }
990
991 void ast_rtp_get_us(struct ast_rtp *rtp, struct sockaddr_in *us)
992 {
993         memcpy(us, &rtp->us, sizeof(rtp->us));
994 }
995
996 void ast_rtp_stop(struct ast_rtp *rtp)
997 {
998         memset(&rtp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
999         memset(&rtp->them.sin_port, 0, sizeof(rtp->them.sin_port));
1000         if (rtp->rtcp) {
1001                 memset(&rtp->rtcp->them.sin_addr, 0, sizeof(rtp->them.sin_addr));
1002                 memset(&rtp->rtcp->them.sin_port, 0, sizeof(rtp->them.sin_port));
1003         }
1004 }
1005
1006 void ast_rtp_reset(struct ast_rtp *rtp)
1007 {
1008         memset(&rtp->rxcore, 0, sizeof(rtp->rxcore));
1009         memset(&rtp->txcore, 0, sizeof(rtp->txcore));
1010         memset(&rtp->dtmfmute, 0, sizeof(rtp->dtmfmute));
1011         rtp->lastts = 0;
1012         rtp->lastrxts = 0;
1013         rtp->lastividtimestamp = 0;
1014         rtp->lastovidtimestamp = 0;
1015         rtp->lasteventseqn = 0;
1016         rtp->lasttxformat = 0;
1017         rtp->lastrxformat = 0;
1018         rtp->dtmfcount = 0;
1019         rtp->dtmfduration = 0;
1020         rtp->seqno = 0;
1021         rtp->rxseqno = 0;
1022 }
1023
1024 void ast_rtp_destroy(struct ast_rtp *rtp)
1025 {
1026         if (rtp->smoother)
1027                 ast_smoother_free(rtp->smoother);
1028         if (rtp->ioid)
1029                 ast_io_remove(rtp->io, rtp->ioid);
1030         if (rtp->s > -1)
1031                 close(rtp->s);
1032         if (rtp->rtcp) {
1033                 close(rtp->rtcp->s);
1034                 free(rtp->rtcp);
1035         }
1036         free(rtp);
1037 }
1038
1039 static unsigned int calc_txstamp(struct ast_rtp *rtp, struct timeval *delivery)
1040 {
1041         struct timeval now;
1042         unsigned int ms;
1043         if (!rtp->txcore.tv_sec && !rtp->txcore.tv_usec) {
1044                 gettimeofday(&rtp->txcore, NULL);
1045                 /* Round to 20ms for nice, pretty timestamps */
1046                 rtp->txcore.tv_usec -= rtp->txcore.tv_usec % 20000;
1047         }
1048         if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
1049                 /* Use previous txcore */
1050                 ms = (delivery->tv_sec - rtp->txcore.tv_sec) * 1000;
1051                 ms += (1000000 + delivery->tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
1052                 rtp->txcore.tv_sec = delivery->tv_sec;
1053                 rtp->txcore.tv_usec = delivery->tv_usec;
1054         } else {
1055                 gettimeofday(&now, NULL);
1056                 ms = (now.tv_sec - rtp->txcore.tv_sec) * 1000;
1057                 ms += (1000000 + now.tv_usec - rtp->txcore.tv_usec) / 1000 - 1000;
1058                 /* Use what we just got for next time */
1059                 rtp->txcore.tv_sec = now.tv_sec;
1060                 rtp->txcore.tv_usec = now.tv_usec;
1061         }
1062         return ms;
1063 }
1064
1065 int ast_rtp_senddigit(struct ast_rtp *rtp, char digit)
1066 {
1067         unsigned int *rtpheader;
1068         int hdrlen = 12;
1069         int res;
1070         int x;
1071         int payload;
1072         char data[256];
1073         char iabuf[INET_ADDRSTRLEN];
1074
1075         if ((digit <= '9') && (digit >= '0'))
1076                 digit -= '0';
1077         else if (digit == '*')
1078                 digit = 10;
1079         else if (digit == '#')
1080                 digit = 11;
1081         else if ((digit >= 'A') && (digit <= 'D')) 
1082                 digit = digit - 'A' + 12;
1083         else if ((digit >= 'a') && (digit <= 'd')) 
1084                 digit = digit - 'a' + 12;
1085         else {
1086                 ast_log(LOG_WARNING, "Don't know how to represent '%c'\n", digit);
1087                 return -1;
1088         }
1089         payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_DTMF);
1090
1091         /* If we have no peer, return immediately */    
1092         if (!rtp->them.sin_addr.s_addr)
1093                 return 0;
1094
1095         gettimeofday(&rtp->dtmfmute, NULL);
1096         rtp->dtmfmute.tv_usec += (500 * 1000);
1097         if (rtp->dtmfmute.tv_usec > 1000000) {
1098                 rtp->dtmfmute.tv_usec -= 1000000;
1099                 rtp->dtmfmute.tv_sec += 1;
1100         }
1101         
1102         /* Get a pointer to the header */
1103         rtpheader = (unsigned int *)data;
1104         rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
1105         rtpheader[1] = htonl(rtp->lastts);
1106         rtpheader[2] = htonl(rtp->ssrc); 
1107         rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
1108         for (x=0;x<6;x++) {
1109                 if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
1110                         res = sendto(rtp->s, (void *)rtpheader, hdrlen + 4, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
1111                         if (res <0) 
1112                                 ast_log(LOG_ERROR, "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));
1113                         if(rtp_debug_test_addr(&rtp->them))
1114                                 ast_verbose("Sent RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n"
1115                                                 , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen);              
1116                    
1117                 }
1118                 if (x == 2) {
1119                         /* Clear marker bit and increment seqno */
1120                         rtpheader[0] = htonl((2 << 30)  | (payload << 16) | (rtp->seqno++));
1121                         /* Make duration 800 (100ms) */
1122                         rtpheader[3] |= htonl((800));
1123                         /* Set the End bit for the last 3 */
1124                         rtpheader[3] |= htonl((1 << 23));
1125                 } else if ( x < 5) {
1126                         rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno++));
1127                 }
1128         }
1129         return 0;
1130 }
1131
1132 int ast_rtp_sendcng(struct ast_rtp *rtp, int level)
1133 {
1134         unsigned int *rtpheader;
1135         int hdrlen = 12;
1136         int res;
1137         int payload;
1138         char data[256];
1139         char iabuf[INET_ADDRSTRLEN];
1140         level = 127 - (level & 0x7f);
1141         payload = ast_rtp_lookup_code(rtp, 0, AST_RTP_CN);
1142
1143         /* If we have no peer, return immediately */    
1144         if (!rtp->them.sin_addr.s_addr)
1145                 return 0;
1146
1147         gettimeofday(&rtp->dtmfmute, NULL);
1148         rtp->dtmfmute.tv_usec += (500 * 1000);
1149         if (rtp->dtmfmute.tv_usec > 1000000) {
1150                 rtp->dtmfmute.tv_usec -= 1000000;
1151                 rtp->dtmfmute.tv_sec += 1;
1152         }
1153         
1154         /* Get a pointer to the header */
1155         rtpheader = (unsigned int *)data;
1156         rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->seqno++));
1157         rtpheader[1] = htonl(rtp->lastts);
1158         rtpheader[2] = htonl(rtp->ssrc); 
1159         data[12] = level;
1160         if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
1161                 res = sendto(rtp->s, (void *)rtpheader, hdrlen + 1, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
1162                 if (res <0) 
1163                         ast_log(LOG_ERROR, "RTP Comfort Noise Transmission error to %s:%d: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), strerror(errno));
1164                 if(rtp_debug_test_addr(&rtp->them))
1165                         ast_verbose("Sent Comfort Noise RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n"
1166                                         , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), payload, rtp->seqno, rtp->lastts,res - hdrlen);              
1167                    
1168         }
1169         return 0;
1170 }
1171
1172 #ifdef SOLARIS
1173 static void put_uint32(unsigned char *buf, int i)
1174 {
1175         unsigned char *c = (unsigned char *)&i;
1176
1177         buf[0] = (i>>24) & 0xff;
1178         buf[1] = (i>>16) & 0xff;
1179         buf[2] = (i>>8)  & 0xff;
1180         buf[3] = i       & 0xff;
1181 }
1182 #else
1183 #define put_uint32(p,v) ((*((unsigned int *)(p))) = (v))
1184 #endif
1185
1186 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
1187 {
1188         unsigned char *rtpheader;
1189         char iabuf[INET_ADDRSTRLEN];
1190         int hdrlen = 12;
1191         int res;
1192         int ms;
1193         int pred;
1194         int mark = 0;
1195
1196         ms = calc_txstamp(rtp, &f->delivery);
1197         /* Default prediction */
1198         if (f->subclass < AST_FORMAT_MAX_AUDIO) {
1199                 pred = rtp->lastts + ms * 8;
1200                 
1201                 switch(f->subclass) {
1202                 case AST_FORMAT_ULAW:
1203                 case AST_FORMAT_ALAW:
1204                         /* If we're within +/- 20ms from when where we
1205                            predict we should be, use that */
1206                         pred = rtp->lastts + f->datalen;
1207                         break;
1208                 case AST_FORMAT_ADPCM:
1209                 case AST_FORMAT_G726:
1210                         /* If we're within +/- 20ms from when where we
1211                            predict we should be, use that */
1212                         pred = rtp->lastts + f->datalen * 2;
1213                         break;
1214                 case AST_FORMAT_G729A:
1215                         pred = rtp->lastts + f->datalen * 8;
1216                         break;
1217                 case AST_FORMAT_GSM:
1218                         pred = rtp->lastts + (f->datalen * 160 / 33);
1219                         break;
1220                 case AST_FORMAT_ILBC:
1221                         pred = rtp->lastts + (f->datalen * 240 / 50);
1222                         break;
1223                 case AST_FORMAT_G723_1:
1224                         pred = rtp->lastts + g723_samples(f->data, f->datalen);
1225                         break;
1226                 case AST_FORMAT_SPEEX:
1227                     pred = rtp->lastts + 160;
1228                         /* assumes that the RTP packet contains one Speex frame */
1229                         break;
1230                 case AST_FORMAT_LPC10:
1231                         /* assumes that the RTP packet contains one LPC10 frame */
1232                         pred = rtp->lastts + 22 * 8;
1233                         pred += (((char *)(f->data))[7] & 0x1) * 8;
1234                         break;
1235                 default:
1236                         ast_log(LOG_WARNING, "Not sure about timestamp format for codec format %s\n", ast_getformatname(f->subclass));
1237                 }
1238                 /* Re-calculate last TS */
1239                 rtp->lastts = rtp->lastts + ms * 8;
1240                 if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
1241                         /* If this isn't an absolute delivery time, Check if it is close to our prediction, 
1242                            and if so, go with our prediction */
1243                         if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
1244                                 rtp->lastts = pred;
1245                         else {
1246                                 if (option_debug > 2)
1247                                         ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
1248                                 mark = 1;
1249                         }
1250                 }
1251         } else {
1252                 mark = f->subclass & 0x1;
1253                 pred = rtp->lastovidtimestamp + f->samples;
1254                 /* Re-calculate last TS */
1255                 rtp->lastts = rtp->lastts + ms * 90;
1256                 /* If it's close to our prediction, go for it */
1257                 if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
1258                         if (abs(rtp->lastts - pred) < 7200) {
1259                                 rtp->lastts = pred;
1260                                 rtp->lastovidtimestamp += f->samples;
1261                         } else {
1262                                 if (option_debug > 2)
1263                                         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);
1264                                 rtp->lastovidtimestamp = rtp->lastts;
1265                         }
1266                 }
1267         }
1268         /* Get a pointer to the header */
1269         rtpheader = (unsigned char *)(f->data - hdrlen);
1270
1271         put_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23)));
1272         put_uint32(rtpheader + 4, htonl(rtp->lastts));
1273         put_uint32(rtpheader + 8, htonl(rtp->ssrc)); 
1274
1275         rtp->seqno++;
1276
1277         if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
1278                 res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
1279                 if (res <0) 
1280                         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));
1281                 if(rtp_debug_test_addr(&rtp->them))
1282                         ast_verbose("Sent RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n"
1283                                         , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen);
1284         }
1285         return 0;
1286 }
1287
1288 int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
1289 {
1290         struct ast_frame *f;
1291         int codec;
1292         int hdrlen = 12;
1293         int subclass;
1294         
1295
1296         /* If we have no peer, return immediately */    
1297         if (!rtp->them.sin_addr.s_addr)
1298                 return 0;
1299
1300         /* If there is no data length, return immediately */
1301         if (!_f->datalen) 
1302                 return 0;
1303         
1304         /* Make sure we have enough space for RTP header */
1305         if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) {
1306                 ast_log(LOG_WARNING, "RTP can only send voice\n");
1307                 return -1;
1308         }
1309
1310         subclass = _f->subclass;
1311         if (_f->frametype == AST_FRAME_VIDEO)
1312                 subclass &= ~0x1;
1313
1314         codec = ast_rtp_lookup_code(rtp, 1, subclass);
1315         if (codec < 0) {
1316                 ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass));
1317                 return -1;
1318         }
1319
1320         if (rtp->lasttxformat != subclass) {
1321                 /* New format, reset the smoother */
1322                 if (option_debug)
1323                         ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
1324                 rtp->lasttxformat = subclass;
1325                 if (rtp->smoother)
1326                         ast_smoother_free(rtp->smoother);
1327                 rtp->smoother = NULL;
1328         }
1329
1330
1331         switch(subclass) {
1332         case AST_FORMAT_ULAW:
1333         case AST_FORMAT_ALAW:
1334                 if (!rtp->smoother) {
1335                         rtp->smoother = ast_smoother_new(160);
1336                 }
1337                 if (!rtp->smoother) {
1338                         ast_log(LOG_WARNING, "Unable to create smoother :(\n");
1339                         return -1;
1340                 }
1341                 ast_smoother_feed(rtp->smoother, _f);
1342                 
1343                 while((f = ast_smoother_read(rtp->smoother)))
1344                         ast_rtp_raw_write(rtp, f, codec);
1345                 break;
1346         case AST_FORMAT_ADPCM:
1347         case AST_FORMAT_G726:
1348                 if (!rtp->smoother) {
1349                         rtp->smoother = ast_smoother_new(80);
1350                 }
1351                 if (!rtp->smoother) {
1352                         ast_log(LOG_WARNING, "Unable to create smoother :(\n");
1353                         return -1;
1354                 }
1355                 ast_smoother_feed(rtp->smoother, _f);
1356                 
1357                 while((f = ast_smoother_read(rtp->smoother)))
1358                         ast_rtp_raw_write(rtp, f, codec);
1359                 break;
1360         case AST_FORMAT_G729A:
1361                 if (!rtp->smoother) {
1362                         rtp->smoother = ast_smoother_new(20);
1363                         if (rtp->smoother)
1364                                 ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_G729);
1365                 }
1366                 if (!rtp->smoother) {
1367                         ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n");
1368                         return -1;
1369                 }
1370                 ast_smoother_feed(rtp->smoother, _f);
1371                 
1372                 while((f = ast_smoother_read(rtp->smoother)))
1373                         ast_rtp_raw_write(rtp, f, codec);
1374                 break;
1375         case AST_FORMAT_GSM:
1376                 if (!rtp->smoother) {
1377                         rtp->smoother = ast_smoother_new(33);
1378                 }
1379                 if (!rtp->smoother) {
1380                         ast_log(LOG_WARNING, "Unable to create GSM smoother :(\n");
1381                         return -1;
1382                 }
1383                 ast_smoother_feed(rtp->smoother, _f);
1384                 while((f = ast_smoother_read(rtp->smoother)))
1385                         ast_rtp_raw_write(rtp, f, codec);
1386                 break;
1387         case AST_FORMAT_ILBC:
1388                 if (!rtp->smoother) {
1389                         rtp->smoother = ast_smoother_new(50);
1390                 }
1391                 if (!rtp->smoother) {
1392                         ast_log(LOG_WARNING, "Unable to create ILBC smoother :(\n");
1393                         return -1;
1394                 }
1395                 ast_smoother_feed(rtp->smoother, _f);
1396                 while((f = ast_smoother_read(rtp->smoother)))
1397                         ast_rtp_raw_write(rtp, f, codec);
1398                 break;
1399         default:        
1400                 ast_log(LOG_WARNING, "Not sure about sending format %s packets\n", ast_getformatname(subclass));
1401                 /* fall through to... */
1402         case AST_FORMAT_H261:
1403         case AST_FORMAT_H263:
1404         case AST_FORMAT_G723_1:
1405         case AST_FORMAT_LPC10:
1406         case AST_FORMAT_SPEEX:
1407                 /* Don't buffer outgoing frames; send them one-per-packet: */
1408                 if (_f->offset < hdrlen) {
1409                         f = ast_frdup(_f);
1410                 } else {
1411                         f = _f;
1412                 }
1413                 ast_rtp_raw_write(rtp, f, codec);
1414         }
1415                 
1416         return 0;
1417 }
1418
1419 void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto)
1420 {
1421         struct ast_rtp_protocol *cur, *prev;
1422
1423         cur = protos;
1424         prev = NULL;
1425         while(cur) {
1426                 if (cur == proto) {
1427                         if (prev)
1428                                 prev->next = proto->next;
1429                         else
1430                                 protos = proto->next;
1431                         return;
1432                 }
1433                 prev = cur;
1434                 cur = cur->next;
1435         }
1436 }
1437
1438 int ast_rtp_proto_register(struct ast_rtp_protocol *proto)
1439 {
1440         struct ast_rtp_protocol *cur;
1441         cur = protos;
1442         while(cur) {
1443                 if (cur->type == proto->type) {
1444                         ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
1445                         return -1;
1446                 }
1447                 cur = cur->next;
1448         }
1449         proto->next = protos;
1450         protos = proto;
1451         return 0;
1452 }
1453
1454 static struct ast_rtp_protocol *get_proto(struct ast_channel *chan)
1455 {
1456         struct ast_rtp_protocol *cur;
1457         cur = protos;
1458         while(cur) {
1459                 if (cur->type == chan->type) {
1460                         return cur;
1461                 }
1462                 cur = cur->next;
1463         }
1464         return NULL;
1465 }
1466
1467 int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
1468 {
1469         struct ast_frame *f;
1470         struct ast_channel *who, *cs[3];
1471         struct ast_rtp *p0, *p1;
1472         struct ast_rtp *vp0, *vp1;
1473         struct ast_rtp_protocol *pr0, *pr1;
1474         struct sockaddr_in ac0, ac1;
1475         struct sockaddr_in vac0, vac1;
1476         struct sockaddr_in t0, t1;
1477         struct sockaddr_in vt0, vt1;
1478         char iabuf[INET_ADDRSTRLEN];
1479         
1480         void *pvt0, *pvt1;
1481         int to;
1482         int codec0,codec1, oldcodec0, oldcodec1;
1483         
1484         memset(&vt0, 0, sizeof(vt0));
1485         memset(&vt1, 0, sizeof(vt1));
1486         memset(&vac0, 0, sizeof(vac0));
1487         memset(&vac1, 0, sizeof(vac1));
1488
1489         /* if need DTMF, cant native bridge */
1490         if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
1491                 return -2;
1492         ast_mutex_lock(&c0->lock);
1493         while(ast_mutex_trylock(&c1->lock)) {
1494                 ast_mutex_unlock(&c0->lock);
1495                 usleep(1);
1496                 ast_mutex_lock(&c0->lock);
1497         }
1498         pr0 = get_proto(c0);
1499         pr1 = get_proto(c1);
1500         if (!pr0) {
1501                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
1502                 ast_mutex_unlock(&c0->lock);
1503                 ast_mutex_unlock(&c1->lock);
1504                 return -1;
1505         }
1506         if (!pr1) {
1507                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
1508                 ast_mutex_unlock(&c0->lock);
1509                 ast_mutex_unlock(&c1->lock);
1510                 return -1;
1511         }
1512         pvt0 = c0->pvt->pvt;
1513         pvt1 = c1->pvt->pvt;
1514         p0 = pr0->get_rtp_info(c0);
1515         if (pr0->get_vrtp_info)
1516                 vp0 = pr0->get_vrtp_info(c0);
1517         else
1518                 vp0 = NULL;
1519         p1 = pr1->get_rtp_info(c1);
1520         if (pr1->get_vrtp_info)
1521                 vp1 = pr1->get_vrtp_info(c1);
1522         else
1523                 vp1 = NULL;
1524         if (!p0 || !p1) {
1525                 /* Somebody doesn't want to play... */
1526                 ast_mutex_unlock(&c0->lock);
1527                 ast_mutex_unlock(&c1->lock);
1528                 return -2;
1529         }
1530         if (pr0->get_codec)
1531                 codec0 = pr0->get_codec(c0);
1532         else
1533                 codec0 = 0;
1534         if (pr1->get_codec)
1535                 codec1 = pr1->get_codec(c1);
1536         else
1537                 codec1 = 0;
1538         if (pr0->get_codec && pr1->get_codec) {
1539                 /* Hey, we can't do reinvite if both parties speak diffrent codecs */
1540                 if (!(codec0 & codec1)) {
1541                         ast_log(LOG_WARNING, "codec0 = %d is not codec1 = %d, cannot native bridge.\n",codec0,codec1);
1542                         ast_mutex_unlock(&c0->lock);
1543                         ast_mutex_unlock(&c1->lock);
1544                         return -2;
1545                 }
1546         }
1547         if (pr0->set_rtp_peer(c0, p1, vp1, codec1)) 
1548                 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
1549         else {
1550                 /* Store RTP peer */
1551                 ast_rtp_get_peer(p1, &ac1);
1552                 if (vp1)
1553                         ast_rtp_get_peer(vp1, &vac1);
1554         }
1555         if (pr1->set_rtp_peer(c1, p0, vp0, codec0))
1556                 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
1557         else {
1558                 /* Store RTP peer */
1559                 ast_rtp_get_peer(p0, &ac0);
1560                 if (vp0)
1561                         ast_rtp_get_peer(vp0, &vac0);
1562         }
1563         ast_mutex_unlock(&c0->lock);
1564         ast_mutex_unlock(&c1->lock);
1565         cs[0] = c0;
1566         cs[1] = c1;
1567         cs[2] = NULL;
1568         oldcodec0 = codec0;
1569         oldcodec1 = codec1;
1570         for (;;) {
1571                 if ((c0->pvt->pvt != pvt0)  ||
1572                         (c1->pvt->pvt != pvt1) ||
1573                         (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
1574                                 ast_log(LOG_DEBUG, "Oooh, something is weird, backing out\n");
1575                                 if (c0->pvt->pvt == pvt0) {
1576                                         if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
1577                                                 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1578                                 }
1579                                 if (c1->pvt->pvt == pvt1) {
1580                                         if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
1581                                                 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1582                                 }
1583                                 /* Tell it to try again later */
1584                                 return -3;
1585                 }
1586                 to = -1;
1587                 ast_rtp_get_peer(p1, &t1);
1588                 ast_rtp_get_peer(p0, &t0);
1589                 if (pr0->get_codec)
1590                         codec0 = pr0->get_codec(c0);
1591                 if (pr1->get_codec)
1592                         codec1 = pr1->get_codec(c1);
1593                 if (vp1)
1594                         ast_rtp_get_peer(vp1, &vt1);
1595                 if (vp0)
1596                         ast_rtp_get_peer(vp0, &vt0);
1597                 if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) {
1598                         if (option_debug) {
1599                                 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
1600                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1);
1601                                 ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", 
1602                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1);
1603                                 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
1604                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
1605                                 ast_log(LOG_DEBUG, "Oooh, '%s' wasv %s:%d/(format %d)\n", 
1606                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
1607                         }
1608                         if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1)) 
1609                                 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
1610                         memcpy(&ac1, &t1, sizeof(ac1));
1611                         memcpy(&vac1, &vt1, sizeof(vac1));
1612                         oldcodec1 = codec1;
1613                 }
1614                 if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) {
1615                         if (option_debug) {
1616                                 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
1617                                         c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0);
1618                                 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
1619                                         c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
1620                         }
1621                         if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0))
1622                                 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
1623                         memcpy(&ac0, &t0, sizeof(ac0));
1624                         memcpy(&vac0, &vt0, sizeof(vac0));
1625                         oldcodec0 = codec0;
1626                 }
1627                 who = ast_waitfor_n(cs, 2, &to);
1628                 if (!who) {
1629                         if (option_debug)
1630                                 ast_log(LOG_DEBUG, "Ooh, empty read...\n");
1631                         /* check for hagnup / whentohangup */
1632                         if (ast_check_hangup(c0) || ast_check_hangup(c1))
1633                                 break;
1634                         continue;
1635                 }
1636                 f = ast_read(who);
1637                 if (!f || ((f->frametype == AST_FRAME_DTMF) &&
1638                                    (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || 
1639                                ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
1640                         *fo = f;
1641                         *rc = who;
1642                         if (option_debug)
1643                                 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
1644                         if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
1645                                 if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
1646                                         ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1647                         }
1648                         if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
1649                                 if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
1650                                         ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1651                         }
1652                         /* That's all we needed */
1653                         return 0;
1654                 } else {
1655                         if ((f->frametype == AST_FRAME_DTMF) || 
1656                                 (f->frametype == AST_FRAME_VOICE) || 
1657                                 (f->frametype == AST_FRAME_VIDEO)) {
1658                                 /* Forward voice or DTMF frames if they happen upon us */
1659                                 if (who == c0) {
1660                                         ast_write(c1, f);
1661                                 } else if (who == c1) {
1662                                         ast_write(c0, f);
1663                                 }
1664                         }
1665                         ast_frfree(f);
1666                 }
1667                 /* Swap priority not that it's a big deal at this point */
1668                 cs[2] = cs[0];
1669                 cs[0] = cs[1];
1670                 cs[1] = cs[2];
1671                 
1672         }
1673         return -1;
1674 }
1675
1676 static int rtp_do_debug_ip(int fd, int argc, char *argv[])
1677 {
1678         struct hostent *hp;
1679         struct ast_hostent ahp;
1680         char iabuf[INET_ADDRSTRLEN];
1681         int port = 0;
1682         char *p, *arg;
1683
1684         if (argc != 4)
1685                 return RESULT_SHOWUSAGE;
1686         arg = argv[3];
1687         p = strstr(arg, ":");
1688         if (p) {
1689                 *p = '\0';
1690                 p++;
1691                 port = atoi(p);
1692         }
1693         hp = ast_gethostbyname(arg, &ahp);
1694         if (hp == NULL)
1695                 return RESULT_SHOWUSAGE;
1696         rtpdebugaddr.sin_family = AF_INET;
1697         memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr));
1698         rtpdebugaddr.sin_port = htons(port);
1699         if (port == 0)
1700                 ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr));
1701         else
1702                 ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr), port);
1703         rtpdebug = 1;
1704         return RESULT_SUCCESS;
1705 }
1706
1707 static int rtp_do_debug(int fd, int argc, char *argv[])
1708 {
1709         if(argc != 2){
1710                 if(argc != 4)
1711                         return RESULT_SHOWUSAGE;
1712                 return rtp_do_debug_ip(fd, argc, argv);
1713         }
1714         rtpdebug = 1;
1715         memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr));
1716         ast_cli(fd, "RTP Debugging Enabled\n");
1717         return RESULT_SUCCESS;
1718 }
1719    
1720 static int rtp_no_debug(int fd, int argc, char *argv[])
1721 {
1722         if(argc !=3)
1723                 return RESULT_SHOWUSAGE;
1724         rtpdebug = 0;
1725         ast_cli(fd,"RTP Debugging Disabled\n");
1726         return RESULT_SUCCESS;
1727 }
1728
1729 static char debug_usage[] =
1730   "Usage: rtp debug [ip host[:port]]\n"
1731   "       Enable dumping of all RTP packets to and from host.\n";
1732
1733 static char no_debug_usage[] =
1734   "Usage: rtp no debug\n"
1735   "       Disable all RTP debugging\n";
1736
1737 static struct ast_cli_entry  cli_debug_ip =
1738 {{ "rtp", "debug", "ip", NULL } , rtp_do_debug, "Enable RTP debugging on IP", debug_usage };
1739
1740 static struct ast_cli_entry  cli_debug =
1741 {{ "rtp", "debug", NULL } , rtp_do_debug, "Enable RTP debugging", debug_usage };
1742
1743 static struct ast_cli_entry  cli_no_debug =
1744 {{ "rtp", "no", "debug", NULL } , rtp_no_debug, "Disable RTP debugging", no_debug_usage };
1745
1746 void ast_rtp_reload(void)
1747 {
1748         struct ast_config *cfg;
1749         char *s;
1750
1751         rtpstart = 5000;
1752         rtpend = 31000;
1753 #ifdef SO_NO_CHECK
1754         checksums = 1;
1755 #endif
1756         cfg = ast_config_load("rtp.conf");
1757         if (cfg) {
1758                 if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
1759                         rtpstart = atoi(s);
1760                         if (rtpstart < 1024)
1761                                 rtpstart = 1024;
1762                         if (rtpstart > 65535)
1763                                 rtpstart = 65535;
1764                 }
1765                 if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) {
1766                         rtpend = atoi(s);
1767                         if (rtpend < 1024)
1768                                 rtpend = 1024;
1769                         if (rtpend > 65535)
1770                                 rtpend = 65535;
1771                 }
1772                 if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
1773 #ifdef SO_NO_CHECK
1774                         if (ast_true(s))
1775                                 checksums = 1;
1776                         else
1777                                 checksums = 0;
1778 #else
1779                         if (ast_true(s))
1780                                 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
1781 #endif
1782                 }
1783                 ast_config_destroy(cfg);
1784         }
1785         if (rtpstart >= rtpend) {
1786                 ast_log(LOG_WARNING, "Unreasonable values for RTP start in rtp.conf/end\n");
1787                 rtpstart = 5000;
1788                 rtpend = 31000;
1789         }
1790         if (option_verbose > 1)
1791                 ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
1792         
1793 }
1794
1795 void ast_rtp_init(void)
1796 {
1797         ast_cli_register(&cli_debug);
1798         ast_cli_register(&cli_debug_ip);
1799         ast_cli_register(&cli_no_debug);
1800         ast_rtp_reload();
1801 }