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