00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
#include <stdio.h>
00017
#include <stdlib.h>
00018
#include <string.h>
00019
#include <sys/time.h>
00020
#include <signal.h>
00021
#include <errno.h>
00022
#include <unistd.h>
00023
#include <netinet/in.h>
00024
#include <sys/time.h>
00025
#include <sys/socket.h>
00026
#include <arpa/inet.h>
00027
#include <fcntl.h>
00028
00029
#include <asterisk/rtp.h>
00030
#include <asterisk/frame.h>
00031
#include <asterisk/logger.h>
00032
#include <asterisk/options.h>
00033
#include <asterisk/channel.h>
00034
#include <asterisk/acl.h>
00035
#include <asterisk/channel.h>
00036
#include <asterisk/channel_pvt.h>
00037
#include <asterisk/config.h>
00038
#include <asterisk/lock.h>
00039
#include <asterisk/utils.h>
00040
00041 #define MAX_TIMESTAMP_SKEW 640
00042
00043 #define RTP_MTU 1200
00044
00045 #define TYPE_HIGH 0x0
00046 #define TYPE_LOW 0x1
00047 #define TYPE_SILENCE 0x2
00048 #define TYPE_DONTSEND 0x3
00049 #define TYPE_MASK 0x3
00050
00051
static int dtmftimeout = 3000;
00052
00053
static int rtpstart = 0;
00054
static int rtpend = 0;
00055
#ifdef SO_NO_CHECK
00056
static int checksums = 1;
00057
#endif
00058
00059
00060 struct rtpPayloadType {
00061 int isAstFormat;
00062 int code;
00063 };
00064
00065 #define MAX_RTP_PT 256
00066
00067 #define FLAG_3389_WARNING (1 << 0)
00068
00069 struct ast_rtp {
00070 int s;
00071 char resp;
00072 struct ast_frame f;
00073 unsigned char rawdata[8192 +
AST_FRIENDLY_OFFSET];
00074 unsigned int ssrc;
00075 unsigned int lastts;
00076 unsigned int lastrxts;
00077 unsigned int lastividtimestamp;
00078 unsigned int lastovidtimestamp;
00079 unsigned int lasteventseqn;
00080 int lasttxformat;
00081 int lastrxformat;
00082 int dtmfcount;
00083 unsigned int dtmfduration;
00084 int nat;
00085 int flags;
00086 struct sockaddr_in us;
00087 struct sockaddr_in them;
00088 struct timeval rxcore;
00089 struct timeval txcore;
00090 struct timeval dtmfmute;
00091 struct ast_smoother *
smoother;
00092 int *
ioid;
00093 unsigned short seqno;
00094 struct sched_context *
sched;
00095 struct io_context *
io;
00096 void *
data;
00097 ast_rtp_callback callback;
00098 struct rtpPayloadType current_RTP_PT[
MAX_RTP_PT];
00099 int rtp_lookup_code_cache_isAstFormat;
00100 int rtp_lookup_code_cache_code;
00101 int rtp_lookup_code_cache_result;
00102 int rtp_offered_from_local;
00103 struct ast_rtcp *
rtcp;
00104 };
00105
00106 struct ast_rtcp {
00107 int s;
00108 struct sockaddr_in us;
00109 struct sockaddr_in them;
00110 };
00111
00112
static struct ast_rtp_protocol *protos = NULL;
00113
00114 int ast_rtp_fd(
struct ast_rtp *rtp)
00115 {
00116
return rtp->
s;
00117 }
00118
00119 int ast_rtcp_fd(
struct ast_rtp *rtp)
00120 {
00121
if (rtp->
rtcp)
00122
return rtp->
rtcp->
s;
00123
return -1;
00124 }
00125
00126
static int g723_len(
unsigned char buf)
00127 {
00128
switch(buf &
TYPE_MASK) {
00129
case TYPE_DONTSEND:
00130
return 0;
00131
break;
00132
case TYPE_SILENCE:
00133
return 4;
00134
break;
00135
case TYPE_HIGH:
00136
return 24;
00137
break;
00138
case TYPE_LOW:
00139
return 20;
00140
break;
00141
default:
00142
ast_log(LOG_WARNING,
"Badly encoded frame (%d)\n", buf & TYPE_MASK);
00143 }
00144
return -1;
00145 }
00146
00147
static int g723_samples(
unsigned char *buf,
int maxlen)
00148 {
00149
int pos = 0;
00150
int samples = 0;
00151
int res;
00152
while(pos < maxlen) {
00153 res = g723_len(buf[pos]);
00154
if (res <= 0)
00155
break;
00156 samples += 240;
00157 pos += res;
00158 }
00159
return samples;
00160 }
00161
00162 void ast_rtp_set_data(
struct ast_rtp *rtp,
void *data)
00163 {
00164 rtp->
data = data;
00165 }
00166
00167 void ast_rtp_set_callback(
struct ast_rtp *rtp,
ast_rtp_callback callback)
00168 {
00169 rtp->
callback = callback;
00170 }
00171
00172 void ast_rtp_setnat(
struct ast_rtp *rtp,
int nat)
00173 {
00174 rtp->
nat = nat;
00175 }
00176
00177
static struct ast_frame *send_dtmf(
struct ast_rtp *rtp)
00178 {
00179
struct timeval tv;
00180
static struct ast_frame null_frame = {
AST_FRAME_NULL, };
00181
char iabuf[INET_ADDRSTRLEN];
00182 gettimeofday(&tv, NULL);
00183
if ((tv.tv_sec < rtp->
dtmfmute.tv_sec) ||
00184 ((tv.tv_sec == rtp->
dtmfmute.tv_sec) && (tv.tv_usec < rtp->
dtmfmute.tv_usec))) {
00185
ast_log(LOG_DEBUG,
"Ignore potential DTMF echo from '%s'\n",
ast_inet_ntoa(iabuf,
sizeof(iabuf), rtp->
them.sin_addr));
00186 rtp->
resp = 0;
00187 rtp->
dtmfduration = 0;
00188
return &null_frame;
00189 }
00190
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));
00191 rtp->
f.
frametype =
AST_FRAME_DTMF;
00192 rtp->
f.
subclass = rtp->
resp;
00193 rtp->
f.
datalen = 0;
00194 rtp->
f.
samples = 0;
00195 rtp->
f.
mallocd = 0;
00196 rtp->
f.
src =
"RTP";
00197 rtp->
resp = 0;
00198 rtp->
dtmfduration = 0;
00199
return &rtp->
f;
00200
00201 }
00202
00203
static struct ast_frame *process_cisco_dtmf(
struct ast_rtp *rtp,
unsigned char *data,
int len)
00204 {
00205
unsigned int event;
00206
char resp = 0;
00207
struct ast_frame *f = NULL;
00208 event = ntohl(*((
unsigned int *)(data)));
00209 event &= 0x001F;
00210
#if 0
00211
printf(
"Cisco Digit: %08x (len = %d)\n", event, len);
00212
#endif
00213
if (event < 10) {
00214 resp =
'0' + event;
00215 }
else if (event < 11) {
00216 resp =
'*';
00217 }
else if (event < 12) {
00218 resp =
'#';
00219 }
else if (event < 16) {
00220 resp =
'A' + (event - 12);
00221 }
00222
if (rtp->
resp && (rtp->
resp != resp)) {
00223 f = send_dtmf(rtp);
00224 }
00225 rtp->
resp = resp;
00226 rtp->
dtmfcount = dtmftimeout;
00227
return f;
00228 }
00229
00230
static struct ast_frame *process_rfc2833(
struct ast_rtp *rtp,
unsigned char *data,
int len)
00231 {
00232
unsigned int event;
00233
unsigned int event_end;
00234
unsigned int duration;
00235
char resp = 0;
00236
struct ast_frame *f = NULL;
00237 event = ntohl(*((
unsigned int *)(data)));
00238 event >>= 24;
00239 event_end = ntohl(*((
unsigned int *)(data)));
00240 event_end <<= 8;
00241 event_end >>= 24;
00242 duration = ntohl(*((
unsigned int *)(data)));
00243 duration &= 0xFFFF;
00244
#if 0
00245
printf(
"Event: %08x (len = %d)\n", event, len);
00246
#endif
00247
if (event < 10) {
00248 resp =
'0' + event;
00249 }
else if (event < 11) {
00250 resp =
'*';
00251 }
else if (event < 12) {
00252 resp =
'#';
00253 }
else if (event < 16) {
00254 resp =
'A' + (event - 12);
00255 }
00256
if (rtp->
resp && (rtp->
resp != resp)) {
00257 f = send_dtmf(rtp);
00258 }
00259
else if(event_end & 0x80)
00260 {
00261
if (rtp->
resp) {
00262 f = send_dtmf(rtp);
00263 rtp->
resp = 0;
00264 }
00265 resp = 0;
00266 duration = 0;
00267 }
00268
else if(rtp->
dtmfduration && (duration < rtp->
dtmfduration))
00269 {
00270 f = send_dtmf(rtp);
00271 }
00272
if (!(event_end & 0x80))
00273 rtp->
resp = resp;
00274 rtp->
dtmfcount = dtmftimeout;
00275 rtp->
dtmfduration = duration;
00276
return f;
00277 }
00278
00279
static struct ast_frame *process_rfc3389(
struct ast_rtp *rtp,
unsigned char *data,
int len)
00280 {
00281
struct ast_frame *f = NULL;
00282
00283
00284
00285
#if 1
00286
printf(
"RFC3389: %d bytes, level %d...\n", len, rtp->
lastrxformat);
00287
#endif
00288
if (!(rtp->
flags &
FLAG_3389_WARNING)) {
00289
ast_log(LOG_NOTICE,
"RFC3389 support incomplete. Turn off on client if possible\n");
00290 rtp->
flags |=
FLAG_3389_WARNING;
00291 }
00292
00293
if (!len)
00294
return NULL;
00295
if (len < 24) {
00296 rtp->
f.
data = rtp->
rawdata +
AST_FRIENDLY_OFFSET;
00297 rtp->
f.
datalen = len - 1;
00298 rtp->
f.
offset =
AST_FRIENDLY_OFFSET;
00299 memcpy(rtp->
f.
data, data + 1, len - 1);
00300 }
else {
00301 rtp->
f.
data = NULL;
00302 rtp->
f.
offset = 0;
00303 rtp->
f.
datalen = 0;
00304 }
00305 rtp->
f.
frametype =
AST_FRAME_CNG;
00306 rtp->
f.
subclass = data[0] & 0x7f;
00307 rtp->
f.
datalen = len - 1;
00308 rtp->
f.
samples = 0;
00309 rtp->
f.
delivery.tv_usec = rtp->
f.
delivery.tv_sec = 0;
00310 f = &rtp->
f;
00311
return f;
00312 }
00313
00314
static int rtpread(
int *
id,
int fd,
short events,
void *cbdata)
00315 {
00316
struct ast_rtp *rtp = cbdata;
00317
struct ast_frame *f;
00318 f =
ast_rtp_read(rtp);
00319
if (f) {
00320
if (rtp->
callback)
00321 rtp->
callback(rtp, f, rtp->
data);
00322 }
00323
return 1;
00324 }
00325
00326 struct ast_frame *
ast_rtcp_read(
struct ast_rtp *rtp)
00327 {
00328
static struct ast_frame null_frame = {
AST_FRAME_NULL, };
00329
int len;
00330
int hdrlen = 8;
00331
int res;
00332
struct sockaddr_in sin;
00333
unsigned int rtcpdata[1024];
00334
char iabuf[INET_ADDRSTRLEN];
00335
00336
if (!rtp->
rtcp)
00337
return &null_frame;
00338
00339 len =
sizeof(sin);
00340
00341 res = recvfrom(rtp->
rtcp->
s, rtcpdata,
sizeof(rtcpdata),
00342 0, (
struct sockaddr *)&sin, &len);
00343
00344
if (res < 0) {
00345
if (errno == EAGAIN)
00346
ast_log(
LOG_NOTICE,
"RTP: Received packet with bad UDP checksum\n");
00347
else
00348
ast_log(
LOG_WARNING,
"RTP Read error: %s\n", strerror(errno));
00349
if (errno == EBADF)
00350
CRASH;
00351
return &null_frame;
00352 }
00353
00354
if (res < hdrlen) {
00355
ast_log(
LOG_WARNING,
"RTP Read too short\n");
00356
return &null_frame;
00357 }
00358
00359
if (rtp->
nat) {
00360
00361
if ((rtp->
rtcp->
them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
00362 (rtp->
rtcp->
them.sin_port != sin.sin_port)) {
00363 memcpy(&rtp->
them, &sin,
sizeof(rtp->
them));
00364
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));
00365 }
00366 }
00367
if (
option_debug)
00368
ast_log(
LOG_DEBUG,
"Got RTCP report of %d bytes\n", res);
00369
return &null_frame;
00370 }
00371
00372
static void calc_rxstamp(
struct timeval *tv,
struct ast_rtp *rtp,
unsigned int timestamp,
int mark)
00373 {
00374
if ((!rtp->
rxcore.tv_sec && !rtp->
rxcore.tv_usec) || mark) {
00375 gettimeofday(&rtp->
rxcore, NULL);
00376 rtp->
rxcore.tv_sec -= timestamp / 8000;
00377 rtp->
rxcore.tv_usec -= (timestamp % 8000) * 125;
00378
00379 rtp->
rxcore.tv_usec -= rtp->
rxcore.tv_usec % 20000;
00380
if (rtp->
rxcore.tv_usec < 0) {
00381
00382 rtp->
rxcore.tv_usec += 1000000;
00383 rtp->
rxcore.tv_sec -= 1;
00384 }
00385 }
00386 tv->tv_sec = rtp->
rxcore.tv_sec + timestamp / 8000;
00387 tv->tv_usec = rtp->
rxcore.tv_usec + (timestamp % 8000) * 125;
00388
if (tv->tv_usec >= 1000000) {
00389 tv->tv_usec -= 1000000;
00390 tv->tv_sec += 1;
00391 }
00392 }
00393
00394 struct ast_frame *
ast_rtp_read(
struct ast_rtp *rtp)
00395 {
00396
int res;
00397
struct sockaddr_in sin;
00398
int len;
00399
unsigned int seqno;
00400
int payloadtype;
00401
int hdrlen = 12;
00402
int mark;
00403
int ext;
00404
char iabuf[INET_ADDRSTRLEN];
00405
unsigned int timestamp;
00406
unsigned int *rtpheader;
00407
static struct ast_frame *f, null_frame = {
AST_FRAME_NULL, };
00408
struct rtpPayloadType rtpPT;
00409
00410 len =
sizeof(sin);
00411
00412
00413 res = recvfrom(rtp->
s, rtp->
rawdata +
AST_FRIENDLY_OFFSET,
sizeof(rtp->
rawdata) -
AST_FRIENDLY_OFFSET,
00414 0, (
struct sockaddr *)&sin, &len);
00415
00416
00417 rtpheader = (
unsigned int *)(rtp->
rawdata +
AST_FRIENDLY_OFFSET);
00418
if (res < 0) {
00419
if (errno == EAGAIN)
00420
ast_log(
LOG_NOTICE,
"RTP: Received packet with bad UDP checksum\n");
00421
else
00422
ast_log(
LOG_WARNING,
"RTP Read error: %s\n", strerror(errno));
00423
if (errno == EBADF)
00424
CRASH;
00425
return &null_frame;
00426 }
00427
if (res < hdrlen) {
00428
ast_log(
LOG_WARNING,
"RTP Read too short\n");
00429
return &null_frame;
00430 }
00431
00432
00433
00434
if (!rtp->
them.sin_addr.s_addr || !rtp->
them.sin_port)
00435
return &null_frame;
00436
00437
if (rtp->
nat) {
00438
00439
if ((rtp->
them.sin_addr.s_addr != sin.sin_addr.s_addr) ||
00440 (rtp->
them.sin_port != sin.sin_port)) {
00441 memcpy(&rtp->
them, &sin,
sizeof(rtp->
them));
00442
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));
00443 }
00444 }
00445
00446
00447 seqno = ntohl(rtpheader[0]);
00448 payloadtype = (seqno & 0x7f0000) >> 16;
00449 mark = seqno & (1 << 23);
00450 ext = seqno & (1 << 28);
00451 seqno &= 0xffff;
00452 timestamp = ntohl(rtpheader[1]);
00453
if (ext) {
00454
00455 hdrlen += 4;
00456 hdrlen += (ntohl(rtpheader[3]) & 0xffff) << 2;
00457 }
00458
00459
if (res < hdrlen) {
00460
ast_log(
LOG_WARNING,
"RTP Read too short (%d, expecting %d)\n", res, hdrlen);
00461
return &null_frame;
00462 }
00463
00464
#if 0
00465
printf(
"Got RTP packet from %s:%d (type %d, seq %d, ts %d, len = %d)\n",
ast_inet_ntoa(iabuf,
sizeof(iabuf), sin.sin_addr), ntohs(sin.sin_port), payloadtype, seqno, timestamp,res - hdrlen);
00466
#endif
00467
rtpPT =
ast_rtp_lookup_pt(rtp, payloadtype);
00468
if (!rtpPT.
isAstFormat) {
00469
00470
if (rtpPT.
code ==
AST_RTP_DTMF) {
00471
00472
if (rtp->
lasteventseqn <= seqno) {
00473 f = process_rfc2833(rtp, rtp->
rawdata +
AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
00474 rtp->
lasteventseqn = seqno;
00475 }
00476
if (f)
return f;
else return &null_frame;
00477 }
else if (rtpPT.
code ==
AST_RTP_CISCO_DTMF) {
00478
00479
if (rtp->
lasteventseqn <= seqno) {
00480 f = process_cisco_dtmf(rtp, rtp->
rawdata +
AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
00481 rtp->
lasteventseqn = seqno;
00482 }
00483
if (f)
return f;
else return &null_frame;
00484 }
else if (rtpPT.
code ==
AST_RTP_CN) {
00485
00486 f = process_rfc3389(rtp, rtp->
rawdata +
AST_FRIENDLY_OFFSET + hdrlen, res - hdrlen);
00487
if (f)
return f;
else return &null_frame;
00488 }
else {
00489
ast_log(
LOG_NOTICE,
"Unknown RTP codec %d received\n", payloadtype);
00490
return &null_frame;
00491 }
00492 }
00493 rtp->
f.
subclass = rtpPT.
code;
00494
if (rtp->
f.
subclass <
AST_FORMAT_MAX_AUDIO)
00495 rtp->
f.
frametype =
AST_FRAME_VOICE;
00496
else
00497 rtp->
f.
frametype =
AST_FRAME_VIDEO;
00498 rtp->
lastrxformat = rtp->
f.
subclass;
00499
00500
if (!rtp->
lastrxts)
00501 rtp->
lastrxts = timestamp;
00502
00503
if (rtp->
dtmfcount) {
00504
#if 0
00505
printf(
"dtmfcount was %d\n", rtp->
dtmfcount);
00506
#endif
00507
rtp->
dtmfcount -= (timestamp - rtp->
lastrxts);
00508
if (rtp->
dtmfcount < 0)
00509 rtp->
dtmfcount = 0;
00510
#if 0
00511
if (dtmftimeout != rtp->
dtmfcount)
00512 printf(
"dtmfcount is %d\n", rtp->
dtmfcount);
00513
#endif
00514
}
00515 rtp->
lastrxts = timestamp;
00516
00517
00518
if (rtp->
resp && !rtp->
dtmfcount) {
00519
ast_log(
LOG_DEBUG,
"Sending pending DTMF\n");
00520
return send_dtmf(rtp);
00521 }
00522 rtp->
f.
mallocd = 0;
00523 rtp->
f.
datalen = res - hdrlen;
00524 rtp->
f.
data = rtp->
rawdata + hdrlen +
AST_FRIENDLY_OFFSET;
00525 rtp->
f.
offset = hdrlen +
AST_FRIENDLY_OFFSET;
00526
if (rtp->
f.
subclass <
AST_FORMAT_MAX_AUDIO) {
00527
switch(rtp->
f.
subclass) {
00528
case AST_FORMAT_ULAW:
00529
case AST_FORMAT_ALAW:
00530 rtp->
f.
samples = rtp->
f.
datalen;
00531
break;
00532
case AST_FORMAT_SLINEAR:
00533 rtp->
f.
samples = rtp->
f.
datalen / 2;
00534
break;
00535
case AST_FORMAT_GSM:
00536 rtp->
f.
samples = 160 * (rtp->
f.
datalen / 33);
00537
break;
00538
case AST_FORMAT_ILBC:
00539 rtp->
f.
samples = 240 * (rtp->
f.
datalen / 50);
00540
break;
00541
case AST_FORMAT_ADPCM:
00542
case AST_FORMAT_G726:
00543 rtp->
f.
samples = rtp->
f.
datalen * 2;
00544
break;
00545
case AST_FORMAT_G729A:
00546 rtp->
f.
samples = rtp->
f.
datalen * 8;
00547
break;
00548
case AST_FORMAT_G723_1:
00549 rtp->
f.
samples = g723_samples(rtp->
f.
data, rtp->
f.
datalen);
00550
break;
00551
case AST_FORMAT_SPEEX:
00552
00553 rtp->
f.
samples = 160;
00554
break;
00555
case AST_FORMAT_LPC10:
00556 rtp->
f.
samples = 22 * 8;
00557 rtp->
f.
samples += (((
char *)(rtp->
f.
data))[7] & 0x1) * 8;
00558
break;
00559
default:
00560
ast_log(
LOG_NOTICE,
"Unable to calculate samples for format %s\n",
ast_getformatname(rtp->
f.
subclass));
00561
break;
00562 }
00563 calc_rxstamp(&rtp->
f.
delivery, rtp, timestamp, mark);
00564 }
else {
00565
00566
if (!rtp->
lastividtimestamp)
00567 rtp->
lastividtimestamp = timestamp;
00568 rtp->
f.
samples = timestamp - rtp->
lastividtimestamp;
00569 rtp->
lastividtimestamp = timestamp;
00570 rtp->
f.
delivery.tv_sec = 0;
00571 rtp->
f.
delivery.tv_usec = 0;
00572
if (mark)
00573 rtp->
f.
subclass |= 0x1;
00574
00575 }
00576 rtp->
f.
src =
"RTP";
00577
return &rtp->
f;
00578 }
00579
00580
00581
00582
static struct {
00583 struct rtpPayloadType payloadType;
00584 char*
type;
00585 char*
subtype;
00586 } mimeTypes[] = {
00587 {{1,
AST_FORMAT_G723_1},
"audio",
"G723"},
00588 {{1,
AST_FORMAT_GSM},
"audio",
"GSM"},
00589 {{1,
AST_FORMAT_ULAW},
"audio",
"PCMU"},
00590 {{1,
AST_FORMAT_ALAW},
"audio",
"PCMA"},
00591 {{1,
AST_FORMAT_G726},
"audio",
"G726-32"},
00592 {{1,
AST_FORMAT_ADPCM},
"audio",
"DVI4"},
00593 {{1,
AST_FORMAT_SLINEAR},
"audio",
"L16"},
00594 {{1,
AST_FORMAT_LPC10},
"audio",
"LPC"},
00595 {{1,
AST_FORMAT_G729A},
"audio",
"G729"},
00596 {{1,
AST_FORMAT_SPEEX},
"audio",
"speex"},
00597 {{1,
AST_FORMAT_ILBC},
"audio",
"iLBC"},
00598 {{0,
AST_RTP_DTMF},
"audio",
"telephone-event"},
00599 {{0,
AST_RTP_CISCO_DTMF},
"audio",
"cisco-telephone-event"},
00600 {{0,
AST_RTP_CN},
"audio",
"CN"},
00601 {{1,
AST_FORMAT_JPEG},
"video",
"JPEG"},
00602 {{1,
AST_FORMAT_PNG},
"video",
"PNG"},
00603 {{1,
AST_FORMAT_H261},
"video",
"H261"},
00604 {{1,
AST_FORMAT_H263},
"video",
"H263"},
00605 };
00606
00607
00608
00609
00610
static struct rtpPayloadType static_RTP_PT[
MAX_RTP_PT] = {
00611 [0] = {1,
AST_FORMAT_ULAW},
00612 [2] = {1,
AST_FORMAT_G726},
00613 [3] = {1,
AST_FORMAT_GSM},
00614 [4] = {1,
AST_FORMAT_G723_1},
00615 [5] = {1,
AST_FORMAT_ADPCM},
00616 [6] = {1,
AST_FORMAT_ADPCM},
00617 [7] = {1,
AST_FORMAT_LPC10},
00618 [8] = {1,
AST_FORMAT_ALAW},
00619 [10] = {1,
AST_FORMAT_SLINEAR},
00620 [11] = {1,
AST_FORMAT_SLINEAR},
00621 [13] = {0,
AST_RTP_CN},
00622 [16] = {1,
AST_FORMAT_ADPCM},
00623 [17] = {1,
AST_FORMAT_ADPCM},
00624 [18] = {1,
AST_FORMAT_G729A},
00625 [19] = {0,
AST_RTP_CN},
00626 [26] = {1,
AST_FORMAT_JPEG},
00627 [31] = {1,
AST_FORMAT_H261},
00628 [34] = {1,
AST_FORMAT_H263},
00629 [97] = {1,
AST_FORMAT_ILBC},
00630 [101] = {0,
AST_RTP_DTMF},
00631 [110] = {1,
AST_FORMAT_SPEEX},
00632 [121] = {0,
AST_RTP_CISCO_DTMF},
00633 };
00634
00635 void ast_rtp_pt_clear(
struct ast_rtp* rtp)
00636 {
00637
int i;
00638
00639
for (i = 0; i <
MAX_RTP_PT; ++i) {
00640 rtp->
current_RTP_PT[i].
isAstFormat = 0;
00641 rtp->
current_RTP_PT[i].
code = 0;
00642 }
00643
00644 rtp->
rtp_lookup_code_cache_isAstFormat = 0;
00645 rtp->
rtp_lookup_code_cache_code = 0;
00646 rtp->
rtp_lookup_code_cache_result = 0;
00647 }
00648
00649 void ast_rtp_pt_default(
struct ast_rtp* rtp)
00650 {
00651
int i;
00652
00653
for (i = 0; i <
MAX_RTP_PT; ++i) {
00654 rtp->
current_RTP_PT[i].
isAstFormat = static_RTP_PT[i].
isAstFormat;
00655 rtp->
current_RTP_PT[i].
code = static_RTP_PT[i].
code;
00656 }
00657
00658 rtp->
rtp_lookup_code_cache_isAstFormat = 0;
00659 rtp->
rtp_lookup_code_cache_code = 0;
00660 rtp->
rtp_lookup_code_cache_result = 0;
00661 }
00662
00663
00664
00665
00666 void ast_rtp_set_m_type(
struct ast_rtp* rtp,
int pt) {
00667
if (pt < 0 || pt >
MAX_RTP_PT)
return;
00668
00669
if (static_RTP_PT[pt].
code != 0) {
00670 rtp->
current_RTP_PT[pt] = static_RTP_PT[pt];
00671 }
00672 }
00673
00674
00675
00676 void ast_rtp_set_rtpmap_type(
struct ast_rtp* rtp,
int pt,
00677
char* mimeType,
char* mimeSubtype) {
00678
int i;
00679
00680
if (pt < 0 || pt >
MAX_RTP_PT)
return;
00681
00682
for (i = 0; i <
sizeof mimeTypes/
sizeof mimeTypes[0]; ++i) {
00683
if (strcasecmp(mimeSubtype, mimeTypes[i].
subtype) == 0 &&
00684 strcasecmp(mimeType, mimeTypes[i].
type) == 0) {
00685 rtp->
current_RTP_PT[pt] = mimeTypes[i].payloadType;
00686
return;
00687 }
00688 }
00689 }
00690
00691
00692
00693 void ast_rtp_get_current_formats(
struct ast_rtp* rtp,
00694
int* astFormats,
int* nonAstFormats) {
00695
int pt;
00696
00697 *astFormats = *nonAstFormats = 0;
00698
for (pt = 0; pt <
MAX_RTP_PT; ++pt) {
00699
if (rtp->
current_RTP_PT[pt].
isAstFormat) {
00700 *astFormats |= rtp->
current_RTP_PT[pt].
code;
00701 }
else {
00702 *nonAstFormats |= rtp->
current_RTP_PT[pt].
code;
00703 }
00704 }
00705 }
00706
00707 void ast_rtp_offered_from_local(
struct ast_rtp* rtp,
int local) {
00708
if (rtp)
00709 rtp->
rtp_offered_from_local = local;
00710
else
00711
ast_log(
LOG_WARNING,
"rtp structure is null\n");
00712 }
00713
00714 struct rtpPayloadType ast_rtp_lookup_pt(struct ast_rtp* rtp,
int pt)
00715 {
00716
struct rtpPayloadType result;
00717
00718 result.
isAstFormat = result.
code = 0;
00719
if (pt < 0 || pt >
MAX_RTP_PT) {
00720
return result;
00721 }
00722
00723
if (!rtp->rtp_offered_from_local)
00724 result = rtp->current_RTP_PT[pt];
00725
00726
if (!result.
code)
00727 result = static_RTP_PT[pt];
00728
return result;
00729 }
00730
00731
00732 int ast_rtp_lookup_code(
struct ast_rtp* rtp,
int isAstFormat,
int code) {
00733
int pt;
00734
00735
00736
if (isAstFormat == rtp->
rtp_lookup_code_cache_isAstFormat &&
00737 code == rtp->
rtp_lookup_code_cache_code) {
00738
00739
return rtp->
rtp_lookup_code_cache_result;
00740 }
00741
00742
00743
for (pt = 0; pt <
MAX_RTP_PT; ++pt) {
00744
if (rtp->
current_RTP_PT[pt].
code == code &&
00745 rtp->
current_RTP_PT[pt].
isAstFormat == isAstFormat) {
00746 rtp->
rtp_lookup_code_cache_isAstFormat = isAstFormat;
00747 rtp->
rtp_lookup_code_cache_code = code;
00748 rtp->
rtp_lookup_code_cache_result = pt;
00749
return pt;
00750 }
00751 }
00752
00753
00754
for (pt = 0; pt <
MAX_RTP_PT; ++pt) {
00755
if (static_RTP_PT[pt].
code == code &&
00756 static_RTP_PT[pt].
isAstFormat == isAstFormat) {
00757 rtp->
rtp_lookup_code_cache_isAstFormat = isAstFormat;
00758 rtp->
rtp_lookup_code_cache_code = code;
00759 rtp->
rtp_lookup_code_cache_result = pt;
00760
return pt;
00761 }
00762 }
00763
return -1;
00764 }
00765
00766 char*
ast_rtp_lookup_mime_subtype(
int isAstFormat,
int code) {
00767
int i;
00768
00769
for (i = 0; i <
sizeof mimeTypes/
sizeof mimeTypes[0]; ++i) {
00770
if (mimeTypes[i].payloadType.code == code &&
00771 mimeTypes[i].payloadType.isAstFormat == isAstFormat) {
00772
return mimeTypes[i].subtype;
00773 }
00774 }
00775
return "";
00776 }
00777
00778
static int rtp_socket(
void)
00779 {
00780
int s;
00781
long flags;
00782
s = socket(AF_INET, SOCK_DGRAM, 0);
00783
if (
s > -1) {
00784 flags = fcntl(s, F_GETFL);
00785 fcntl(s, F_SETFL, flags | O_NONBLOCK);
00786
#ifdef SO_NO_CHECK
00787
if (checksums) {
00788 setsockopt(s, SOL_SOCKET, SO_NO_CHECK, &checksums,
sizeof(checksums));
00789 }
00790
#endif
00791
}
00792
return s;
00793 }
00794
00795
static struct ast_rtcp *ast_rtcp_new(
void)
00796 {
00797
struct ast_rtcp *rtcp;
00798 rtcp =
malloc(
sizeof(
struct ast_rtcp));
00799
if (!rtcp)
00800
return NULL;
00801 memset(rtcp, 0,
sizeof(
struct ast_rtcp));
00802 rtcp->s = rtp_socket();
00803 rtcp->us.sin_family = AF_INET;
00804
if (rtcp->s < 0) {
00805
free(rtcp);
00806
ast_log(LOG_WARNING,
"Unable to allocate socket: %s\n", strerror(errno));
00807
return NULL;
00808 }
00809
return rtcp;
00810 }
00811
00812 struct ast_rtp *
ast_rtp_new_with_bindaddr(
struct sched_context *
sched,
struct io_context *io,
int rtcpenable,
int callbackmode,
struct in_addr addr)
00813 {
00814
struct ast_rtp *rtp;
00815
int x;
00816
int first;
00817
int startplace;
00818 rtp =
malloc(
sizeof(
struct ast_rtp));
00819
if (!rtp)
00820
return NULL;
00821 memset(rtp, 0,
sizeof(
struct ast_rtp));
00822 rtp->them.sin_family = AF_INET;
00823 rtp->us.sin_family = AF_INET;
00824 rtp->s = rtp_socket();
00825 rtp->ssrc = rand();
00826 rtp->seqno = rand() & 0xffff;
00827
if (rtp->s < 0) {
00828
free(rtp);
00829
ast_log(
LOG_WARNING,
"Unable to allocate socket: %s\n", strerror(errno));
00830
return NULL;
00831 }
00832
if (sched && rtcpenable) {
00833 rtp->sched = sched;
00834 rtp->rtcp = ast_rtcp_new();
00835 }
00836
00837 x = (rand() % (rtpend-rtpstart)) + rtpstart;
00838 x = x & ~1;
00839 startplace = x;
00840
for (;;) {
00841
00842 rtp->us.sin_port = htons(x);
00843 rtp->us.sin_addr = addr;
00844
if (rtp->rtcp)
00845 rtp->rtcp->us.sin_port = htons(x + 1);
00846
if (!(first = bind(rtp->s, (
struct sockaddr *)&rtp->us,
sizeof(rtp->us))) &&
00847 (!rtp->rtcp || !bind(rtp->rtcp->s, (
struct sockaddr *)&rtp->rtcp->us,
sizeof(rtp->rtcp->us))))
00848
break;
00849
if (!first) {
00850
00851 close(rtp->s);
00852 rtp->s = rtp_socket();
00853 }
00854
if (errno != EADDRINUSE) {
00855
ast_log(
LOG_WARNING,
"Unexpected bind error: %s\n", strerror(errno));
00856 close(rtp->s);
00857
if (rtp->rtcp) {
00858 close(rtp->rtcp->s);
00859
free(rtp->rtcp);
00860 }
00861
free(rtp);
00862
return NULL;
00863 }
00864 x += 2;
00865
if (x > rtpend)
00866 x = (rtpstart + 1) & ~1;
00867
if (x == startplace) {
00868
ast_log(
LOG_WARNING,
"No RTP ports remaining\n");
00869 close(rtp->s);
00870
if (rtp->rtcp) {
00871 close(rtp->rtcp->s);
00872
free(rtp->rtcp);
00873 }
00874
free(rtp);
00875
return NULL;
00876 }
00877 }
00878
if (io && sched && callbackmode) {
00879
00880 rtp->sched = sched;
00881 rtp->io = io;
00882 rtp->ioid =
ast_io_add(rtp->io, rtp->s, rtpread,
AST_IO_IN, rtp);
00883 }
00884
ast_rtp_pt_default(rtp);
00885
return rtp;
00886 }
00887
00888 struct ast_rtp *
ast_rtp_new(
struct sched_context *
sched,
struct io_context *io,
int rtcpenable,
int callbackmode)
00889 {
00890
struct in_addr ia;
00891 memset(&ia, 0,
sizeof(ia));
00892
return ast_rtp_new_with_bindaddr(sched, io, rtcpenable, callbackmode, ia);
00893 }
00894
00895 int ast_rtp_settos(
struct ast_rtp *rtp,
int tos)
00896 {
00897
int res;
00898
if ((res = setsockopt(rtp->
s, IPPROTO_IP, IP_TOS, &tos,
sizeof(tos))))
00899
ast_log(
LOG_WARNING,
"Unable to set TOS to %d\n", tos);
00900
return res;
00901 }
00902
00903 void ast_rtp_set_peer(
struct ast_rtp *rtp,
struct sockaddr_in *them)
00904 {
00905 rtp->
them.sin_port = them->sin_port;
00906 rtp->
them.sin_addr = them->sin_addr;
00907
if (rtp->
rtcp) {
00908 rtp->
rtcp->
them.sin_port = htons(ntohs(them->sin_port) + 1);
00909 rtp->
rtcp->
them.sin_addr = them->sin_addr;
00910 }
00911 }
00912
00913 void ast_rtp_get_peer(
struct ast_rtp *rtp,
struct sockaddr_in *them)
00914 {
00915 them->sin_family = AF_INET;
00916 them->sin_port = rtp->
them.sin_port;
00917 them->sin_addr = rtp->
them.sin_addr;
00918 }
00919
00920 void ast_rtp_get_us(
struct ast_rtp *rtp,
struct sockaddr_in *us)
00921 {
00922 memcpy(us, &rtp->
us,
sizeof(rtp->
us));
00923 }
00924
00925 void ast_rtp_stop(
struct ast_rtp *rtp)
00926 {
00927 memset(&rtp->
them.sin_addr, 0,
sizeof(rtp->
them.sin_addr));
00928 memset(&rtp->
them.sin_port, 0,
sizeof(rtp->
them.sin_port));
00929
if (rtp->
rtcp) {
00930 memset(&rtp->
rtcp->
them.sin_addr, 0,
sizeof(rtp->
them.sin_addr));
00931 memset(&rtp->
rtcp->
them.sin_port, 0,
sizeof(rtp->
them.sin_port));
00932 }
00933 }
00934
00935 void ast_rtp_destroy(
struct ast_rtp *rtp)
00936 {
00937
if (rtp->
smoother)
00938
ast_smoother_free(rtp->
smoother);
00939
if (rtp->
ioid)
00940
ast_io_remove(rtp->
io, rtp->
ioid);
00941
if (rtp->
s > -1)
00942 close(rtp->
s);
00943
if (rtp->
rtcp) {
00944 close(rtp->
rtcp->
s);
00945
free(rtp->
rtcp);
00946 }
00947
free(rtp);
00948 }
00949
00950
static unsigned int calc_txstamp(
struct ast_rtp *rtp,
struct timeval *delivery)
00951 {
00952
struct timeval now;
00953
unsigned int ms;
00954
if (!rtp->
txcore.tv_sec && !rtp->
txcore.tv_usec) {
00955 gettimeofday(&rtp->
txcore, NULL);
00956
00957 rtp->
txcore.tv_usec -= rtp->
txcore.tv_usec % 20000;
00958 }
00959
if (delivery && (delivery->tv_sec || delivery->tv_usec)) {
00960
00961 ms = (delivery->tv_sec - rtp->
txcore.tv_sec) * 1000;
00962 ms += (1000000 + delivery->tv_usec - rtp->
txcore.tv_usec) / 1000 - 1000;
00963 rtp->
txcore.tv_sec = delivery->tv_sec;
00964 rtp->
txcore.tv_usec = delivery->tv_usec;
00965 }
else {
00966 gettimeofday(&now, NULL);
00967 ms = (now.tv_sec - rtp->
txcore.tv_sec) * 1000;
00968 ms += (1000000 + now.tv_usec - rtp->
txcore.tv_usec) / 1000 - 1000;
00969
00970 rtp->
txcore.tv_sec = now.tv_sec;
00971 rtp->
txcore.tv_usec = now.tv_usec;
00972 }
00973
return ms;
00974 }
00975
00976 int ast_rtp_senddigit(
struct ast_rtp *rtp,
char digit)
00977 {
00978
unsigned int *rtpheader;
00979
int hdrlen = 12;
00980
int res;
00981
int ms;
00982
int x;
00983
int payload;
00984
char data[256];
00985
char iabuf[INET_ADDRSTRLEN];
00986
00987
if ((digit <= '9') && (digit >=
'0'))
00988 digit -=
'0';
00989
else if (digit ==
'*')
00990 digit = 10;
00991
else if (digit ==
'#')
00992 digit = 11;
00993
else if ((digit >=
'A') && (digit <=
'D'))
00994 digit = digit -
'A' + 12;
00995
else if ((digit >=
'a') && (digit <=
'd'))
00996 digit = digit -
'a' + 12;
00997
else {
00998
ast_log(
LOG_WARNING,
"Don't know how to represent '%c'\n", digit);
00999
return -1;
01000 }
01001 payload =
ast_rtp_lookup_code(rtp, 0,
AST_RTP_DTMF);
01002
01003
01004
if (!rtp->
them.sin_addr.s_addr)
01005
return 0;
01006
01007 gettimeofday(&rtp->
dtmfmute, NULL);
01008 rtp->
dtmfmute.tv_usec += (500 * 1000);
01009
if (rtp->
dtmfmute.tv_usec > 1000000) {
01010 rtp->
dtmfmute.tv_usec -= 1000000;
01011 rtp->
dtmfmute.tv_sec += 1;
01012 }
01013
01014 ms = calc_txstamp(rtp, NULL);
01015
01016 rtp->
lastts = rtp->
lastts + ms * 8;
01017
01018
01019 rtpheader = (
unsigned int *)data;
01020 rtpheader[0] = htonl((2 << 30) | (1 << 23) | (payload << 16) | (rtp->
seqno++));
01021 rtpheader[1] = htonl(rtp->
lastts);
01022 rtpheader[2] = htonl(rtp->
ssrc);
01023 rtpheader[3] = htonl((digit << 24) | (0xa << 16) | (0));
01024
for (x=0;x<4;x++) {
01025
if (rtp->
them.sin_port && rtp->
them.sin_addr.s_addr) {
01026 res = sendto(rtp->
s, (
void *)rtpheader, hdrlen + 4, 0, (
struct sockaddr *)&rtp->
them,
sizeof(rtp->
them));
01027
if (res <0)
01028
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));
01029
#if 0
01030
printf(
"Sent %d bytes of RTP data to %s:%d\n", res,
ast_inet_ntoa(iabuf,
sizeof(iabuf), rtp->
them.sin_addr), ntohs(rtp->
them.sin_port));
01031
#endif
01032
}
01033
if (x ==0) {
01034
01035 rtpheader[0] = htonl((2 << 30) | (payload << 16) | (rtp->
seqno++));
01036
01037 rtpheader[3] |= htonl((800));
01038
01039 rtpheader[3] |= htonl((1 << 23));
01040 }
01041 }
01042
return 0;
01043 }
01044
01045
static int ast_rtp_raw_write(
struct ast_rtp *rtp,
struct ast_frame *f,
int codec)
01046 {
01047
unsigned int *rtpheader;
01048
char iabuf[INET_ADDRSTRLEN];
01049
int hdrlen = 12;
01050
int res;
01051
int ms;
01052
int pred;
01053
int mark = 0;
01054
01055 ms = calc_txstamp(rtp, &f->
delivery);
01056
01057
if (f->
subclass <
AST_FORMAT_MAX_AUDIO) {
01058 pred = rtp->
lastts + ms * 8;
01059
01060
switch(f->
subclass) {
01061
case AST_FORMAT_ULAW:
01062
case AST_FORMAT_ALAW:
01063
01064
01065 pred = rtp->
lastts + f->
datalen;
01066
break;
01067
case AST_FORMAT_ADPCM:
01068
case AST_FORMAT_G726:
01069
01070
01071 pred = rtp->
lastts + f->
datalen * 2;
01072
break;
01073
case AST_FORMAT_G729A:
01074 pred = rtp->
lastts + f->
datalen * 8;
01075
break;
01076
case AST_FORMAT_GSM:
01077 pred = rtp->
lastts + (f->
datalen * 160 / 33);
01078
break;
01079
case AST_FORMAT_ILBC:
01080 pred = rtp->
lastts + (f->
datalen * 240 / 50);
01081
break;
01082
case AST_FORMAT_G723_1:
01083 pred = rtp->
lastts + g723_samples(f->
data, f->
datalen);
01084
break;
01085
case AST_FORMAT_SPEEX:
01086 pred = rtp->
lastts + 160;
01087
01088
break;
01089
case AST_FORMAT_LPC10:
01090
01091 pred = rtp->
lastts + 22 * 8;
01092 pred += (((
char *)(f->
data))[7] & 0x1) * 8;
01093
break;
01094
default:
01095
ast_log(LOG_WARNING,
"Not sure about timestamp format for codec format %s\n",
ast_getformatname(f->
subclass));
01096 }
01097
01098 rtp->
lastts = rtp->
lastts + ms * 8;
01099
if (!f->
delivery.tv_sec && !f->
delivery.tv_usec) {
01100
01101
01102
if (abs(rtp->
lastts - pred) <
MAX_TIMESTAMP_SKEW)
01103 rtp->
lastts = pred;
01104
else {
01105
ast_log(LOG_DEBUG,
"Difference is %d, ms is %d\n", abs(rtp->
lastts - pred), ms);
01106 mark = 1;
01107 }
01108 }
01109 }
else {
01110 mark = f->
subclass & 0x1;
01111 pred = rtp->
lastovidtimestamp + f->
samples;
01112
01113 rtp->
lastts = rtp->
lastts + ms * 90;
01114
01115
if (!f->
delivery.tv_sec && !f->
delivery.tv_usec) {
01116
if (abs(rtp->
lastts - pred) < 7200) {
01117 rtp->
lastts = pred;
01118 rtp->
lastovidtimestamp += f->
samples;
01119 }
else {
01120
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);
01121 rtp->
lastovidtimestamp = rtp->
lastts;
01122 }
01123 }
01124 }
01125
01126 rtpheader = (
unsigned int *)(f->
data - hdrlen);
01127 rtpheader[0] = htonl((2 << 30) | (codec << 16) | (rtp->
seqno++) | (mark << 23));
01128 rtpheader[1] = htonl(rtp->
lastts);
01129 rtpheader[2] = htonl(rtp->
ssrc);
01130
if (rtp->
them.sin_port && rtp->
them.sin_addr.s_addr) {
01131 res = sendto(rtp->
s, (
void *)rtpheader, f->
datalen + hdrlen, 0, (
struct sockaddr *)&rtp->
them,
sizeof(rtp->
them));
01132
if (res <0)
01133
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));
01134
#if 0
01135
printf(
"Sent %d bytes of RTP data to %s:%d\n", res,
ast_inet_ntoa(iabuf,
sizeof(iabuf), rtp->
them.sin_addr), ntohs(rtp->
them.sin_port));
01136
#endif
01137
}
01138
return 0;
01139 }
01140
01141 int ast_rtp_write(
struct ast_rtp *rtp,
struct ast_frame *_f)
01142 {
01143
struct ast_frame *f;
01144
int codec;
01145
int hdrlen = 12;
01146
int subclass;
01147
01148
01149
01150
if (!rtp->
them.sin_addr.s_addr)
01151
return 0;
01152
01153
01154
if (!_f->
datalen)
01155
return 0;
01156
01157
01158
if ((_f->
frametype !=
AST_FRAME_VOICE) && (_f->
frametype !=
AST_FRAME_VIDEO)) {
01159
ast_log(
LOG_WARNING,
"RTP can only send voice\n");
01160
return -1;
01161 }
01162
01163 subclass = _f->
subclass;
01164
if (_f->
frametype ==
AST_FRAME_VIDEO)
01165 subclass &= ~0x1;
01166
01167 codec =
ast_rtp_lookup_code(rtp, 1, subclass);
01168
if (codec < 0) {
01169
ast_log(
LOG_WARNING,
"Don't know how to send format %s packets with RTP\n",
ast_getformatname(_f->
subclass));
01170
return -1;
01171 }
01172
01173
if (rtp->
lasttxformat != subclass) {
01174
01175
ast_log(
LOG_DEBUG,
"Ooh, format changed from %s to %s\n",
ast_getformatname(rtp->
lasttxformat),
ast_getformatname(subclass));
01176 rtp->
lasttxformat = subclass;
01177
if (rtp->
smoother)
01178
ast_smoother_free(rtp->
smoother);
01179 rtp->
smoother = NULL;
01180 }
01181
01182
01183
switch(subclass) {
01184
case AST_FORMAT_ULAW:
01185
case AST_FORMAT_ALAW:
01186
if (!rtp->
smoother) {
01187 rtp->
smoother =
ast_smoother_new(160);
01188 }
01189
if (!rtp->
smoother) {
01190
ast_log(
LOG_WARNING,
"Unable to create smoother :(\n");
01191
return -1;
01192 }
01193
ast_smoother_feed(rtp->
smoother, _f);
01194
01195
while((f =
ast_smoother_read(rtp->
smoother)))
01196 ast_rtp_raw_write(rtp, f, codec);
01197
break;
01198
case AST_FORMAT_ADPCM:
01199
case AST_FORMAT_G726:
01200
if (!rtp->
smoother) {
01201 rtp->
smoother =
ast_smoother_new(80);
01202 }
01203
if (!rtp->
smoother) {
01204
ast_log(
LOG_WARNING,
"Unable to create smoother :(\n");
01205
return -1;
01206 }
01207
ast_smoother_feed(rtp->
smoother, _f);
01208
01209
while((f =
ast_smoother_read(rtp->
smoother)))
01210 ast_rtp_raw_write(rtp, f, codec);
01211
break;
01212
case AST_FORMAT_G729A:
01213
if (!rtp->
smoother) {
01214 rtp->
smoother =
ast_smoother_new(20);
01215
if (rtp->
smoother)
01216
ast_smoother_set_flags(rtp->
smoother,
AST_SMOOTHER_FLAG_G729);
01217 }
01218
if (!rtp->
smoother) {
01219
ast_log(
LOG_WARNING,
"Unable to create g729 smoother :(\n");
01220
return -1;
01221 }
01222
ast_smoother_feed(rtp->
smoother, _f);
01223
01224
while((f =
ast_smoother_read(rtp->
smoother)))
01225 ast_rtp_raw_write(rtp, f, codec);
01226
break;
01227
case AST_FORMAT_GSM:
01228
if (!rtp->
smoother) {
01229 rtp->
smoother =
ast_smoother_new(33);
01230 }
01231
if (!rtp->
smoother) {
01232
ast_log(
LOG_WARNING,
"Unable to create GSM smoother :(\n");
01233
return -1;
01234 }
01235
ast_smoother_feed(rtp->
smoother, _f);
01236
while((f =
ast_smoother_read(rtp->
smoother)))
01237 ast_rtp_raw_write(rtp, f, codec);
01238
break;
01239
case AST_FORMAT_ILBC:
01240
if (!rtp->
smoother) {
01241 rtp->
smoother =
ast_smoother_new(50);
01242 }
01243
if (!rtp->
smoother) {
01244
ast_log(
LOG_WARNING,
"Unable to create ILBC smoother :(\n");
01245
return -1;
01246 }
01247
ast_smoother_feed(rtp->
smoother, _f);
01248
while((f =
ast_smoother_read(rtp->
smoother)))
01249 ast_rtp_raw_write(rtp, f, codec);
01250
break;
01251
default:
01252
ast_log(
LOG_WARNING,
"Not sure about sending format %s packets\n",
ast_getformatname(subclass));
01253
01254
case AST_FORMAT_H261:
01255
case AST_FORMAT_H263:
01256
case AST_FORMAT_G723_1:
01257
case AST_FORMAT_LPC10:
01258
case AST_FORMAT_SPEEX:
01259
01260
if (_f->
offset < hdrlen) {
01261 f =
ast_frdup(_f);
01262 }
else {
01263 f = _f;
01264 }
01265 ast_rtp_raw_write(rtp, f, codec);
01266 }
01267
01268
return 0;
01269 }
01270
01271 void ast_rtp_proto_unregister(
struct ast_rtp_protocol *proto)
01272 {
01273
struct ast_rtp_protocol *cur, *prev;
01274 cur = protos;
01275 prev = NULL;
01276
while(cur) {
01277
if (cur == proto) {
01278
if (prev)
01279 prev->
next = proto->
next;
01280
else
01281 protos = proto->
next;
01282
return;
01283 }
01284 prev = cur;
01285 cur = cur->
next;
01286 }
01287 }
01288
01289 int ast_rtp_proto_register(
struct ast_rtp_protocol *proto)
01290 {
01291
struct ast_rtp_protocol *cur;
01292 cur = protos;
01293
while(cur) {
01294
if (cur->type == proto->
type) {
01295
ast_log(
LOG_WARNING,
"Tried to register same protocol '%s' twice\n", cur->type);
01296
return -1;
01297 }
01298 cur = cur->next;
01299 }
01300 proto->
next = protos;
01301 protos = proto;
01302
return 0;
01303 }
01304
01305
static struct ast_rtp_protocol *get_proto(
struct ast_channel *chan)
01306 {
01307
struct ast_rtp_protocol *cur;
01308 cur = protos;
01309
while(cur) {
01310
if (cur->type == chan->
type) {
01311
return cur;
01312 }
01313 cur = cur->
next;
01314 }
01315
return NULL;
01316 }
01317
01318 int ast_rtp_bridge(
struct ast_channel *c0,
struct ast_channel *c1,
int flags,
struct ast_frame **fo,
struct ast_channel **rc)
01319 {
01320
struct ast_frame *f;
01321
struct ast_channel *who, *cs[3];
01322
struct ast_rtp *p0, *p1;
01323
struct ast_rtp *vp0, *vp1;
01324
struct ast_rtp_protocol *pr0, *pr1;
01325
struct sockaddr_in ac0, ac1;
01326
struct sockaddr_in vac0, vac1;
01327
struct sockaddr_in t0, t1;
01328
struct sockaddr_in vt0, vt1;
01329
char iabuf[INET_ADDRSTRLEN];
01330
01331
void *pvt0, *pvt1;
01332
int to;
01333
int codec0,codec1, oldcodec0, oldcodec1;
01334
01335 memset(&vt0, 0,
sizeof(vt0));
01336 memset(&vt1, 0,
sizeof(vt1));
01337 memset(&vac0, 0,
sizeof(vac0));
01338 memset(&vac1, 0,
sizeof(vac1));
01339
01340
01341
if (flags & (
AST_BRIDGE_DTMF_CHANNEL_0 |
AST_BRIDGE_DTMF_CHANNEL_1))
01342
return -2;
01343
ast_mutex_lock(&c0->
lock);
01344
while(
ast_mutex_trylock(&c1->
lock)) {
01345
ast_mutex_unlock(&c0->
lock);
01346 usleep(1);
01347
ast_mutex_lock(&c0->
lock);
01348 }
01349 pr0 = get_proto(c0);
01350 pr1 = get_proto(c1);
01351
if (!pr0) {
01352
ast_log(
LOG_WARNING,
"Can't find native functions for channel '%s'\n", c0->
name);
01353
ast_mutex_unlock(&c0->
lock);
01354
ast_mutex_unlock(&c1->
lock);
01355
return -1;
01356 }
01357
if (!pr1) {
01358
ast_log(
LOG_WARNING,
"Can't find native functions for channel '%s'\n", c1->
name);
01359
ast_mutex_unlock(&c0->
lock);
01360
ast_mutex_unlock(&c1->
lock);
01361
return -1;
01362 }
01363 pvt0 = c0->
pvt->
pvt;
01364 pvt1 = c1->
pvt->
pvt;
01365 p0 = pr0->get_rtp_info(c0);
01366
if (pr0->get_vrtp_info)
01367 vp0 = pr0->get_vrtp_info(c0);
01368
else
01369 vp0 = NULL;
01370 p1 = pr1->get_rtp_info(c1);
01371
if (pr1->get_vrtp_info)
01372 vp1 = pr1->get_vrtp_info(c1);
01373
else
01374 vp1 = NULL;
01375
if (!p0 || !p1) {
01376
01377
ast_mutex_unlock(&c0->
lock);
01378
ast_mutex_unlock(&c1->
lock);
01379
return -2;
01380 }
01381
if (pr0->get_codec)
01382 codec0 = pr0->get_codec(c0);
01383
else
01384 codec0 = 0;
01385
if (pr1->get_codec)
01386 codec1 = pr1->get_codec(c1);
01387
else
01388 codec1 = 0;
01389
if (pr0->get_codec && pr1->get_codec) {
01390
01391
if (!(codec0 & codec1)) {
01392
ast_log(
LOG_WARNING,
"codec0 = %d is not codec1 = %d, cannot native bridge.\n",codec0,codec1);
01393
ast_mutex_unlock(&c0->
lock);
01394
ast_mutex_unlock(&c1->
lock);
01395
return -2;
01396 }
01397 }
01398
if (pr0->set_rtp_peer(c0, p1, vp1, codec1))
01399
ast_log(
LOG_WARNING,
"Channel '%s' failed to talk to '%s'\n", c0->
name, c1->
name);
01400
else {
01401
01402
ast_rtp_get_peer(p1, &ac1);
01403
if (vp1)
01404
ast_rtp_get_peer(vp1, &vac1);
01405 }
01406
if (pr1->set_rtp_peer(c1, p0, vp0, codec0))
01407
ast_log(
LOG_WARNING,
"Channel '%s' failed to talk back to '%s'\n", c1->
name, c0->
name);
01408
else {
01409
01410
ast_rtp_get_peer(p0, &ac0);
01411
if (vp0)
01412
ast_rtp_get_peer(vp0, &vac0);
01413 }
01414
ast_mutex_unlock(&c0->
lock);
01415
ast_mutex_unlock(&c1->
lock);
01416 cs[0] = c0;
01417 cs[1] = c1;
01418 cs[2] = NULL;
01419 oldcodec0 = codec0;
01420 oldcodec1 = codec1;
01421
for (;;) {
01422
if ((c0->pvt->pvt != pvt0) ||
01423 (c1->pvt->pvt != pvt1) ||
01424 (c0->masq || c0->masqr || c1->masq || c1->masqr)) {
01425
ast_log(
LOG_DEBUG,
"Oooh, something is weird, backing out\n");
01426
if (c0->pvt->pvt == pvt0) {
01427
if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
01428
ast_log(
LOG_WARNING,
"Channel '%s' failed to revert\n", c0->name);
01429 }
01430
if (c1->pvt->pvt == pvt1) {
01431
if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
01432
ast_log(
LOG_WARNING,
"Channel '%s' failed to revert back\n", c1->name);
01433 }
01434
01435
return -3;
01436 }
01437 to = -1;
01438
ast_rtp_get_peer(p1, &t1);
01439
ast_rtp_get_peer(p0, &t0);
01440
if (pr0->get_codec)
01441 codec0 = pr0->get_codec(c0);
01442
if (pr1->get_codec)
01443 codec1 = pr1->get_codec(c1);
01444
if (vp1)
01445
ast_rtp_get_peer(vp1, &vt1);
01446
if (vp0)
01447
ast_rtp_get_peer(vp0, &vt0);
01448
if (inaddrcmp(&t1, &ac1) || (vp1 && inaddrcmp(&vt1, &vac1)) || (codec1 != oldcodec1)) {
01449
ast_log(
LOG_DEBUG,
"Oooh, '%s' changed end address to %s:%d (format %d)\n",
01450 c1->name,
ast_inet_ntoa(iabuf,
sizeof(iabuf), t1.sin_addr), ntohs(t1.sin_port), codec1);
01451
ast_log(
LOG_DEBUG,
"Oooh, '%s' changed end vaddress to %s:%d (format %d)\n",
01452 c1->name,
ast_inet_ntoa(iabuf,
sizeof(iabuf), vt1.sin_addr), ntohs(vt1.sin_port), codec1);
01453
ast_log(
LOG_DEBUG,
"Oooh, '%s' was %s:%d/(format %d)\n",
01454 c1->name,
ast_inet_ntoa(iabuf,
sizeof(iabuf), ac1.sin_addr), ntohs(ac1.sin_port), oldcodec1);
01455
ast_log(
LOG_DEBUG,
"Oooh, '%s' wasv %s:%d/(format %d)\n",
01456 c1->name,
ast_inet_ntoa(iabuf,
sizeof(iabuf), vac1.sin_addr), ntohs(vac1.sin_port), oldcodec1);
01457
if (pr0->set_rtp_peer(c0, t1.sin_addr.s_addr ? p1 : NULL, vt1.sin_addr.s_addr ? vp1 : NULL, codec1))
01458
ast_log(
LOG_WARNING,
"Channel '%s' failed to update to '%s'\n", c0->name, c1->name);
01459 memcpy(&ac1, &t1,
sizeof(ac1));
01460 memcpy(&vac1, &vt1,
sizeof(vac1));
01461 oldcodec1 = codec1;
01462 }
01463
if (inaddrcmp(&t0, &ac0) || (vp0 && inaddrcmp(&vt0, &vac0))) {
01464
ast_log(
LOG_DEBUG,
"Oooh, '%s' changed end address to %s:%d (format %d)\n",
01465 c0->name,
ast_inet_ntoa(iabuf,
sizeof(iabuf), t0.sin_addr), ntohs(t0.sin_port), codec0);
01466
ast_log(
LOG_DEBUG,
"Oooh, '%s' was %s:%d/(format %d)\n",
01467 c0->name,
ast_inet_ntoa(iabuf,
sizeof(iabuf), ac0.sin_addr), ntohs(ac0.sin_port), oldcodec0);
01468
if (pr1->set_rtp_peer(c1, t0.sin_addr.s_addr ? p0 : NULL, vt0.sin_addr.s_addr ? vp0 : NULL, codec0))
01469
ast_log(
LOG_WARNING,
"Channel '%s' failed to update to '%s'\n", c1->name, c0->name);
01470 memcpy(&ac0, &t0,
sizeof(ac0));
01471 memcpy(&vac0, &vt0,
sizeof(vac0));
01472 oldcodec0 = codec0;
01473 }
01474 who =
ast_waitfor_n(cs, 2, &to);
01475
if (!who) {
01476
ast_log(
LOG_DEBUG,
"Ooh, empty read...\n");
01477
01478
if (
ast_check_hangup(c0) ||
ast_check_hangup(c1))
01479
break;
01480
continue;
01481 }
01482 f =
ast_read(who);
01483
if (!f || ((f->
frametype ==
AST_FRAME_DTMF) &&
01484 (((who == c0) && (flags &
AST_BRIDGE_DTMF_CHANNEL_0)) ||
01485 ((who == c1) && (flags &
AST_BRIDGE_DTMF_CHANNEL_1))))) {
01486 *fo = f;
01487 *rc = who;
01488
ast_log(
LOG_DEBUG,
"Oooh, got a %s\n", f ?
"digit" :
"hangup");
01489
if ((c0->pvt->pvt == pvt0) && (!c0->_softhangup)) {
01490
if (pr0->set_rtp_peer(c0, NULL, NULL, 0))
01491
ast_log(
LOG_WARNING,
"Channel '%s' failed to revert\n", c0->name);
01492 }
01493
if ((c1->pvt->pvt == pvt1) && (!c1->_softhangup)) {
01494
if (pr1->set_rtp_peer(c1, NULL, NULL, 0))
01495
ast_log(
LOG_WARNING,
"Channel '%s' failed to revert back\n", c1->name);
01496 }
01497
01498
return 0;
01499 }
else {
01500
if ((f->
frametype ==
AST_FRAME_DTMF) ||
01501 (f->
frametype ==
AST_FRAME_VOICE) ||
01502 (f->
frametype ==
AST_FRAME_VIDEO)) {
01503
01504
if (who == c0) {
01505
ast_write(c1, f);
01506 }
else if (who == c1) {
01507
ast_write(c0, f);
01508 }
01509 }
01510
ast_frfree(f);
01511 }
01512
01513 cs[2] = cs[0];
01514 cs[0] = cs[1];
01515 cs[1] = cs[2];
01516
01517 }
01518
return -1;
01519 }
01520
01521 void ast_rtp_reload(
void)
01522 {
01523
struct ast_config *cfg;
01524
char *
s;
01525 rtpstart = 5000;
01526 rtpend = 31000;
01527
#ifdef SO_NO_CHECK
01528
checksums = 1;
01529
#endif
01530
cfg =
ast_load(
"rtp.conf");
01531
if (cfg) {
01532
if ((
s =
ast_variable_retrieve(cfg,
"general",
"rtpstart"))) {
01533 rtpstart = atoi(
s);
01534
if (rtpstart < 1024)
01535 rtpstart = 1024;
01536
if (rtpstart > 65535)
01537 rtpstart = 65535;
01538 }
01539
if ((
s =
ast_variable_retrieve(cfg,
"general",
"rtpend"))) {
01540 rtpend = atoi(
s);
01541
if (rtpend < 1024)
01542 rtpend = 1024;
01543
if (rtpend > 65535)
01544 rtpend = 65535;
01545 }
01546
if ((
s =
ast_variable_retrieve(cfg,
"general",
"rtpchecksums"))) {
01547
#ifdef SO_NO_CHECK
01548
if (
ast_true(
s))
01549 checksums = 1;
01550
else
01551 checksums = 0;
01552
#else
01553
if (
ast_true(
s))
01554
ast_log(
LOG_WARNING,
"Disabling RTP checksums is not supported on this operating system!\n");
01555
#endif
01556
}
01557
ast_destroy(cfg);
01558 }
01559
if (rtpstart >= rtpend) {
01560
ast_log(
LOG_WARNING,
"Unreasonable values for RTP start/end\n");
01561 rtpstart = 5000;
01562 rtpend = 31000;
01563 }
01564
if (
option_verbose > 1)
01565
ast_verbose(
VERBOSE_PREFIX_2 "RTP Allocating from port range %d -> %d\n", rtpstart, rtpend);
01566 }
01567
01568 void ast_rtp_init(
void)
01569 {
01570
ast_rtp_reload();
01571 }