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