You can subscribe to this list here.
2003 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
(68) |
Jul
(27) |
Aug
(1) |
Sep
(9) |
Oct
(16) |
Nov
(64) |
Dec
(18) |
---|---|---|---|---|---|---|---|---|---|---|---|---|
2004 |
Jan
(11) |
Feb
(5) |
Mar
(20) |
Apr
(9) |
May
(8) |
Jun
(8) |
Jul
(2) |
Aug
|
Sep
(11) |
Oct
(34) |
Nov
(23) |
Dec
(34) |
2005 |
Jan
(41) |
Feb
(25) |
Mar
(25) |
Apr
(32) |
May
(27) |
Jun
(9) |
Jul
(36) |
Aug
(6) |
Sep
(3) |
Oct
(11) |
Nov
(2) |
Dec
(21) |
2006 |
Jan
(14) |
Feb
(8) |
Mar
(18) |
Apr
(6) |
May
|
Jun
(17) |
Jul
(14) |
Aug
(26) |
Sep
(34) |
Oct
(24) |
Nov
(48) |
Dec
(64) |
2007 |
Jan
(72) |
Feb
(21) |
Mar
(50) |
Apr
(41) |
May
(35) |
Jun
(50) |
Jul
(33) |
Aug
(32) |
Sep
(50) |
Oct
(85) |
Nov
(43) |
Dec
(33) |
2008 |
Jan
(10) |
Feb
(29) |
Mar
(15) |
Apr
(45) |
May
(5) |
Jun
(2) |
Jul
(14) |
Aug
(3) |
Sep
|
Oct
|
Nov
(3) |
Dec
|
2009 |
Jan
|
Feb
|
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
(1) |
Sep
|
Oct
|
Nov
|
Dec
|
2010 |
Jan
(9) |
Feb
(3) |
Mar
|
Apr
|
May
|
Jun
|
Jul
|
Aug
|
Sep
|
Oct
|
Nov
|
Dec
|
From: <jpg...@us...> - 2008-07-01 16:38:55
|
Revision: 1442 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1442&view=rev Author: jpgrayson Date: 2008-07-01 09:39:02 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Many updates to libiax2: - Add timeval related functions: iax_tvadd_ms(), iax_tvdiff_ms(), iax_tvcmp(), and iax_tvzero(). These replace a bunch of duplicated calculations throughout iax.c. - Cleanup iax_sched_add() - Use calloc() instead of malloc() + memset(). - Reduce nesting by checking for allocation error where it may happen. - Cleanup iax_sched_del() - Fix variable scoping. - Cleanup iax_time_to_next_event(). - Fix variable scoping. - Use iax_tvdiff_ms(). - Better error checking and handling in speex_get_wb_sz_at() and speex_get_samples(). - Big cleanup to iax_send() - No longer use struct ast_frame, just pass needed bits as parameters. - Pull functionality out of calc_timestamp(). - iax_send() takes responsibility for initializing pvt->offset. - iax_send() only calls calc_timestamp() if "ts" is not set. - iax_send() updates pvt->lastsent. - Rename "now" to "immediate". - Check for ts error where it might happen. - Use new iax_frame_specialize() to encapsulate the complexity of pointer and buffer management of struct iax_frame. - Use ternary operators to reduce logic. - Pass ownership of iax_frame when calling iax_reliable_xmit() -- no longer need to free frame at end of function. - Cleanup calc_timestamp() by reducing responsibilities and changing parameters. - Remove unused parameters (i.e. seqno) from send_command() and friends. - Cleanup iax_handle_vnak(). - Use some variables; rename others. - Cleanup logic and reduce nesting in iax_header_to_event(). - Use calloc() when allocating struct iax_event. - Fix iax_get_sched() to take advantage of schedq being an in-order list. - Fix suspicious double free() code in iax_get_event(). This was not broken, but it required a lot of analysis to determine that. New code is much simpler. Modified Paths: -------------- trunk/lib/libiax2/src/frame.h trunk/lib/libiax2/src/iax.c trunk/lib/libiax2/src/iax2-parser.c trunk/lib/libiax2/src/iax2-parser.h Modified: trunk/lib/libiax2/src/frame.h =================================================================== --- trunk/lib/libiax2/src/frame.h 2008-07-01 16:17:53 UTC (rev 1441) +++ trunk/lib/libiax2/src/frame.h 2008-07-01 16:39:02 UTC (rev 1442) @@ -83,38 +83,6 @@ #define AST_FRIENDLY_OFFSET 64 /* Reserved header space */ -struct ast_frame { - /*! Kind of frame */ - int frametype; - /*! Subclass, frame dependent */ - int subclass; - /*! Length of data */ - int datalen; - /*! Number of 8khz samples in this frame */ - int samples; - /*! Was the data malloc'd? i.e. should we free it when we discard the f -rame? */ - int mallocd; - /*! How far into "data" the data really starts */ - int offset; - /*! Optional source of frame for debugging */ - char *src; - /*! Pointer to actual data */ - void *data; - /*! Next/Prev for linking stand alone frames */ - struct ast_frame *prev; - /*! Next/Prev for linking stand alone frames */ - struct ast_frame *next; - /* Unused except - if debugging is turned on, but left - in the struct - so that it can be turned on without - requiring a r -ecompile of the whole thing */ -}; - - - #if defined(__cplusplus) || defined(c_plusplus) } #endif Modified: trunk/lib/libiax2/src/iax.c =================================================================== --- trunk/lib/libiax2/src/iax.c 2008-07-01 16:17:53 UTC (rev 1441) +++ trunk/lib/libiax2/src/iax.c 2008-07-01 16:39:02 UTC (rev 1442) @@ -364,6 +364,44 @@ static struct iax_session *sessions = NULL; static int callnums = 1; +static inline struct timeval iax_tvadd_ms(struct timeval tv, int ms) +{ + const int million = 1000000; + tv.tv_sec += ms / 1000; + ms %= 1000; + tv.tv_usec += ms * 1000; + if ( tv.tv_usec > million ) + { + tv.tv_sec += 1; + tv.tv_usec -= million; + } + return tv; +} + +static inline int iax_tvdiff_ms(struct timeval end, struct timeval start) +{ + return ((end.tv_sec - start.tv_sec) * 1000) + + (((1000000 + end.tv_usec - start.tv_usec) / 1000) - 1000); +} + +static inline int iax_tvcmp(struct timeval a, struct timeval b) +{ + if ( a.tv_sec < b.tv_sec ) + return -1; + if ( a.tv_sec > b.tv_sec ) + return 1; + if ( a.tv_usec < b.tv_usec ) + return -1; + if ( a.tv_usec > b.tv_usec ) + return 1; + return 0; +} + +static inline int iax_tvzero(const struct timeval t) +{ + return t.tv_sec == 0 && t.tv_usec == 0; +} + unsigned int iax_session_get_capability(struct iax_session *s) { return s->capability; @@ -376,65 +414,56 @@ static int iax_sched_add(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int ms) { + /* Schedule event to be delivered to the client in ms milliseconds from + * now, or a reliable frame to be retransmitted */ + struct iax_sched *sched; + struct iax_sched *cur = schedq; + struct iax_sched *prev = NULL; - /* Schedule event to be delivered to the client - in ms milliseconds from now, or a reliable frame to be retransmitted */ - struct iax_sched *sched, *cur, *prev = NULL; - if (!event && !frame && !func) { DEBU(G "No event, no frame, no func? what are we scheduling?\n"); return -1; } - //fprintf(stderr, "scheduling event %d ms from now\n", ms); - sched = (struct iax_sched*)malloc(sizeof(struct iax_sched)); - if (sched) { - memset(sched, 0, sizeof(struct iax_sched)); - sched->when = iax_tvnow(); - sched->when.tv_sec += (ms / 1000); - ms = ms % 1000; - sched->when.tv_usec += (ms * 1000); - if (sched->when.tv_usec > 1000000) { - sched->when.tv_usec -= 1000000; - sched->when.tv_sec++; - } - sched->event = event; - sched->frame = frame; - sched->func = func; - sched->arg = arg; - /* Put it in the list, in order */ - cur = schedq; - while(cur && ((cur->when.tv_sec < sched->when.tv_sec) || - ((cur->when.tv_usec <= sched->when.tv_usec) && - (cur->when.tv_sec == sched->when.tv_sec)))) { - prev = cur; - cur = cur->next; - } - sched->next = cur; - if (prev) { - prev->next = sched; - } else { - schedq = sched; - } - return 0; - } else { + sched = calloc(1, sizeof(struct iax_sched)); + if (!sched) { DEBU(G "Out of memory!\n"); return -1; } + + sched->when = iax_tvadd_ms(iax_tvnow(), ms); + sched->event = event; + sched->frame = frame; + sched->func = func; + sched->arg = arg; + + /* Put it in the list, in order */ + while (cur && iax_tvcmp(cur->when, sched->when) <= 0) { + prev = cur; + cur = cur->next; + } + sched->next = cur; + if (prev) { + prev->next = sched; + } else { + schedq = sched; + } + + return 0; } static int iax_sched_del(struct iax_event *event, struct iax_frame *frame, sched_func func, void *arg, int all) { - struct iax_sched *cur, *tmp, *prev = NULL; + struct iax_sched *cur = schedq; + struct iax_sched *prev = NULL; - cur = schedq; while (cur) { if (cur->event == event && cur->frame == frame && cur->func == func && cur->arg == arg) { + struct iax_sched *tmp = cur; if (prev) prev->next = cur->next; else schedq = cur->next; - tmp = cur; cur = cur->next; free(tmp); if (!all) @@ -447,27 +476,25 @@ return 0; } - int iax_time_to_next_event(void) { - struct timeval tv; + struct timeval now; struct iax_sched *cur = schedq; - int ms, min = 999999999; + int min = 999999999; /* If there are no pending events, we don't need to timeout */ if (!cur) return -1; - tv = iax_tvnow(); + + now = iax_tvnow(); + while(cur) { - ms = (cur->when.tv_sec - tv.tv_sec) * 1000 + - (cur->when.tv_usec - tv.tv_usec) / 1000; + int ms = iax_tvdiff_ms(cur->when, now); if (ms < min) min = ms; cur = cur->next; } - if (min < 0) - min = 0; - return min; + return min < 0 ? 0 : min; } struct iax_session *iax_session_new(void) @@ -542,7 +569,8 @@ local->jitter = stats.jitter; /* XXX: should be short-term loss pct.. */ - if(stats.frames_in == 0) stats.frames_in = 1; + if(stats.frames_in == 0) + stats.frames_in = 1; local->losspct = stats.losspct/1000; local->losscnt = stats.frames_lost; local->packets = stats.frames_in; @@ -553,74 +581,29 @@ return 0; } -#ifdef USE_VOICE_TS_PREDICTION -static void add_ms(struct timeval *tv, int ms) +static int calc_timestamp(struct iax_session *session, int frametype, int samples) { - tv->tv_usec += ms * 1000; - if (tv->tv_usec > 999999) { - tv->tv_sec += tv->tv_usec / 1000000; - tv->tv_usec %= 1000000; - } - - if (tv->tv_usec < 0) { - tv->tv_sec += (tv->tv_usec / 1000000 - 1); - tv->tv_usec = (tv->tv_usec % 1000000) + 1000000; - } -} -#endif - -static int calc_timestamp(struct iax_session *session, unsigned int ts, struct ast_frame *f) -{ - int ms; - struct timeval tv; - int voice = 0; - int video = 0; - int genuine = 0; - - if ( f && f->frametype == AST_FRAME_VOICE ) - { - voice = 1; - } else if ( f && f->frametype == AST_FRAME_VIDEO ) - { - video = 1; - } else if (!f || f->frametype == AST_FRAME_IAX) - { - genuine = 1; - } - - /* If this is the first packet we're sending, get our - offset now. */ - if (!session->offset.tv_sec && !session->offset.tv_usec) - session->offset = iax_tvnow(); - - /* If the timestamp is specified, just use their specified - timestamp no matter what. Usually this is done for - special cases. */ - if (ts) - { - if ( f && session ) - session->lastsent = ts; - return ts; - } - - /* Otherwise calculate the timestamp from the current time */ - tv = iax_tvnow(); - /* Calculate the number of milliseconds since we sent the first packet */ - ms = (tv.tv_sec - session->offset.tv_sec) * 1000 + - (tv.tv_usec - session->offset.tv_usec) / 1000; + int ms = iax_tvdiff_ms(iax_tvnow(), session->offset); + int genuine = !frametype || frametype == AST_FRAME_IAX; + int voice = frametype == AST_FRAME_VOICE; + int video = frametype == AST_FRAME_VIDEO; - if (ms < 0) + if (ms < 0) { + fprintf(stderr, "iax2: calc_timestamp: negative time delta " + "ms => %d\n", ms); ms = 0; + } - if(voice) { + if (voice) { #ifdef USE_VOICE_TS_PREDICTION /* If we haven't most recently sent silence, and we're * close in time, use predicted time */ if(session->notsilenttx && abs(ms - session->nextpred) <= 240) { /* Adjust our txcore, keeping voice and non-voice * synchronized */ - add_ms(&session->offset, (int)(ms - session->nextpred)/10); + session->offset = iax_tvadd_ms(session->offset, + (int)(ms - session->nextpred) / 10); if(!session->nextpred) session->nextpred = ms; @@ -632,30 +615,34 @@ * time. Also, round ms to the next multiple of * frame size (so our silent periods are multiples * of frame size too) */ - int diff = ms % (f->samples / 8); + int diff = ms % (samples / 8); if(diff) - ms += f->samples/8 - diff; + ms += samples / 8 - diff; session->nextpred = ms; } session->notsilenttx = 1; + + /* set next predicted ts based on 8khz samples */ + session->nextpred += samples / 8; #else if(ms <= session->lastsent) ms = session->lastsent + 3; #endif } else if ( video ) { - /* - * IAX2 draft 03 says that timestamps MUST be in order. - * It does not say anything about several frames having the same timestamp - * When transporting video, we can have a frame that spans multiple iax packets - * (so called slices), so it would make sense to use the same timestamp for all of - * them - * We do want to make sure that frames don't go backwards though + /* IAX2 draft 03 says that timestamps MUST be in order. It + * does not say anything about several frames having the same + * timestamp. When transporting video, we can have a frame + * that spans multiple iax packets (so called slices), so it + * would make sense to use the same timestamp for all of them. + * We do want to make sure that frames don't go backwards + * though. */ if ( (unsigned int)ms < session->lastsent ) ms = session->lastsent; } else { - /* On a dataframe, use last value + 3 (to accomodate jitter buffer shrinking) - if appropriate unless it's a genuine frame */ + /* On a dataframe, use last value + 3 (to accomodate jitter + * buffer shrinking) if appropriate unless it's a genuine frame + */ if (genuine) { if ((unsigned int)ms <= session->lastsent) ms = session->lastsent + 3; @@ -665,21 +652,10 @@ } - /* Record the last sent packet for future reference */ - /* unless an AST_FRAME_IAX */ - if (!genuine) - session->lastsent = ms; - -#ifdef USE_VOICE_TS_PREDICTION - /* set next predicted ts based on 8khz samples */ - if(voice) - session->nextpred += f->samples / 8; -#endif - return ms; } -static unsigned char get_n_bits_at(unsigned char *data, int n, int bit) +static unsigned char get_n_bits_at(const unsigned char *data, const int n, const int bit) { int byte = bit / 8; /* byte containing first bit */ int rem = 8 - (bit % 8); /* remaining bits in first byte */ @@ -698,101 +674,106 @@ return (ret & (0xff >> (8 - n))); } -static int speex_get_wb_sz_at(unsigned char *data, int len, int bit) +static int speex_get_wb_sz_at(const unsigned char *data, const int len, const int bit) { - static int SpeexWBSubModeSz[] = { - 0, 36, 112, 192, - 352, 0, 0, 0 }; + static const int wb_skip_table[] = { + 0, 36, 112, 192, 352, 0, 0, 0 + }; + const int bit_len = len * 8; int off = bit; - unsigned char c; + int wideband; + if (bit_len - off < 5) + return -5; + + wideband = get_n_bits_at(data, 1, off); + /* skip up to two wideband frames */ - if (((len * 8 - off) >= 5) && - get_n_bits_at(data, 1, off)) { - c = get_n_bits_at(data, 3, off + 1); - off += SpeexWBSubModeSz[c]; + if (wideband) + { + int submode = get_n_bits_at(data, 3, off + 1); + off += wb_skip_table[submode]; - if (((len * 8 - off) >= 5) && - get_n_bits_at(data, 1, off)) { - c = get_n_bits_at(data, 3, off + 1); - off += SpeexWBSubModeSz[c]; + if (bit_len - off < 5) + return -6; - if (((len * 8 - off) >= 5) && - get_n_bits_at(data, 1, off)) { + wideband = get_n_bits_at(data, 1, off); + + if (wideband) + { + submode = get_n_bits_at(data, 3, off + 1); + off += wb_skip_table[submode]; + + if (bit_len - off < 5) + return -7; + + wideband = get_n_bits_at(data, 1, off); + if (wideband) /* too many in a row */ - DEBU(G "\tCORRUPT too many wideband streams in a row\n"); - return -1; - } + return -8; } } return off - bit; } -static int speex_get_samples(unsigned char *data, int len) +static int speex_get_samples(const unsigned char *data, const int len) { - static int SpeexSubModeSz[] = { + static const int SpeexSubModeSz[] = { 0, 43, 119, 160, 220, 300, 364, 492, 79, 0, 0, 0, 0, 0, 0, 0 }; - static int SpeexInBandSz[] = { + static const int SpeexInBandSz[] = { 1, 1, 4, 4, 4, 4, 4, 4, 8, 8, 16, 16, 32, 32, 64, 64 }; + const int bit_len = len * 8; int bit = 0; int cnt = 0; - int off = 0; - unsigned char c; - DEBU(G "speex_get_samples(%d)\n", len); - while ((len * 8 - bit) >= 5) { + while (bit_len - bit >= 5) { + unsigned char c; + /* skip wideband frames */ - off = speex_get_wb_sz_at(data, len, bit); - if (off < 0) { - DEBU(G "\tERROR reading wideband frames\n"); - break; - } - bit += off; + const int advance = speex_get_wb_sz_at(data, len, bit); + if (advance < 0) + return advance; - if ((len * 8 - bit) < 5) { - DEBU(G "\tERROR not enough bits left after wb\n"); - break; - } + bit += advance; + if (bit_len - bit < 5) + return -1; + /* get control bits */ c = get_n_bits_at(data, 5, bit); - DEBU(G "\tCONTROL: %d at %d\n", c, bit); bit += 5; if (c == 15) { - DEBU(G "\tTERMINATOR\n"); + /* terminator */ break; } else if (c == 14) { /* in-band signal; next 4 bits contain signal id */ + if (bit_len - bit < 4) + return -3; c = get_n_bits_at(data, 4, bit); - bit += 4; - DEBU(G "\tIN-BAND %d bits\n", SpeexInBandSz[c]); - bit += SpeexInBandSz[c]; + bit += 4 + SpeexInBandSz[c]; } else if (c == 13) { /* user in-band; next 5 bits contain msg len */ + if (bit_len - bit < 5) + return -4; c = get_n_bits_at(data, 5, bit); - bit += 5; - DEBU(G "\tUSER-BAND %d bytes\n", c); - bit += c * 8; + bit += 5 + c * 8; } else if (c > 8) { - DEBU(G "\tUNKNOWN sub-mode %d\n", c); - break; + /* unknown submode */ + return -2; } else { /* skip number bits for submode (less the 5 control bits) */ - DEBU(G "\tSUBMODE %d %d bits\n", c, SpeexSubModeSz[c]); bit += SpeexSubModeSz[c] - 5; - cnt += 160; /* new frame */ } } - DEBU(G "\tSAMPLES: %d\n", cnt); return cnt; } @@ -863,7 +844,7 @@ } #endif /* Send the frame raw */ - res = f->session->sendto(netfd, (const char *) f->data, f->datalen, + res = f->session->sendto(netfd, f->rawdata, f->rawdatalen, IAX_SOCKOPTS, f->transfer ? (struct sockaddr *)&(f->session->transfer) : (struct sockaddr *)&(f->session->peeraddr), @@ -873,34 +854,13 @@ static int iax_reliable_xmit(struct iax_frame *f) { - struct iax_frame *fc; - struct ast_iax2_full_hdr *fh; - fh = (struct ast_iax2_full_hdr *) f->data; - if (!fh->type) { + struct ast_iax2_full_hdr *fh = f->rawdata; + + if (!fh->type) return -2; - } - fc = (struct iax_frame *)malloc(sizeof(struct iax_frame)); - if (fc) { - /* Make a copy of the frame */ - memcpy(fc, f, sizeof(struct iax_frame)); - /* And a copy of the data if applicable */ - if (!fc->data || !fc->datalen) { - IAXERROR "No frame data?"); - DEBU(G "No frame data?\n"); - return -1; - } else { - fc->data = (char *)malloc(fc->datalen); - if (!fc->data) { - DEBU(G "Out of memory\n"); - IAXERROR "Out of memory\n"); - return -1; - } - memcpy(fc->data, f->data, f->datalen); - iax_sched_add(NULL, fc, NULL, NULL, fc->retrytime); - return iax_xmit_frame(fc); - } - } else - return -1; + + iax_sched_add(NULL, f, NULL, NULL, f->retrytime); + return iax_xmit_frame(f); } void iax_set_networking(iax_sendto_t st, iax_recvfrom_t rf) @@ -1065,22 +1025,25 @@ return power | IAX_FLAG_SC_LOG; } -static int iax_send(struct iax_session *pvt, struct ast_frame *f, unsigned int ts, int seqno, int now, int transfer, int final, int fullframe) +static int iax_send(struct iax_session *pvt, + int frametype, + int subclass, + const unsigned char *data, + const size_t datalen, + unsigned int ts, + int seqno, + int immediate, + int transfer, + int final, + int fullframe, + int samples) { - /* Queue a packet for delivery on a given private structure. Use "ts" for - timestamp, or calculate if ts is 0. Send immediately without retransmission - or delayed, with retransmission */ - struct ast_iax2_full_hdr *fh; - struct ast_iax2_mini_hdr *mh; - struct ast_iax2_video_hdr *vh; - //unsigned char buf[5120]; //fd: changed max packet size[5120]; - unsigned char buf[32 * 1024]; //Mihai: let's see if this is where it crashes - + /* Queue a packet for delivery on a given private structure. Use "ts" + * for timestamp, or calculate if ts is 0. Send immediately without + * retransmission or delayed, with retransmission */ + char buf[8192]; struct iax_frame *fr; - int res; - int sendmini=0; - unsigned int lastsent; - unsigned int fts; + int sendmini = 0; if (!pvt) { @@ -1088,115 +1051,116 @@ return -1; } - /* this must come before the next call to calc_timestamp() since - calc_timestamp() will change lastsent to the returned value */ - lastsent = pvt->lastsent; + /* If this is the first packet we're sending, get our offset now. */ + if (iax_tvzero(pvt->offset)) + pvt->offset = iax_tvnow(); - /* Calculate actual timestamp */ - fts = calc_timestamp(pvt, ts, f); - - if (((fts & 0xFFFF0000L) == (lastsent & 0xFFFF0000L)) - /* High two bits are the same on timestamp, or sending on a trunk */ && - (f->frametype == AST_FRAME_VOICE) - /* is a voice frame */ && - (f->subclass == pvt->svoiceformat) - /* is the same type */ ) + if (!ts) { - /* Force immediate rather than delayed transmission */ - now = 1; - /* Mark that mini-style frame is appropriate */ - sendmini = 1; + /* Calculate actual timestamp */ + ts = calc_timestamp(pvt, frametype, samples); + + if (!ts) + { + IAXERROR "timestamp is 0?\n"); + return -1; + } } - /* Bitmask taken from chan_iax2.c... I must ask Mark Spencer for this? I think not... */ - if ( f->frametype == AST_FRAME_VIDEO ) + if ( frametype == AST_FRAME_VOICE ) { - /* Check if the timestamp has rolled over or if the video codec has changed */ - if ( ((fts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L)) && - (f->subclass == pvt->svideoformat) - ) + /* High two bits are the same on timestamp, or sending on a trunk */ + if ((ts & 0xFFFF0000L) == (pvt->lastsent & 0xFFFF0000L) && + subclass == pvt->svoiceformat) { + /* Force immediate rather than delayed transmission */ + immediate = 1; + /* Mark that mini-style frame is appropriate */ + sendmini = 1; + } + + pvt->lastsent = ts; + } + else if ( frametype == AST_FRAME_VIDEO ) + { + /* Check if the timestamp has rolled over or if the video codec + * has changed */ + if ( (ts & 0xFFFF8000L) == (pvt->lastvsent & 0xFFFF8000L) && + subclass == pvt->svideoformat ) + { /* send a mini video frame immediately */ - now = 1; + immediate = 1; sendmini = 1; - } else + } + else { - /* we want to send a fullframe and be able to retransmit it */ - now = 0; + /* we want to send a fullframe and be able to + * retransmit it */ + immediate = 0; sendmini = 0; } - pvt->lastvsent = fts; + + pvt->lastvsent = ts; + pvt->lastsent = ts; } /* if requested, force a full frame */ if ( fullframe ) { - now = 0; + immediate = 0; sendmini = 0; } - + /* Allocate an iax_frame */ - if (now) + if (immediate) { + if ( sizeof(*fr) + datalen > sizeof(buf) ) + { + IAXERROR "frame buffer too small"); + return -1; + } fr = (struct iax_frame *) buf; - } else + } + else { - fr = iax_frame_new(DIRECTION_OUTGRESS, f->datalen); + fr = iax_frame_new(datalen); if ( fr == NULL ) { IAXERROR "Out of memory\n"); return -1; } } - - /* Copy our prospective frame into our immediate or retransmitted wrapper */ - iax_frame_wrap(fr, f); - fr->ts = fts; - if (!fr->ts) - { - IAXERROR "timestamp is 0?\n"); - if (!now) - iax_frame_free(fr); - return -1; - } - + fr->ts = ts; fr->callno = pvt->callno; fr->transfer = transfer; fr->final = final; fr->session = pvt; + if (!sendmini) { /* We need a full frame */ - if (seqno > -1) - fr->oseqno = seqno; - else - fr->oseqno = pvt->oseqno++; + struct ast_iax2_full_hdr *fh; + + iax_frame_specialize(fr, ast_iax2_full_hdr, data, datalen); + + fh = fr->rawdata; + + fr->oseqno = seqno > -1 ? seqno : pvt->oseqno++; fr->iseqno = pvt->iseqno; - fh = (struct ast_iax2_full_hdr *)(((char *)fr->af.data) - sizeof(struct ast_iax2_full_hdr)); fh->scallno = htons(fr->callno | IAX_FLAG_FULL); fh->ts = htonl(fr->ts); fh->oseqno = fr->oseqno; - if (transfer) - { - fh->iseqno = 0; - } else - fh->iseqno = fr->iseqno; - /* Keep track of the last thing we've acknowledged */ + fh->iseqno = transfer ? 0 : fr->iseqno; + /* Keep track of the last thing we've acknowledged */ pvt->aseqno = fr->iseqno; - fh->type = fr->af.frametype & 0xFF; - if (f->frametype == AST_FRAME_VIDEO) - fh->csub = compress_subclass(fr->af.subclass & ~0x1) | ((fr->af.subclass & 0x1) << 6); + fh->type = frametype & 0xFF; + if (frametype == AST_FRAME_VIDEO) + fh->csub = compress_subclass(subclass & ~0x1) | ((subclass & 0x1) << 6); else - fh->csub = compress_subclass(fr->af.subclass); - if (transfer) - { - fr->dcallno = pvt->transfercallno; - } else - fr->dcallno = pvt->peercallno; + fh->csub = compress_subclass(subclass); + fr->dcallno = transfer ? pvt->transfercallno : pvt->peercallno; fh->dcallno = htons(fr->dcallno); - fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_full_hdr); - fr->data = fh; fr->retries = maxretries; /* Retry after 2x the ping time has passed */ fr->retrytime = pvt->pingtime * 2; @@ -1205,54 +1169,47 @@ if (fr->retrytime > MAX_RETRY_TIME) fr->retrytime = MAX_RETRY_TIME; /* Acks' don't get retried */ - if ((f->frametype == AST_FRAME_IAX) && (f->subclass == IAX_COMMAND_ACK)) + if (frametype == AST_FRAME_IAX && subclass == IAX_COMMAND_ACK) fr->retries = -1; - if (f->frametype == AST_FRAME_VOICE) - { - pvt->svoiceformat = f->subclass; - } - else if (f->frametype == AST_FRAME_VIDEO) - { - pvt->svideoformat = f->subclass & ~0x1; - } - if (now) - { - res = iax_xmit_frame(fr); - } else - res = iax_reliable_xmit(fr); - } else + if (frametype == AST_FRAME_VOICE) + pvt->svoiceformat = subclass; + else if (frametype == AST_FRAME_VIDEO) + pvt->svideoformat = subclass & ~0x1; + } + else { - if (fr->af.frametype == AST_FRAME_VIDEO) + /* Mini-frames have no sequence number */ + fr->oseqno = -1; + fr->iseqno = -1; + fr->retries = -1; + + if (frametype == AST_FRAME_VIDEO) { - /* Video frame have no sequence number */ - fr->oseqno = -1; - fr->iseqno = -1; - vh = (struct ast_iax2_video_hdr *)(((char* )fr->af.data) - sizeof(struct ast_iax2_video_hdr)); + struct ast_iax2_video_hdr *vh; + + iax_frame_specialize(fr, ast_iax2_video_hdr, data, datalen); + + vh = fr->rawdata; vh->zeros = 0; vh->callno = htons(IAX_FLAG_FULL | fr->callno); - vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); - fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); - fr->data = vh; - fr->retries = -1; - res = iax_xmit_frame(fr); - } else + vh->ts = htons((fr->ts & 0x7FFF) | (subclass & 0x1 ? 0x8000 : 0)); + } + else { - /* Mini-frames have no sequence number */ - fr->oseqno = -1; - fr->iseqno = -1; /* Mini frame will do */ - mh = (struct ast_iax2_mini_hdr *)(((char *)fr->af.data) - sizeof(struct ast_iax2_mini_hdr)); + struct ast_iax2_mini_hdr *mh; + + iax_frame_specialize(fr, ast_iax2_mini_hdr, data, datalen); + + mh = fr->rawdata; mh->callno = htons(fr->callno); mh->ts = htons(fr->ts & 0xFFFF); - fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_mini_hdr); - fr->data = mh; - fr->retries = -1; - res = iax_xmit_frame(fr); } } - if( !now && fr!=NULL ) - iax_frame_free( fr ); - return res; + + return immediate ? + iax_xmit_frame(fr) : + iax_reliable_xmit(fr); } #if 0 @@ -1281,61 +1238,78 @@ } #endif -static int __send_command(struct iax_session *i, char type, int command, - unsigned int ts, unsigned char *data, int datalen, int seqno, - int now, int transfer, int final, int fullframe, int samples) +static int send_command(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen) { - struct ast_frame f; - f.frametype = type; - f.subclass = command; - f.datalen = datalen; - f.samples = samples; - f.mallocd = 0; - f.offset = 0; -#ifdef __GNUC__ - f.src = (char *) __FUNCTION__; -#else - f.src = (char *) __FILE__; -#endif - f.data = data; - return iax_send(i, &f, ts, seqno, now, transfer, final, fullframe); + return iax_send(i, type, command, data, datalen, ts, + -1, /* seqno */ + 0, /* immediate */ + 0, /* transfer */ + 0, /* final */ + 0, /* fullframe */ + 0 /* samples */ + ); } -static int send_command(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno) +static int send_command_video(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int fullframe) { - return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, 0, 0); + return iax_send(i, type, command, data, datalen, ts, + -1, /* seqno */ + 1, /* immediate */ + 0, /* transfer */ + 0, /* final */ + fullframe, + 0); /* samples */ } -static int send_command_video(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno, int fullframe) +static int send_command_final(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen) { - return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0, fullframe, 0); -} - -static int send_command_final(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno) -{ #if 0 /* It is assumed that the callno has already been locked */ iax_predestroy(i); #endif - int r; - r = __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 1, 0, 0); - if (r >= 0) destroy_session(i); + int r = iax_send(i, type, command, data, datalen, ts, + -1, /* seqno */ + 1, /* immediate */ + 0, /* transfer */ + 1, /* final */ + 0, /* fullframe */ + 0); /* samples */ + if (r >= 0) + destroy_session(i); return r; } static int send_command_immediate(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno) { - return __send_command(i, type, command, ts, data, datalen, seqno, 1, 0, 0, 0, 0); + return iax_send(i, type, command, data, datalen, ts, seqno, + 1, /* immediate */ + 0, /* transfer */ + 0, /* final */ + 0, /* fullframe */ + 0); /* samples */ } -static int send_command_transfer(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen) +static int send_command_transfer(struct iax_session *i, char type, int command, unsigned char *data, int datalen) { - return __send_command(i, type, command, ts, data, datalen, 0, 0, 1, 0, 0, 0); + return iax_send(i, type, command, data, datalen, + 0, /* ts */ + 0, /* seqno */ + 0, /* immediate */ + 1, /* transfer */ + 0, /* final */ + 0, /* fullframe */ + 0); /* samples */ } -static int send_command_samples(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int seqno, int samples) +static int send_command_samples(struct iax_session *i, char type, int command, unsigned int ts, unsigned char *data, int datalen, int samples) { - return __send_command(i, type, command, ts, data, datalen, seqno, 0, 0, 0, 0, samples); + return iax_send(i, type, command, data, datalen, ts, + -1, /* seqno */ + 0, /* immediate */ + 0, /* transfer */ + 0, /* final */ + 0, /* fullframe */ + samples); } @@ -1351,7 +1325,7 @@ iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number); // Send The Transfer Command - Asterisk Will Handle The Rest! - res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos, -1); + res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_TRANSFER, 0, ied.buf, ied.pos); // Return Success return 0; @@ -1363,11 +1337,11 @@ sch = schedq; while(sch) { - if (sch->frame && (sch->frame->session == session)) - sch->frame->retries = -1; + if (sch->frame && sch->frame->session == session) + sch->frame->retries = -1; sch = sch->next; } -} /* stop_transfer */ +} static void complete_transfer(struct iax_session *session, int peercallno, int xfr2peer, int preserveSeq) { @@ -1458,12 +1432,12 @@ } #endif - res = send_command(s0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos, -1); + res = send_command(s0, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied0.buf, ied0.pos); if (res < 0) { return -1; } - res = send_command(s1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos, -1); + res = send_command(s1, AST_FRAME_IAX, IAX_COMMAND_TXREQ, 0, ied1.buf, ied1.pos); if (res < 0) { return -1; } @@ -1480,7 +1454,7 @@ iax_ie_append_short(&ied, IAX_IE_CALLNO, new_peer); - res = send_command(s, AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied.buf, ied.pos, -1); + res = send_command(s, AST_FRAME_IAX, IAX_COMMAND_TXREL, 0, ied.buf, ied.pos); complete_transfer(s, new_peer, 0, 1); @@ -1564,7 +1538,6 @@ { struct iax_session *cur, *prev=NULL; struct iax_sched *curs, *prevs=NULL, *nexts=NULL; - int loop_cnt=0; curs = schedq; while(curs) { nexts = curs->next; @@ -1583,7 +1556,6 @@ prevs = curs; } curs = nexts; - loop_cnt++; } cur = sessions; @@ -1673,14 +1645,14 @@ int iax_send_dtmf(struct iax_session *session, char digit) { - return send_command(session, AST_FRAME_DTMF, digit, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_DTMF, digit, 0, NULL, 0); } int iax_send_voice(struct iax_session *session, int format, unsigned char *data, int datalen, int samples) { /* Send a (possibly compressed) voice frame */ if (!session->quelch) - return send_command_samples(session, AST_FRAME_VOICE, format, 0, data, datalen, -1, samples); + return send_command_samples(session, AST_FRAME_VOICE, format, 0, data, datalen, samples); return 0; } @@ -1690,14 +1662,14 @@ #ifdef USE_VOICE_TS_PREDICTION session->notsilenttx = 0; #endif - return send_command(session, AST_FRAME_CNG, level, 0, data, datalen, -1); + return send_command(session, AST_FRAME_CNG, level, 0, data, datalen); } int iax_send_image(struct iax_session *session, int format, unsigned char *data, int datalen) { /* Send an image frame */ - return send_command(session, AST_FRAME_IMAGE, format, 0, data, datalen, -1); + return send_command(session, AST_FRAME_IMAGE, format, 0, data, datalen); } int iax_send_video(struct iax_session *session, int format, unsigned char *data, @@ -1706,7 +1678,7 @@ if (!session->quelch) { int res = send_command_video(session, AST_FRAME_VIDEO, format, - 0, data, datalen, -1, fullframe); + 0, data, datalen, fullframe); return res; } return 0; @@ -1718,12 +1690,12 @@ static int my_lastts = 0; if ( ntrunk == 0 ) - my_lastts = calc_timestamp(session, 0, NULL); + my_lastts = calc_timestamp(session, 0, 0); if ( !session->quelch ) { return send_command_video(session, AST_FRAME_VIDEO, format, - my_lastts, (unsigned char *)data, datalen, -1, + my_lastts, (unsigned char *)data, datalen, fullframe); } return 0; @@ -1774,7 +1746,7 @@ session->refresh = refresh; iax_ie_append_str(&ied, IAX_IE_USERNAME, peer); iax_ie_append_short(&ied, IAX_IE_REFRESH, refresh); - res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); + res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos); return res; } @@ -1818,7 +1790,7 @@ strncpy(session->username, peer, sizeof(session->username) - 1); iax_ie_append_str(&ied, IAX_IE_USERNAME, peer); iax_ie_append_str(&ied, IAX_IE_CAUSE, session->unregreason); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos); } int iax_reject(struct iax_session *session, char *reason) @@ -1826,7 +1798,7 @@ struct iax_ie_data ied; memset(&ied, 0, sizeof(ied)); iax_ie_append_str(&ied, IAX_IE_CAUSE, reason ? reason : "Unspecified"); - return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos, -1); + return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_REJECT, 0, ied.buf, ied.pos); } int iax_hangup(struct iax_session *session, char *byemsg) @@ -1835,33 +1807,33 @@ iax_sched_del(NULL, NULL, send_ping, (void *) session, 1); memset(&ied, 0, sizeof(ied)); iax_ie_append_str(&ied, IAX_IE_CAUSE, byemsg ? byemsg : "Normal clearing"); - return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos, -1); + return send_command_final(session, AST_FRAME_IAX, IAX_COMMAND_HANGUP, 0, ied.buf, ied.pos); } int iax_sendurl(struct iax_session *session, char *url) { return send_command(session, AST_FRAME_HTML, AST_HTML_URL, 0, - (unsigned char *)url, (int)strlen(url), -1); + (unsigned char *)url, (int)strlen(url)); } int iax_ring_announce(struct iax_session *session) { - return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_RINGING, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_RINGING, 0, NULL, 0); } int iax_lag_request(struct iax_session *session) { - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRQ, 0, NULL, 0); } int iax_busy(struct iax_session *session) { - return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_BUSY, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_BUSY, 0, NULL, 0); } int iax_congestion(struct iax_session *session) { - return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_CONGESTION, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_CONGESTION, 0, NULL, 0); } @@ -1870,50 +1842,50 @@ struct iax_ie_data ied; memset(&ied, 0, sizeof(ied)); iax_ie_append_int(&ied, IAX_IE_FORMAT, format); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_ACCEPT, 0, ied.buf, ied.pos); } int iax_answer(struct iax_session *session) { - return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_ANSWER, 0, NULL, 0); } int iax_key_radio(struct iax_session *session) { - return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_KEY, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_KEY, 0, NULL, 0); } int iax_unkey_radio(struct iax_session *session) { - return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_UNKEY, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_CONTROL, AST_CONTROL_UNKEY, 0, NULL, 0); } int iax_load_complete(struct iax_session *session) { - return send_command(session, AST_FRAME_HTML, AST_HTML_LDCOMPLETE, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_HTML, AST_HTML_LDCOMPLETE, 0, NULL, 0); } int iax_send_url(struct iax_session *session, const char *url, int link) { return send_command(session, AST_FRAME_HTML, link ? AST_HTML_LINKURL : AST_HTML_URL, 0, - (unsigned char *)url, (int)strlen(url), -1); + (unsigned char *)url, (int)strlen(url)); } int iax_send_text(struct iax_session *session, const char *text) { return send_command(session, AST_FRAME_TEXT, 0, 0, - (unsigned char *)text, (int)strlen(text) + 1, -1); + (unsigned char *)text, (int)strlen(text) + 1); } int iax_send_unlink(struct iax_session *session) { - return send_command(session, AST_FRAME_HTML, AST_HTML_UNLINK, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_HTML, AST_HTML_UNLINK, 0, NULL, 0); } int iax_send_link_reject(struct iax_session *session) { - return send_command(session, AST_FRAME_HTML, AST_HTML_LINKREJECT, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_HTML, AST_HTML_LINKREJECT, 0, NULL, 0); } static int iax_send_pong(struct iax_session *session, unsigned int ts) @@ -1937,13 +1909,13 @@ iax_ie_append_int(&ied,IAX_IE_RR_DROPPED, stats.frames_dropped); iax_ie_append_int(&ied,IAX_IE_RR_OOO, stats.frames_ooo); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PONG, ts, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PONG, ts, ied.buf, ied.pos); } /* external API; deprecated since we send pings ourselves now (finally) */ int iax_send_ping(struct iax_session *session) { - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0); } /* scheduled ping sender; sends ping, then reschedules */ @@ -1954,14 +1926,14 @@ /* important, eh? */ if(!iax_session_valid(session)) return; - send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0, -1); + send_command(session, AST_FRAME_IAX, IAX_COMMAND_PING, 0, NULL, 0); session->pingid = iax_sched_add(NULL,NULL, send_ping, (void *)session, ping_time * 1000); return; } static int iax_send_lagrp(struct iax_session *session, unsigned int ts) { - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRP, ts, NULL, 0, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_LAGRP, ts, NULL, 0); } static int iax_send_txcnt(struct iax_session *session) @@ -1969,7 +1941,7 @@ struct iax_ie_data ied; memset(&ied, 0, sizeof(ied)); iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid); - return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXCNT, 0, ied.buf, ied.pos); + return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXCNT, ied.buf, ied.pos); } static int iax_send_txrej(struct iax_session *session) @@ -1977,7 +1949,7 @@ struct iax_ie_data ied; memset(&ied, 0, sizeof(ied)); iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid); - return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXREJ, 0, ied.buf, ied.pos); + return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXREJ, ied.buf, ied.pos); } static int iax_send_txaccept(struct iax_session *session) @@ -1985,7 +1957,7 @@ struct iax_ie_data ied; memset(&ied, 0, sizeof(ied)); iax_ie_append_int(&ied, IAX_IE_TRANSFERID, session->transferid); - return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXACC, 0, ied.buf, ied.pos); + return send_command_transfer(session, AST_FRAME_IAX, IAX_COMMAND_TXACC, ied.buf, ied.pos); } static int iax_send_txready(struct iax_session *session) @@ -1994,7 +1966,7 @@ memset(&ied, 0, sizeof(ied)); /* see asterisk chan_iax2.c */ iax_ie_append_short(&ied, IAX_IE_CALLNO, session->callno); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_TXREADY, 0, ied.buf, ied.pos); } int iax_auth_reply(struct iax_session *session, char *password, char *challenge, int methods) @@ -2017,7 +1989,7 @@ } else { iax_ie_append_str(&ied, IAX_IE_PASSWORD, password); } - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_AUTHREP, 0, ied.buf, ied.pos); } static int iax_regauth_reply(struct iax_session *session, char *password, char *challenge, int methods) @@ -2043,10 +2015,10 @@ } if (strlen(session->unregreason)) { /* Non-zero unregreason length indicates REGREL */ iax_ie_append_str(&ied, IAX_IE_CAUSE, session->unregreason); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREL, 0, ied.buf, ied.pos); } else { iax_ie_append_short(&ied, IAX_IE_REFRESH, session->refresh); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_REGREQ, 0, ied.buf, ied.pos); } } @@ -2056,17 +2028,17 @@ struct iax_ie_data ied; memset(&ied, 0, sizeof(ied)); iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DIAL, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DIAL, 0, ied.buf, ied.pos); } int iax_quelch(struct iax_session *session) { - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_QUELCH, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_QUELCH, 0, NULL, 0); } int iax_unquelch(struct iax_session *session) { - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_UNQUELCH, 0, NULL, 0); } int iax_dialplan_request(struct iax_session *session, char *number) @@ -2074,7 +2046,7 @@ struct iax_ie_data ied; memset(&ied, 0, sizeof(ied)); iax_ie_append_str(&ied, IAX_IE_CALLED_NUMBER, number); - return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos, -1); + return send_command(session, AST_FRAME_IAX, IAX_COMMAND_DPREQ, 0, ied.buf, ied.pos); } static inline int which_bit(unsigned int i) @@ -2223,7 +2195,7 @@ memcpy(&session->peeraddr.sin_addr, hp->h_addr, sizeof(session->peeraddr.sin_addr)); session->peeraddr.sin_port = htons(portno); session->peeraddr.sin_family = AF_INET; - res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos, -1); + res = send_command(session, AST_FRAME_IAX, IAX_COMMAND_NEW, 0, ied.buf, ied.pos); if (res < 0) return res; if (wait) { @@ -2235,42 +2207,14 @@ static int calc_rxstamp(struct iax_session *session) { - struct timeval tv; - int ms; + struct timeval now = iax_tvnow(); - if (!session->rxcore.tv_sec && !session->rxcore.tv_usec) { - session->rxcore = iax_tvnow(); - } - tv = iax_tvnow(); + if (iax_tvzero(session->rxcore)) + session->rxcore = now; - ms = (tv.tv_sec - session->rxcore.tv_sec) * 1000 + - (tv.tv_usec - session->rxcore.tv_usec) / 1000; - return ms; + return iax_tvdiff_ms(now, session->rxcore); } -#ifdef notdef_cruft -static int match(struct sockaddr_in *sin, short callno, short dcallno, struct iax_session *cur) -{ - if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->peeraddr.sin_port == sin->sin_port)) { - /* This is the main host */ - if ((cur->peercallno == callno) || - ((dcallno == cur->callno) && !cur->peercallno)) { - /* That's us. Be sure we keep track of the peer call number */ - cur->peercallno = callno; - return 1; - } - } - if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { - /* We're transferring */ - if (dcallno == cur->callno) - return 1; - } - return 0; -} -#endif - /* splitted match into 2 passes otherwise causing problem of matching up the wrong session using the dcallno and the peercallno because during a transfer (2 IAX channels on the same client/system) the @@ -2279,17 +2223,13 @@ */ static int forward_match(struct sockaddr_in *sin, short callno, short dcallno, struct iax_session *cur) { - if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { + if (inaddrcmp(&cur->transfer, sin) == 0 && cur->transferring) { /* We're transferring */ if (dcallno == cur->callno) - { return 1; - } } - if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->peeraddr.sin_port == sin->sin_port)) { + if (inaddrcmp(&cur->peeraddr, sin) == 0) { if (dcallno == cur->callno && dcallno != 0) { /* That's us. Be sure we keep track of the peer call number */ if (cur->peercallno == 0) { @@ -2312,18 +2252,15 @@ static int reverse_match(struct sockaddr_in *sin, short callno, struct iax_session *cur) { - if ((cur->transfer.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->transfer.sin_port == sin->sin_port) && (cur->transferring)) { + if (inaddrcmp(&cur->transfer, sin) == 0 && cur->transferring) { /* We're transferring */ - if (callno == cur->peercallno) { + if (callno == cur->peercallno) return 1; - } } - if ((cur->peeraddr.sin_addr.s_addr == sin->sin_addr.s_addr) && - (cur->peeraddr.sin_port == sin->sin_port)) { - if (callno == cur->peercallno) { + + if (inaddrcmp(&cur->peeraddr, sin) == 0) { + if (callno == cur->peercallno) return 1; - } } return 0; @@ -2335,18 +2272,16 @@ int makenew) { struct iax_session *cur = sessions; - while(cur) { - if (forward_match(sin, callno, dcallno, cur)) { + while (cur) { + if (forward_match(sin, callno, dcallno, cur)) return cur; - } cur = cur->next; } cur = sessions; - while(cur) { - if (reverse_match(sin, callno, cur)) { + while (cur) { + if (reverse_match(sin, callno, cur)) return cur; - } cur = cur->next; } @@ -2364,22 +2299,6 @@ return cur; } -#ifdef EXTREME_DEBUG -static int display_time(int ms) -{ - static int oldms = -1; - if (oldms < 0) { - DEBU(G "First measure\n"); - oldms = ms; - return 0; - } - DEBU(G "Time from last frame is %d ms\n", ms - oldms); - oldms = ms; - return 0; -} -#endif - -/* From chan_iax2/steve davies: need to get permission from steve or digium, I guess */ static long unwrap_timestamp(long ts, long last, int is_video) { const int ts_shift = is_video ? 15 : 16; @@ -2422,9 +2341,8 @@ * before delivering the packet. */ -#ifdef EXTREME_DEBUG - DEBU(G "[%p] We are at %d, packet is for %d\n", e->session, calc_rxstamp(e->session), ts); -#endif + int type = JB_TYPE_CONTROL; + int ms = 0; /* insert into jitterbuffer */ /* TODO: Perhaps we could act immediately if it's not droppable and late */ @@ -2434,41 +2352,51 @@ { iax_sched_add(e, NULL, NULL, NULL, 0); return NULL; - } else + } + + if (e->etype == IAX_EVENT_VOICE) { - int type = JB_TYPE_CONTROL; - int len = 0; + const int samples = get_sample_cnt(e); - if(e->etype == IAX_EVENT_VOICE) + if ( samples < 0 ) { - type = JB_TYPE_VOICE; - /* The frame time only has an effect for voice */ - len = get_sample_cnt(e) / 8; - } else if(e->etype == IAX_EVENT_VIDEO) - { - type = JB_TYPE_VIDEO; - } else if(e->etype == IAX_EVENT_CNG) - { - type = JB_TYPE_SILENCE; + /* If get_sample_cnt fails, then something very bad + * is occurring, drop the frame and log the problem. + */ + fprintf(stderr, "iax2: get_sample_cnt failed %d\n", + samples); + iax_event_free(e); + return NULL; } - /* unwrap timestamp */ - ts = unwrap_timestamp(ts, e->session->last_ts, - e->etype == IAX_EVENT_VIDEO); + /* The frame time only has an effect for voice */ + ms = samples * 1000 / 8000; - /* move forward last_ts if it's greater. We do this _after_ - * unwrapping, because asterisk _still_ has cases where it - * doesn't send full frames when it ought to */ - if(ts > e->session->last_ts) - { - e->session->last_ts = ts; - } + type = JB_TYPE_VOICE; + } + else if (e->etype == IAX_EVENT_VIDEO) + { + type = JB_TYPE_VIDEO; + } + else if (e->etype == IAX_EVENT_CNG) + { + type = JB_TYPE_SILENCE; + } - if(jb_put(e->session->jb, e, type, len, ts, - calc_rxstamp(e->session)) == JB_DROP) - { - iax_event_free(e); - } + /* unwrap timestamp */ + ts = unwrap_timestamp(ts, e->session->last_ts, + e->etype == IAX_EVENT_VIDEO); + + /* move forward last_ts if it's greater. We do this _after_ + * unwrapping, because asterisk _still_ has cases where it + * doesn't send full frames when it ought to */ + if ( ts > e->session->last_ts ) + e->session->last_ts = ts; + + if ( jb_put(e->session->jb, e, type, ms, ts, + calc_rxstamp(e->session)) == JB_DROP ) + { + iax_event_free(e); } return NULL; @@ -2485,58 +2413,64 @@ static void iax_handle_vnak(struct iax_session *session, struct ast_iax2_full_hdr *fh) { - struct iax_sched *sch, *list, *l, *tmp; + struct iax_sched *sch = schedq; + struct iax_sched *retrans_list = NULL; + const unsigned char vnak_seqno = fh->iseqno - session->rseqno; - /* - * According to the IAX2 02 draft, we MUST immediately retransmit all frames - * with higher sequence number than the VNAK's iseqno - * However, it seems that the right thing to do would be to retransmit - * frames with sequence numbers higher OR EQUAL to VNAK's iseqno. + /* According to the IAX2 02 draft, we MUST immediately retransmit all + * frames with higher sequence number than the VNAK's iseqno. However, + * it seems that the right thing to do would be to retransmit frames + * with sequence numbers higher OR EQUAL to VNAK's iseqno. */ - sch = schedq; - list = NULL; while ( sch != NULL ) { if ( sch->frame != NULL && sch->frame->session == session ) { - /* - * We want to check if our frame's oseqno is greater or equal than - * the VNAK's iseqno, but we need to take into account sequence - * number wrap-arounds - * session->rseqno is our last acknowledged sequence number, so - * we use that as a base + /* We want to check if our frame's oseqno is greater or + * equal than the VNAK's iseqno, but we need to take + * into account sequence number wrap-arounds. + * session->rseqno is our last acknowledged sequence + * number, so we use that as a base. */ - if ( (unsigned char)(fh->iseqno - session->rseqno) <= (unsigned char)(sch->frame->oseqno - session->rseqno) ) + const unsigned char frame_seqno = + sch->frame->oseqno - session->rseqno; + + if ( vnak_seqno <= frame_seqno ) { - /* - * We cannot retransmit immediately, since the frames are ordered by retransmit time - * We need to collect them and orrange them in ascending order of their oseqno - */ - tmp = (struct iax_sched *)calloc(1, sizeof(struct iax_sched)); + /* We cannot retransmit immediately since the + * frames are ordered by retransmit time. We + * need to first collect them and arrange them + * in ascending order by their oseqno. */ + struct iax_sched *tmp = + calloc(1, sizeof(struct iax_sched)); tmp->frame = sch->frame; - if ( list == NULL || - (list->frame->oseqno - session->rseqno) > (tmp->frame->oseqno - session->rseqno) + if ( retrans_list == NULL || + (retrans_list->frame->oseqno - session->rseqno) > frame_seqno ) { - tmp->next = list; - list = tmp; - } else + tmp->next = retrans_list; + retrans_list = tmp; + } + else { - l = list; - while ( l != NULL ) + struct iax_sched *item = retrans_list; + while ( item != NULL ) { - if ( l->next == NULL || - (l->next->frame->oseqno - session->rseqno) > (tmp->frame->oseqno - session->rseqno) + const unsigned char next_seqno = + item->next->frame->oseqno - + session->rseqno; + if ( item->next == NULL || + next_seqno > frame_seqno ) { - tmp->next = l->next; - l->next = tmp; + tmp->next = item->next; + item->next = tmp; break; } - l = l->next; + item = item->next; } } } @@ -2545,11 +2479,11 @@ } /* Transmit collected frames and free the space */ - while ( list != NULL ) + while ( retrans_list != NULL ) { - tmp = list; - iax_xmit_frame(tmp->frame); - list = list->next; + struct iax_sched * tmp = retrans_list; + iax_xmit_frame(retrans_list->frame); + retrans_list = retrans_list->next; free(tmp); } } @@ -2584,11 +2518,10 @@ iax_showframe(NULL, fh, 1, sin, datalen); #endif - /* Get things going with it, timestamp wise, if we - haven't already. */ + /* Get things going with it, timestamp wise, if we haven't already. */ /* Handle implicit ACKing unless this is an INVAL, and only if this is - from the real peer, not the transfer peer */ + * from the real peer, not the transfer peer */ if ( !inaddrcmp(sin, &session->peeraddr) && ( subclass != IAX_COMMAND_INVAL || fh->type != AST_FRAME_IAX @@ -2629,25 +2562,25 @@ /* Check where we are */ if ((ntohs(fh->dcallno) & IAX_FLAG_RETRANS) || - ((fh->type != AST_FRAME_VOICE) && (fh->type != AST_FRAME_VIDEO))) + (fh->type != AST_FRAME_VOICE && + fh->type != AST_FRAME_VIDEO)) updatehistory = 0; - if ((session->iseqno != fh->oseqno) && - (session->iseqno || - ((subclass != IAX_COMMAND_TXREADY) && - (subclass != IAX_COMMAND_TXREL) && - (subclass != IAX_COMMAND_TXCNT) && - (subclass != IAX_COMMAND_TXACC)) || - (fh->type != AST_FRAME_IAX))) + + if (session->iseqno != fh->oseqno && + (session->iseqno || fh->type != AST_FRAME_IAX || + (subclass != IAX_COMMAND_TXREADY && + subclass != IAX_COMMAND_TXREL && + subclass != IAX_COMMAND_TXCNT && + subclass != IAX_COMMAND_TXACC))) { - if ( - ((subclass != IAX_COMMAND_ACK) && - (subclass != IAX_COMMAND_INVAL) && - (subclass != IAX_COMMAND_TXREADY) && - (subclass != IAX_COMMAND_TXREL) && - (subclass != IAX_COMMAND_TXCNT) && - (subclass != IAX_COMMAND_TXACC) && - (subclass != IAX_COMMAND_VNAK)) || - (fh->type != AST_FRAME_IAX)) + if (fh->type != AST_FRAME_IAX || + (subclass != IAX_COMMAND_ACK && + subclass != IAX_COMMAND_INVAL && + subclass != IAX_COMMAND_TXREADY && + subclass != IAX_COMMAND_TXREL && + subclass != IAX_COMMAND_TXCNT && + subclass != IAX_COMMAND_TXACC && + subclass != IAX_COMMAND_VNAK)) { /* If it's not an ACK packet, it's out of order. */ DEBU(G "Packet arrived out of order (expecting %d, got %d) (frametype = %d, subclass = %d)\n", @@ -2661,376 +2594,377 @@ { /* If we've already seen it, ack it XXX There's a border condition here XXX */ if ((fh->type != AST_FRAME_IAX) || - ((subclass != IAX_COMMAND_ACK) && (subclass != IAX_COMMAND_INVAL))) + (subclass != IAX_COMMAND_ACK && + subclass != IAX_COMMAND_INVAL)) { DEBU(G "Acking anyway\n"); /* XXX Maybe we should handle its ack to us, but then again, it's probably outdated anyway, and if we have anything to send, we'll retransmit and get an ACK back anyway XXX */ send_command_immediate(session, AST_FRAME_IAX, IAX_COMMAND_ACK, ts, NULL, 0,fh->iseqno); } - } else + } + else { /* Send a VNAK requesting retransmission */ iax2_vnak(session); } return NULL; } - } else + } + else { /* Increment unless it's an ACK or VNAK */ - if (((subclass != IAX_COMMAND_ACK) && - (subclass != IAX_COMMAND_INVAL) && - (subclass != IAX_COMMAND_TXCNT) && - (subclass != IAX_COMMAND_TXACC) && - (subclass != IAX_COMMAND_VNAK)) || - (fh->type != AST_FRAME_IAX)) + if (fh->type != AST_FRAME_IAX || + (subclass != IAX_COMMAND_ACK && + subclass != IAX_COMMAND_INVAL && + subclass != IAX_COMMAND_TXCNT && + subclass != IAX_COMMAND_TXACC && + subclass != IAX_COMMAND_VNAK)) session->iseqno++; } - e = (struct iax_event *)malloc(sizeof(struct iax_event) + datalen + 1); + e = calloc(1, sizeof(struct iax_event) + datalen + 1); - if (e) { - memset(e, 0, sizeof(struct iax_event) + datalen); - /* Set etype to some unknown value so do not inavertently - sending IAX_EVENT_CONNECT event, which is 0 to application. - */ - e->etype = -1; - e->session = session; - switch(fh->type) { - case AST_FRAME_DTMF: - e->etype = IAX_EVENT_DTMF; - e->subclass = subclass; - /* - We want the DTMF event deliver immediately so all I/O can be - terminate quickly in an IVR system. - e = schedule_delivery(e, ts, updatehistory); */ + if (!e) { + DEBU(G "Out of memory\n"); + return NULL; + } + + /* Set etype to some unknown value so do not inavertently + * sending IAX_EVENT_CONNECT event, which is 0 to application. + */ + e->etype = -1; + e->session = session; + switch(fh->type) { + case AST_FRAME_DTMF: + e->etype = IAX_EVENT_DTMF; + e->subclass = subclass; + /* + We want the DTMF event deliver immediately so all I/O can be + terminate quickly in an IVR system. + e = schedule_delivery(e, ts, updatehistory); */ + break; + case AST_FRAME_VOICE: + e->etype = IAX_EVENT_VOICE; + e->subclass = subclass; + e->ts = ts; + session->voiceformat = subclass; + if (datalen) { + memcpy(e->data, fh->iedata, datalen); + e->datalen = datalen; + } + e = schedule_delivery(e, ts, updatehistory); + break; + case AST_FRAME_CNG: + e->etype = IAX_EVENT_CNG; + e->subclass = subclass; + if (datalen) { + memcpy(e->data, fh->iedata, datalen); + e->datalen = datalen; + } + e = schedule_delivery(e, ts, updatehistory); + break; + case AST_FRAME_IAX: + /* Parse IE's */ + if (datalen) { + memcpy(e->data, fh->iedata, datalen); + e->datalen = datalen; + } + if (iax_parse_ies(&e->ies, e->data, e->datalen)) { + IAXERROR "Unable to parse IE's"); + free(e); + e = NULL; break; - case AST_FRAME_VOICE: - e->etype = IAX_EVENT_VOICE; - e->subclass = subclass; - e->ts = ts; - session->voiceformat = subclass; - if (datalen) { - memcpy(e->data, fh->iedata, datalen); - e->datalen = datalen; + } + switch(subclass) { + case IAX_COMMAND_NEW: + /* This is a new, incoming call */ + /* save the capability for validat... [truncated message content] |
From: <jpg...@us...> - 2008-07-01 16:17:44
|
Revision: 1441 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1441&view=rev Author: jpgrayson Date: 2008-07-01 09:17:53 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Explicitly initialize null function pointers. - Resolves compiler warnings. Modified Paths: -------------- trunk/lib/libiax2/src/iax2-parser.c Modified: trunk/lib/libiax2/src/iax2-parser.c =================================================================== --- trunk/lib/libiax2/src/iax2-parser.c 2008-07-01 16:17:12 UTC (rev 1440) +++ trunk/lib/libiax2/src/iax2-parser.c 2008-07-01 16:17:53 UTC (rev 1441) @@ -173,17 +173,17 @@ { IAX_IE_CAUSE, "CAUSE", dump_string }, { IAX_IE_IAX_UNKNOWN, "UNKNOWN IAX CMD", dump_byte }, { IAX_IE_MSGCOUNT, "MESSAGE COUNT", dump_short }, - { IAX_IE_AUTOANSWER, "AUTO ANSWER REQ" }, + { IAX_IE_AUTOANSWER, "AUTO ANSWER REQ", 0 }, { IAX_IE_TRANSFERID, "TRANSFER ID", dump_int }, { IAX_IE_RDNIS, "REFERRING DNIS", dump_string }, { IAX_IE_PROVISIONING, "PROVISIONING", dump_prov }, - { IAX_IE_AESPROVISIONING, "AES PROVISIONG" }, + { IAX_IE_AESPROVISIONING, "AES PROVISIONG", 0 }, { IAX_IE_DATETIME, "DATE TIME", dump_int }, { IAX_IE_DEVICETYPE, "DEVICE TYPE", dump_string }, { IAX_IE_SERVICEIDENT, "SERVICE IDENT", dump_string }, { IAX_IE_FIRMWAREVER, "FIRMWARE VER", dump_short }, { IAX_IE_FWBLOCKDESC, "FW BLOCK DESC", dump_int }, - { IAX_IE_FWBLOCKDATA, "FW BLOCK DATA" }, + { IAX_IE_FWBLOCKDATA, "FW BLOCK DATA", 0 }, { IAX_IE_PROVVER, "PROVISIONG VER", dump_int }, { IAX_IE_CALLINGPRES, "CALLING PRESNTN", dump_byte }, { IAX_IE_CALLINGTON, "CALLING TYPEOFNUM", dump_byte }, This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-07-01 16:17:03
|
Revision: 1440 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1440&view=rev Author: jpgrayson Date: 2008-07-01 09:17:12 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Fix spacing. Modified Paths: -------------- trunk/lib/libiax2/src/frame.h Modified: trunk/lib/libiax2/src/frame.h =================================================================== --- trunk/lib/libiax2/src/frame.h 2008-07-01 16:14:08 UTC (rev 1439) +++ trunk/lib/libiax2/src/frame.h 2008-07-01 16:17:12 UTC (rev 1440) @@ -21,88 +21,67 @@ #endif /* Frame types */ -#define AST_FRAME_DTMF 1 /* A DTMF digit, subclass is the digit */ -#define AST_FRAME_VOICE 2 /* Voice data, subclass is AST_FORMAT_* */ -#define AST_FRAME_VIDEO 3 /* Video frame, maybe?? :) */ -#define AST_FRAME_CONTROL 4 /* A control frame, subclass is AST_CONTROL_* */ -#define AST_FRAME_NULL 5 /* An empty, useless frame */ -#define AST_FRAME_IAX 6 /* Inter Aterisk Exchange private frame type */ -#define AST_FRAME_TEXT 7 /* Text messages */ -#define AST_FRAME_IMAGE 8 /* Image Frames */ -#define AST_FRAME_HTML 9 /* HTML Frames */ -#define AST_FRAME_CNG 10 /* Comfort Noise frame (subclass is level of CNG in -dBov) */ +#define AST_FRAME_DTMF 1 /* A DTMF digit, subclass is the digit */ +#define AST_FRAME_VOICE 2 /* Voice data, subclass is AST_FORMAT_* */ +#define AST_FRAME_VIDEO 3 /* Video frame, maybe?? :) */ +#define AST_FRAME_CONTROL 4 /* A control frame, subclass is AST_CONTROL_* */ +#define AST_FRAME_NULL 5 /* An empty, useless frame */ +#define AST_FRAME_IAX 6 /* Inter Aterisk Exchange private frame type */ +#define AST_FRAME_TEXT 7 /* Text messages */ +#define AST_FRAME_IMAGE 8 /* Image Frames */ +#define AST_FRAME_HTML 9 /* HTML Frames */ +#define AST_FRAME_CNG 10 /* Comfort Noise frame (subclass is level of CNG in -dBov) */ /* HTML subclasses */ -#define AST_HTML_URL 1 /* Sending a URL */ -#define AST_HTML_DATA 2 /* Data frame */ -#define AST_HTML_BEGIN 4 /* Beginning frame */ -#define AST_HTML_END 8 /* End frame */ -#define AST_HTML_LDCOMPLETE 16 /* Load is complete */ -#define AST_HTML_NOSUPPORT 17 /* Peer is unable to support HTML */ -#define AST_HTML_LINKURL 18 /* Send URL and track */ -#define AST_HTML_UNLINK 19 /* Request no more linkage */ -#define AST_HTML_LINKREJECT 20 /* Reject LINKURL */ +#define AST_HTML_URL 1 /* Sending a URL */ +#define AST_HTML_DATA 2 /* Data frame */ +#define AST_HTML_BEGIN 4 /* Beginning frame */ +#define AST_HTML_END 8 /* End frame */ +#define AST_HTML_LDCOMPLETE 16 /* Load is complete */ +#define AST_HTML_NOSUPPORT 17 /* Peer is unable to support HTML */ +#define AST_HTML_LINKURL 18 /* Send URL and track */ +#define AST_HTML_UNLINK 19 /* Request no more linkage */ +#define AST_HTML_LINKREJECT 20 /* Reject LINKURL */ /* Data formats for capabilities and frames alike */ -/*! G.723.1 compression */ -#define AST_FORMAT_G723_1 (1 << 0) - /*! GSM compression */ -#define AST_FORMAT_GSM (1 << 1) - /*! Raw mu-law data (G.711) */ -#define AST_FORMAT_ULAW (1 << 2) - /*! Raw A-law data (G.711) */ -#define AST_FORMAT_ALAW (1 << 3) - /*! ADPCM (G.726, 32kbps) */ -#define AST_FORMAT_G726 (1 << 4) - /*! ADPCM (IMA) */ -#define AST_FORMAT_ADPCM (1 << 5) - /*! Raw 16-bit Signed Linear (8000 Hz) PCM */ -#define AST_FORMAT_SLINEAR (1 << 6) - /*! LPC10, 180 samples/frame */ -#define AST_FORMAT_LPC10 (1 << 7) - /*! G.729A audio */ -#define AST_FORMAT_G729A (1 << 8) - /*! SpeeX Free Compression */ -#define AST_FORMAT_SPEEX (1 << 9) - /*! iLBC Free Compression */ -#define AST_FORMAT_ILBC (1 << 10) - /*! Maximum audio format */ -#define AST_FORMAT_MAX_AUDIO (1 << 15) - /*! JPEG Images */ -#define AST_FORMAT_JPEG (1 << 16) - /*! PNG Images */ -#define AST_FORMAT_PNG (1 << 17) - /*! H.261 Video */ -#define AST_FORMAT_H261 (1 << 18) - /*! H.263 Video */ -#define AST_FORMAT_H263 (1 << 19) - /*! H.263+ Video */ -#define AST_FORMAT_H263p (1 << 20) - /*! H.264 Video*/ -#define AST_FORMAT_H264 (1 << 21) - /*! MPEG4 Video*/ -#define AST_FORMAT_MPEG4 (1 << 22) - /*! Theora Video */ -#define AST_FORMAT_THEORA (1 << 24) - /*! Max one */ -#define AST_FORMAT_MAX_VIDEO (1 << 24) +#define AST_FORMAT_G723_1 (1 << 0) /*! G.723.1 compression */ +#define AST_FORMAT_GSM (1 << 1) /*! GSM compression */ +#define AST_FORMAT_ULAW (1 << 2) /*! Raw mu-law data (G.711) */ +#define AST_FORMAT_ALAW (1 << 3) /*! Raw A-law data (G.711) */ +#define AST_FORMAT_G726 (1 << 4) /*! ADPCM (G.726, 32kbps) */ +#define AST_FORMAT_ADPCM (1 << 5) /*! ADPCM (IMA) */ +#define AST_FORMAT_SLINEAR (1 << 6) /*! Raw 16-bit Signed Linear (8000 Hz) PCM */ +#define AST_FORMAT_LPC10 (1 << 7) /*! LPC10, 180 samples/frame */ +#define AST_FORMAT_G729A (1 << 8) /*! G.729A audio */ +#define AST_FORMAT_SPEEX (1 << 9) /*! SpeeX Free Compression */ +#define AST_FORMAT_ILBC (1 << 10) /*! iLBC Free Compression */ +#define AST_FORMAT_MAX_AUDIO (1 << 15) /*! Maximum audio format */ +#define AST_FORMAT_JPEG (1 << 16) /*! JPEG Images */ +#define AST_FORMAT_PNG (1 << 17) /*! PNG Images */ +#define AST_FORMAT_H261 (1 << 18) /*! H.261 Video */ +#define AST_FORMAT_H263 (1 << 19) /*! H.263 Video */ +#define AST_FORMAT_H263p (1 << 20) /*! H.263+ Video */ +#define AST_FORMAT_H264 (1 << 21) /*! H.264 Video*/ +#define AST_FORMAT_MPEG4 (1 << 22) /*! MPEG4 Video*/ +#define AST_FORMAT_THEORA (1 << 24) /*! Theora Video */ +#define AST_FORMAT_MAX_VIDEO (1 << 24) /*! Maximum video format */ /* Control frame types */ -#define AST_CONTROL_HANGUP 1 /* Other end has hungup */ -#define AST_CONTROL_RING 2 /* Local ring */ -#define AST_CONTROL_RINGING 3 /* Remote end is ringing */ -#define AST_CONTROL_ANSWER 4 /* Remote end has answered */ -#define AST_CONTROL_BUSY 5 /* Remote end is busy */ -#define AST_CONTROL_TAKEOFFHOOK 6 /* Make it go off hook */ -#define AST_CONTROL_OFFHOOK 7 /* Line is off hook */ -#define AST_CONTROL_CONGESTION 8 /* Congestion (circuits busy) */ -#define AST_CONTROL_FLASH 9 /* Flash hook */ -#define AST_CONTROL_WINK 10 /* Wink */ -#define AST_CONTROL_OPTION 11 /* Set an option */ -#define AST_CONTROL_KEY 12 /* Key Radio */ -#define AST_CONTROL_UNKEY 13 /* Unkey Radio */ +#define AST_CONTROL_HANGUP 1 /* Other end has hungup */ +#define AST_CONTROL_RING 2 /* Local ring */ +#define AST_CONTROL_RINGING 3 /* Remote end is ringing */ +#define AST_CONTROL_ANSWER 4 /* Remote end has answered */ +#define AST_CONTROL_BUSY 5 /* Remote end is busy */ +#define AST_CONTROL_TAKEOFFHOOK 6 /* Make it go off hook */ +#define AST_CONTROL_OFFHOOK 7 /* Line is off hook */ +#define AST_CONTROL_CONGESTION 8 /* Congestion (circuits busy) */ +#define AST_CONTROL_FLASH 9 /* Flash hook */ +#define AST_CONTROL_WINK 10 /* Wink */ +#define AST_CONTROL_OPTION 11 /* Set an option */ +#define AST_CONTROL_KEY 12 /* Key Radio */ +#define AST_CONTROL_UNKEY 13 /* Unkey Radio */ -#define AST_FRIENDLY_OFFSET 64 /* Reserved header space */ +#define AST_FRIENDLY_OFFSET 64 /* Reserved header space */ struct ast_frame { /*! Kind of frame */ @@ -140,5 +119,4 @@ } #endif - #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-07-01 16:14:05
|
Revision: 1439 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1439&view=rev Author: jpgrayson Date: 2008-07-01 09:14:08 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Fix problem where outgoing calls would be in the active state (IAXC_CALL_STATE_ACTIVE) prior to the other end even ACCEPTing the call. This potentially allowed TEXT, DTMF, and other frames to go out prior to the call being ACCEPTed by the other end. Recent versions of asterisk (1.4.19+) have security fixes in-place that don't take to kindly to this kind of bogus protocol. - The fix is to only put the call into the active state after we have received an ACCEPT frame from the other end. Modified Paths: -------------- trunk/lib/iaxclient_lib.c Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2008-07-01 15:52:43 UTC (rev 1438) +++ trunk/lib/iaxclient_lib.c 2008-07-01 16:14:08 UTC (rev 1439) @@ -1194,6 +1194,7 @@ iaxc_clear_call(callNo); break; case IAX_EVENT_ACCEPT: + calls[callNo].state |= IAXC_CALL_STATE_ACTIVE; calls[callNo].format = e->ies.format & IAXC_AUDIO_FORMAT_MASK; calls[callNo].vformat = e->ies.format & IAXC_VIDEO_FORMAT_MASK; #if USE_VIDEO @@ -1203,6 +1204,7 @@ "Failed video codec negotiation."); } #endif + iaxci_do_state_callback(callNo); iaxci_usermsg(IAXC_STATUS,"Call %d accepted", callNo); break; case IAX_EVENT_ANSWER: @@ -1372,7 +1374,7 @@ } else { // use selected call if not active, otherwise, get a new appearance - if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE ) + if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE ) { callNo = iaxc_first_free_call(); } else @@ -1426,7 +1428,7 @@ strncpy(calls[callNo].local , calls[callNo].callerid_name, IAXC_EVENT_BUFSIZ); strncpy(calls[callNo].local_context, "default", IAXC_EVENT_BUFSIZ); - calls[callNo].state = IAXC_CALL_STATE_ACTIVE | IAXC_CALL_STATE_OUTGOING; + calls[callNo].state = IAXC_CALL_STATE_OUTGOING; /* reset activity and ping "timers" */ iaxc_note_activity(callNo); @@ -1530,7 +1532,7 @@ EXPORT void iaxc_dump_call_number( int callNo ) { - if ( ( callNo >= 0 ) && ( callNo < max_calls ) ) + if ( callNo >= 0 && callNo < max_calls ) { get_iaxc_lock(); iaxc_dump_one_call(callNo); @@ -1558,7 +1560,7 @@ EXPORT void iaxc_reject_call_number( int callNo ) { - if ( ( callNo >= 0 ) && ( callNo < max_calls ) ) + if ( callNo >= 0 && callNo < max_calls ) { get_iaxc_lock(); iax_reject(calls[callNo].session, "Call rejected manually."); @@ -1591,13 +1593,13 @@ EXPORT void iaxc_send_text_call(int callNo, const char * text) { - if ( callNo < 0 || !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE) ) - return; - - get_iaxc_lock(); - if ( calls[callNo].state & IAXC_CALL_STATE_ACTIVE ) - iax_send_text(calls[callNo].session, text); - put_iaxc_lock(); + if ( callNo >= 0 && callNo < max_calls ) + { + get_iaxc_lock(); + if ( calls[callNo].state & IAXC_CALL_STATE_ACTIVE ) + iax_send_text(calls[callNo].session, text); + put_iaxc_lock(); + } } EXPORT void iaxc_send_url(const char * url, int link) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-07-01 15:52:34
|
Revision: 1438 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1438&view=rev Author: jpgrayson Date: 2008-07-01 08:52:43 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Updates to stresstest to allow for simple commands to be passed to it via stdin. Modified Paths: -------------- trunk/simpleclient/stresstest/file.c trunk/simpleclient/stresstest/file.h trunk/simpleclient/stresstest/stresstest.c Modified: trunk/simpleclient/stresstest/file.c =================================================================== --- trunk/simpleclient/stresstest/file.c 2008-07-01 15:42:30 UTC (rev 1437) +++ trunk/simpleclient/stresstest/file.c 2008-07-01 15:52:43 UTC (rev 1438) @@ -1,11 +1,12 @@ #include <string.h> #include <stdlib.h> #include <stdio.h> -#include "file.h" #include <oggz/oggz.h> #include <theora/theora.h> +#include "file.h" + #ifdef __GNUC__ void mylog(const char * fmt, ...) __attribute__ ((format (printf, 1, 2))); #else @@ -211,7 +212,8 @@ { if ( serialno == audio_stream->serialno ) { - audio_stream->page_ts = ogg_page_granulepos(og) * 1000 / + audio_stream->page_ts = + ogg_page_granulepos((ogg_page *)og) * 1000 / SPEEX_SAMPLING_RATE; audio_stream->page_count = 0; } @@ -221,7 +223,7 @@ return 0; } -void +int load_ogg_file(const char *filename) { OGGZ *oggz; @@ -230,6 +232,7 @@ if ( oggz == NULL ) { mylog("Error opening ogg file\n"); + return -1; } mylog("Successfully opened ogg file %s\n", filename); @@ -243,28 +246,30 @@ oggz_run(oggz); oggz_close(oggz); + + return 0; } -static ogg_packet * get_next_op(struct ogg_stream *os) +static ogg_packet * get_next_op(struct ogg_stream *os, struct timeval tv) { - ogg_packet *op; - struct timeval tv; - long time_now; + ogg_packet *op = 0; + long time_now; - if ( os == NULL ) + if ( !os ) return NULL; - gettimeofday(&tv, NULL); time_now = tv.tv_sec * 1000 + tv.tv_usec / 1000; - if ( os->current == NULL ) + if ( !os->current ) { + if ( !os->first ) + return NULL; + // point to the beginning of the stream and reset the time base os->base_ts = time_now; os->current = os->first; } - op = NULL; if ( os->current->timestamp < time_now - os->base_ts ) { op = os->current->op; @@ -274,14 +279,14 @@ return op; } -ogg_packet * get_next_audio_op() +ogg_packet * get_next_audio_op(struct timeval now) { - return get_next_op(audio_stream); + return get_next_op(audio_stream, now); } -ogg_packet * get_next_video_op() +ogg_packet * get_next_video_op(struct timeval now) { - return get_next_op(video_stream); + return get_next_op(video_stream, now); } int audio_is_eos() Modified: trunk/simpleclient/stresstest/file.h =================================================================== --- trunk/simpleclient/stresstest/file.h 2008-07-01 15:42:30 UTC (rev 1437) +++ trunk/simpleclient/stresstest/file.h 2008-07-01 15:52:43 UTC (rev 1438) @@ -1,15 +1,21 @@ #ifndef __FILE_H__ #define __FILE_H__ +#ifdef WIN32 +#include <windows.h> +#else +#include <time.h> +#endif + #include <ogg/ogg.h> -#define SPEEX_FRAME_DURATION 20 -#define SPEEX_SAMPLING_RATE 8000 +static const int SPEEX_FRAME_DURATION = 20; +static const int SPEEX_SAMPLING_RATE = 8000; -void load_ogg_file(const char *filename); +int load_ogg_file(const char *filename); -ogg_packet * get_next_audio_op(); -ogg_packet * get_next_video_op(); +ogg_packet * get_next_audio_op(struct timeval now); +ogg_packet * get_next_video_op(struct timeval now); int audio_is_eos(); int video_is_eos(); Modified: trunk/simpleclient/stresstest/stresstest.c =================================================================== --- trunk/simpleclient/stresstest/stresstest.c 2008-07-01 15:42:30 UTC (rev 1437) +++ trunk/simpleclient/stresstest/stresstest.c 2008-07-01 15:52:43 UTC (rev 1438) @@ -29,16 +29,31 @@ #include "file.h" #ifdef WIN32 -// Only under windows... +#include <process.h> +typedef uintptr_t a_thread; +#define STDCALL __stdcall +#define snprintf _snprintf #undef main +#else +#include <pthread.h> +typedef pthread_t a_thread; +#define STDCALL #endif -#define MAX_CALLS 1 +static const char STRESS_CMD_UNMUTE_AUDIO[] = "unmute_audio"; +static const char STRESS_CMD_MUTE_AUDIO[] = "mute_audio"; +static const char STRESS_CMD_UNMUTE_VIDEO[] = "unmute_video"; +static const char STRESS_CMD_MUTE_VIDEO[] = "mute_video"; +static const char STRESS_CMD_SHOW_STATE[] = "show_state"; +static const char STRESS_CMD_QUIT[] = "quit"; -#define TEST_OK 0 -#define TEST_NO_CONNECTION -1 -#define TEST_NO_MEDIA -2 -#define TEST_UNKNOWN_ERROR -99 +enum +{ + TEST_OK = 0, + TEST_NO_CONNECTION = -1, + TEST_NO_MEDIA = -2, + TEST_UNKNOWN_ERROR = -99, +}; static const int format = IAXC_FORMAT_H263 | @@ -63,6 +78,7 @@ static int connect_timeout_ms = 5000; static int video_frames_count = 0; static int audio_frames_count = 0; +static int audio_sent_count = 0; static struct timeval start_time; @@ -91,8 +107,54 @@ va_end(ap); } +static int +create_thread(a_thread *thread, + unsigned int (STDCALL * thread_func)(void *), + void *args, unsigned int *thread_id) +{ + int ret = 0; +#ifdef WIN32 + *thread = (uintptr_t)_beginthreadex(NULL, 0, thread_func, + (void *)args, 0, thread_id); + + if ( thread == 0 ) + ret = errno; +#else + void * (*func)(void *) = (void * (*)(void *))thread_func; + + ret = pthread_create(thread, NULL, func, args); +#endif + + return ret; +} + +static struct timeval +get_now(void) +{ + struct timeval tv; +#ifdef WIN32 + FILETIME ft; + LARGE_INTEGER li; + __int64 t; + static int tzflag; + const __int64 EPOCHFILETIME = 116444736000000000i64; + + GetSystemTimeAsFileTime(&ft); + li.LowPart = ft.dwLowDateTime; + li.HighPart = ft.dwHighDateTime; + t = li.QuadPart; /* In 100-nanosecond intervals */ + t -= EPOCHFILETIME; /* Offset to the Epoch time */ + t /= 10; /* In microseconds */ + tv.tv_sec = (long)(t / 1000000); + tv.tv_usec = (long)(t % 1000000); +#else + gettimeofday(&tv, 0); +#endif + return tv; +} + /* routine used to shutdown and close nicely.*/ -void hangup_and_exit(int code) +void hangup_call() { mylog("Dump call\n"); iaxc_dump_call(); @@ -102,8 +164,6 @@ iaxc_stop_processing_thread(); mylog("Calling iaxc_shutdown...\n"); iaxc_shutdown(); - mylog("Exiting with code %d\n", code); - exit(code); } void signal_handler(int signum) @@ -117,7 +177,6 @@ void fatal_error(char *err) { mylog("FATAL ERROR: %s\n", err); - exit(TEST_UNKNOWN_ERROR); } int levels_callback(float input, float output) { @@ -188,12 +247,12 @@ void usage() { - printf("Usage: stresstest <options>\n\n" + printf("Usage: stresstest <options> <dial_string>\n\n" "available options:\n" " -F <codec> <framerate> <bitrate> <width> <height> <fragsize> set video parameters\n" " -o <filename> media file to run\n" - " -v stop sending video\n" - " -a stop sending audio\n" + " -a start with audio muted\n" + " -v start with video 'muted'\n" " -l run file in a loop\n" " -n dump periodic netstats to log file\n" " -t <TIMEOUT> terminate call after TIMEOUT seconds\n" @@ -253,12 +312,88 @@ return (t1->tv_sec - t0->tv_sec) * 1000L + (t1->tv_usec - t0->tv_usec) / 1000L; } +unsigned int STDCALL check_for_command(void *param) +{ + int *cmd_thread_ready = (int *)param; + + *cmd_thread_ready = 1; + + while ( 1 ) + { + char data[512]; + char *str; + + if ( fgets(data, sizeof(data), stdin) ) + { + + data[sizeof(data) - 1] = 0; + + if ( !(str = strtok(data, "\n")) ) + { + mylog("WARNING: invalid input\n"); + } + else if ( !strncmp(str, STRESS_CMD_UNMUTE_AUDIO, + strlen(STRESS_CMD_UNMUTE_AUDIO)) ) + { + // mylog("got command to unmute audio\n"); + send_audio = 1; + } + else if ( !strncmp(str, STRESS_CMD_MUTE_AUDIO, + strlen(STRESS_CMD_MUTE_AUDIO)) ) + { + // mylog("got command to mute audio\n"); + send_audio = 0; + } + else if ( !strncmp(str, STRESS_CMD_UNMUTE_VIDEO, + strlen(STRESS_CMD_UNMUTE_VIDEO)) ) + { + // mylog("got command to unmute video\n"); + send_video = 1; + } + else if ( !strncmp(str, STRESS_CMD_MUTE_VIDEO, + strlen(STRESS_CMD_MUTE_VIDEO)) ) + { + // mylog("got command to mute video\n"); + send_video = 0; + } + else if ( !strncmp(str, STRESS_CMD_SHOW_STATE, + strlen(STRESS_CMD_SHOW_STATE)) ) + { + mylog("got command to show state:\n"); + mylog("running = %d call_established = %d\n", + running, call_established); + mylog("send_video = %d send audio = %d\n", + send_video, send_audio); + mylog("audio frames recvd = %d video frames recvd = %d\n", + audio_frames_count, video_frames_count); + mylog("audio frames sent = %d\n\n", audio_sent_count); + } + else if ( !strncmp(str, STRESS_CMD_QUIT, + strlen(STRESS_CMD_QUIT)) ) + { + mylog("got command to quit\n"); + running = 0; + } + else + { + mylog("invalid input: '%s'\n", str); + } + } + } + + return 0; +} + int main(int argc, char **argv) { int i; char *dest = NULL; char *ogg_file = NULL; int loop = 0; + a_thread command_thread = 0; + unsigned int command_thread_id; + int ret = -1; + int cmd_thread_ready = 0; /* install signal handler to catch CRTL-Cs */ signal(SIGINT, signal_handler); @@ -331,24 +466,34 @@ if ( dest == NULL ) { mylog("No destination, quitting\n"); - return -1; + goto exit; } if ( ogg_file ) - load_ogg_file(ogg_file); + { + if ( load_ogg_file(ogg_file) ) + { + mylog("Failed loading ogg file. Quitting.\n"); + goto exit; + } + } else mylog("No media file, running dry\n"); // Get start time for timeouts - gettimeofday(&start_time, NULL); + start_time = get_now(); // Initialize iaxclient iaxc_video_format_set(formatp, format, framerate, bitrate, width, height, fragsize); iaxc_set_test_mode(1); - if (iaxc_initialize(MAX_CALLS)) + if (iaxc_initialize(1)) + { fatal_error("cannot initialize iaxclient!"); + ret = TEST_UNKNOWN_ERROR; + goto exit; + } iaxc_set_formats(IAXC_FORMAT_SPEEX, IAXC_FORMAT_SPEEX); iaxc_video_bypass_jitter(0); @@ -358,42 +503,71 @@ // Crank the engine if ( iaxc_start_processing_thread() < 0 ) + { fatal_error("failed iaxc_start_processing_thread()\n"); + ret = TEST_UNKNOWN_ERROR; + goto exit; + } + // spin a thread to check for commands from stdin + if ( ret = create_thread(&command_thread, + &check_for_command, + (void *)&cmd_thread_ready, &command_thread_id) ) + { + mylog("failed creating command thread\n"); + goto exit; + } + else + { + while ( !cmd_thread_ready ) + iaxc_millisleep(10); + } + // Dial out if ( iaxc_call(dest) < 0 ) + { fatal_error("failed iaxc_call()"); + ret = TEST_UNKNOWN_ERROR; + goto exit; + } // Wait for the call to be established; while ( !call_established && running ) { struct timeval now; - gettimeofday(&now, NULL); + now = get_now(); if ( connect_timeout_ms > 0 && msecdiff(&start_time, &now) > connect_timeout_ms ) - hangup_and_exit(TEST_NO_CONNECTION); + { + hangup_call(); + ret = TEST_NO_CONNECTION; + goto exit; + } iaxc_millisleep(5); } running = 1; while ( running ) { - struct timeval now; + struct timeval now = get_now(); // We only need this if we actually want to send something - if ( ogg_file && ( send_audio || send_video ) ) + if ( ogg_file ) { ogg_packet *op; - op = get_next_audio_op(); + op = get_next_audio_op(now); if ( !loop && audio_is_eos() ) break; if ( send_audio && op != NULL && op->bytes > 0 ) + { iaxc_push_audio(op->packet, op->bytes, SPEEX_SAMPLING_RATE * SPEEX_FRAME_DURATION / 1000); + audio_sent_count++; + } - op = get_next_video_op(); + op = get_next_video_op(now); if ( !loop && video_is_eos() ) break; if ( send_video && op != NULL && op->bytes > 0 ) @@ -404,7 +578,6 @@ iaxc_millisleep(5); // Exit after a positive timeout - gettimeofday(&now, NULL); if ( call_timeout_ms > 0 && msecdiff(&start_time, &now) > call_timeout_ms ) running = 0; @@ -414,8 +587,14 @@ audio_frames_count, video_frames_count); if ( audio_frames_count == 0 && video_frames_count == 0 ) - hangup_and_exit(TEST_NO_MEDIA); + ret = TEST_NO_MEDIA; else - hangup_and_exit(TEST_OK); - return 0; + ret = TEST_OK; + + hangup_call(); + +exit: + mylog("Exiting with code %d\n", ret); + + return ret; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-07-01 15:42:30
|
Revision: 1437 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1437&view=rev Author: jpgrayson Date: 2008-07-01 08:42:30 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Move audio startup retry logic from audio_portaudio.c to higher-level main_proc_thread_func(). - Allows iaxclient to be usable on systems with no audio hardware. Modified Paths: -------------- trunk/lib/audio_portaudio.c trunk/lib/iaxclient_lib.c Modified: trunk/lib/audio_portaudio.c =================================================================== --- trunk/lib/audio_portaudio.c 2008-07-01 15:35:07 UTC (rev 1436) +++ trunk/lib/audio_portaudio.c 2008-07-01 15:42:30 UTC (rev 1437) @@ -643,8 +643,6 @@ static int pa_start(struct iaxc_audio_driver *d) { - static int errcnt = 0; - if ( running ) return 0; @@ -661,29 +659,13 @@ oMixer = NULL; } - if ( errcnt > 5 ) - { - iaxci_usermsg(IAXC_TEXT_TYPE_FATALERROR, - "iaxclient audio: Can't open Audio Device. " - "Perhaps you do not have an input or output device?"); - /* OK, we'll give the application the option to abort or - * not here, but we will throw a fatal error anyway */ - iaxc_millisleep(1000); - //return -1; // Give Up. Too many errors. - } - /* flush the ringbuffers */ rb_InitializeRingBuffer(&inRing, INRBSZ, inRingBuf); rb_InitializeRingBuffer(&outRing, OUTRBSZ, outRingBuf); if ( pa_openstreams(d) ) - { - errcnt++; return -1; - } - errcnt = 0; // only count consecutive errors. - if ( Pa_StartStream(iStream) != paNoError ) return -1; Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2008-07-01 15:35:07 UTC (rev 1436) +++ trunk/lib/iaxclient_lib.c 2008-07-01 15:42:30 UTC (rev 1437) @@ -407,7 +407,7 @@ return count; } -EXPORT int iaxc_first_free_call() +EXPORT int iaxc_first_free_call(void) { int i; for ( i = 0; i < max_calls; i++ ) @@ -769,10 +769,13 @@ } } -#define LOOP_SLEEP 5 // In ms static THREADFUNCDECL(main_proc_thread_func) { + const int sleep_ms = 5; + const int counts_per_second = 1000 / sleep_ms; static int refresh_registration_count = 0; + static int audio_error_count = 0; + static int audio_error_state = 0; THREADFUNCRET(ret); @@ -784,11 +787,31 @@ get_iaxc_lock(); service_network(); - if ( !test_mode ) - service_audio(); + if ( !test_mode && + (!audio_error_state || + audio_error_count++ % counts_per_second == 0) ) + { + /* There are cases when service audio fails such + * as when there is no audio devices present in + * the system. In these cases, only call + * service_audio() once per second until it + * succeeds. + */ + if ( (audio_error_state = service_audio()) ) + { + iaxci_usermsg(IAXC_NOTICE, + "failed to service audio"); + + if ( audio_error_count / counts_per_second == 5 ) + iaxci_usermsg(IAXC_TEXT_TYPE_FATALERROR, + "cannot open audio device" + " after several tries"); + } + } + // Check registration refresh once a second - if ( refresh_registration_count++ > 1000/LOOP_SLEEP ) + if ( refresh_registration_count++ > counts_per_second ) { iaxc_refresh_registrations(); refresh_registration_count = 0; @@ -796,7 +819,7 @@ put_iaxc_lock(); - iaxc_millisleep(LOOP_SLEEP); + iaxc_millisleep(sleep_ms); } /* Decrease priority */ @@ -853,7 +876,8 @@ int to_read; int cmin; - audio_driver.start(&audio_driver); + if ( audio_driver.start(&audio_driver) ) + return -1; /* use codec minimum if higher */ cmin = want_send_audio && call->encoder ? @@ -941,7 +965,7 @@ } /* handle IAX URL events */ -void handle_url_event( struct iax_event *e, int callNo ) +static void handle_url_event( struct iax_event *e, int callNo ) { iaxc_event ev; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-07-01 15:35:17
|
Revision: 1436 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1436&view=rev Author: jpgrayson Date: 2008-07-01 08:35:07 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Fix AAGC. - Previously it was very common for the AAGC code to drive the input mixer level (input volume) very low and potentially take a long time to recover. - The new AAGC heuristic takes into account the amount of time needed for the speex-provided "loudness" value to recover after a loud event. - Also fixup input_postprocess() so that speex_preprocess_run() is called with the audio_lock held. Modified Paths: -------------- trunk/lib/audio_encode.c Modified: trunk/lib/audio_encode.c =================================================================== --- trunk/lib/audio_encode.c 2008-07-01 15:21:20 UTC (rev 1435) +++ trunk/lib/audio_encode.c 2008-07-01 15:35:07 UTC (rev 1436) @@ -41,7 +41,7 @@ #include "codec_ilbc.h" #endif -float iaxci_silence_threshold = AUDIO_ENCODE_SILENCE_DB; +static float iaxci_silence_threshold = AUDIO_ENCODE_SILENCE_DB; static float input_level = 0.0f; static float output_level = 0.0f; @@ -51,7 +51,11 @@ static SpeexPreprocessState *st = NULL; static int speex_state_size = 0; static int speex_state_rate = 0; -int iaxci_filters = IAXC_FILTER_AGC|IAXC_FILTER_DENOISE|IAXC_FILTER_AAGC|IAXC_FILTER_CN; +static int iaxci_filters = + IAXC_FILTER_AGC | + IAXC_FILTER_DENOISE | + IAXC_FILTER_AAGC | + IAXC_FILTER_CN; static MUTEX audio_lock; @@ -72,16 +76,6 @@ static char outRingBuf[EC_RING_SIZE]; #endif -/* AAGC threshold */ -#define AAGC_VERY_HOT 16 -#define AAGC_HOT 8 -#define AAGC_COLD 4 - -/* AAGC increments */ -#define AAGC_RISE_SLOW 0.10f -#define AAGC_DROP_SLOW 0.15f -#define AAGC_DROP_FAST 0.20f - /* use to measure time since last audio was processed */ static struct timeval timeLastInput ; static struct timeval timeLastOutput ; @@ -178,11 +172,17 @@ static int input_postprocess(short * audio, int len, int rate) { - static float lowest_volume = 1.0f; - float volume; - int silent = 0; + static int aagc_frame_count = 0; + static int aagc_periods_to_skip = 0; + const int using_vad = iaxci_silence_threshold > 0.0f; + const int aagc_period = rate / len; /* 1 second */ + + int speaking = 1; + int loudness = 0; + MUTEXLOCK(&audio_lock); + if ( !st || speex_state_size != len || speex_state_rate != rate ) { if (st) @@ -199,75 +199,114 @@ i = ECHO_SUPPRESS_ACTIVE; speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &i); } -#endif +#endif speex_state_size = len; speex_state_rate = rate; set_speex_filters(); } + + /* go through the motions only if we need at least one of the + * preprocessor filters */ + if ( using_vad || (iaxci_filters & + (IAXC_FILTER_DENOISE | + IAXC_FILTER_AGC | + IAXC_FILTER_DEREVERB | + IAXC_FILTER_ECHO)) ) + { + speaking = speex_preprocess_run(st, audio); + speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, + &loudness); + } + MUTEXUNLOCK(&audio_lock); - calculate_level(audio, len, &input_level); + /* If we are using the VAD test and if speex indicates non-speaking, + * ignore the computed input level and indicate to the user that the + * input level was zero. + */ + if ( using_vad && !speaking ) + input_level = 0.0f; + else + calculate_level(audio, len, &input_level); - /* go through the motions only if we need at least one of the preprocessor filters */ - if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC | IAXC_FILTER_DEREVERB | IAXC_FILTER_ECHO)) || - iaxci_silence_threshold > 0.0f ) - silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL); - - /* Analog AGC: Bring speex AGC gain out to mixer, with lots of hysteresis */ - /* use a higher continuation threshold for AAGC than for VAD itself */ - if ( !silent && - iaxci_silence_threshold != 0.0f && - (iaxci_filters & IAXC_FILTER_AGC) && - (iaxci_filters & IAXC_FILTER_AAGC) - ) + /* Analog Automatic Gain Control, AAGC. */ + if ( speaking && iaxci_silence_threshold != 0.0f && + (iaxci_filters & IAXC_FILTER_AGC) && + (iaxci_filters & IAXC_FILTER_AAGC) && + ++aagc_frame_count % aagc_period == 0 && + !aagc_periods_to_skip-- ) { - static int i = 0; + /* This heuristic uses the loudness value from the speex + * preprocessor to determine a new mixer level. The loudness + * ranges from 0 to up over 80. When mixer level, speex AGC, + * and the actual speaker's level are in equilibrium, the + * loudness tends to be from 4 to 16. When the loudness goes + * above this comfortable range, there is a risk of the input + * signal being clipped. AAGC's primary purpose is to avoid + * clipping. + * + * After a loud event (think cough), the loudness level will + * spike and then decay over time (assuming the speaker + * speaking at a relatively constant level). To avoid + * over-adjusting, we skip some number of aagc sampling periods + * before making any more adjustments. This gives the loudness + * value time to normalize after one-time spikes in the input + * level. + */ - i++; + /* The mixer level is a percentage ranging from 0.00 to 1.00 */ + const float mixer_level = iaxc_input_level_get(); + float new_mixer_level = mixer_level; - if ( (i & 0x3f) == 0 ) + if ( loudness > 40 ) { - int loudness; - speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness); - if ( loudness > AAGC_HOT || loudness < AAGC_COLD ) - { - const float level = iaxc_input_level_get(); + new_mixer_level -= 0.20f; + aagc_periods_to_skip = 8; + } + else if ( loudness > 25 ) + { + new_mixer_level -= 0.15f; + aagc_periods_to_skip = 4; + } + else if ( loudness > 15 ) + { + new_mixer_level -= 0.10f; + aagc_periods_to_skip = 2; + } + else if ( loudness > 12 ) + { + new_mixer_level -= 0.05f; + aagc_periods_to_skip = 4; + } + else if ( loudness < 2 ) + { + new_mixer_level += 0.15f; + aagc_periods_to_skip = 4; + } + else if ( loudness < 4 ) + { + new_mixer_level += 0.10f; + aagc_periods_to_skip = 4; + } + else + { + aagc_periods_to_skip = 0; + } - if ( loudness > AAGC_VERY_HOT && level > 0.5f ) - { - /* lower quickly if we're really too hot */ - iaxc_input_level_set(level - AAGC_DROP_FAST); - } - else if ( loudness > AAGC_HOT && level >= 0.15f ) - { - /* lower less quickly if we're a bit too hot */ - iaxc_input_level_set(level - AAGC_DROP_SLOW); - } - else if ( loudness < AAGC_COLD && level <= 0.9f ) - { - /* raise slowly if we're cold */ - iaxc_input_level_set(level + AAGC_RISE_SLOW); - } - } - } + /* Normalize the proposed new mixer level */ + if ( new_mixer_level < 0.05f ) + new_mixer_level = 0.05f; + else if ( new_mixer_level > 1.00f ) + new_mixer_level = 1.00f; + + if ( new_mixer_level != mixer_level ) + iaxc_input_level_set(new_mixer_level); } - /* This is ugly. Basically just don't get volume level if speex thought - * we were silent. Just set it to 0 in that case */ - if ( iaxci_silence_threshold > 0.0f && silent ) - input_level = 0.0f; - do_level_callback(); - volume = vol_to_db(input_level); - - if ( volume < lowest_volume ) - lowest_volume = volume; - - if ( iaxci_silence_threshold > 0.0f ) - return silent; - else - return volume < iaxci_silence_threshold; + return using_vad ? !speaking : + vol_to_db(input_level) < iaxci_silence_threshold; } static int output_postprocess(const short * audio, int len) @@ -517,6 +556,36 @@ rb_ReadRingBuffer(&ecOutRing, delayedBuf, SAMPLES_PER_FRAME * 2); + /* TODO: speex_echo_cancellation() and speex_preprocess_run() operate + * on the same state and thus must be serialized. Because the audio + * lock is not held, this call has the potential to mess-up the + * preprocessor (which is serialized by the audio lock). I believe the + * net effect of this problem is to break residual echo cancellation + * when these calls overlap. Unfortunately, just serializing this + * speex_echo_cancellation() call with the audio lock may not be + * sufficient since the next call to speex_preprocess_run() is counting + * on operating on this cancelledBuffer -- since we buffer the input + * audio (cancelledBuffer), we are actually explicitly decoupling the + * calls to speex_echo_cancellation() and speex_preprocess_run(). Oops. + * + * In other words, it should go like this: + * + * speex_echo_cancellation(A) + * speex_preprocess_run(A) + * speex_echo_cancellation(B) + * speex_preprocess_run(B) + * speex_echo_cancellation(C) + * speex_preprocess_run(C) + * + * but it actually may be going like this: + * + * speex_echo_cancellation(A) + * speex_echo_cancellation(B) + * speex_preprocess_run(A) -- bad, residual echo from B is applied to A + * speex_echo_cancellation(C) + * speex_preprocess_run(B) -- bad, residual echo from C is applied to B + * speex_preprocess_run(C) + */ speex_echo_cancellation(ec, inputBuffer, delayedBuf, cancelledBuffer); memcpy(inputBuffer, cancelledBuffer, samples * sizeof(short)); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-07-01 15:22:25
|
Revision: 1435 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1435&view=rev Author: jpgrayson Date: 2008-07-01 08:21:20 -0700 (Tue, 01 Jul 2008) Log Message: ----------- Rudimentary changes to allow simpleclient/tkphone to build. Modified Paths: -------------- trunk/simpleclient/tkphone/Makefile.am trunk/simpleclient/tkphone/iaxcli.c Modified: trunk/simpleclient/tkphone/Makefile.am =================================================================== --- trunk/simpleclient/tkphone/Makefile.am 2008-06-11 22:25:26 UTC (rev 1434) +++ trunk/simpleclient/tkphone/Makefile.am 2008-07-01 15:21:20 UTC (rev 1435) @@ -1,5 +1,5 @@ # Should support LINUX MACOSX WIN32 SOLARIS FREEBSD -bin_SCRIPTS = tkphone +bin_SCRIPTS = tkiaxphone iaxcli_PROGRAMS=iaxcli iaxcli_SOURCES = iaxcli.c tones.c tones.h @@ -9,9 +9,9 @@ iaxcli_SCRIPTS = tkiaxphone dist_iaxcli_DATA = monitor.ui monitor.ui.tcl phone.ui phone.ui.tcl pref.ui pref.ui.tcl -LDADD = $(top_builddir)/lib/libiaxclient.la $(GTK_LIBS) $(GDK_LIBS) +LDADD = $(top_builddir)/lib/libiaxclient.la $(GTK_LIBS) $(GDK_LIBS) $(PORTAUDIO_LIBS) $(SPEEX_LIBS) AM_CPPFLAGS = -I$(top_srcdir)/lib -DUSE_HOTKEY=0 -AM_CFLAGS = $(GTK_CFLAGS) $(GDK2_CFLAGS) +AM_CFLAGS = $(GTK_CFLAGS) $(GDK2_CFLAGS) $(PORTAUDIO_CFLAGS) $(SPEEX_CFLAGS) if ! WIN32 AM_CPPFLAGS += -DPOSIXSLEEP Modified: trunk/simpleclient/tkphone/iaxcli.c =================================================================== --- trunk/simpleclient/tkphone/iaxcli.c 2008-06-11 22:25:26 UTC (rev 1434) +++ trunk/simpleclient/tkphone/iaxcli.c 2008-07-01 15:21:20 UTC (rev 1435) @@ -413,7 +413,7 @@ #endif atexit(iaxc_shutdown); /* activate the exit handler */ - if (iaxc_initialize(AUDIO_INTERNAL_PA,1)) { + if (iaxc_initialize(1)) { fatal_error("cannot initialize iaxclient!"); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <do...@us...> - 2008-06-11 22:25:18
|
Revision: 1434 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1434&view=rev Author: dohpaz Date: 2008-06-11 15:25:26 -0700 (Wed, 11 Jun 2008) Log Message: ----------- Add some additional protection on shutdown by making sure to set max_calls to 0. Also initialize max_calls to 0, and calls to NULL to allow condom code to work. Modified Paths: -------------- branches/team/elbunce/iaxclient/lib/iaxclient_lib.c Modified: branches/team/elbunce/iaxclient/lib/iaxclient_lib.c =================================================================== --- branches/team/elbunce/iaxclient/lib/iaxclient_lib.c 2008-06-04 14:03:56 UTC (rev 1433) +++ branches/team/elbunce/iaxclient/lib/iaxclient_lib.c 2008-06-11 22:25:26 UTC (rev 1434) @@ -108,8 +108,8 @@ int iaxci_audio_output_mode = 0; // Normal int selected_call; // XXX to be protected by mutex? -struct iaxc_call* calls; -int max_calls; // number of calls for this library session +struct iaxc_call* calls = NULL; +int max_calls = 0; // number of calls for this library session static void service_network(); static int service_audio(); @@ -691,7 +691,7 @@ /* destroy enocders and decoders for all existing calls */ if ( calls ) { - int i; + int i; for ( i=0 ; i<max_calls ; i++ ) { if ( calls[i].encoder ) @@ -702,17 +702,23 @@ calls[i].vencoder->destroy(calls[i].vencoder); if ( calls[i].vdecoder ) calls[i].vdecoder->destroy(calls[i].vdecoder); - } + } + + /* Since we're de-initialized the maximum number of calls is 0, + this lets the calls size checks handle + array validity for us. ;-) + */ + max_calls = 0; + free(calls); calls = NULL; } + put_iaxc_lock(); #ifdef WIN32 closesocket(iax_get_fd()); //fd: #endif - free(calls); - MUTEXDESTROY(&event_queue_lock); MUTEXDESTROY(&iaxc_lock); } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-06-04 14:03:48
|
Revision: 1433 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1433&view=rev Author: jpgrayson Date: 2008-06-04 07:03:56 -0700 (Wed, 04 Jun 2008) Log Message: ----------- Add newline to log message. Modified Paths: -------------- trunk/lib/libiax2/src/iax.c Modified: trunk/lib/libiax2/src/iax.c =================================================================== --- trunk/lib/libiax2/src/iax.c 2008-05-23 16:40:33 UTC (rev 1432) +++ trunk/lib/libiax2/src/iax.c 2008-06-04 14:03:56 UTC (rev 1433) @@ -2299,7 +2299,7 @@ { // print a warning when the callno's don't match fprintf( stderr, "WARNING: peercallno does not match callno" - ", peercallno => %d, callno => %d, dcallno => %d", + ", peercallno => %d, callno => %d, dcallno => %d\n", cur->peercallno, callno, dcallno ) ; return 0 ; } This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-05-23 16:40:27
|
Revision: 1432 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1432&view=rev Author: jpgrayson Date: 2008-05-23 09:40:33 -0700 (Fri, 23 May 2008) Log Message: ----------- Fix unwrap_timestamp() to correctly account for mini video packets. Mini video packets only encode the lower 15-bits of their timestamps instead of the lower 16-bits that audio mini packets do. This may cause sporadic video packet loss. Modified Paths: -------------- trunk/lib/libiax2/src/iax.c Modified: trunk/lib/libiax2/src/iax.c =================================================================== --- trunk/lib/libiax2/src/iax.c 2008-05-19 15:00:26 UTC (rev 1431) +++ trunk/lib/libiax2/src/iax.c 2008-05-23 16:40:33 UTC (rev 1432) @@ -2380,51 +2380,33 @@ #endif /* From chan_iax2/steve davies: need to get permission from steve or digium, I guess */ -static long unwrap_timestamp(long ts, long last) +static long unwrap_timestamp(long ts, long last, int is_video) { - int x; + const int ts_shift = is_video ? 15 : 16; + const long lower_mask = (1 << ts_shift) - 1; + const long upper_mask = ~lower_mask; - if ( (ts & 0xFFFF0000) == (last & 0xFFFF0000) ) { - x = ts - last; - if (x < -50000) { - /* Sudden big jump backwards in timestamp: - What likely happened here is that miniframe - timestamp has circled but we haven't gotten the - update from the main packet. We'll just pretend - that we did, and update the timestamp - appropriately. */ - ts = ( (last & 0xFFFF0000) + 0x10000) | (ts & 0xFFFF); + if ( (ts & upper_mask) == (last & upper_mask) ) { + const long x = ts - last; + const long threshold = is_video ? 25000 : 50000; + + if (x < -threshold) { + /* Sudden big jump backwards in timestamp: What likely + * happened here is that miniframe timestamp has + * circled but we haven't gotten the update from the + * main packet. We'll just pretend that we did, and + * update the timestamp appropriately. + */ + ts = ((last & upper_mask) + (1 << ts_shift)) | (ts & lower_mask); DEBU(G "schedule_delivery: pushed forward timestamp\n"); - } - if (x > 50000) { + } else if (x > threshold) { /* Sudden apparent big jump forwards in timestamp: - What's likely happened is this is an old miniframe - belonging to the previous top-16-bit timestamp that - has turned up out of order. Adjust the timestamp - appropriately. */ - ts = ( (last & 0xFFFF0000) - 0x10000) | (ts & 0xFFFF); - DEBU(G "schedule_delivery: pushed back timestamp\n"); - } - } - else if ( (ts & 0xFFFF8000L) == (last & 0xFFFF8000L) ) { - x = ts - last; - if (x < -50000) { - /* Sudden big jump backwards in timestamp: - What likely happened here is that miniframe - timestamp has circled but we haven't gotten the - update from the main packet. We'll just pretend - that we did, and update the timestamp - appropriately. */ - ts = ( (last & 0xFFFF8000L) + 0x10000) | (ts & 0xFFFF); - DEBU(G "schedule_delivery: pushed forward timestamp\n"); - } - if (x > 50000) { - /* Sudden apparent big jump forwards in timestamp: * What's likely happened is this is an old miniframe - * belonging to the previous top-16-bit timestamp that - * has turned up out of order. Adjust the timestamp - * appropriately. */ - ts = ( (last & 0xFFFF8000L) - 0x10000) | (ts & 0xFFFF); + * belonging to the previous top 15-bit or 16-bit + * timestamp that has turned up out of order. Adjust + * the timestamp appropriately. + */ + ts = ((last & upper_mask) - (1 << ts_shift)) | (ts & lower_mask); DEBU(G "schedule_delivery: pushed back timestamp\n"); } } @@ -2471,7 +2453,8 @@ } /* unwrap timestamp */ - ts = unwrap_timestamp(ts,e->session->last_ts); + ts = unwrap_timestamp(ts, e->session->last_ts, + e->etype == IAX_EVENT_VIDEO); /* move forward last_ts if it's greater. We do this _after_ * unwrapping, because asterisk _still_ has cases where it This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <sb...@us...> - 2008-05-19 15:00:30
|
Revision: 1431 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1431&view=rev Author: sbalea Date: 2008-05-19 08:00:26 -0700 (Mon, 19 May 2008) Log Message: ----------- Instrument code in service_audio() in an attempt to spot an elusive crash Modified Paths: -------------- branches/team/elbunce/iaxclient/lib/iaxclient_lib.c Modified: branches/team/elbunce/iaxclient/lib/iaxclient_lib.c =================================================================== --- branches/team/elbunce/iaxclient/lib/iaxclient_lib.c 2008-05-08 14:10:11 UTC (rev 1430) +++ branches/team/elbunce/iaxclient/lib/iaxclient_lib.c 2008-05-19 15:00:26 UTC (rev 1431) @@ -863,6 +863,16 @@ int cmin; audio_driver.start(&audio_driver); + + /* check and report if pointers are not good here */ + if ( !((unsigned int)call & 0xffffff00) ) + fprintf(stderr, "*** INVALID POINTER call = 0x%x ***\n", call); + + if ( !((unsigned int)call->encoder & 0xffffff00) ) + fprintf(stderr, "*** INVALID POINTER call->encoder = 0x%x ***\n", call->encoder); + + if ( !call->state ) + fprintf(stderr, "*** INVALID CALL STATE (0) ***\n"); /* use codec minimum if higher */ cmin = want_send_audio && call->encoder ? This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <do...@us...> - 2008-05-08 14:10:33
|
Revision: 1430 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1430&view=rev Author: dohpaz Date: 2008-05-08 07:10:11 -0700 (Thu, 08 May 2008) Log Message: ----------- Remove erroneous assumption. The user may have video preview up and take a non-video call. Modified Paths: -------------- branches/team/elbunce/iaxclient/lib/video.c Modified: branches/team/elbunce/iaxclient/lib/video.c =================================================================== --- branches/team/elbunce/iaxclient/lib/video.c 2008-05-05 05:07:10 UTC (rev 1429) +++ branches/team/elbunce/iaxclient/lib/video.c 2008-05-08 14:10:11 UTC (rev 1430) @@ -678,12 +678,6 @@ * start sending video. */ } - else if ( !call->vformat && call->state & IAXC_CALL_STATE_COMPLETE ) - { - fprintf(stderr, "video format not set for call %d\n", - selected_call); - goto callback_failed; - } else { goto callback_done; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <do...@us...> - 2008-05-05 05:07:03
|
Revision: 1429 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1429&view=rev Author: dohpaz Date: 2008-05-04 22:07:10 -0700 (Sun, 04 May 2008) Log Message: ----------- Additional prophylactic code to prevent certain problems. Modified Paths: -------------- branches/team/elbunce/iaxclient/lib/iaxclient_lib.c Modified: branches/team/elbunce/iaxclient/lib/iaxclient_lib.c =================================================================== --- branches/team/elbunce/iaxclient/lib/iaxclient_lib.c 2008-05-04 15:33:56 UTC (rev 1428) +++ branches/team/elbunce/iaxclient/lib/iaxclient_lib.c 2008-05-05 05:07:10 UTC (rev 1429) @@ -1483,7 +1483,7 @@ EXPORT void iaxc_setup_call_transfer(int sourceCallNo, int targetCallNo) { - if ( sourceCallNo < 0 || targetCallNo < 0 || + if ( ( sourceCallNo < 0 ) || ( targetCallNo < 0 ) || !(calls[sourceCallNo].state & IAXC_CALL_STATE_ACTIVE) || !(calls[targetCallNo].state & IAXC_CALL_STATE_ACTIVE) ) return; @@ -1491,12 +1491,15 @@ iax_setup_transfer(calls[sourceCallNo].session, calls[targetCallNo].session); } +/* + iaxc_dump_one_call dumps \a callNo. Expects the routine calling it to have + obtained the iaxc lock. + */ static void iaxc_dump_one_call(int callNo) { - if ( callNo < 0 ) + if ( ( callNo < 0 ) || ( callNo >= max_calls ) || + ( calls[callNo].state == IAXC_CALL_STATE_FREE ) ) return; - if ( calls[callNo].state == IAXC_CALL_STATE_FREE ) - return; iax_hangup(calls[callNo].session,"Dumped Call"); iaxci_usermsg(IAXC_STATUS, "Hanging up call %d", callNo); @@ -1515,12 +1518,9 @@ EXPORT void iaxc_dump_call_number( int callNo ) { - if ( ( callNo >= 0 ) && ( callNo < max_calls ) ) - { - get_iaxc_lock(); - iaxc_dump_one_call(callNo); - put_iaxc_lock(); - } + get_iaxc_lock(); + iaxc_dump_one_call(callNo); + put_iaxc_lock(); } EXPORT void iaxc_dump_call(void) @@ -1543,13 +1543,14 @@ EXPORT void iaxc_reject_call_number( int callNo ) { - if ( ( callNo >= 0 ) && ( callNo < max_calls ) ) - { - get_iaxc_lock(); - iax_reject(calls[callNo].session, "Call rejected manually."); - iaxc_clear_call(callNo); - put_iaxc_lock(); - } + if ( ( callNo < 0 ) || ( callNo >= max_calls ) || + ( calls[callNo].state == IAXC_CALL_STATE_FREE ) ) + return; + + get_iaxc_lock(); + iax_reject(calls[callNo].session, "Call rejected manually."); + iaxc_clear_call(callNo); + put_iaxc_lock(); } EXPORT void iaxc_send_dtmf(char digit) @@ -1567,21 +1568,18 @@ { if ( selected_call >= 0 ) { - get_iaxc_lock(); - if ( calls[selected_call].state & IAXC_CALL_STATE_ACTIVE ) - iax_send_text(calls[selected_call].session, text); - put_iaxc_lock(); + iaxc_send_text_call(selected_call, text); } } EXPORT void iaxc_send_text_call(int callNo, const char * text) { - if ( callNo < 0 || !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE) ) + if ( ( callNo < 0 ) || ( callNo >= max_calls ) || + ( !(calls[callNo].state & IAXC_CALL_STATE_ACTIVE) ) ) return; get_iaxc_lock(); - if ( calls[callNo].state & IAXC_CALL_STATE_ACTIVE ) - iax_send_text(calls[callNo].session, text); + iax_send_text(calls[callNo].session, text); put_iaxc_lock(); } @@ -1942,16 +1940,30 @@ EXPORT int iaxc_quelch(int callNo, int MOH) { - struct iax_session *session = calls[callNo].session; - if ( !session ) + int ret; + + if ( ( callNo < 0 ) || ( callNo >= max_calls ) || + !( calls[callNo].state & IAXC_CALL_STATE_ACTIVE ) ) return -1; - return iax_quelch_moh(session, MOH); + get_iaxc_lock(); + ret = iax_quelch_moh(calls[callNo].session, MOH); + put_iaxc_lock(); + return ret; } -EXPORT int iaxc_unquelch(int call) +EXPORT int iaxc_unquelch(int callNo) { - return iax_unquelch(calls[call].session); + int ret; + + if ( ( callNo < 0 ) || ( callNo >= max_calls ) || + !( calls[callNo].state & IAXC_CALL_STATE_ACTIVE ) ) + return -1; + + get_iaxc_lock(); + ret = iax_unquelch(calls[callNo].session); + put_iaxc_lock(); + return ret; } EXPORT int iaxc_mic_boost_get( void ) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <do...@us...> - 2008-05-04 15:33:51
|
Revision: 1428 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1428&view=rev Author: dohpaz Date: 2008-05-04 08:33:56 -0700 (Sun, 04 May 2008) Log Message: ----------- Merge up to trunk of r1427. Modified Paths: -------------- branches/team/elbunce/iaxclient/Makefile.am branches/team/elbunce/iaxclient/README.VisualStudio branches/team/elbunce/iaxclient/autogen.sh branches/team/elbunce/iaxclient/configure.ac branches/team/elbunce/iaxclient/contrib/macosx/Prefixes.h branches/team/elbunce/iaxclient/contrib/tcl/Prefixes.h branches/team/elbunce/iaxclient/contrib/tcl/XThreadUtil.c branches/team/elbunce/iaxclient/contrib/tcl/configure branches/team/elbunce/iaxclient/contrib/tcl/configure.in branches/team/elbunce/iaxclient/contrib/tcl/iaxclient.c branches/team/elbunce/iaxclient/contrib/tcl/macosx/PBExportedSymbols branches/team/elbunce/iaxclient/contrib/tcl/pkgIndex.tcl branches/team/elbunce/iaxclient/contrib/tcl/pkgIndex.tcl.in branches/team/elbunce/iaxclient/contrib/win/vs2003/iaxclient_dll.vcproj branches/team/elbunce/iaxclient/contrib/win/vs2003/iaxclient_lib.vcproj branches/team/elbunce/iaxclient/contrib/win/vs2005/iaxclient.sln branches/team/elbunce/iaxclient/contrib/win/vs2005/libiaxclient.vcproj branches/team/elbunce/iaxclient/contrib/win/vs2005/libportmixer.vcproj branches/team/elbunce/iaxclient/contrib/win/vs2005/libspeex.vcproj branches/team/elbunce/iaxclient/contrib/win/vs2005/libtheora.vcproj branches/team/elbunce/iaxclient/contrib/win/vs2005/libvidcap.vcproj branches/team/elbunce/iaxclient/contrib/win/vs2005/testcall.vcproj branches/team/elbunce/iaxclient/iaxclient.pc.in branches/team/elbunce/iaxclient/lib/Makefile.am branches/team/elbunce/iaxclient/lib/audio_encode.c branches/team/elbunce/iaxclient/lib/audio_encode.h branches/team/elbunce/iaxclient/lib/audio_portaudio.c branches/team/elbunce/iaxclient/lib/iaxclient.h branches/team/elbunce/iaxclient/lib/iaxclient_lib.c branches/team/elbunce/iaxclient/lib/libiax2/src/frame.h branches/team/elbunce/iaxclient/lib/libiax2/src/iax-client.h branches/team/elbunce/iaxclient/lib/libiax2/src/iax.c branches/team/elbunce/iaxclient/lib/libiax2/src/iax2.h branches/team/elbunce/iaxclient/lib/portmixer/px_win_wmme/px_win_wmme.c branches/team/elbunce/iaxclient/lib/video.c branches/team/elbunce/iaxclient/m4/speex.m4 branches/team/elbunce/iaxclient/simpleclient/iaxcomm/Makefile.am branches/team/elbunce/iaxclient/simpleclient/iaxcomm/prefs.cc branches/team/elbunce/iaxclient/simpleclient/stresstest/Makefile.am branches/team/elbunce/iaxclient/simpleclient/stresstest/file.c branches/team/elbunce/iaxclient/simpleclient/stresstest/file.h branches/team/elbunce/iaxclient/simpleclient/testcall/Makefile.am branches/team/elbunce/iaxclient/simpleclient/testcall/testcall.c branches/team/elbunce/iaxclient/simpleclient/vtestcall/Makefile.am Added Paths: ----------- branches/team/elbunce/iaxclient/contrib/tcl/build-iaxclient.txt branches/team/elbunce/iaxclient/contrib/tcl/macosx/iaxclient.xcodeproj/ branches/team/elbunce/iaxclient/contrib/tcl/macosx/iaxclient.xcodeproj/project.pbxproj branches/team/elbunce/iaxclient/contrib/win/vs2005/vtestcall.vcproj branches/team/elbunce/iaxclient/simpleclient/iaxcomm/iaxcomm.sln branches/team/elbunce/iaxclient/simpleclient/iaxcomm/iaxcomm.vcproj Removed Paths: ------------- branches/team/elbunce/iaxclient/contrib/tcl/macosx/iaxclient.pbproj/ branches/team/elbunce/iaxclient/contrib/tcl/macosx/iaxclient.xcodeproj/project.pbxproj branches/team/elbunce/iaxclient/simpleclient/videotest/mihai.vcproj branches/team/elbunce/iaxclient/simpleclient/vtestcall/vtestcall.vcproj Modified: branches/team/elbunce/iaxclient/Makefile.am =================================================================== --- branches/team/elbunce/iaxclient/Makefile.am 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/Makefile.am 2008-05-04 15:33:56 UTC (rev 1428) @@ -12,6 +12,8 @@ README.VisualStudio \ autogen.sh \ contrib \ + doc \ + Doxyfile \ m4 dist-hook: Modified: branches/team/elbunce/iaxclient/README.VisualStudio =================================================================== --- branches/team/elbunce/iaxclient/README.VisualStudio 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/README.VisualStudio 2008-05-04 15:33:56 UTC (rev 1428) @@ -2,69 +2,90 @@ 2005. A reference solution file and project files are located in the contrib/win/vs2005 directory. - 1) The following environment variables must be set. Use the "System" - properties dialog in the Windows Control Panel to set these - variables either for the user or system-wide. +Steps demarked with (*) are only required if building with video +support. - %DXSDK_DIR% + 1*) Set the DXSDK_DIR environment variable. + + Use the "System" properties dialog in the Windows Control Panel to + set this variable either for the user or system-wide. The value is + the path to the DirectX SDK. The June 2007, August 2007, and + December 2006 versions of the DirectX SDK are known to work. - Path to the DirectX SDK. The June 2007 version of the DirectX - SDK is known to work. The December 2006 version is also know to - work. + 2*) Install the Microsoft Windows Software Development Kit. + + Version 6.0 is known to work. After installing the Windows SDK, run + the program "Start -> Microsoft Windows SDK -> Visual Studio + Registration -> Integrate Windows SDK with Visual Studio". This + registers include and library paths with Visual Studio. + + See here for the Windows SDK: - %PSDK_DIR% + http://www.microsoft.com/downloads/details.aspx?familyid=4377F86D-C913-4B5C-B87E-EF72E5B4E065 + + 3) Obtain dependencies. + + 3a) At the time of this writing, portaudio-v19 and speex-1.2beta3 are + required for all configurations. Sources may be found here: - Path to the Platform SDK. The Windows SDK is known to work for - this. Assuming the Windows SDK is installed in the default - location, PSDK_DIR would be set to: + http://portaudio.com/archives/pa_snapshot_v19.tar.gz + http://downloads.xiph.org/releases/speex/speex-1.2beta3.tar.gz - C:\Program Files\Microsoft SDKs\Windows\v6.0 + 3b*) For video support, libogg-1.1.3, libtheora-1.0beta2, and + libvidcap-0.2.1 are also required. Source for these dependencies + are available here: - The older Platform SDK for Windows Server 2003 Release 2 is also - known to work. + http://downloads.xiph.org/releases/ogg/libogg-1.1.3.tar.gz + http://downloads.xiph.org/releases/theora/libtheora-1.0beta2.tar.gz + http://downloads.sourceforge.net/libvidcap/libvidcap-0.2.1.tar.gz - See here for the Windows SDK: + 3c*) Additionally, to build vtestcall, SDL is required. A prebuilt + binary development package is available here: - http://www.microsoft.com/downloads/details.aspx?FamilyID=c2b1e300-f358-4523-b479-f53d234cdccf + http://www.libsdl.org/release/SDL-devel-1.2.13-VC8.zip - 2) Obtain dependencies. At the time of this writing, portaudio-v19, - libogg 1.1.3, speex 1.2beta1, libtheora 1.0alpha7, and libvidcap are required. - Source for these dependencies are available here: + 4) Rename/move directories. - http://portaudio.com/archives/pa_snapshot_v19.tar.gz - http://downloads.xiph.org/releases/ogg/libogg-1.1.3.tar.gz - http://downloads.xiph.org/releases/speex/speex-1.2beta1.tar.gz - http://downloads.xiph.org/releases/theora/libtheora-1.0alpha7.tar.gz - http://downloads.sourceforge.net/libvidcap/libvidcap-0.1.tar.gz + In order to build with the vcproj files provided by iaxclient, these + dependent libraries must be moved to be peer directories to the + iaxclient source directory. They also must have the following names: + portaudio, speex, libogg, libtheora, libvidcap, and SDL. So the + final directory layout must look like this: - In order to build with the vcproj files provided by iaxclient, - these dependent libraries must be moved to be peer directories to - the iaxclient source directory. They also must have the following - names: libogg, speex, libtheora and libvidcap. So the final directory - layout would be as follows: - C:\...\whereever\iaxclient C:\...\whereever\portaudio + C:\...\whereever\speex C:\...\whereever\libogg - C:\...\whereever\speex C:\...\whereever\libtheora C:\...\whereever\libvidcap + C:\...\whereever\SDL - 2) Open the solution file: contrib/win/vs2005/iaxclient.sln + 5) Open the solution file. + + Using Visual Studio 2005, open contrib/win/vs2005/iaxclient.sln. - 3) Choose configuration. There are four options: - Release -- optimized static library - Release_dll -- optimized dynamic link library - Debug -- debug static library - Debug_dll -- debug dynamic link library + 6) Choose configuration. - 4) Build the solution. This will build iaxclient and all its - dependent libraries. All dependent libraries are linked into - the final library. The final libiaxclient library can be found - here (depending on the configuration chosen): + There are four options: + Release -- optimized static library + Release_dll -- optimized dynamic link library + Release_novideo -- optimized static library without video support + Debug -- debug static library + Debug_dll -- debug dynamic link library + Debug_novideo -- debug static library without video support + + 6) Build the solution. + + This will build iaxclient and all its dependent libraries. All + dependent libraries are linked into the final library. The final + libiaxclient library can be found here (depending on the + configuration chosen): + Release\libiaxclient\libiaxclient.lib Release_dll\libiaxclient\libiaxclient.dll + Release_novideo\libiaxclient\libiaxclient.lib Debug\libiaxclient\libiaxclient.lib Debug_dll\libiaxclient\libiaxclient.dll + Debug_novideo\libiaxclient\libiaxclient.lib Modified: branches/team/elbunce/iaxclient/autogen.sh =================================================================== --- branches/team/elbunce/iaxclient/autogen.sh 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/autogen.sh 2008-05-04 15:33:56 UTC (rev 1428) @@ -1,4 +1,4 @@ -#!/bin/sh -e +#!/bin/bash -e error() { Modified: branches/team/elbunce/iaxclient/configure.ac =================================================================== --- branches/team/elbunce/iaxclient/configure.ac 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/configure.ac 2008-05-04 15:33:56 UTC (rev 1428) @@ -3,9 +3,9 @@ AC_PREREQ(2.59) dnl Package version -m4_define(IAXC_VERSION, [2.1-svn]) +m4_define(IAXC_VERSION, [2.x-trunk]) -AC_INIT(iaxclient, IAXC_VERSION, [jpg...@gm...]) +AC_INIT(iaxclient, IAXC_VERSION, [iax...@li...]) AC_CONFIG_SRCDIR([lib/iaxclient.h]) AC_CONFIG_HEADERS([config.h]) @@ -15,7 +15,7 @@ dnl Libtool library version IAXC_LT_CURRENT=1 -IAXC_LT_REVISION=0 +IAXC_LT_REVISION=2 IAXC_LT_AGE=0 AC_SUBST(IAXC_LT_CURRENT) @@ -66,7 +66,6 @@ CFLAGS=${CFLAGS-"-O2 -g -Wall --std=gnu99"} CXXFLAGS=${CXXFLAGS-"-O2 -g -Wall"} -# AC_ARG_ENABLE saves the option's argument in enable_FEATURE AC_ARG_ENABLE(local-gsm, [AS_HELP_STRING([--enable-local-gsm], [Use local gsm library [default=auto]])],, @@ -80,17 +79,17 @@ AC_ARG_ENABLE(debug-iax, [AS_HELP_STRING([--enable-debug-iax], [Enable debug support in local iax library])], - enable_debug_iax2=$enableval, - enable_debug_iax2="no") + enable_debug_iax2=$enableval, + enable_debug_iax2="no") -AC_ARG_ENABLE(speex_preprocess, - [AS_HELP_STRING([--disable-speex-preprocess], - [Turn off speex preprocessing])],, - [enable_speex_preprocess="yes"]) +AC_ARG_ENABLE(video, + [AS_HELP_STRING([--enable-video], + [Enable video support [default=yes]])],, + [enable_video="yes"]) AC_ARG_WITH(echo-can, [AS_HELP_STRING([--with-echo-can], - [use echo can (span, speex or mec2) [default=speex]])], + [use echo can (span or speex) [default=speex]])], use_echo_can=$withval, use_echo_can="speex") @@ -104,35 +103,12 @@ [Enable iLBC support (You need to place the iLBC reference sources in lib/iLBC) [default=auto]])],, with_ilbc="auto") -case "$with_ilbc" in - yes) - enable_local_ilbc=yes ;; - no) - enable_local_ilbc=no ;; - auto) - AC_MSG_CHECKING([for iLBC reference sources in lib/iLBC]) - if test -r lib/iLBC/iLBC_encode.c; then - enable_local_ilbc=yes - else - enable_local_ilbc=no - fi - AC_MSG_RESULT([$enable_local_ilbc]) ;; - - *) - AC_MSG_ERROR([bad value ${with_ilbc} for --with-ilbc]) ;; -esac - AC_ARG_WITH(wish, [AS_HELP_STRING([--with-wish], [Path to Tcl command language interpreter])], WISH="${with_wish}", with_wish="auto") -AC_ARG_WITH(video, - [AS_HELP_STRING([--without-video], - [Video support])],, - with_video="yes") - AC_ARG_WITH(ogg, [AS_HELP_STRING([--without-ogg], [OGG support])],, @@ -154,24 +130,23 @@ FFMPEG="${with_ffmpeg}", with_ffmpeg="no") -if test ! "x$enable_clients" = "xauto"; then - for client in ${enable_clients}; do - case "$client" in - iaxcomm | iaxphone | stresstest | testcall | tkphone | vtestcall | WinIAX | wx) - clients="$clients $client" ;; - all | yes) - clients="iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx" - break ;; - none | no) - clients="" - break ;; - *) - AC_MSG_ERROR(bad value ${client} for --enable-clients) ;; - esac - done -fi +case "$with_ilbc" in + yes) + enable_local_ilbc=yes ;; + no) + enable_local_ilbc=no ;; + auto) + AC_MSG_CHECKING([for iLBC reference sources in lib/iLBC]) + if test -r lib/iLBC/iLBC_encode.c; then + enable_local_ilbc=yes + else + enable_local_ilbc=no + fi + AC_MSG_RESULT([$enable_local_ilbc]) ;; -AM_OPTIONS_WXCONFIG + *) + AC_MSG_ERROR([bad value ${with_ilbc} for --with-ilbc]) ;; +esac case $host_os in *mingw32*|*cygwin* ) @@ -200,6 +175,28 @@ obtain a copy. ])) +PKG_CHECK_MODULES(SPEEX, [speex >= 1.2],,AC_MSG_ERROR([ + speex is required to build this package! + please see http://www.xiph.org/ for how to + obtain a copy. +])) + +PKG_CHECK_MODULES(SPEEXDSP, [speexdsp >= 1.2],,AC_MSG_ERROR([ + speexdsp is required to build this package! + please see http://www.xiph.org/ for how to + obtain a copy. +])) + +PKG_CHECK_MODULES(SDL, [sdl >= 1.2], has_sdl=yes, has_sdl=no) +PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.0], has_gtk2=yes, has_gtk2=no) +PKG_CHECK_MODULES(GDK2, [gdk-2.0 >= 2.0.0], has_gdk2=yes, has_gdk2=no) +PKG_CHECK_MODULES(ALSA, [alsa >= 1.0], has_alsa=yes, has_alsa=no) +PKG_CHECK_MODULES(OGG, [ogg >= 1.1.3], has_ogg=yes, has_ogg=no) +PKG_CHECK_MODULES(OGGZ, [oggz >= 0.9.5], has_oggz=yes, has_oggz=no) +PKG_CHECK_MODULES(THEORA, [theora >= 1.0alpha7], has_theora=yes, has_theora=no) +PKG_CHECK_MODULES(VIDCAP, [vidcap >= 0.1], has_vidcap=yes, has_vidcap=no) +PKG_CHECK_MODULES(FFMPEG, [libavcodec >= 51.40.3], has_ffmpeg=yes, has_ffmpeg=no) + has_gsm=no if test x$enable_local_gsm = xyes; then has_gsm=yes @@ -208,93 +205,67 @@ AM_PATH_GSM(has_gsm=yes, has_gsm=no) fi -if test x$with_video = xyes; then - AC_DEFINE(USE_VIDEO, 1, [Define to 1 to enable Video support]) -fi -AM_CONDITIONAL(VIDEO, test x$with_video = xyes) +PACKAGE_REQUIRES="" -has_ogg=no -if test ! x$with_ogg = xno; then -PKG_CHECK_MODULES(OGG, [ogg >= 1.1.3],has_ogg=yes) -if test x$has_ogg = xyes; then - AC_DEFINE(USE_OGG, 1, [OGG]) - PKG_REQUIRES="$PKG_REQUIRES ogg" -elif test ! x$with_ogg = xauto ; then - AC_MSG_ERROR([ - libogg is required to build this package! - please see http://www.xiph.org/ for how to - obtain a copy. - ]) -fi -fi -AM_CONDITIONAL(OGG, test x$has_ogg = xyes) - -PKG_CHECK_MODULES(SPEEX, [speex >= 1.2],,AC_MSG_ERROR([ - speex is required to build this package! - please see http://www.xiph.org/ for how to - obtain a copy. -])) +if test x$enable_video = xyes; then -has_theora=no -if test ! x$with_theora = xno; then -PKG_CHECK_MODULES(THEORA, [theora >= 1.0alpha7],has_theora=yes) -if test x$has_theora = xyes; then - AC_DEFINE(USE_THEORA, 1, [THEORA]) - PKG_REQUIRES="$PKG_REQUIRES theora" -elif test ! x$with_theora = xauto ; then - AC_MSG_ERROR([ - libtheora is required to build this package! - please see http://www.xiph.org/ for how to - obtain a copy. - ]) -fi -fi -AM_CONDITIONAL(THEORA, test x$has_theora = xyes) - -has_vidcap=no -if test ! x$with_vidcap = xno; then - PKG_CHECK_MODULES(VIDCAP, [vidcap >= 0.1],has_vidcap=yes) + if test x$with_ogg != xno; then + if test x$has_ogg = xyes; then + AC_DEFINE(USE_OGG, 1, [OGG]) + PACKAGE_REQUIRES="$PACKAGE_REQUIRES ogg" + elif test x$with_ogg != xauto ; then + AC_MSG_ERROR([ + libogg is required to build this package! + please see http://www.xiph.org/ for how to + obtain a copy. + ]) + fi + fi + + if test x$with_theora != xno; then + if test x$has_theora = xyes; then + AC_DEFINE(USE_THEORA, 1, [THEORA]) + PACKAGE_REQUIRES="$PACKAGE_REQUIRES theora" + elif test x$with_theora != xauto ; then + AC_MSG_ERROR([ + libtheora is required to build this package! + please see http://www.xiph.org/ for how to + obtain a copy. + ]) + fi + fi + if test x$has_vidcap = xyes; then AC_DEFINE(USE_VIDCAP, 1, [VIDCAP]) - PKG_REQUIRES="$PKG_REQUIRES vidcap" - elif test ! x$with_vidcap = xauto ; then + PACKAGE_REQUIRES="$PACKAGE_REQUIRES vidcap" + else AC_MSG_ERROR([ libvidcap is required to build this package! please see http://libvidcap.sourceforge.net/ for how to obtain a copy. ]) fi + + if test x$with_ffmpeg != xno; then + if test x$has_ffmpeg = xyes; then + AC_DEFINE(USE_FFMPEG, 1, [FFMPEG]) + PACKAGE_REQUIRES="$PACKAGE_REQUIRES ffmpeg" + elif test x$with_ffmpeg != xauto ; then + AC_MSG_ERROR([ + FFmpeg is required to build this package! + please see http://ffmpeg.mplayerhq.hu/ for how to + obtain a copy. + ]) + fi + fi fi -AM_CONDITIONAL(VIDCAP, test x$has_vidcap = xyes) -has_ffmpeg=no -if test ! x$with_ffmpeg = xno; then -PKG_CHECK_MODULES(FFMPEG, [libavcodec >= 51.40.3],has_ffmpeg=yes) -if test x$has_ffmpeg = xyes; then - AC_DEFINE(USE_FFMPEG, 1, [FFMPEG]) - PKG_REQUIRES="$PKG_REQUIRES ffmpeg" -elif test ! x$with_ffmpeg = xauto ; then - AC_MSG_ERROR([ - FFmpeg is required to build this package! - please see http://ffmpeg.mplayerhq.hu/ for how to - obtain a copy. - ]) -fi -fi -AM_CONDITIONAL(FFMPEG, test x$has_ffmpeg = xyes) - -PKG_CHECK_MODULES(SDL, [sdl >= 1.2], has_sdl=yes, has_sdl=no) -PKG_CHECK_MODULES(GTK, [gtk+-2.0 >= 2.0], has_gtk2=yes, has_gtk2=no) -PKG_CHECK_MODULES(GDK2, [gdk-2.0 >= 2.0.0], has_gdk2=yes, has_gdk2=no) -PKG_CHECK_MODULES(ALSA, [alsa >= 1.0], has_alsa=yes, has_alsa=no) -PKG_CHECK_MODULES(OGGZ, [oggz >= 0.9.5], has_oggz=yes, has_oggz=no) - has_iax2=no -if test ! x$enable_local_iax = xyes; then +if test x$enable_local_iax != xyes; then AM_PATH_IAX2(0.2.3,has_iax2=yes,has_iax2=no) fi -if test x$has_iax2 = xno && test ! x$enable_local_iax = xno; then +if test x$has_iax2 = xno && test x$enable_local_iax != xno; then has_iax2=yes enable_local_iax2=yes IAX2_CFLAGS='-I$(top_srcdir)/lib/libiax2/src -DLIBIAX' @@ -302,6 +273,8 @@ IAX2_CONFIG="" fi +AM_OPTIONS_WXCONFIG + has_wx="no" AM_PATH_WXCONFIG(2.6.0, [has_wx="2.6"], [AM_PATH_WXCONFIG(2.4.0, [has_wx="2.4"])]) @@ -316,7 +289,7 @@ CXXFLAGS="$WX_CXXFLAGS_ONLY" AC_LANG_PUSH(C++) -if test ! x$has_wx = xno; then +if test x$has_wx != xno; then AC_CHECK_HEADER(wx/xrc/xmlres.h,has_wx_xrc=yes, [AC_MSG_WARN([Can't find wx/xrc/xml.h]) has_wx_xrc=no]) @@ -358,32 +331,33 @@ CXXFLAGS="$save_CXXFLAGS" dnl End wx xrc check -if test x$enable_speex_preprocess = xyes; then - AC_DEFINE(SPEEX_PREPROCESS, 1, [Speex preprocess]) +if test x$enable_video = xyes; then + AC_DEFINE(USE_VIDEO, 1, [Define to 1 to enable video support]) fi -AM_CONDITIONAL(SPAN_EC, test x$use_echo_can = xspan) if test x$use_echo_can = xspan; then - AC_DEFINE(SPAN_EC, 1, [Span echo can]) + AC_DEFINE(SPAN_EC, 1, [Define to 1 to enable span echo cancellation]) fi if test x$use_echo_can = xspeex; then - AC_DEFINE(SPEEX_EC, 1, [Speex echo can]) + AC_DEFINE(SPEEX_EC, 1, [Define to 1 to enable speex echo cancellation]) fi -if test x$use_echo_can = xmec2; then - AC_DEFINE(MEC2_EC, 1, [Mec echo can]) -fi - if test x$enable_local_ilbc = xyes; then - AC_DEFINE(CODEC_ILBC,,[Enable ILBC support]) + AC_DEFINE(CODEC_ILBC,,[Define to 1 to enable ILBC support]) fi -if test x$has_gsm = xyes && test ! x$with_gsm = xno; then - AC_DEFINE(CODEC_GSM,,[Enable GSM support]) +if test x$has_gsm = xyes && test x$with_gsm != xno; then + AC_DEFINE(CODEC_GSM,,[Define to 1 to enable GSM support]) fi -AM_CONDITIONAL(USE_CODEC_GSM, test x$has_gsm = xyes && test ! x$with_gsm = xno) +AM_CONDITIONAL(VIDEO, test x$enable_video = xyes) +AM_CONDITIONAL(OGG, test x$has_ogg = xyes && test x$with_ogg != xno) +AM_CONDITIONAL(THEORA, test x$has_theora = xyes && test x$with_theora != xno) +AM_CONDITIONAL(VIDCAP, test x$has_vidcap = xyes && test x$with_vidcap != xno) +AM_CONDITIONAL(FFMPEG, test x$has_ffmpeg = xyes && test x$with_ffmpeg != xno) +AM_CONDITIONAL(SPAN_EC, test x$use_echo_can = xspan) +AM_CONDITIONAL(USE_CODEC_GSM, test x$has_gsm = xyes && test x$with_gsm != xno) AM_CONDITIONAL(USE_LOCAL_GSM, test x$enable_local_gsm = xyes) AM_CONDITIONAL(USE_LOCAL_IAX2, test x$enable_local_iax2 = xyes) AM_CONDITIONAL(USE_DEBUG_IAX2, test x$enable_debug_iax2 = xyes) @@ -393,14 +367,29 @@ AM_CONDITIONAL(MACOSX, test x$OSTYPE = xMACOSX) # Autodetect clients -if test "x$enable_clients" = "xauto"; then +if test "x$enable_clients" != "xauto"; then + for client in ${enable_clients}; do + case "$client" in + iaxcomm | iaxphone | stresstest | testcall | tkphone | vtestcall | WinIAX | wx) + clients="$clients $client" ;; + all | yes) + clients="iaxcomm iaxphone stresstest testcall tkphone vtestcall WinIAX wx" + break ;; + none | no) + clients="" + break ;; + *) + AC_MSG_ERROR(bad value ${client} for --enable-clients) ;; + esac + done +else clients="$clients testcall" - if test x$has_oggz = xyes && test x$has_theora = xyes; then + if test x$enable_video = xyes && test x$has_oggz = xyes && test x$has_theora = xyes; then clients="$clients stresstest" fi - if test ! x$has_wx = xno; then + if test x$has_wx != xno; then clients="$clients iaxphone" if test "x$has_gdk2" = xyes; then clients="$clients wx" @@ -411,7 +400,7 @@ fi fi - if test x$has_sdl = xyes && test x$with_video = xyes; then + if test x$has_sdl = xyes && test x$enable_video = xyes; then clients="$clients vtestcall" fi @@ -419,7 +408,7 @@ clients="$clients WinIAX" fi - if test ! x$WISH = x && test "x$has_gdk2" = "xyes"; then + if test x$WISH != x && test "x$has_gdk2" = "xyes"; then clients="$clients tkphone" fi fi @@ -434,7 +423,7 @@ CLIENTS="$CLIENTS $client";; vtestcall) - if test ! x$has_sdl = xyes || test ! x$with_video = xyes ; then + if test x$has_sdl != xyes || test x$enable_video != xyes ; then AC_MSG_ERROR([vtestcall requires SDL and video]) fi CLIENTS="$CLIENTS $client";; @@ -474,7 +463,7 @@ done AC_SUBST(CLIENTS) -AC_SUBST(PKG_REQUIRES) +AC_SUBST(PACKAGE_REQUIRES) AC_CONFIG_FILES([ Makefile Modified: branches/team/elbunce/iaxclient/contrib/macosx/Prefixes.h =================================================================== --- branches/team/elbunce/iaxclient/contrib/macosx/Prefixes.h 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/contrib/macosx/Prefixes.h 2008-05-04 15:33:56 UTC (rev 1428) @@ -3,10 +3,8 @@ #define LIBIAX //#define CODEC_ILBC 0 -#define SPEEX_PREPROCESS 1 //#define SPAN_EC 0 #define SPEEX_EC 1 -//#define MEC2_EC 0 Modified: branches/team/elbunce/iaxclient/contrib/tcl/Prefixes.h =================================================================== --- branches/team/elbunce/iaxclient/contrib/tcl/Prefixes.h 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/contrib/tcl/Prefixes.h 2008-05-04 15:33:56 UTC (rev 1428) @@ -5,10 +5,8 @@ //#define CODEC_ILBC 0 -#define SPEEX_PREPROCESS 1 //#define SPAN_EC 0 #define SPEEX_EC 1 -//#define MEC2_EC 0 #define USE_NEWJB 1 //#define USE_VIDEO 0 Modified: branches/team/elbunce/iaxclient/contrib/tcl/XThreadUtil.c =================================================================== --- branches/team/elbunce/iaxclient/contrib/tcl/XThreadUtil.c 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/contrib/tcl/XThreadUtil.c 2008-05-04 15:33:56 UTC (rev 1428) @@ -12,9 +12,9 @@ * * By Mats Bengtsson and Zoran Vasiljevic 2006 * - * \xCA 1. XThread_RegisterThread - * \xCA 2. XThread_UnregisterThread - * \xCA 3. XThread_EvalInThread + * 1. XThread_RegisterThread + * 2. XThread_UnregisterThread + * 3. XThread_EvalInThread * * The 1. needs to be called from your master thread, i.e. the * one you would like to execute the callbacks within. @@ -30,9 +30,9 @@ #include <string.h> #if TARGET_API_MAC_CARBON -# include <Tcl/tcl.h> +# include <Tcl/tcl.h> #else -# include "tcl.h" +# include "tcl.h" #endif #ifndef TCL_TSD_INIT @@ -46,7 +46,7 @@ */ typedef struct ThreadSpecificData { - Tcl_Interp *interp; /* Interp to evaluate scripts */ + Tcl_Interp *interp; /* Interp to evaluate scripts */ } ThreadSpecificData; static Tcl_ThreadDataKey dataKey; @@ -76,15 +76,10 @@ } ThreadSendData; -static void -ThreadSend _ANSI_ARGS_((Tcl_ThreadId targetId, ThreadSendData *send)); +static void ThreadSend _ANSI_ARGS_((Tcl_ThreadId targetId, ThreadSendData *send)); +static int ThreadEventProc _ANSI_ARGS_((Tcl_Event *evPtr, int mask)); +static void ThreadFreeProc _ANSI_ARGS_((ClientData clientData)); -static int -ThreadEventProc _ANSI_ARGS_((Tcl_Event *evPtr, int mask)); - -static void -ThreadFreeProc _ANSI_ARGS_((ClientData clientData)); - /* *---------------------------------------------------------------------- * @@ -102,7 +97,8 @@ *---------------------------------------------------------------------- */ -void XThread_RegisterThread(Tcl_Interp *interp) +void +XThread_RegisterThread(Tcl_Interp *interp) { ThreadSpecificData* tsdPtr = TCL_TSD_INIT(&dataKey); @@ -126,7 +122,8 @@ *---------------------------------------------------------------------- */ -void XThread_UnregisterThread() +void +XThread_UnregisterThread() { ThreadSpecificData* tsdPtr = TCL_TSD_INIT(&dataKey); @@ -158,7 +155,8 @@ *---------------------------------------------------------------------- */ -void XThread_EvalInThread(Tcl_ThreadId threadId, const char *script, int flags) +void +XThread_EvalInThread(Tcl_ThreadId threadId, const char *script, int flags) { ThreadSendData *sendPtr; int len = strlen(script); Copied: branches/team/elbunce/iaxclient/contrib/tcl/build-iaxclient.txt (from rev 1427, trunk/contrib/tcl/build-iaxclient.txt) =================================================================== --- branches/team/elbunce/iaxclient/contrib/tcl/build-iaxclient.txt (rev 0) +++ branches/team/elbunce/iaxclient/contrib/tcl/build-iaxclient.txt 2008-05-04 15:33:56 UTC (rev 1428) @@ -0,0 +1,78 @@ + +My own HOWTO of how I built all this stuff +------------------------------------------ + +Linux/Unix: +----------- + +1) Portaudio: +./configure --disable-shared --without-jack +make +make install + +2) Speex: +./configure --disable-shared +make +make install + +for the external libs. For iaxclient I do: + +./configure --without-ogg --without-theora --without-vidcap \ + --disable-video --disable-clients --disable-shared + +etc. The tcl package should build as usual using ./configure && make. +You may need to edit configure.in since I have added -lasound which +I really don't know the details of. Don't forget to use autconf after +editing. I read somewhere that setting + +export LDFLAGS="-Wl,-static" + +can be helpful to force linking to static libs. Use this *only* for the +tcl package. Noted that ./configure bails with hese flags. + + +MacOSX 10.5 +----------- + +1) pkg-config: +Installed darwinports and|or fink and be sure to get pkgconfig as well + +2) Portaudio: +http://www.portaudio.com/archives/pa_stable_v19_20071207.tar.gz +#export CFLAGS="-isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" +./configure --disable-shared && make install + +3) Speex: +http://downloads.xiph.org/releases/speex/speex-1.2beta3.tar.gz +#export CFLAGS="-arch ppc -arch i386 -isysroot /Developer/SDKs/MacOSX10.4u.sdk -mmacosx-version-min=10.4" +./configure --disable-shared && make install + +4) iaxclient 2.1beta3: + PKG_CONFIG path to pkg-config utility +export PKG_CONFIG=`which pkg-config` +export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig/ +./autogen.sh +./configure --without-ogg --without-theora --without-vidcap \ + --disable-video --disable-clients --disable-shared +make +ll lib/.libs/ +make install + +For the actual tcl package you have two options: +1) use the Xcode project +2) use the TEA configure/make system as: + ./configure --prefix=/usr/local --libdir=/Library/Tcl --with-tcl=/Library/Frameworks/Tcl.framework --with-tclinclude=/Library/Frameworks/Tcl.framework/Headers --enable-threads + make + +Alternatively you can create a separate build directory. +cd iaxclient/contrib/tcl/ +mkdir build +cd build +../configure ... +I haven't figured out how to make a universal build since portaudio (?) +complains when setting export CFLAGS="-arch ppc -arch i386" + + +Windows: +-------- + Modified: branches/team/elbunce/iaxclient/contrib/tcl/configure =================================================================== --- branches/team/elbunce/iaxclient/contrib/tcl/configure 2008-04-24 18:58:00 UTC (rev 1427) +++ branches/team/elbunce/iaxclient/contrib/tcl/configure 2008-05-04 15:33:56 UTC (rev 1428) @@ -1,9 +1,8 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.57 for iaxclient 0.2. +# Generated by GNU Autoconf 2.59 for tcliaxclient 0.2. # -# Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -# Free Software Foundation, Inc. +# Copyright (C) 2003 Free Software Foundation, Inc. # This configure script is free software; the Free Software Foundation # gives unlimited permission to copy, distribute and modify it. ## --------------------- ## @@ -20,9 +19,10 @@ elif test -n "${BASH_VERSION+set}" && (set -o posix) >/dev/null 2>&1; then set -o posix fi +DUALCASE=1; export DUALCASE # for MKS sh # Support unset when possible. -if (FOO=FOO; unset FOO) >/dev/null 2>&1; then +if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then as_unset=unset else as_unset=false @@ -41,7 +41,7 @@ LC_MEASUREMENT LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER \ LC_TELEPHONE LC_TIME do - if (set +x; test -n "`(eval $as_var=C; export $as_var) 2>&1`"); then + if (set +x; test -z "`(eval $as_var=C; export $as_var) 2>&1`"); then eval $as_var=C; export $as_var else $as_unset $as_var @@ -218,16 +218,17 @@ if mkdir -p . 2>/dev/null; then as_mkdir_p=: else + test -d ./-p && rmdir ./-p as_mkdir_p=false fi as_executable_p="test -f" # Sed expression to map a string onto a valid CPP name. -as_tr_cpp="sed y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g" +as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" # Sed expression to map a string onto a valid variable name. -as_tr_sh="sed y%*+%pp%;s%[^_$as_cr_alnum]%_%g" +as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" # IFS @@ -264,10 +265,10 @@ : ${ac_max_here_lines=38} # Identity of this package. -PACKAGE_NAME='iaxclient' -PACKAGE_TARNAME='iaxclient' +PACKAGE_NAME='tcliaxclient' +PACKAGE_TARNAME='tcliaxclient' PACKAGE_VERSION='0.2' -PACKAGE_STRING='iaxclient 0.2' +PACKAGE_STRING='tcliaxclient 0.2' PACKAGE_BUGREPORT='' # Factoring default headers for most tests. @@ -666,7 +667,7 @@ # Be sure to have absolute paths. for ac_var in bindir sbindir libexecdir datadir sysconfdir sharedstatedir \ - localstatedir libdir includedir oldincludedir infodir mandir + localstatedir libdir includedir oldincludedir infodir mandir do eval ac_val=$`echo $ac_var` case $ac_val in @@ -706,10 +707,10 @@ # Try the directory containing this script, then its parent. ac_confdir=`(dirname "$0") 2>/dev/null || $as_expr X"$0" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$0" : 'X\(//\)[^/]' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| \ - . : '\(.\)' 2>/dev/null || + X"$0" : 'X\(//\)[^/]' \| \ + X"$0" : 'X\(//\)$' \| \ + X"$0" : 'X\(/\)' \| \ + . : '\(.\)' 2>/dev/null || echo X"$0" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/; q; } /^X\(\/\/\)[^/].*/{ s//\1/; q; } @@ -776,7 +777,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures iaxclient 0.2 to adapt to many kinds of systems. +\`configure' configures tcliaxclient 0.2 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -801,9 +802,9 @@ cat <<_ACEOF Installation directories: --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] + [$ac_default_prefix] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] + [PREFIX] By default, \`make install' will install all the files in \`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify @@ -833,7 +834,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of iaxclient 0.2:";; + short | recursive ) echo "Configuration of tcliaxclient 0.2:";; esac cat <<\_ACEOF @@ -902,13 +903,46 @@ ac_srcdir=$ac_top_builddir$srcdir$ac_dir_suffix ac_top_srcdir=$ac_top_builddir$srcdir ;; esac -# Don't blindly perform a `cd "$ac_dir"/$ac_foo && pwd` since $ac_foo can be -# absolute. -ac_abs_builddir=`cd "$ac_dir" && cd $ac_builddir && pwd` -ac_abs_top_builddir=`cd "$ac_dir" && cd ${ac_top_builddir}. && pwd` -ac_abs_srcdir=`cd "$ac_dir" && cd $ac_srcdir && pwd` -ac_abs_top_srcdir=`cd "$ac_dir" && cd $ac_top_srcdir && pwd` +# Do not use `cd foo && pwd` to compute absolute paths, because +# the directories may not exist. +case `pwd` in +.) ac_abs_builddir="$ac_dir";; +*) + case "$ac_dir" in + .) ac_abs_builddir=`pwd`;; + [\\/]* | ?:[\\/]* ) ac_abs_builddir="$ac_dir";; + *) ac_abs_builddir=`pwd`/"$ac_dir";; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_builddir=${ac_top_builddir}.;; +*) + case ${ac_top_builddir}. in + .) ac_abs_top_builddir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_builddir=${ac_top_builddir}.;; + *) ac_abs_top_builddir=$ac_abs_builddir/${ac_top_builddir}.;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_srcdir=$ac_srcdir;; +*) + case $ac_srcdir in + .) ac_abs_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_srcdir=$ac_srcdir;; + *) ac_abs_srcdir=$ac_abs_builddir/$ac_srcdir;; + esac;; +esac +case $ac_abs_builddir in +.) ac_abs_top_srcdir=$ac_top_srcdir;; +*) + case $ac_top_srcdir in + .) ac_abs_top_srcdir=$ac_abs_builddir;; + [\\/]* | ?:[\\/]* ) ac_abs_top_srcdir=$ac_top_srcdir;; + *) ac_abs_top_srcdir=$ac_abs_builddir/$ac_top_srcdir;; + esac;; +esac + cd $ac_dir # Check for guested configure; otherwise get Cygnus style configure. if test -f $ac_srcdir/configure.gnu; then @@ -918,7 +952,7 @@ echo $SHELL $ac_srcdir/configure --help=recursive elif test -f $ac_srcdir/configure.ac || - test -f $ac_srcdir/configure.in; then + test -f $ac_srcdir/configure.in; then echo $ac_configure --help else @@ -931,11 +965,10 @@ test -n "$ac_init_help" && exit 0 if $ac_init_version; then cat <<\_ACEOF -iaxclient configure 0.2 -generated by GNU Autoconf 2.57 +tcliaxclient configure 0.2 +generated by GNU Autoconf 2.59 -Copyright 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001, 2002 -Free Software Foundation, Inc. +Copyright (C) 2003 Free Software Foundation, Inc. This configure script is free software; the Free Software Foundation gives unlimited permission to copy, distribute and modify it. _ACEOF @@ -946,8 +979,8 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by iaxclient $as_me 0.2, which was -generated by GNU Autoconf 2.57. Invocation command line was +It was created by tcliaxclient $as_me 0.2, which was +generated by GNU Autoconf 2.59. Invocation command line was $ $0 $@ @@ -1024,19 +1057,19 @@ 2) ac_configure_args1="$ac_configure_args1 '$ac_arg'" if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. + ac_must_keep_next=false # Got value, back to normal. else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac + case $ac_arg in + *=* | --config-cache | -C | -disable-* | --disable-* \ + | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ + | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ + | -with-* | --with-* | -without-* | --without-* | --x) + case "$ac_configure_args0 " in + "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; + esac + ;; + -* ) ac_must_keep_next=true ;; + esac fi ac_configure_args="$ac_configure_args$ac_sep'$ac_arg'" # Get rid of the leading space. @@ -1070,12 +1103,12 @@ case `(ac_space='"'"' '"'"'; set | grep ac_space) 2>&1` in *ac_space=\ *) sed -n \ - "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" + "s/'"'"'/'"'"'\\\\'"'"''"'"'/g; + s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='"'"'\\2'"'"'/p" ;; *) sed -n \ - "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" + "s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1=\\2/p" ;; esac; } @@ -1104,7 +1137,7 @@ for ac_var in $ac_subst_files do eval ac_val=$`echo $ac_var` - echo "$ac_var='"'"'$ac_val'"'"'" + echo "$ac_var='"'"'$ac_val'"'"'" done | sort echo fi @@ -1123,7 +1156,7 @@ echo "$as_me: caught signal $ac_signal" echo "$as_me: exit $exit_status" } >&5 - rm -f core core.* *.core && + rm -f core *.core && rm -rf conftest* confdefs* conf$$* $ac_clean_files && exit $exit_status ' 0 @@ -1203,7 +1236,7 @@ # value. ac_cache_corrupted=false for ac_var in `(set) 2>&1 | - sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do + sed -n 's/^ac_env_\([a-zA-Z_0-9]*\)_set=.*/\1/p'`; do eval ac_old_set=\$ac_cv_env_${ac_var}_set eval ac_new_set=\$ac_env_${ac_var}_set eval ac_old_val="\$ac_cv_env_${ac_var}_value" @@ -1220,13 +1253,13 @@ ,);; *) if test "x$ac_old_val" != "x$ac_new_val"; then - { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 + { echo "$as_me:$LINENO: error: \`$ac_var' has changed since the previous run:" >&5 echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 + { echo "$as_me:$LINENO: former value: $ac_old_val" >&5 echo "$as_me: former value: $ac_old_val" >&2;} - { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 + { echo "$as_me:$LINENO: current value: $ac_new_val" >&5 echo "$as_me: current value: $ac_new_val" >&2;} - ac_cache_corrupted=: + ac_cache_corrupted=: fi;; esac # Pass precious variables to config.status. @@ -2027,7 +2060,6 @@ (exit $ac_status); } cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2047,8 +2079,8 @@ # Try to create an executable without -o first, disregard a.out. # It will help us diagnose broken compilers, and finding out an intuition # of exeext. -echo "$as_me:$LINENO: checking for C compiler default output" >&5 -echo $ECHO_N "checking for C compiler default output... $ECHO_C" >&6 +echo "$as_me:$LINENO: checking for C compiler default output file name" >&5 +echo $ECHO_N "checking for C compiler default output file name... $ECHO_C" >&6 ac_link_default=`echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` if { (eval echo "$as_me:$LINENO: \"$ac_link_default\"") >&5 (eval $ac_link_default) 2>&5 @@ -2068,23 +2100,23 @@ test -f "$ac_file" || continue case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) - ;; + ;; conftest.$ac_ext ) - # This is the source file. - ;; + # This is the source file. + ;; [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; + # We found the default executable, but exeext='' is most + # certainly right. + break;; *.* ) - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - # FIXME: I believe we export ac_cv_exeext for Libtool, - # but it would be cool to find out if it's true. Does anybody - # maintain Libtool? --akim. - export ac_cv_exeext - break;; + ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` + # FIXME: I believe we export ac_cv_exeext for Libtool, + # but it would be cool to find out if it's true. Does anybody + # maintain Libtool? --akim. + export ac_cv_exeext + break;; * ) - break;; + break;; esac done else @@ -2158,8 +2190,8 @@ case $ac_file in *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.o | *.obj ) ;; *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - export ac_cv_exeext - break;; + export ac_cv_exeext + break;; * ) break;; esac done @@ -2184,7 +2216,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2235,7 +2266,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2255,15 +2285,25 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_compiler_gnu=yes else @@ -2272,7 +2312,7 @@ ac_compiler_gnu=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_cv_c_compiler_gnu=$ac_compiler_gnu fi @@ -2288,7 +2328,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2305,15 +2344,25 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_g=yes else @@ -2322,7 +2371,7 @@ ac_cv_prog_cc_g=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext fi echo "$as_me:$LINENO: result: $ac_cv_prog_cc_g" >&5 echo "${ECHO_T}$ac_cv_prog_cc_g" >&6 @@ -2349,7 +2398,6 @@ ac_cv_prog_cc_stdc=no ac_save_CC=$CC cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2377,6 +2425,16 @@ va_end (v); return s; } + +/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has + function prototypes and stuff, but not '\xHH' hex character constants. + These don't provoke an error unfortunately, instead are silently treated + as 'x'. The following induces an error, until -std1 is added to get + proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an + array size at least. It's necessary to write '\x00'==0 to get something + that's true only with -std1. */ +int osf4_cc_array ['\x00' == 0 ? 1 : -1]; + int test (int i, double x); struct s1 {int (*f) (int a);}; struct s2 {int (*f) (double a);}; @@ -2403,15 +2461,25 @@ CC="$ac_save_CC $ac_arg" rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_prog_cc_stdc=$ac_arg break @@ -2420,7 +2488,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext +rm -f conftest.err conftest.$ac_objext done rm -f conftest.$ac_ext conftest.$ac_objext CC=$ac_save_CC @@ -2448,19 +2516,28 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then for ac_declaration in \ - ''\ - '#include <stdlib.h>' \ + '' \ 'extern "C" void std::exit (int) throw (); using std::exit;' \ 'extern "C" void std::exit (int); using std::exit;' \ 'extern "C" void exit (int) throw ();' \ @@ -2468,14 +2545,13 @@ 'void exit (int);' do cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext cat >>conftest.$ac_ext <<_ACEOF /* end confdefs.h. */ +$ac_declaration #include <stdlib.h> -$ac_declaration int main () { @@ -2486,15 +2562,25 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then : else @@ -2503,9 +2589,8 @@ continue fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2522,15 +2607,25 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then break else @@ -2538,7 +2633,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext done rm -f conftest* if test -n "$ac_declaration"; then @@ -2552,7 +2647,7 @@ sed 's/^/| /' conftest.$ac_ext >&5 fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext ac_ext=c ac_cpp='$CPP $CPPFLAGS' ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' @@ -2587,7 +2682,6 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2598,7 +2692,7 @@ #else # include <assert.h> #endif - Syntax error + Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 @@ -2610,6 +2704,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -2630,7 +2725,6 @@ # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2648,6 +2742,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -2694,7 +2789,6 @@ # On the NeXT, cc -E runs the code through the compiler's parser, # not just through cpp. "Syntax error" is here to catch this case. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2705,7 +2799,7 @@ #else # include <assert.h> #endif - Syntax error + Syntax error _ACEOF if { (eval echo "$as_me:$LINENO: \"$ac_cpp conftest.$ac_ext\"") >&5 (eval $ac_cpp conftest.$ac_ext) 2>conftest.er1 @@ -2717,6 +2811,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -2737,7 +2832,6 @@ # OK, works on sane cases. Now check whether non-existent headers # can be detected and how. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -2755,6 +2849,7 @@ (exit $ac_status); } >/dev/null; then if test -s conftest.err; then ac_cpp_err=$ac_c_preproc_warn_flag + ac_cpp_err=$ac_cpp_err$ac_c_werror_flag else ac_cpp_err= fi @@ -2805,6 +2900,7 @@ # AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag # AFS /usr/afsws/bin/install, which mishandles nonexistent args # SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" +# OS/2's system install, which has a completely different semantic # ./install, which can be erroneously created by make from ./install.sh. echo "$as_me:$LINENO: checking for a BSD-compatible install" >&5 echo $ECHO_N "checking for a BSD-compatible install... $ECHO_C" >&6 @@ -2821,6 +2917,7 @@ case $as_dir/ in ./ | .// | /cC/* | \ /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ + ?:\\/os2\\/install\\/* | ?:\\/OS2\\/INSTALL\\/* | \ /usr/ucb/* ) ;; *) # OSF1 and SCO ODT 3.0 have their own names for install. @@ -2828,20 +2925,20 @@ # by default. for ac_prog in ginstall scoinst install; do for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi + if $as_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then + if test $ac_prog = install && + grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # AIX install. It has an incompatible calling convention. + : + elif test $ac_prog = install && + grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then + # program-specific install script used by HP pwplus--don't use. + : + else + ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" + break 3 + fi + fi done done ;; @@ -2878,7 +2975,7 @@ echo "$as_me:$LINENO: checking whether ${MAKE-make} sets \$(MAKE)" >&5 echo $ECHO_N "checking whether ${MAKE-make} sets \$(MAKE)... $ECHO_C" >&6 -set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,./+-,__p_,'` +set dummy ${MAKE-make}; ac_make=`echo "$2" | sed 'y,:./+-,___p_,'` if eval "test \"\${ac_cv_prog_make_${ac_make}_set+set}\" = set"; then echo $ECHO_N "(cached) $ECHO_C" >&6 else @@ -3021,7 +3118,6 @@ echo $ECHO_N "(cached) $ECHO_C" >&6 else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3042,15 +3138,25 @@ _ACEOF rm -f conftest.$ac_objext if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5 - (eval $ac_compile) 2>&5 + (eval $ac_compile) 2>conftest.er1 ac_status=$? + grep -v '^ *+' conftest.er1 >conftest.err + rm -f conftest.er1 + cat conftest.err >&5 echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); } && - { ac_try='test -s conftest.$ac_objext' + { ac_try='test -z "$ac_c_werror_flag" + || test ! -s conftest.err' { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 (eval $ac_try) 2>&5 ac_status=$? echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); }; } && + { ac_try='test -s conftest.$ac_objext' + { (eval echo "$as_me:$LINENO: \"$ac_try\"") >&5 + (eval $ac_try) 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 (exit $ac_status); }; }; then ac_cv_header_stdc=yes else @@ -3059,12 +3165,11 @@ ac_cv_header_stdc=no fi -rm -f conftest.$ac_objext conftest.$ac_ext +rm -f conftest.err conftest.$ac_objext conftest.$ac_ext if test $ac_cv_header_stdc = yes; then # SunOS 4.x string.h does not declare mem*, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3086,7 +3191,6 @@ if test $ac_cv_header_stdc = yes; then # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3111,7 +3215,6 @@ : else cat >conftest.$ac_ext <<_ACEOF -#line $LINENO "configure" /* confdefs.h. */ _ACEOF cat confdefs.h >>conftest.$ac_ext @@ -3123,9 +3226,9 @@ # define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) #else # define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) + (('a' <= (c) && (c) <= 'i') \ + || ('j' <= (c) && (c) <= 'r') \ + || ('s' <= (c) && (c) <= 'z')) # define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) #endif @@ -3136,7 +3239,7 @@ int i; for (i = 0; i < 256; i++) if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) + || toupper (i) != TOUPPER (i)) exit(2); exit (0); } @@ -3161,7 +3264,7 @@ ( exit $ac_status ) ac_cv_header_stdc=no fi -rm -f core core.* *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext +rm -f core *.core gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext fi fi fi @@ -3186,7 +3289,7 @@ for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h + inttypes.h stdint.h unistd.h do as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh` echo "$as_me:$LINENO: checking for $ac_h... [truncated message content] |
From: <jpg...@us...> - 2008-04-24 18:57:59
|
Revision: 1427 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1427&view=rev Author: jpgrayson Date: 2008-04-24 11:58:00 -0700 (Thu, 24 Apr 2008) Log Message: ----------- Rename PKG_REQUIRES to PACKAGE_REQUIRES. This fixes a build problem that shows up on SuSE Linux Enterprise Desktop 10 SP1 because variable names beginning "PKG_" are forbidden. Thanks to Matt Crane for the fix! Modified Paths: -------------- trunk/configure.ac trunk/iaxclient.pc.in Modified: trunk/configure.ac =================================================================== --- trunk/configure.ac 2008-04-24 18:49:01 UTC (rev 1426) +++ trunk/configure.ac 2008-04-24 18:58:00 UTC (rev 1427) @@ -205,12 +205,14 @@ AM_PATH_GSM(has_gsm=yes, has_gsm=no) fi +PACKAGE_REQUIRES="" + if test x$enable_video = xyes; then if test x$with_ogg != xno; then if test x$has_ogg = xyes; then AC_DEFINE(USE_OGG, 1, [OGG]) - PKG_REQUIRES="$PKG_REQUIRES ogg" + PACKAGE_REQUIRES="$PACKAGE_REQUIRES ogg" elif test x$with_ogg != xauto ; then AC_MSG_ERROR([ libogg is required to build this package! @@ -223,7 +225,7 @@ if test x$with_theora != xno; then if test x$has_theora = xyes; then AC_DEFINE(USE_THEORA, 1, [THEORA]) - PKG_REQUIRES="$PKG_REQUIRES theora" + PACKAGE_REQUIRES="$PACKAGE_REQUIRES theora" elif test x$with_theora != xauto ; then AC_MSG_ERROR([ libtheora is required to build this package! @@ -235,7 +237,7 @@ if test x$has_vidcap = xyes; then AC_DEFINE(USE_VIDCAP, 1, [VIDCAP]) - PKG_REQUIRES="$PKG_REQUIRES vidcap" + PACKAGE_REQUIRES="$PACKAGE_REQUIRES vidcap" else AC_MSG_ERROR([ libvidcap is required to build this package! @@ -247,7 +249,7 @@ if test x$with_ffmpeg != xno; then if test x$has_ffmpeg = xyes; then AC_DEFINE(USE_FFMPEG, 1, [FFMPEG]) - PKG_REQUIRES="$PKG_REQUIRES ffmpeg" + PACKAGE_REQUIRES="$PACKAGE_REQUIRES ffmpeg" elif test x$with_ffmpeg != xauto ; then AC_MSG_ERROR([ FFmpeg is required to build this package! @@ -461,7 +463,7 @@ done AC_SUBST(CLIENTS) -AC_SUBST(PKG_REQUIRES) +AC_SUBST(PACKAGE_REQUIRES) AC_CONFIG_FILES([ Makefile Modified: trunk/iaxclient.pc.in =================================================================== --- trunk/iaxclient.pc.in 2008-04-24 18:49:01 UTC (rev 1426) +++ trunk/iaxclient.pc.in 2008-04-24 18:58:00 UTC (rev 1427) @@ -9,5 +9,5 @@ Libs: -L${libdir} -liaxclient @PTHREAD_LIBS@ Libs.private: @GSM_LIBS@ Cflags: -I${includedir} -Requires.private: portaudio-2.0 speex @PKG_REQUIRES@ +Requires.private: portaudio-2.0 speex @PACKAGE_REQUIRES@ This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-24 18:48:57
|
Revision: 1426 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1426&view=rev Author: jpgrayson Date: 2008-04-24 11:49:01 -0700 (Thu, 24 Apr 2008) Log Message: ----------- Merge new acoustic echo cancellation (AEC) code into trunk. This code has been simmering in branches/team/mihai/echocan for some time. This new code takes advantage of the speex echo cancellation improvements introduced in speex-1.2beta2. Echo cancellation is disabled by default on Windows. Echo cancellation is not yet working well with WMME. Modified Paths: -------------- trunk/lib/audio_encode.c trunk/lib/audio_encode.h trunk/lib/audio_portaudio.c Modified: trunk/lib/audio_encode.c =================================================================== --- trunk/lib/audio_encode.c 2008-04-24 17:52:51 UTC (rev 1425) +++ trunk/lib/audio_encode.c 2008-04-24 18:49:01 UTC (rev 1426) @@ -25,6 +25,18 @@ #include "codec_speex.h" #include <speex/speex_preprocess.h> +/* Determine if we should do AEC */ +#if defined(SPEEX_EC) && !defined(WIN32) +#define DO_EC +#else +#undef DO_EC +#endif + +#ifdef DO_EC +#include <speex/speex_echo.h> +#include "ringbuffer.h" +#endif + #ifdef CODEC_ILBC #include "codec_ilbc.h" #endif @@ -41,6 +53,35 @@ static int speex_state_rate = 0; int iaxci_filters = IAXC_FILTER_AGC|IAXC_FILTER_DENOISE|IAXC_FILTER_AAGC|IAXC_FILTER_CN; +static MUTEX audio_lock; + +/* echo_tail length, in samples */ +#define ECHO_TAIL 512 + +/* Maximum attenuation of residual echo in dB (negative number) */ +#define ECHO_SUPPRESS -60 +/* Maximum attenuation of residual echo when near end is active, in dB (negative number) */ +#define ECHO_SUPPRESS_ACTIVE -60 + +/* Size of ring buffer used for echo cancellation. Must be power of 2. */ +#define EC_RING_SIZE 512 + +#ifdef DO_EC +static SpeexEchoState *ec = 0; +static rb_RingBuffer ecOutRing; +static char outRingBuf[EC_RING_SIZE]; +#endif + +/* AAGC threshold */ +#define AAGC_VERY_HOT 16 +#define AAGC_HOT 8 +#define AAGC_COLD 4 + +/* AAGC increments */ +#define AAGC_RISE_SLOW 0.10f +#define AAGC_DROP_SLOW 0.15f +#define AAGC_DROP_FAST 0.20f + /* use to measure time since last audio was processed */ static struct timeval timeLastInput ; static struct timeval timeLastOutput ; @@ -141,20 +182,34 @@ float volume; int silent = 0; + MUTEXLOCK(&audio_lock); if ( !st || speex_state_size != len || speex_state_rate != rate ) { if (st) speex_preprocess_state_destroy(st); st = speex_preprocess_state_init(len,rate); +#ifdef DO_EC + if ( ec ) + { + int i; + + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, ec); + i = ECHO_SUPPRESS; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &i); + i = ECHO_SUPPRESS_ACTIVE; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &i); + } +#endif speex_state_size = len; speex_state_rate = rate; set_speex_filters(); } + MUTEXUNLOCK(&audio_lock); calculate_level(audio, len, &input_level); /* go through the motions only if we need at least one of the preprocessor filters */ - if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC | IAXC_FILTER_DEREVERB)) || + if ( (iaxci_filters & (IAXC_FILTER_DENOISE | IAXC_FILTER_AGC | IAXC_FILTER_DEREVERB | IAXC_FILTER_ECHO)) || iaxci_silence_threshold > 0.0f ) silent = !speex_preprocess(st, (spx_int16_t *)audio, NULL); @@ -410,12 +465,87 @@ set_speex_filters(); } +int audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples) +{ +#ifdef DO_EC + int i; + short delayedBuf[1024]; + short cancelledBuffer[1024]; + + /* if ec is off, clear ec state -- this way, we start fresh if/when + * it's turned back on. */ + MUTEXLOCK(&audio_lock); + if ( !(iaxci_filters & IAXC_FILTER_ECHO) ) + { + if ( ec ) + { + speex_echo_state_destroy(ec); + ec = NULL; + if ( st ) + { + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, NULL); + } + } + + MUTEXUNLOCK(&audio_lock); + return 0; + } + + /* we want echo cancellation */ + if ( !ec ) + { + rb_InitializeRingBuffer(&ecOutRing, EC_RING_SIZE, &outRingBuf); + ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL); + + if ( st ) + { + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_STATE, ec); + i = ECHO_SUPPRESS; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS, &i); + i = ECHO_SUPPRESS_ACTIVE; + speex_preprocess_ctl(st, SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE, &i); + } + } + MUTEXUNLOCK(&audio_lock); + + // Put our data in the EC ring buffer. + // Echo canceller needs SAMPLES_PER_FRAME samples, so if we don't have enough + // at this time, we just store what we have and return. + rb_WriteRingBuffer(&ecOutRing, outputBuffer, samples * 2); + if ( rb_GetRingBufferReadAvailable(&ecOutRing) < (SAMPLES_PER_FRAME * 2) ) + return -1; + + rb_ReadRingBuffer(&ecOutRing, delayedBuf, SAMPLES_PER_FRAME * 2); + + speex_echo_cancellation(ec, inputBuffer, delayedBuf, cancelledBuffer); + + memcpy(inputBuffer, cancelledBuffer, samples * sizeof(short)); +#endif + return 0; +} + int audio_initialize() { + MUTEXINIT(&audio_lock); return 0; } int audio_destroy() { + MUTEXLOCK(&audio_lock); + if ( st ) + { + speex_preprocess_state_destroy(st); + st = NULL; + } +#ifdef DO_EC + if ( ec ) + { + speex_echo_state_destroy(ec); + ec = NULL; + } +#endif + MUTEXUNLOCK(&audio_lock); + MUTEXDESTROY(&audio_lock); return 0; } Modified: trunk/lib/audio_encode.h =================================================================== --- trunk/lib/audio_encode.h 2008-04-24 17:52:51 UTC (rev 1425) +++ trunk/lib/audio_encode.h 2008-04-24 18:49:01 UTC (rev 1426) @@ -15,6 +15,14 @@ #ifndef _AUDIO_ENCODE_H #define _AUDIO_ENCODE_H +/* Some audio parameters */ +#define MAX_SAMPLE_RATE 48000 +#ifndef MS_PER_FRAME +# define MS_PER_FRAME 20 +#endif +#define SAMPLES_PER_FRAME (MS_PER_FRAME * iaxci_sample_rate / 1000) +#define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) + extern int iaxci_sample_rate; /* Minimum dB possible in the iaxclient world. This level @@ -22,16 +30,6 @@ */ #define AUDIO_ENCODE_SILENCE_DB -99.0f -/* AAGC threshold */ -#define AAGC_VERY_HOT 16 -#define AAGC_HOT 8 -#define AAGC_COLD 4 - -/* AAGC increments */ -#define AAGC_RISE_SLOW 0.10f -#define AAGC_DROP_SLOW 0.15f -#define AAGC_DROP_FAST 0.20f - struct iaxc_call; struct iax_event; @@ -44,5 +42,7 @@ int audio_decode_audio(struct iaxc_call * p, void * out, void * data, int len, int iEncodeType, int * samples); +int audio_echo_cancellation(short *inputBuffer, short *outputBuffer, int samples); + #endif Modified: trunk/lib/audio_portaudio.c =================================================================== --- trunk/lib/audio_portaudio.c 2008-04-24 17:52:51 UTC (rev 1425) +++ trunk/lib/audio_portaudio.c 2008-04-24 18:49:01 UTC (rev 1426) @@ -38,27 +38,6 @@ #include "ringbuffer.h" #include "portmixer.h" -#ifdef USE_MEC2 -#define DO_EC -#include "mec3.h" -static echo_can_state_t *ec; -#endif - -#ifdef SPAN_EC -#define DO_EC -#include "ec/echo.h" -static echo_can_state_t *ec; -#endif - -#if defined(SPEEX_EC) && ! defined (WIN32) -#define DO_EC -#define restrict __restrict -#include "speex/speex_echo.h" -static SpeexEchoState *ec; -#endif - -#define EC_RING_SZ 8192 /* must be pow(2) */ - typedef short SAMPLE; static PaStream *iStream, *oStream, *aStream; @@ -68,18 +47,6 @@ static int mixers_initialized; -#define MAX_SAMPLE_RATE 48000 -#ifndef MS_PER_FRAME -# define MS_PER_FRAME 20 -#endif -#define SAMPLES_PER_FRAME (MS_PER_FRAME * iaxci_sample_rate / 1000) - -/* static frame buffer allocation */ -#define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) - -/* echo_tail length, in frames must be pow(2) for mec/span ? */ -#define ECHO_TAIL 4096 - /* RingBuffer Size; Needs to be Pow(2), 1024 = 512 samples = 64ms */ #ifndef OUTRBSZ # define OUTRBSZ 32768 @@ -372,84 +339,6 @@ return retval; /* found? */ } -static void iaxc_echo_can(short *inputBuffer, short *outputBuffer, int n) -{ - static rb_RingBuffer ecOutRing; - static char outRingBuf[EC_RING_SZ]; - static long bias = 0; - short delayedBuf[1024]; - int i; - - /* remove bias -- whether ec is on or not. */ - for ( i = 0; i < n; i++ ) - { - bias += ((((long int) inputBuffer[i]) << 15) - bias) >> 14; - inputBuffer[i] -= (short int) (bias >> 15); - } - - /* if ec is off, clear ec state -- this way, we start fresh if/when - * it's turned back on. */ - if ( !(iaxc_get_filters() & IAXC_FILTER_ECHO) ) - { -#if defined(DO_EC) - if ( ec ) - { -#if defined(USE_MEC2) || defined(SPAN_EC) - echo_can_free(ec); - ec = NULL; -#elif defined(SPEEX_EC) - speex_echo_state_destroy(ec); - ec = NULL; -#endif - } -#endif - - return; - } - - /* we want echo cancellation */ - -#if defined(DO_EC) - if ( !ec ) - { - rb_InitializeRingBuffer(&ecOutRing, EC_RING_SZ, &outRingBuf); -#if defined(USE_MEC2) || defined(SPAN_EC) - ec = echo_can_create(ECHO_TAIL, 0); -#elif defined(SPEEX_EC) - ec = speex_echo_state_init(SAMPLES_PER_FRAME, ECHO_TAIL); -#endif - } -#endif - - /* fill ecOutRing */ - rb_WriteRingBuffer(&ecOutRing, outputBuffer, n * 2); - - // Make sure we have enough buffer. - // Currently, just one SAMPLES_PER_FRAME's worth. - if ( rb_GetRingBufferReadAvailable(&ecOutRing) < ((n + SAMPLES_PER_FRAME) * 2) ) - return; - - rb_ReadRingBuffer(&ecOutRing, delayedBuf, n * 2); - -#if defined(DO_EC) && defined(SPEEX_EC) - { - short cancelledBuffer[1024]; - - speex_echo_cancel(ec, inputBuffer, delayedBuf, - cancelledBuffer, NULL); - - for ( i = 0; i < n; i++ ) - inputBuffer[i] = cancelledBuffer[i]; - } -#endif - -#if defined(USE_MEC2) || defined(SPAN_EC) - for ( i = 0; i < n; i++ ) - inputBuffer[i] = echo_can_update(ec, delayedBuf[i], - inputBuffer[i]); -#endif -} - static int pa_callback(const void *inputBuffer, void *outputBuffer, unsigned long samplesPerFrame, const PaStreamCallbackTimeInfo* outTime, @@ -524,23 +413,26 @@ if ( inputBuffer ) { + int res; + /* input overflow might happen here */ if ( virtualMonoIn ) { stereo2mono(virtualInBuffer, (SAMPLE *)inputBuffer, samplesPerFrame); - iaxc_echo_can(virtualInBuffer, virtualOutBuffer, - samplesPerFrame); - - rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes); + res = audio_echo_cancellation(virtualInBuffer, + virtualOutBuffer, + samplesPerFrame); + if ( !res ) + rb_WriteRingBuffer(&inRing, virtualInBuffer, totBytes); } else { - iaxc_echo_can((short *)inputBuffer, - (short *)outputBuffer, - samplesPerFrame); - - rb_WriteRingBuffer(&inRing, inputBuffer, totBytes); + res = audio_echo_cancellation((short *)inputBuffer, + (short *)outputBuffer, + samplesPerFrame); + if ( !res) + rb_WriteRingBuffer(&inRing, inputBuffer, totBytes); } } @@ -599,7 +491,7 @@ &in_stream_params, &out_stream_params, iaxci_sample_rate, - paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + SAMPLES_PER_FRAME, paNoFlag, (PaStreamCallback *)pa_callback, NULL); @@ -612,7 +504,7 @@ &in_stream_params, &no_device, iaxci_sample_rate, - paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + SAMPLES_PER_FRAME, paNoFlag, (PaStreamCallback *)pa_callback, NULL); @@ -622,7 +514,7 @@ &no_device, &out_stream_params, iaxci_sample_rate, - paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate + SAMPLES_PER_FRAME, paNoFlag, (PaStreamCallback *)pa_callback, NULL); This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-24 17:52:45
|
Revision: 1425 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1425&view=rev Author: jpgrayson Date: 2008-04-24 10:52:51 -0700 (Thu, 24 Apr 2008) Log Message: ----------- Merge some cleanups from the echo cancellation branch into trunk. Modified Paths: -------------- trunk/lib/audio_encode.c trunk/lib/audio_encode.h trunk/lib/audio_portaudio.c trunk/lib/iaxclient_lib.c Modified: trunk/lib/audio_encode.c =================================================================== --- trunk/lib/audio_encode.c 2008-04-24 17:15:57 UTC (rev 1424) +++ trunk/lib/audio_encode.c 2008-04-24 17:52:51 UTC (rev 1425) @@ -34,6 +34,8 @@ static float input_level = 0.0f; static float output_level = 0.0f; +int iaxci_sample_rate = 8000; + static SpeexPreprocessState *st = NULL; static int speex_state_size = 0; static int speex_state_rate = 0; @@ -408,3 +410,12 @@ set_speex_filters(); } +int audio_initialize() +{ + return 0; +} + +int audio_destroy() +{ + return 0; +} Modified: trunk/lib/audio_encode.h =================================================================== --- trunk/lib/audio_encode.h 2008-04-24 17:15:57 UTC (rev 1424) +++ trunk/lib/audio_encode.h 2008-04-24 17:52:51 UTC (rev 1425) @@ -15,6 +15,8 @@ #ifndef _AUDIO_ENCODE_H #define _AUDIO_ENCODE_H +extern int iaxci_sample_rate; + /* Minimum dB possible in the iaxclient world. This level * is intended to represent silence. */ @@ -33,6 +35,9 @@ struct iaxc_call; struct iax_event; +int audio_initialize(); +int audio_destroy(); + int audio_send_encoded_audio(struct iaxc_call * most_recent_answer, int callNo, void * data, int iEncodeType, int samples); Modified: trunk/lib/audio_portaudio.c =================================================================== --- trunk/lib/audio_portaudio.c 2008-04-24 17:15:57 UTC (rev 1424) +++ trunk/lib/audio_portaudio.c 2008-04-24 17:52:51 UTC (rev 1425) @@ -33,6 +33,7 @@ #endif #include "audio_portaudio.h" +#include "audio_encode.h" #include "iaxclient_lib.h" #include "ringbuffer.h" #include "portmixer.h" @@ -58,7 +59,6 @@ #define EC_RING_SZ 8192 /* must be pow(2) */ - typedef short SAMPLE; static PaStream *iStream, *oStream, *aStream; @@ -66,15 +66,13 @@ static int selectedInput, selectedOutput, selectedRing; -static int sample_rate = 8000; static int mixers_initialized; - #define MAX_SAMPLE_RATE 48000 #ifndef MS_PER_FRAME -# define MS_PER_FRAME 40 +# define MS_PER_FRAME 20 #endif -#define SAMPLES_PER_FRAME (MS_PER_FRAME * sample_rate / 1000) +#define SAMPLES_PER_FRAME (MS_PER_FRAME * iaxci_sample_rate / 1000) /* static frame buffer allocation */ #define MAX_SAMPLES_PER_FRAME (MS_PER_FRAME * MAX_SAMPLE_RATE / 1000) @@ -124,11 +122,12 @@ #endif /* size in bytes of ringbuffer target */ -#define RBOUTTARGET_BYTES (RBOUTTARGET * (sample_rate / 1000) * sizeof(SAMPLE)) +#define RBOUTTARGET_BYTES (RBOUTTARGET * (iaxci_sample_rate / 1000) * sizeof(SAMPLE)) static char inRingBuf[INRBSZ], outRingBuf[OUTRBSZ]; static rb_RingBuffer inRing, outRing; +/* TODO: This is used without explicit initialization */ static int outRingLenAvg; static int oneStream; @@ -457,11 +456,10 @@ PaStreamCallbackFlags statusFlags, void *userData) { + short virtualInBuffer[MAX_SAMPLES_PER_FRAME]; + short virtualOutBuffer[MAX_SAMPLES_PER_FRAME]; int totBytes = samplesPerFrame * sizeof(SAMPLE); - short virtualInBuffer[MAX_SAMPLES_PER_FRAME * 2]; - short virtualOutBuffer[MAX_SAMPLES_PER_FRAME * 2]; - #if 0 /* I think this can't happen */ if(virtualMono && samplesPerFrame > SAMPLES_PER_FRAME) { @@ -600,7 +598,7 @@ err = Pa_OpenStream(&iStream, &in_stream_params, &out_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -613,7 +611,7 @@ err = Pa_OpenStream(&iStream, &in_stream_params, &no_device, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -623,7 +621,7 @@ err = Pa_OpenStream(&oStream, &no_device, &out_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_callback, @@ -714,7 +712,7 @@ err = Pa_OpenStream(&aStream, NULL, &ring_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_aux_callback, @@ -728,7 +726,7 @@ err = Pa_OpenStream(&aStream, NULL, &ring_stream_params, - sample_rate, + iaxci_sample_rate, paFramesPerBufferUnspecified, //FEEBACK - unsure if appropriate paNoFlag, (PaStreamCallback *)pa_aux_callback, @@ -1092,7 +1090,7 @@ { PaError err; - sample_rate = sr; + iaxci_sample_rate = sr; /* initialize portaudio */ if ( paNoError != (err = Pa_Initialize()) ) Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2008-04-24 17:15:57 UTC (rev 1424) +++ trunk/lib/iaxclient_lib.c 2008-04-24 17:52:51 UTC (rev 1425) @@ -626,6 +626,7 @@ if ( !test_mode ) { + audio_initialize(); #ifndef AUDIO_ALSA if ( pa_initialize(&audio_driver, 8000) ) { @@ -672,6 +673,7 @@ if ( !test_mode ) { audio_driver.destroy(&audio_driver); + audio_destroy(); #ifdef USE_VIDEO video_destroy(); #endif This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-24 17:15:52
|
Revision: 1424 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1424&view=rev Author: jpgrayson Date: 2008-04-24 10:15:57 -0700 (Thu, 24 Apr 2008) Log Message: ----------- Only print video-related warning message if video is enabled. Modified Paths: -------------- trunk/lib/iaxclient_lib.c Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2008-04-24 14:18:28 UTC (rev 1423) +++ trunk/lib/iaxclient_lib.c 2008-04-24 17:15:57 UTC (rev 1424) @@ -1170,11 +1170,13 @@ case IAX_EVENT_ACCEPT: calls[callNo].format = e->ies.format & IAXC_AUDIO_FORMAT_MASK; calls[callNo].vformat = e->ies.format & IAXC_VIDEO_FORMAT_MASK; +#if USE_VIDEO if ( !(e->ies.format & IAXC_VIDEO_FORMAT_MASK) ) { iaxci_usermsg(IAXC_NOTICE, "Failed video codec negotiation."); } +#endif iaxci_usermsg(IAXC_STATUS,"Call %d accepted", callNo); break; case IAX_EVENT_ANSWER: This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-24 14:18:31
|
Revision: 1423 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1423&view=rev Author: jpgrayson Date: 2008-04-24 07:18:28 -0700 (Thu, 24 Apr 2008) Log Message: ----------- Fix problem where media (audio, video, CNG) frames might be sent prior to the call being ACCEPTed. When iaxclient initiates a call, it sends a NEW frame. The server end of the call must send back an ACCEPT frame prior to the call being in the "Linked" state. It is only after the call is in this Linked state that media frames may be transmitted by iaxclient. Note that media frames _are_ allowed to be transmitted prior to the call being ANSWERed (or completed in iaxclient parlance). See this thread for details: http://osdir.com/ml/telephony.pbx.asterisk.iaxclient.devel/2005-08/msg00021.html This modifies iaxclient's decision logic for when it may send audio. Basically either the call has to have been answered (IAXC_CALL_STATE_COMPLETE) or the call has to be outgoing and the audio format set (which happens when the ACCEPT frame comes back from the server). For video, we take the same approach and only allow video to go out after ACCEPT for outgoing calls and after ANSWER (complete) for incoming calls. Without this fix, it is possible for iaxclient to send a NEW and (for example) CNG frames in short succession. The server may then receive the CNG frame first, before the NEW frame. The server sends the correct INVAL response to this call-less CNG frame which results in iaxclient destroying the call and sending a hangup event to the application. This is pretty bad, but then to make things wierder, the server will, of course, receive the NEW frame shortly after the CNG frame and respond to that with an ACCEPT frame. C --> NEW -\/--> S C --> CNG -/\--> S C <-- INVAL <-- S * server received CNG first C <-- ACCEPT <-- S * server responds to NEW second! Modified Paths: -------------- trunk/lib/iaxclient_lib.c trunk/lib/video.c Modified: trunk/lib/iaxclient_lib.c =================================================================== --- trunk/lib/iaxclient_lib.c 2008-04-24 13:24:06 UTC (rev 1422) +++ trunk/lib/iaxclient_lib.c 2008-04-24 14:18:28 UTC (rev 1423) @@ -832,11 +832,13 @@ /* TODO: maybe we shouldn't allocate 8kB on the stack here. */ short buf [4096]; + struct iaxc_call * call = + selected_call >= 0 ? &calls[selected_call] : 0; + int want_send_audio = - selected_call >= 0 && - ((calls[selected_call].state & IAXC_CALL_STATE_OUTGOING) || - (calls[selected_call].state & IAXC_CALL_STATE_COMPLETE)) - && !(audio_prefs & IAXC_AUDIO_PREF_SEND_DISABLE); + call && !(audio_prefs & IAXC_AUDIO_PREF_SEND_DISABLE) && + ((call->state & IAXC_CALL_STATE_COMPLETE) || + (call->format && (call->state & IAXC_CALL_STATE_OUTGOING))); int want_local_audio = (audio_prefs & IAXC_AUDIO_PREF_RECV_LOCAL_RAW) || @@ -852,9 +854,8 @@ audio_driver.start(&audio_driver); /* use codec minimum if higher */ - cmin = want_send_audio && calls[selected_call].encoder ? - calls[selected_call].encoder->minimum_frame_size : - 1; + cmin = want_send_audio && call->encoder ? + call->encoder->minimum_frame_size : 1; to_read = cmin > minimum_outgoing_framesize ? cmin : minimum_outgoing_framesize; @@ -887,10 +888,9 @@ to_read * 2, (unsigned char *)buf); if ( want_send_audio ) - audio_send_encoded_audio(&calls[selected_call], - selected_call, buf, - calls[selected_call].format & - IAXC_AUDIO_FORMAT_MASK, + audio_send_encoded_audio(call, selected_call, + buf, call->format & + IAXC_AUDIO_FORMAT_MASK, to_read); } } @@ -1370,6 +1370,15 @@ codec_destroy( callNo ); + /* When the ACCEPT comes back from the other-end, these formats + * are set. Whether the format is set or not determines whether + * we are in the Linked state (see the iax2 rfc). + * These will have already been cleared by iaxc_clear_call(), + * but we reset them anyway just to be pedantic. + */ + calls[callNo].format = 0; + calls[callNo].vformat = 0; + if ( ext ) { strncpy(calls[callNo].remote_name, num, IAXC_EVENT_BUFSIZ); Modified: trunk/lib/video.c =================================================================== --- trunk/lib/video.c 2008-04-24 13:24:06 UTC (rev 1422) +++ trunk/lib/video.c 2008-04-24 14:18:28 UTC (rev 1423) @@ -668,18 +668,26 @@ call = &calls[selected_call]; - if ( !call || !(call->state & (IAXC_CALL_STATE_COMPLETE | - IAXC_CALL_STATE_OUTGOING)) ) + if ( call->vformat && + ( call->state & IAXC_CALL_STATE_COMPLETE || + call->state & IAXC_CALL_STATE_OUTGOING ) ) { - goto callback_done; + /* For incoming calls, we must ANSWER (complete) the + * call before sending video. For outgoing calls, the + * call must only be ACCEPTed (vformat set) before we + * start sending video. + */ } - - if ( call->vformat == 0 ) + else if ( !call->vformat && call->state & IAXC_CALL_STATE_COMPLETE ) { fprintf(stderr, "video format not set for call %d\n", selected_call); goto callback_failed; } + else + { + goto callback_done; + } if ( !need_encode ) { This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-24 13:24:13
|
Revision: 1422 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1422&view=rev Author: jpgrayson Date: 2008-04-24 06:24:06 -0700 (Thu, 24 Apr 2008) Log Message: ----------- Fix analog automatic gain control (AAGC). - Speex changed SPEEX_PREPROCESS_GET_AGC_LOUDNESS to return an int instead of a float; adjust for that change. - Use constants instead of magic numbers in AAGC logic. Modified Paths: -------------- trunk/lib/audio_encode.c trunk/lib/audio_encode.h Modified: trunk/lib/audio_encode.c =================================================================== --- trunk/lib/audio_encode.c 2008-04-23 15:33:35 UTC (rev 1421) +++ trunk/lib/audio_encode.c 2008-04-24 13:24:06 UTC (rev 1422) @@ -170,26 +170,26 @@ if ( (i & 0x3f) == 0 ) { - float loudness; + int loudness; speex_preprocess_ctl(st, SPEEX_PREPROCESS_GET_AGC_LOUDNESS, &loudness); - if ( loudness > 8000.0f || loudness < 4000.0f ) + if ( loudness > AAGC_HOT || loudness < AAGC_COLD ) { const float level = iaxc_input_level_get(); - if ( loudness > 16000.0f && level > 0.5f ) + if ( loudness > AAGC_VERY_HOT && level > 0.5f ) { /* lower quickly if we're really too hot */ - iaxc_input_level_set(level - 0.2f); + iaxc_input_level_set(level - AAGC_DROP_FAST); } - else if ( loudness > 8000.0f && level >= 0.15f ) + else if ( loudness > AAGC_HOT && level >= 0.15f ) { /* lower less quickly if we're a bit too hot */ - iaxc_input_level_set(level - 0.1f); + iaxc_input_level_set(level - AAGC_DROP_SLOW); } - else if ( loudness < 4000.0f && level <= 0.9f ) + else if ( loudness < AAGC_COLD && level <= 0.9f ) { /* raise slowly if we're cold */ - iaxc_input_level_set(level + 0.1f); + iaxc_input_level_set(level + AAGC_RISE_SLOW); } } } Modified: trunk/lib/audio_encode.h =================================================================== --- trunk/lib/audio_encode.h 2008-04-23 15:33:35 UTC (rev 1421) +++ trunk/lib/audio_encode.h 2008-04-24 13:24:06 UTC (rev 1422) @@ -20,6 +20,16 @@ */ #define AUDIO_ENCODE_SILENCE_DB -99.0f +/* AAGC threshold */ +#define AAGC_VERY_HOT 16 +#define AAGC_HOT 8 +#define AAGC_COLD 4 + +/* AAGC increments */ +#define AAGC_RISE_SLOW 0.10f +#define AAGC_DROP_SLOW 0.15f +#define AAGC_DROP_FAST 0.20f + struct iaxc_call; struct iax_event; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-23 15:37:41
|
Revision: 1420 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1420&view=rev Author: jpgrayson Date: 2008-04-23 08:22:48 -0700 (Wed, 23 Apr 2008) Log Message: ----------- Security fixes from Alex Vassilev (Thank you!). - Check for super-short (< 2 byte) frames. - Check video header size. - Detect non-video meta frames correctly -- no longer make bogus assumption that they are audio mini frames. Modified Paths: -------------- trunk/lib/libiax2/src/iax.c Modified: trunk/lib/libiax2/src/iax.c =================================================================== --- trunk/lib/libiax2/src/iax.c 2008-04-23 15:00:22 UTC (rev 1419) +++ trunk/lib/libiax2/src/iax.c 2008-04-23 15:22:48 UTC (rev 1420) @@ -3207,6 +3207,12 @@ struct ast_iax2_video_hdr *vh = (struct ast_iax2_video_hdr *)buf; struct iax_session *session; + if ((size_t)len < sizeof(fh->scallno)) { + DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr)); + IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr)); + return NULL; + } + if (ntohs(fh->scallno) & IAX_FLAG_FULL) { /* Full size header */ if ((size_t)len < sizeof(struct ast_iax2_full_hdr)) { @@ -3225,32 +3231,49 @@ ntohs(fh->dcallno) & ~IAX_FLAG_RETRANS); if (session) return iax_header_to_event(session, fh, len - sizeof(struct ast_iax2_full_hdr), sin); - DEBU(G "No session?\n"); - return NULL; } else { if ((size_t)len < sizeof(struct ast_iax2_mini_hdr)) { DEBU(G "Short header received from %s\n", inet_ntoa(sin->sin_addr)); IAXERROR "Short header received from %s\n", inet_ntoa(sin->sin_addr)); return NULL; } - /* Miniature, voice frame */ - if ((vh->zeros == 0) && (ntohs(vh->callno) & 0x8000)) - { + + if (mh->callno == 0) { + /* We have a meta frame, could be a video meta frame + * or an ordinary meta frame, to find out we check + * the V flag. + */ + if (!(ntohs(vh->callno) & 0x8000)) { + DEBU(G "Meta frame received from %s, but we cannot handle it\n", + inet_ntoa(sin->sin_addr)); + IAXERROR "Meta frame received from %s, but we cannot handle it\n", + inet_ntoa(sin->sin_addr)); + return NULL; + } + /* it is a video metaframe, verify its size */ + if ((size_t)len < sizeof(struct ast_iax2_video_hdr)) { + DEBU(G "Short video mini header received from %s\n", + inet_ntoa(sin->sin_addr)); + IAXERROR "Short video mini header received from %s\n", + inet_ntoa(sin->sin_addr)); + return NULL; + } + session = iax_find_session(sin, ntohs(vh->callno) & ~0x8000, 0, 0); if (session) return iax_videoheader_to_event(session, vh, len - sizeof(struct ast_iax2_video_hdr)); } else { - /* audio frame */ - session = iax_find_session(sin, ntohs(fh->scallno), 0, 0); + /* mini audio frame */ + session = iax_find_session(sin, ntohs(mh->callno), 0, 0); if (session) return iax_miniheader_to_event(session, mh, len - sizeof(struct ast_iax2_mini_hdr)); } - DEBU(G "No session?\n"); - return NULL; } + DEBU(G "No session?\n"); + return NULL; } static struct iax_sched *iax_get_sched(struct timeval tv) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-23 15:33:29
|
Revision: 1421 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1421&view=rev Author: jpgrayson Date: 2008-04-23 08:33:35 -0700 (Wed, 23 Apr 2008) Log Message: ----------- Add preprocessor definition IAX_FLAG_VIDEO and use it. Use IAX_FLAG_FULL in an appropriate spot. Modified Paths: -------------- trunk/lib/libiax2/src/iax.c trunk/lib/libiax2/src/iax2.h Modified: trunk/lib/libiax2/src/iax.c =================================================================== --- trunk/lib/libiax2/src/iax.c 2008-04-23 15:22:48 UTC (rev 1420) +++ trunk/lib/libiax2/src/iax.c 2008-04-23 15:33:35 UTC (rev 1421) @@ -1229,7 +1229,7 @@ fr->iseqno = -1; vh = (struct ast_iax2_video_hdr *)(((char* )fr->af.data) - sizeof(struct ast_iax2_video_hdr)); vh->zeros = 0; - vh->callno = htons(0x8000 | fr->callno); + vh->callno = htons(IAX_FLAG_FULL | fr->callno); vh->ts = htons((fr->ts & 0x7FFF) | (fr->af.subclass & 0x1 ? 0x8000 : 0)); fr->datalen = fr->af.datalen + sizeof(struct ast_iax2_video_hdr); fr->data = vh; @@ -3243,11 +3243,11 @@ * or an ordinary meta frame, to find out we check * the V flag. */ - if (!(ntohs(vh->callno) & 0x8000)) { + if (!(ntohs(vh->callno) & IAX_FLAG_VIDEO)) { DEBU(G "Meta frame received from %s, but we cannot handle it\n", inet_ntoa(sin->sin_addr)); IAXERROR "Meta frame received from %s, but we cannot handle it\n", - inet_ntoa(sin->sin_addr)); + inet_ntoa(sin->sin_addr)); return NULL; } /* it is a video metaframe, verify its size */ @@ -3255,11 +3255,11 @@ DEBU(G "Short video mini header received from %s\n", inet_ntoa(sin->sin_addr)); IAXERROR "Short video mini header received from %s\n", - inet_ntoa(sin->sin_addr)); + inet_ntoa(sin->sin_addr)); return NULL; } - session = iax_find_session(sin, ntohs(vh->callno) & ~0x8000, 0, 0); + session = iax_find_session(sin, ntohs(vh->callno) & ~IAX_FLAG_VIDEO, 0, 0); if (session) return iax_videoheader_to_event(session, vh, Modified: trunk/lib/libiax2/src/iax2.h =================================================================== --- trunk/lib/libiax2/src/iax2.h 2008-04-23 15:22:48 UTC (rev 1420) +++ trunk/lib/libiax2/src/iax2.h 2008-04-23 15:33:35 UTC (rev 1421) @@ -20,7 +20,7 @@ #define IAX_MAX_CALLS 32768 #define IAX_FLAG_FULL 0x8000 - +#define IAX_FLAG_VIDEO 0x8000 #define IAX_FLAG_RETRANS 0x8000 #define IAX_FLAG_SC_LOG 0x80 This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-23 15:00:26
|
Revision: 1419 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1419&view=rev Author: jpgrayson Date: 2008-04-23 08:00:22 -0700 (Wed, 23 Apr 2008) Log Message: ----------- Fix bug where testcall would crash when CTRL-C was used to kill it. This avoids calling iaxc_shutdown() twice. Modified Paths: -------------- trunk/simpleclient/testcall/testcall.c Modified: trunk/simpleclient/testcall/testcall.c =================================================================== --- trunk/simpleclient/testcall/testcall.c 2008-04-23 14:58:50 UTC (rev 1418) +++ trunk/simpleclient/testcall/testcall.c 2008-04-23 15:00:22 UTC (rev 1419) @@ -44,12 +44,16 @@ cleanly and has to be rebooted. What a pile of doo doo!! */ void killem(void) { - if (initialized) + if ( initialized ) + { iaxc_shutdown(); - if (reg_id){ + initialized = 0; + } + if ( reg_id ) + { iaxc_unregister(reg_id); + reg_id = 0; } - return; } void signal_handler(int signum) This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |
From: <jpg...@us...> - 2008-04-23 14:58:44
|
Revision: 1418 http://iaxclient.svn.sourceforge.net/iaxclient/?rev=1418&view=rev Author: jpgrayson Date: 2008-04-23 07:58:50 -0700 (Wed, 23 Apr 2008) Log Message: ----------- Whitespace. Modified Paths: -------------- trunk/simpleclient/testcall/testcall.c Modified: trunk/simpleclient/testcall/testcall.c =================================================================== --- trunk/simpleclient/testcall/testcall.c 2008-04-23 14:32:05 UTC (rev 1417) +++ trunk/simpleclient/testcall/testcall.c 2008-04-23 14:58:50 UTC (rev 1418) @@ -47,14 +47,14 @@ if (initialized) iaxc_shutdown(); if (reg_id){ - iaxc_unregister(reg_id); + iaxc_unregister(reg_id); } return; } void signal_handler(int signum) { - if ( signum == SIGTERM || signum == SIGINT ) + if ( signum == SIGTERM || signum == SIGINT ) { killem(); exit(0); @@ -76,7 +76,7 @@ if((call.state & IAXC_CALL_STATE_RINGING)) { printf("Receiving Incoming Call Request...\n"); - if ( intercom ) + if ( intercom ) { printf("Intercom mode, answer automatically\n"); return iaxc_select_call(call.callNo); @@ -152,7 +152,7 @@ } void usage() -{ +{ fprintf(stderr, "Usage: testcall [-?] [-v] [-i] [-s SILENCE_THRESHOLD] [-u USERNAME -p PASSWORD -h HOST]\n"); exit(1); } @@ -170,7 +170,7 @@ for(i=1;i<argc;i++) { - if(argv[i][0] == '-') + if(argv[i][0] == '-') { switch(tolower(argv[i][1])) { @@ -215,11 +215,11 @@ /* activate the exit handler */ atexit(killem); - + /* install signal handler to catch CRTL-Cs */ signal(SIGINT, signal_handler); signal(SIGTERM, signal_handler); - + if ( iaxc_initialize(1) ) fatal_error("cannot initialize iaxclient!"); initialized = 1; @@ -233,7 +233,7 @@ list_devices(); //if(do_levels) - iaxc_set_event_callback(iaxc_callback); + iaxc_set_event_callback(iaxc_callback); fprintf(f, "\n\ @@ -262,19 +262,19 @@ reg_id = iaxc_register(username, password, host); printf("ready for keyboard input\n"); - + if(output_filename) { for(;;) iaxc_millisleep(10*1000); } - while((c = getc(stdin))) + while((c = getc(stdin))) { - switch (tolower(c)) + switch (tolower(c)) { case 'a': printf("Answering call 0\n"); iaxc_select_call(0); - break; + break; case 'g': level = iaxc_input_level_get(); level += LEVEL_INCREMENT; @@ -289,7 +289,7 @@ printf("Decreasing input level to %f\n", level); iaxc_input_level_set(level); break; - case 'h': + case 'h': level = iaxc_output_level_get(); level += LEVEL_INCREMENT; if ( level > 1.00 ) level = 1.00; This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |