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

Generated on Sat Jun 12 16:40:59 2004 for Asterisk by doxygen 1.3.7