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