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