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