Main Page | Alphabetical List | Data Structures | File List | Data Fields | Globals

rtp.c

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

Generated on Tue Aug 17 16:13:53 2004 for Asterisk by doxygen 1.3.8