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