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

Generated on Fri Sep 24 21:03:48 2004 for Asterisk by doxygen 1.3.8