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