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