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