Ignore invalid RTP packets (bug #3030)
[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-2004, 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<4;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 ==0) {
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 < 3) {
1126                         rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->seqno++));
1127                 }
1128         }
1129         return 0;
1130 }
1131
1132 #ifdef SOLARIS
1133 static void put_uint32(unsigned char *buf, int i)
1134 {
1135         unsigned char *c = (unsigned char *)&i;
1136
1137         buf[0] = (i>>24) & 0xff;
1138         buf[1] = (i>>16) & 0xff;
1139         buf[2] = (i>>8)  & 0xff;
1140         buf[3] = i       & 0xff;
1141 }
1142 #else
1143 #define put_uint32(p,v) ((*((unsigned int *)(p))) = (v))
1144 #endif
1145
1146 static int ast_rtp_raw_write(struct ast_rtp *rtp, struct ast_frame *f, int codec)
1147 {
1148         unsigned char *rtpheader;
1149         char iabuf[INET_ADDRSTRLEN];
1150         int hdrlen = 12;
1151         int res;
1152         int ms;
1153         int pred;
1154         int mark = 0;
1155
1156         ms = calc_txstamp(rtp, &f->delivery);
1157         /* Default prediction */
1158         if (f->subclass < AST_FORMAT_MAX_AUDIO) {
1159                 pred = rtp->lastts + ms * 8;
1160                 
1161                 switch(f->subclass) {
1162                 case AST_FORMAT_ULAW:
1163                 case AST_FORMAT_ALAW:
1164                         /* If we're within +/- 20ms from when where we
1165                            predict we should be, use that */
1166                         pred = rtp->lastts + f->datalen;
1167                         break;
1168                 case AST_FORMAT_ADPCM:
1169                 case AST_FORMAT_G726:
1170                         /* If we're within +/- 20ms from when where we
1171                            predict we should be, use that */
1172                         pred = rtp->lastts + f->datalen * 2;
1173                         break;
1174                 case AST_FORMAT_G729A:
1175                         pred = rtp->lastts + f->datalen * 8;
1176                         break;
1177                 case AST_FORMAT_GSM:
1178                         pred = rtp->lastts + (f->datalen * 160 / 33);
1179                         break;
1180                 case AST_FORMAT_ILBC:
1181                         pred = rtp->lastts + (f->datalen * 240 / 50);
1182                         break;
1183                 case AST_FORMAT_G723_1:
1184                         pred = rtp->lastts + g723_samples(f->data, f->datalen);
1185                         break;
1186                 case AST_FORMAT_SPEEX:
1187                     pred = rtp->lastts + 160;
1188                         /* assumes that the RTP packet contains one Speex frame */
1189                         break;
1190                 case AST_FORMAT_LPC10:
1191                         /* assumes that the RTP packet contains one LPC10 frame */
1192                         pred = rtp->lastts + 22 * 8;
1193                         pred += (((char *)(f->data))[7] & 0x1) * 8;
1194                         break;
1195                 default:
1196                         ast_log(LOG_WARNING, "Not sure about timestamp format for codec format %s\n", ast_getformatname(f->subclass));
1197                 }
1198                 /* Re-calculate last TS */
1199                 rtp->lastts = rtp->lastts + ms * 8;
1200                 if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
1201                         /* If this isn't an absolute delivery time, Check if it is close to our prediction, 
1202                            and if so, go with our prediction */
1203                         if (abs(rtp->lastts - pred) < MAX_TIMESTAMP_SKEW)
1204                                 rtp->lastts = pred;
1205                         else {
1206                                 if (option_debug > 2)
1207                                         ast_log(LOG_DEBUG, "Difference is %d, ms is %d\n", abs(rtp->lastts - pred), ms);
1208                                 mark = 1;
1209                         }
1210                 }
1211         } else {
1212                 mark = f->subclass & 0x1;
1213                 pred = rtp->lastovidtimestamp + f->samples;
1214                 /* Re-calculate last TS */
1215                 rtp->lastts = rtp->lastts + ms * 90;
1216                 /* If it's close to our prediction, go for it */
1217                 if (!f->delivery.tv_sec && !f->delivery.tv_usec) {
1218                         if (abs(rtp->lastts - pred) < 7200) {
1219                                 rtp->lastts = pred;
1220                                 rtp->lastovidtimestamp += f->samples;
1221                         } else {
1222                                 if (option_debug > 2)
1223                                         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);
1224                                 rtp->lastovidtimestamp = rtp->lastts;
1225                         }
1226                 }
1227         }
1228         /* Get a pointer to the header */
1229         rtpheader = (unsigned char *)(f->data - hdrlen);
1230
1231         put_uint32(rtpheader, htonl((2 << 30) | (codec << 16) | (rtp->seqno) | (mark << 23)));
1232         put_uint32(rtpheader + 4, htonl(rtp->lastts));
1233         put_uint32(rtpheader + 8, htonl(rtp->ssrc)); 
1234
1235         rtp->seqno++;
1236
1237         if (rtp->them.sin_port && rtp->them.sin_addr.s_addr) {
1238                 res = sendto(rtp->s, (void *)rtpheader, f->datalen + hdrlen, 0, (struct sockaddr *)&rtp->them, sizeof(rtp->them));
1239                 if (res <0) 
1240                         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));
1241                 if(rtp_debug_test_addr(&rtp->them))
1242                         ast_verbose("Sent RTP packet to %s:%d (type %d, seq %d, ts %d, len %d)\n"
1243                                         , ast_inet_ntoa(iabuf, sizeof(iabuf), rtp->them.sin_addr), ntohs(rtp->them.sin_port), codec, rtp->seqno, rtp->lastts,res - hdrlen);
1244         }
1245         return 0;
1246 }
1247
1248 int ast_rtp_write(struct ast_rtp *rtp, struct ast_frame *_f)
1249 {
1250         struct ast_frame *f;
1251         int codec;
1252         int hdrlen = 12;
1253         int subclass;
1254         
1255
1256         /* If we have no peer, return immediately */    
1257         if (!rtp->them.sin_addr.s_addr)
1258                 return 0;
1259
1260         /* If there is no data length, return immediately */
1261         if (!_f->datalen) 
1262                 return 0;
1263         
1264         /* Make sure we have enough space for RTP header */
1265         if ((_f->frametype != AST_FRAME_VOICE) && (_f->frametype != AST_FRAME_VIDEO)) {
1266                 ast_log(LOG_WARNING, "RTP can only send voice\n");
1267                 return -1;
1268         }
1269
1270         subclass = _f->subclass;
1271         if (_f->frametype == AST_FRAME_VIDEO)
1272                 subclass &= ~0x1;
1273
1274         codec = ast_rtp_lookup_code(rtp, 1, subclass);
1275         if (codec < 0) {
1276                 ast_log(LOG_WARNING, "Don't know how to send format %s packets with RTP\n", ast_getformatname(_f->subclass));
1277                 return -1;
1278         }
1279
1280         if (rtp->lasttxformat != subclass) {
1281                 /* New format, reset the smoother */
1282                 if (option_debug)
1283                         ast_log(LOG_DEBUG, "Ooh, format changed from %s to %s\n", ast_getformatname(rtp->lasttxformat), ast_getformatname(subclass));
1284                 rtp->lasttxformat = subclass;
1285                 if (rtp->smoother)
1286                         ast_smoother_free(rtp->smoother);
1287                 rtp->smoother = NULL;
1288         }
1289
1290
1291         switch(subclass) {
1292         case AST_FORMAT_ULAW:
1293         case AST_FORMAT_ALAW:
1294                 if (!rtp->smoother) {
1295                         rtp->smoother = ast_smoother_new(160);
1296                 }
1297                 if (!rtp->smoother) {
1298                         ast_log(LOG_WARNING, "Unable to create smoother :(\n");
1299                         return -1;
1300                 }
1301                 ast_smoother_feed(rtp->smoother, _f);
1302                 
1303                 while((f = ast_smoother_read(rtp->smoother)))
1304                         ast_rtp_raw_write(rtp, f, codec);
1305                 break;
1306         case AST_FORMAT_ADPCM:
1307         case AST_FORMAT_G726:
1308                 if (!rtp->smoother) {
1309                         rtp->smoother = ast_smoother_new(80);
1310                 }
1311                 if (!rtp->smoother) {
1312                         ast_log(LOG_WARNING, "Unable to create smoother :(\n");
1313                         return -1;
1314                 }
1315                 ast_smoother_feed(rtp->smoother, _f);
1316                 
1317                 while((f = ast_smoother_read(rtp->smoother)))
1318                         ast_rtp_raw_write(rtp, f, codec);
1319                 break;
1320         case AST_FORMAT_G729A:
1321                 if (!rtp->smoother) {
1322                         rtp->smoother = ast_smoother_new(20);
1323                         if (rtp->smoother)
1324                                 ast_smoother_set_flags(rtp->smoother, AST_SMOOTHER_FLAG_G729);
1325                 }
1326                 if (!rtp->smoother) {
1327                         ast_log(LOG_WARNING, "Unable to create g729 smoother :(\n");
1328                         return -1;
1329                 }
1330                 ast_smoother_feed(rtp->smoother, _f);
1331                 
1332                 while((f = ast_smoother_read(rtp->smoother)))
1333                         ast_rtp_raw_write(rtp, f, codec);
1334                 break;
1335         case AST_FORMAT_GSM:
1336                 if (!rtp->smoother) {
1337                         rtp->smoother = ast_smoother_new(33);
1338                 }
1339                 if (!rtp->smoother) {
1340                         ast_log(LOG_WARNING, "Unable to create GSM smoother :(\n");
1341                         return -1;
1342                 }
1343                 ast_smoother_feed(rtp->smoother, _f);
1344                 while((f = ast_smoother_read(rtp->smoother)))
1345                         ast_rtp_raw_write(rtp, f, codec);
1346                 break;
1347         case AST_FORMAT_ILBC:
1348                 if (!rtp->smoother) {
1349                         rtp->smoother = ast_smoother_new(50);
1350                 }
1351                 if (!rtp->smoother) {
1352                         ast_log(LOG_WARNING, "Unable to create ILBC smoother :(\n");
1353                         return -1;
1354                 }
1355                 ast_smoother_feed(rtp->smoother, _f);
1356                 while((f = ast_smoother_read(rtp->smoother)))
1357                         ast_rtp_raw_write(rtp, f, codec);
1358                 break;
1359         default:        
1360                 ast_log(LOG_WARNING, "Not sure about sending format %s packets\n", ast_getformatname(subclass));
1361                 /* fall through to... */
1362         case AST_FORMAT_H261:
1363         case AST_FORMAT_H263:
1364         case AST_FORMAT_G723_1:
1365         case AST_FORMAT_LPC10:
1366         case AST_FORMAT_SPEEX:
1367                 /* Don't buffer outgoing frames; send them one-per-packet: */
1368                 if (_f->offset < hdrlen) {
1369                         f = ast_frdup(_f);
1370                 } else {
1371                         f = _f;
1372                 }
1373                 ast_rtp_raw_write(rtp, f, codec);
1374         }
1375                 
1376         return 0;
1377 }
1378
1379 void ast_rtp_proto_unregister(struct ast_rtp_protocol *proto)
1380 {
1381         struct ast_rtp_protocol *cur, *prev;
1382
1383         cur = protos;
1384         prev = NULL;
1385         while(cur) {
1386                 if (cur == proto) {
1387                         if (prev)
1388                                 prev->next = proto->next;
1389                         else
1390                                 protos = proto->next;
1391                         return;
1392                 }
1393                 prev = cur;
1394                 cur = cur->next;
1395         }
1396 }
1397
1398 int ast_rtp_proto_register(struct ast_rtp_protocol *proto)
1399 {
1400         struct ast_rtp_protocol *cur;
1401         cur = protos;
1402         while(cur) {
1403                 if (cur->type == proto->type) {
1404                         ast_log(LOG_WARNING, "Tried to register same protocol '%s' twice\n", cur->type);
1405                         return -1;
1406                 }
1407                 cur = cur->next;
1408         }
1409         proto->next = protos;
1410         protos = proto;
1411         return 0;
1412 }
1413
1414 static struct ast_rtp_protocol *get_proto(struct ast_channel *chan)
1415 {
1416         struct ast_rtp_protocol *cur;
1417         cur = protos;
1418         while(cur) {
1419                 if (cur->type == chan->type) {
1420                         return cur;
1421                 }
1422                 cur = cur->next;
1423         }
1424         return NULL;
1425 }
1426
1427 int ast_rtp_bridge(struct ast_channel *c0, struct ast_channel *c1, int flags, struct ast_frame **fo, struct ast_channel **rc)
1428 {
1429         struct ast_frame *f;
1430         struct ast_channel *who, *cs[3];
1431         struct ast_rtp *p0, *p1;
1432         struct ast_rtp *vp0, *vp1;
1433         struct ast_rtp_protocol *pr0, *pr1;
1434         struct sockaddr_in ac0, ac1;
1435         struct sockaddr_in vac0, vac1;
1436         struct sockaddr_in t0, t1;
1437         struct sockaddr_in vt0, vt1;
1438         char iabuf[INET_ADDRSTRLEN];
1439         
1440         void *pvt0, *pvt1;
1441         int to;
1442         int codec0,codec1, oldcodec0, oldcodec1;
1443         
1444         memset(&vt0, 0, sizeof(vt0));
1445         memset(&vt1, 0, sizeof(vt1));
1446         memset(&vac0, 0, sizeof(vac0));
1447         memset(&vac1, 0, sizeof(vac1));
1448
1449         /* if need DTMF, cant native bridge */
1450         if (flags & (AST_BRIDGE_DTMF_CHANNEL_0 | AST_BRIDGE_DTMF_CHANNEL_1))
1451                 return -2;
1452         ast_mutex_lock(&c0->lock);
1453         while(ast_mutex_trylock(&c1->lock)) {
1454                 ast_mutex_unlock(&c0->lock);
1455                 usleep(1);
1456                 ast_mutex_lock(&c0->lock);
1457         }
1458         pr0 = get_proto(c0);
1459         pr1 = get_proto(c1);
1460         if (!pr0) {
1461                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c0->name);
1462                 ast_mutex_unlock(&c0->lock);
1463                 ast_mutex_unlock(&c1->lock);
1464                 return -1;
1465         }
1466         if (!pr1) {
1467                 ast_log(LOG_WARNING, "Can't find native functions for channel '%s'\n", c1->name);
1468                 ast_mutex_unlock(&c0->lock);
1469                 ast_mutex_unlock(&c1->lock);
1470                 return -1;
1471         }
1472         pvt0 = c0->pvt->pvt;
1473         pvt1 = c1->pvt->pvt;
1474         p0 = pr0->get_rtp_info(c0);
1475         if (pr0->get_vrtp_info)
1476                 vp0 = pr0->get_vrtp_info(c0);
1477         else
1478                 vp0 = NULL;
1479         p1 = pr1->get_rtp_info(c1);
1480         if (pr1->get_vrtp_info)
1481                 vp1 = pr1->get_vrtp_info(c1);
1482         else
1483                 vp1 = NULL;
1484         if (!p0 || !p1) {
1485                 /* Somebody doesn't want to play... */
1486                 ast_mutex_unlock(&c0->lock);
1487                 ast_mutex_unlock(&c1->lock);
1488                 return -2;
1489         }
1490         if (pr0->get_codec)
1491                 codec0 = pr0->get_codec(c0);
1492         else
1493                 codec0 = 0;
1494         if (pr1->get_codec)
1495                 codec1 = pr1->get_codec(c1);
1496         else
1497                 codec1 = 0;
1498         if (pr0->get_codec && pr1->get_codec) {
1499                 /* Hey, we can't do reinvite if both parties speak diffrent codecs */
1500                 if (!(codec0 & codec1)) {
1501                         ast_log(LOG_WARNING, "codec0 = %d is not codec1 = %d, cannot native bridge.\n",codec0,codec1);
1502                         ast_mutex_unlock(&c0->lock);
1503                         ast_mutex_unlock(&c1->lock);
1504                         return -2;
1505                 }
1506         }
1507         if (pr0->set_rtp_peer(c0, p1, vp1, codec1)) 
1508                 ast_log(LOG_WARNING, "Channel '%s' failed to talk to '%s'\n", c0->name, c1->name);
1509         else {
1510                 /* Store RTP peer */
1511                 ast_rtp_get_peer(p1, &ac1);
1512                 if (vp1)
1513                         ast_rtp_get_peer(vp1, &vac1);
1514         }
1515         if (pr1->set_rtp_peer(c1, p0, vp0, codec0))
1516                 ast_log(LOG_WARNING, "Channel '%s' failed to talk back to '%s'\n", c1->name, c0->name);
1517         else {
1518                 /* Store RTP peer */
1519                 ast_rtp_get_peer(p0, &ac0);
1520                 if (vp0)
1521                         ast_rtp_get_peer(vp0, &vac0);
1522         }
1523         ast_mutex_unlock(&c0->lock);
1524         ast_mutex_unlock(&c1->lock);
1525         cs[0] = c0;
1526         cs[1] = c1;
1527         cs[2] = NULL;
1528         oldcodec0 = codec0;
1529         oldcodec1 = codec1;
1530         for (;;) {
1531                 if ((c0->pvt->pvt != pvt0)  ||
1532                         (c1->pvt->pvt != pvt1) ||
1533                         (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
1534                                 ast_log(LOG_WARNING, "Oooh, something is weird, backing out\n");
1535                                 if (c0->pvt->pvt == pvt0) {
1536                                         if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
1537                                                 ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1538                                 }
1539                                 if (c1->pvt->pvt == pvt1) {
1540                                         if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
1541                                                 ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1542                                 }
1543                                 /* Tell it to try again later */
1544                                 return -3;
1545                 }
1546                 to = -1;
1547                 ast_rtp_get_peer(p1, &t1);
1548                 ast_rtp_get_peer(p0, &t0);
1549                 if (pr0->get_codec)
1550                         codec0 = pr0->get_codec(c0);
1551                 if (pr1->get_codec)
1552                         codec1 = pr1->get_codec(c1);
1553                 if (vp1)
1554                         ast_rtp_get_peer(vp1, &vt1);
1555                 if (vp0)
1556                         ast_rtp_get_peer(vp0, &vt0);
1557                 if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) {
1558                         if (option_debug) {
1559                                 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
1560                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1);
1561                                 ast_log(LOG_DEBUG, "Oooh, '%s' changed end vaddress to %s:%d (format %d)\n", 
1562                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1);
1563                                 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
1564                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
1565                                 ast_log(LOG_DEBUG, "Oooh, '%s' wasv %s:%d/(format %d)\n", 
1566                                         c1->name, ast_inet_ntoa(iabuf, sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
1567                         }
1568                         if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1)) 
1569                                 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
1570                         memcpy(&ac1, &t1, sizeof(ac1));
1571                         memcpy(&vac1, &vt1, sizeof(vac1));
1572                         oldcodec1 = codec1;
1573                 }
1574                 if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) {
1575                         if (option_debug) {
1576                                 ast_log(LOG_DEBUG, "Oooh, '%s' changed end address to %s:%d (format %d)\n", 
1577                                         c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0);
1578                                 ast_log(LOG_DEBUG, "Oooh, '%s' was %s:%d/(format %d)\n", 
1579                                         c0->name, ast_inet_ntoa(iabuf, sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
1580                         }
1581                         if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0))
1582                                 ast_log(LOG_WARNING, "Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
1583                         memcpy(&ac0, &t0, sizeof(ac0));
1584                         memcpy(&vac0, &vt0, sizeof(vac0));
1585                         oldcodec0 = codec0;
1586                 }
1587                 who = ast_waitfor_n(cs, 2, &to);
1588                 if (!who) {
1589                         if (option_debug)
1590                                 ast_log(LOG_DEBUG, "Ooh, empty read...\n");
1591                         /* check for hagnup / whentohangup */
1592                         if (ast_check_hangup(c0) || ast_check_hangup(c1))
1593                                 break;
1594                         continue;
1595                 }
1596                 f = ast_read(who);
1597                 if (!f || ((f->frametype == AST_FRAME_DTMF) &&
1598                                    (((who == c0) && (flags & AST_BRIDGE_DTMF_CHANNEL_0)) || 
1599                                ((who == c1) && (flags & AST_BRIDGE_DTMF_CHANNEL_1))))) {
1600                         *fo = f;
1601                         *rc = who;
1602                         if (option_debug)
1603                                 ast_log(LOG_DEBUG, "Oooh, got a %s\n", f ? "digit" : "hangup");
1604                         if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
1605                                 if (pr0->set_rtp_peer(c0, NULL, NULL, 0)) 
1606                                         ast_log(LOG_WARNING, "Channel '%s' failed to revert\n", c0->name);
1607                         }
1608                         if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
1609                                 if (pr1->set_rtp_peer(c1, NULL, NULL, 0)) 
1610                                         ast_log(LOG_WARNING, "Channel '%s' failed to revert back\n", c1->name);
1611                         }
1612                         /* That's all we needed */
1613                         return 0;
1614                 } else {
1615                         if ((f->frametype == AST_FRAME_DTMF) || 
1616                                 (f->frametype == AST_FRAME_VOICE) || 
1617                                 (f->frametype == AST_FRAME_VIDEO)) {
1618                                 /* Forward voice or DTMF frames if they happen upon us */
1619                                 if (who == c0) {
1620                                         ast_write(c1, f);
1621                                 } else if (who == c1) {
1622                                         ast_write(c0, f);
1623                                 }
1624                         }
1625                         ast_frfree(f);
1626                 }
1627                 /* Swap priority not that it's a big deal at this point */
1628                 cs[2] = cs[0];
1629                 cs[0] = cs[1];
1630                 cs[1] = cs[2];
1631                 
1632         }
1633         return -1;
1634 }
1635
1636 static int rtp_do_debug_ip(int fd, int argc, char *argv[])
1637 {
1638         struct hostent *hp;
1639         struct ast_hostent ahp;
1640         char iabuf[INET_ADDRSTRLEN];
1641         int port = 0;
1642         char *p, *arg;
1643
1644         if (argc != 4)
1645                 return RESULT_SHOWUSAGE;
1646         arg = argv[3];
1647         p = strstr(arg, ":");
1648         if (p) {
1649                 *p = '\0';
1650                 p++;
1651                 port = atoi(p);
1652         }
1653         hp = ast_gethostbyname(arg, &ahp);
1654         if (hp == NULL)
1655                 return RESULT_SHOWUSAGE;
1656         rtpdebugaddr.sin_family = AF_INET;
1657         memcpy(&rtpdebugaddr.sin_addr, hp->h_addr, sizeof(rtpdebugaddr.sin_addr));
1658         rtpdebugaddr.sin_port = htons(port);
1659         if (port == 0)
1660                 ast_cli(fd, "RTP Debugging Enabled for IP: %s\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr));
1661         else
1662                 ast_cli(fd, "RTP Debugging Enabled for IP: %s:%d\n", ast_inet_ntoa(iabuf, sizeof(iabuf), rtpdebugaddr.sin_addr), port);
1663         rtpdebug = 1;
1664         return RESULT_SUCCESS;
1665 }
1666
1667 static int rtp_do_debug(int fd, int argc, char *argv[])
1668 {
1669         if(argc != 2){
1670                 if(argc != 4)
1671                         return RESULT_SHOWUSAGE;
1672                 return rtp_do_debug_ip(fd, argc, argv);
1673         }
1674         rtpdebug = 1;
1675         memset(&rtpdebugaddr,0,sizeof(rtpdebugaddr));
1676         ast_cli(fd, "RTP Debugging Enabled\n");
1677         return RESULT_SUCCESS;
1678 }
1679    
1680 static int rtp_no_debug(int fd, int argc, char *argv[])
1681 {
1682         if(argc !=3)
1683                 return RESULT_SHOWUSAGE;
1684         rtpdebug = 0;
1685         ast_cli(fd,"RTP Debugging Disabled\n");
1686         return RESULT_SUCCESS;
1687 }
1688
1689 static char debug_usage[] =
1690   "Usage: rtp debug [ip host[:port]]\n"
1691   "       Enable dumping of all RTP packets to and from host.\n";
1692
1693 static char no_debug_usage[] =
1694   "Usage: rtp no debug\n"
1695   "       Disable all RTP debugging\n";
1696
1697 static struct ast_cli_entry  cli_debug_ip =
1698 {{ "rtp", "debug", "ip", NULL } , rtp_do_debug, "Enable RTP debugging on IP", debug_usage };
1699
1700 static struct ast_cli_entry  cli_debug =
1701 {{ "rtp", "debug", NULL } , rtp_do_debug, "Enable RTP debugging", debug_usage };
1702
1703 static struct ast_cli_entry  cli_no_debug =
1704 {{ "rtp", "no", "debug", NULL } , rtp_no_debug, "Disable RTP debugging", no_debug_usage };
1705
1706 void ast_rtp_reload(void)
1707 {
1708         struct ast_config *cfg;
1709         char *s;
1710
1711         rtpstart = 5000;
1712         rtpend = 31000;
1713 #ifdef SO_NO_CHECK
1714         checksums = 1;
1715 #endif
1716         cfg = ast_load("rtp.conf");
1717         if (cfg) {
1718                 if ((s = ast_variable_retrieve(cfg, "general", "rtpstart"))) {
1719                         rtpstart = atoi(s);
1720                         if (rtpstart < 1024)
1721                                 rtpstart = 1024;
1722                         if (rtpstart > 65535)
1723                                 rtpstart = 65535;
1724                 }
1725                 if ((s = ast_variable_retrieve(cfg, "general", "rtpend"))) {
1726                         rtpend = atoi(s);
1727                         if (rtpend < 1024)
1728                                 rtpend = 1024;
1729                         if (rtpend > 65535)
1730                                 rtpend = 65535;
1731                 }
1732                 if ((s = ast_variable_retrieve(cfg, "general", "rtpchecksums"))) {
1733 #ifdef SO_NO_CHECK
1734                         if (ast_true(s))
1735                                 checksums = 1;
1736                         else
1737                                 checksums = 0;
1738 #else
1739                         if (ast_true(s))
1740                                 ast_log(LOG_WARNING, "Disabling RTP checksums is not supported on this operating system!\n");
1741 #endif
1742                 }
1743                 ast_destroy(cfg);
1744         }
1745         if (rtpstart >= rtpend) {
1746                 ast_log(LOG_WARNING, "Unreasonable values for RTP start in rtp.conf/end\n");
1747                 rtpstart = 5000;
1748                 rtpend = 31000;
1749         }
1750         if (option_verbose > 1)
1751                 ast_verbose(VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
1752         
1753 }
1754
1755 void ast_rtp_init(void)
1756 {
1757         ast_cli_register(&cli_debug);
1758         ast_cli_register(&cli_debug_ip);
1759         ast_cli_register(&cli_no_debug);
1760         ast_rtp_reload();
1761 }