[asterisk-commits] branch oej/res_auth r22315 - in
/team/oej/res_auth: ./ build_tools/ channels/...
asterisk-commits at lists.digium.com
asterisk-commits at lists.digium.com
Mon Apr 24 13:28:58 MST 2006
Author: oej
Date: Mon Apr 24 15:28:57 2006
New Revision: 22315
URL: http://svn.digium.com/view/asterisk?rev=22315&view=rev
Log:
Moving on...
Modified:
team/oej/res_auth/ (props changed)
team/oej/res_auth/build_tools/make_defaults_h
team/oej/res_auth/cdr.c
team/oej/res_auth/channel.c
team/oej/res_auth/channels/chan_alsa.c
team/oej/res_auth/channels/chan_features.c
team/oej/res_auth/channels/chan_local.c
team/oej/res_auth/channels/chan_mgcp.c
team/oej/res_auth/channels/chan_misdn.c
team/oej/res_auth/channels/chan_nbs.c
team/oej/res_auth/channels/chan_phone.c
team/oej/res_auth/channels/chan_skinny.c
team/oej/res_auth/channels/chan_vpb.c
team/oej/res_auth/channels/chan_zap.c
team/oej/res_auth/loader.c
team/oej/res_auth/pbx/pbx_ael.c
team/oej/res_auth/pbx/pbx_config.c
team/oej/res_auth/pbx/pbx_dundi.c
team/oej/res_auth/pbx/pbx_loopback.c
team/oej/res_auth/pbx/pbx_realtime.c
team/oej/res_auth/pbx/pbx_spool.c
Propchange: team/oej/res_auth/
------------------------------------------------------------------------------
automerge = http://edvina.net/training/
Modified: team/oej/res_auth/build_tools/make_defaults_h
URL: http://svn.digium.com/view/asterisk/team/oej/res_auth/build_tools/make_defaults_h?rev=22315&r1=22314&r2=22315&view=diff
==============================================================================
--- team/oej/res_auth/build_tools/make_defaults_h (original)
+++ team/oej/res_auth/build_tools/make_defaults_h Mon Apr 24 15:28:57 2006
@@ -11,6 +11,7 @@
#define AST_MODULE_DIR "${INSTALL_PATH}${MODULES_DIR}"
#define AST_SPOOL_DIR "${INSTALL_PATH}${ASTSPOOLDIR}"
#define AST_VAR_DIR "${INSTALL_PATH}${ASTVARLIBDIR}"
+#define AST_DATA_DIR "${INSTALL_PATH}${ASTDATADIR}"
#define AST_LOG_DIR "${INSTALL_PATH}${ASTLOGDIR}"
#define AST_AGI_DIR "${INSTALL_PATH}${AGI_DIR}"
#define AST_KEY_DIR "${INSTALL_PATH}${ASTVARLIBDIR}/keys"
@@ -19,7 +20,7 @@
#define AST_CONFIG_FILE "${INSTALL_PATH}${ASTCONFPATH}"
-#define AST_SOUNDS "${INSTALL_PATH}${ASTVARLIBDIR}/sounds"
-#define AST_IMAGES "${INSTALL_PATH}${ASTVARLIBDIR}/images"
+#define AST_SOUNDS "${INSTALL_PATH}${ASTDATADIR}/sounds"
+#define AST_IMAGES "${INSTALL_PATH}${ASTDATADIR}/images"
END
Modified: team/oej/res_auth/cdr.c
URL: http://svn.digium.com/view/asterisk/team/oej/res_auth/cdr.c?rev=22315&r1=22314&r2=22315&view=diff
==============================================================================
--- team/oej/res_auth/cdr.c (original)
+++ team/oej/res_auth/cdr.c Mon Apr 24 15:28:57 2006
@@ -53,7 +53,7 @@
#include "asterisk/sched.h"
#include "asterisk/config.h"
#include "asterisk/cli.h"
-#include "asterisk/module.h"
+// XXX #include "asterisk/module.h"
#include "asterisk/stringfields.h"
/*! Default AMA flag for billing records (CDR's) */
@@ -536,35 +536,37 @@
}
}
+/* set cid info for one record */
+static void set_one_cid(struct ast_cdr *cdr, struct ast_channel *c)
+{
+ /* Grab source from ANI or normal Caller*ID */
+ const char *num = S_OR(c->cid.cid_ani, c->cid.cid_num);
+
+ if (!ast_strlen_zero(c->cid.cid_name)) {
+ if (!ast_strlen_zero(num)) /* both name and number */
+ snprintf(cdr->clid, sizeof(cdr->clid), "\"%s\" <%s>", c->cid.cid_name, num);
+ else /* only name */
+ ast_copy_string(cdr->clid, c->cid.cid_name, sizeof(cdr->clid));
+ } else if (!ast_strlen_zero(num)) { /* only number */
+ ast_copy_string(cdr->clid, num, sizeof(cdr->clid));
+ } else { /* nothing known */
+ cdr->clid[0] = '\0';
+ }
+ ast_copy_string(cdr->src, S_OR(num, ""), sizeof(cdr->src));
+
+}
int ast_cdr_setcid(struct ast_cdr *cdr, struct ast_channel *c)
{
- char tmp[AST_MAX_EXTENSION] = "";
-
for (; cdr; cdr = cdr->next) {
- if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- /* Grab source from ANI or normal Caller*ID */
- char *num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num; /* XXX ast_strlen_zero ? */
-
- if (c->cid.cid_name && num)
- snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num);
- else if (c->cid.cid_name)
- ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp));
- else if (num)
- ast_copy_string(tmp, num, sizeof(tmp));
- ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid));
- ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src));
- }
- }
-
- return 0;
-}
-
+ if (ast_test_flag(cdr, AST_CDR_FLAG_LOCKED))
+ set_one_cid(cdr, c);
+ }
+ return 0;
+}
int ast_cdr_init(struct ast_cdr *cdr, struct ast_channel *c)
{
char *chan;
- char *num;
- char tmp[AST_MAX_EXTENSION] = "";
for ( ; cdr ; cdr = cdr->next) {
if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
@@ -572,17 +574,7 @@
if (!ast_strlen_zero(cdr->channel))
ast_log(LOG_WARNING, "CDR already initialized on '%s'\n", chan);
ast_copy_string(cdr->channel, c->name, sizeof(cdr->channel));
- /* Grab source from ANI or normal Caller*ID */
- num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num;
-
- if (c->cid.cid_name && num)
- snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num);
- else if (c->cid.cid_name)
- ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp));
- else if (num)
- ast_copy_string(tmp, num, sizeof(tmp));
- ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid));
- ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src));
+ set_one_cid(cdr, c);
cdr->disposition = (c->_state == AST_STATE_UP) ? AST_CDR_ANSWERED : AST_CDR_NOANSWER;
cdr->amaflags = c->amaflags ? c->amaflags : ast_default_amaflags;
@@ -608,10 +600,7 @@
cdr->disposition = AST_CDR_FAILED;
} else
cdr->duration = cdr->end.tv_sec - cdr->start.tv_sec;
- if (!ast_tvzero(cdr->answer))
- cdr->billsec = cdr->end.tv_sec - cdr->answer.tv_sec;
- else
- cdr->billsec = 0;
+ cdr->billsec = ast_tvzero(cdr->answer) ? 0 : cdr->end.tv_sec - cdr->answer.tv_sec;
}
}
@@ -697,21 +686,10 @@
int ast_cdr_update(struct ast_channel *c)
{
struct ast_cdr *cdr = c->cdr;
- char *num;
- char tmp[AST_MAX_EXTENSION] = "";
for ( ; cdr ; cdr = cdr->next) {
if (!ast_test_flag(cdr, AST_CDR_FLAG_LOCKED)) {
- num = c->cid.cid_ani ? c->cid.cid_ani : c->cid.cid_num;
-
- if (c->cid.cid_name && num)
- snprintf(tmp, sizeof(tmp), "\"%s\" <%s>", c->cid.cid_name, num);
- else if (c->cid.cid_name)
- ast_copy_string(tmp, c->cid.cid_name, sizeof(tmp));
- else if (num)
- ast_copy_string(tmp, num, sizeof(tmp));
- ast_copy_string(cdr->clid, tmp, sizeof(cdr->clid));
- ast_copy_string(cdr->src, num ? num : "", sizeof(cdr->src));
+ set_one_cid(cdr, c);
/* Copy account code et-al */
ast_copy_string(cdr->accountcode, c->accountcode, sizeof(cdr->accountcode));
Modified: team/oej/res_auth/channel.c
URL: http://svn.digium.com/view/asterisk/team/oej/res_auth/channel.c?rev=22315&r1=22314&r2=22315&view=diff
==============================================================================
--- team/oej/res_auth/channel.c (original)
+++ team/oej/res_auth/channel.c Mon Apr 24 15:28:57 2006
@@ -401,7 +401,7 @@
}
}
- if (!(chan = ast_malloc(sizeof(*chan)))) {
+ if (!(chan = ast_calloc(1, sizeof(*chan)))) {
AST_LIST_UNLOCK(&channels);
return -1;
}
@@ -793,60 +793,48 @@
const char *context, const char *exten)
{
const char *msg = prev ? "deadlock" : "initial deadlock";
- int retries, done;
+ int retries;
struct ast_channel *c;
for (retries = 0; retries < 10; retries++) {
+ int done;
AST_LIST_LOCK(&channels);
AST_LIST_TRAVERSE(&channels, c, chan_list) {
- if (!prev) {
- /* want head of list */
- if (!name && !exten)
- break;
- if (name) {
- /* want match by full name */
- if (!namelen) {
- if (!strcasecmp(c->name, name))
- break;
- else
- continue;
- }
- /* want match by name prefix */
- if (!strncasecmp(c->name, name, namelen))
- break;
- } else if (exten) {
- /* want match by context and exten */
- if (context && (strcasecmp(c->context, context) &&
- strcasecmp(c->macrocontext, context)))
- continue;
- /* match by exten */
- if (strcasecmp(c->exten, exten) &&
- strcasecmp(c->macroexten, exten))
- continue;
- else
- break;
- }
- } else if (c == prev) { /* found, return c->next */
+ if (prev) { /* look for next item */
+ if (c != prev) /* not this one */
+ continue;
+ /* found, prepare to return c->next */
c = AST_LIST_NEXT(c, chan_list);
- break;
+ } else if (name) { /* want match by name */
+ if ( (!namelen && strcasecmp(c->name, name)) ||
+ (namelen && strncasecmp(c->name, name, namelen)) )
+ continue; /* name match failed */
+ } else if (exten) {
+ if (context && strcasecmp(c->context, context) &&
+ strcasecmp(c->macrocontext, context))
+ continue; /* context match failed */
+ if (strcasecmp(c->exten, exten) &&
+ strcasecmp(c->macroexten, exten))
+ continue; /* exten match failed */
}
+ /* if we get here, c points to the desired record */
+ break;
}
/* exit if chan not found or mutex acquired successfully */
- done = (c == NULL) || (ast_mutex_trylock(&c->lock) == 0);
- /* this is slightly unsafe, as we _should_ hold the lock to access c->name */
- if (!done && c)
- ast_log(LOG_DEBUG, "Avoiding %s for '%s'\n", msg, c->name);
+ done = c == NULL || ast_mutex_trylock(&c->lock) == 0;
+ if (!done)
+ ast_log(LOG_DEBUG, "Avoiding %s for channel '%p'\n", msg, c);
AST_LIST_UNLOCK(&channels);
if (done)
return c;
- usleep(1);
+ usleep(1); /* give other threads a chance before retrying */
}
/*
* c is surely not null, but we don't have the lock so cannot
* access c->name
*/
- ast_log(LOG_WARNING, "Avoided %s for '%p', %d retries!\n",
- msg, c, retries);
+ ast_log(LOG_WARNING, "Failure, could not lock '%p' after %d retries!\n",
+ c, retries);
return NULL;
}
@@ -1270,13 +1258,15 @@
{
struct ast_frame *translated_frame = NULL;
struct ast_channel_spy *spy;
- struct ast_channel_spy_queue *queue;
struct channel_spy_trans *trans;
- struct ast_frame *last;
trans = (dir == SPY_READ) ? &chan->spies->read_translator : &chan->spies->write_translator;
AST_LIST_TRAVERSE(&chan->spies->list, spy, list) {
+ struct ast_frame *last;
+ struct ast_frame *f1; /* the frame to append */
+ struct ast_channel_spy_queue *queue;
+
ast_mutex_lock(&spy->lock);
queue = (dir == SPY_READ) ? &spy->read_queue : &spy->write_queue;
@@ -1306,12 +1296,7 @@
break;
}
}
-
- for (last = queue->head; last && last->next; last = last->next);
- if (last)
- last->next = ast_frdup(translated_frame);
- else
- queue->head = ast_frdup(translated_frame);
+ f1 = translated_frame;
} else {
if (f->subclass != queue->format) {
ast_log(LOG_WARNING, "Spy '%s' on channel '%s' wants format '%s', but frame is '%s', dropping\n",
@@ -1320,13 +1305,17 @@
ast_mutex_unlock(&spy->lock);
continue;
}
-
- for (last = queue->head; last && last->next; last = last->next);
- if (last)
- last->next = ast_frdup(f);
- else
- queue->head = ast_frdup(f);
- }
+ f1 = f;
+ }
+ /* duplicate and append f1 to the tail */
+ f1 = ast_frdup(f1);
+
+ for (last = queue->head; last && last->next; last = last->next)
+ ;
+ if (last)
+ last->next = f1;
+ else
+ queue->head = f1;
queue->samples += f->samples;
@@ -1408,7 +1397,7 @@
/* Don't actually hang up a channel that will masquerade as someone else, or
if someone is going to masquerade as us */
- ast_mutex_lock(&chan->lock);
+ ast_channel_lock(chan);
detach_spies(chan); /* get rid of spies */
@@ -1419,14 +1408,14 @@
if (chan->masq) {
ast_log(LOG_WARNING, "%s getting hung up, but someone is trying to masq into us?!?\n", chan->name);
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
return 0;
}
/* If this channel is one which will be masqueraded into something,
mark it as a zombie already, so we know to free it later */
if (chan->masqr) {
ast_set_flag(chan, AST_FLAG_ZOMBIE);
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
return 0;
}
free_translation(chan);
@@ -1464,7 +1453,7 @@
ast_log(LOG_DEBUG, "Hanging up zombie '%s'\n", chan->name);
}
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
manager_event(EVENT_FLAG_CALL, "Hangup",
"Channel: %s\r\n"
"Uniqueid: %s\r\n"
@@ -1482,7 +1471,7 @@
int ast_answer(struct ast_channel *chan)
{
int res = 0;
- ast_mutex_lock(&chan->lock);
+ ast_channel_lock(chan);
/* Stop if we're a zombie or need a soft hangup */
if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
ast_mutex_unlock(&chan->lock);
@@ -1496,16 +1485,14 @@
ast_setstate(chan, AST_STATE_UP);
if (chan->cdr)
ast_cdr_answer(chan->cdr);
- ast_mutex_unlock(&chan->lock);
- return res;
break;
case AST_STATE_UP:
if (chan->cdr)
ast_cdr_answer(chan->cdr);
break;
}
- ast_mutex_unlock(&chan->lock);
- return 0;
+ ast_channel_unlock(chan);
+ return res;
}
void ast_deactivate_generator(struct ast_channel *chan)
@@ -1546,7 +1533,7 @@
{
int res = 0;
- ast_mutex_lock(&chan->lock);
+ ast_channel_lock(chan);
if (chan->generatordata) {
if (chan->generator && chan->generator->release)
@@ -1564,7 +1551,7 @@
chan->generator = gen;
}
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
return res;
}
@@ -1609,12 +1596,12 @@
/* Perform any pending masquerades */
for (x=0; x < n; x++) {
- ast_mutex_lock(&c[x]->lock);
+ ast_channel_lock(c[x]);
if (c[x]->masq) {
if (ast_do_masquerade(c[x])) {
ast_log(LOG_WARNING, "Masquerade failed\n");
*ms = -1;
- ast_mutex_unlock(&c[x]->lock);
+ ast_channel_unlock(c[x]);
return NULL;
}
}
@@ -1625,13 +1612,13 @@
if (diff < 1) {
/* Should already be hungup */
c[x]->_softhangup |= AST_SOFTHANGUP_TIMEOUT;
- ast_mutex_unlock(&c[x]->lock);
+ ast_channel_unlock(c[x]);
return c[x];
}
if (!whentohangup || (diff < whentohangup))
whentohangup = diff;
}
- ast_mutex_unlock(&c[x]->lock);
+ ast_channel_unlock(c[x]);
}
/* Wait full interval */
rms = *ms;
@@ -1735,7 +1722,7 @@
int ast_waitfor(struct ast_channel *c, int ms)
{
- int oldms = ms;
+ int oldms = ms; /* -1 if no timeout */
ast_waitfor_nandfds(&c, 1, NULL, 0, NULL, NULL, &ms);
if ((ms < 0) && (oldms < 0))
@@ -1743,33 +1730,10 @@
return ms;
}
+/* XXX never to be called with ms = -1 */
int ast_waitfordigit(struct ast_channel *c, int ms)
{
- /* XXX Should I be merged with waitfordigit_full XXX */
- struct ast_frame *f;
- int result = 0;
-
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
- return -1;
-
- /* Wait for a digit, no more than ms milliseconds total. */
- while(ms && !result) {
- ms = ast_waitfor(c, ms);
- if (ms < 0) /* Error */
- result = -1;
- else if (ms > 0) {
- /* Read something */
- f = ast_read(c);
- if (f) {
- if (f->frametype == AST_FRAME_DTMF)
- result = f->subclass;
- ast_frfree(f);
- } else
- result = -1;
- }
- }
- return result;
+ return ast_waitfordigit_full(c, ms, -1, -1);
}
int ast_settimeout(struct ast_channel *c, int samples, int (*func)(void *data), void *data)
@@ -1792,19 +1756,18 @@
int ast_waitfordigit_full(struct ast_channel *c, int ms, int audiofd, int cmdfd)
{
- struct ast_frame *f;
- struct ast_channel *rchan;
- int outfd;
- int res;
/* Stop if we're a zombie or need a soft hangup */
if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
return -1;
/* Wait for a digit, no more than ms milliseconds total. */
- while(ms) {
+ while (ms) {
+ struct ast_channel *rchan;
+ int outfd;
+
errno = 0;
rchan = ast_waitfor_nandfds(&c, 1, &cmdfd, (cmdfd > -1) ? 1 : 0, NULL, &outfd, &ms);
- if ((!rchan) && (outfd < 0) && (ms)) {
+ if (!rchan && outfd < 0 && ms) {
if (errno == 0 || errno == EINTR)
continue;
ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno));
@@ -1813,10 +1776,10 @@
/* The FD we were watching has something waiting */
return 1;
} else if (rchan) {
- f = ast_read(c);
- if(!f) {
+ int res;
+ struct ast_frame *f = ast_read(c);
+ if (!f)
return -1;
- }
switch(f->frametype) {
case AST_FRAME_DTMF:
@@ -1849,31 +1812,28 @@
static struct ast_frame *__ast_read(struct ast_channel *chan, int dropaudio)
{
- struct ast_frame *f = NULL;
+ struct ast_frame *f = NULL; /* the return value */
int blah;
int prestate;
-#ifdef ZAPTEL_OPTIMIZATIONS
- int (*func)(void *);
- void *data;
- int res;
-#endif
- ast_mutex_lock(&chan->lock);
+
+ /* this function is very long so make sure there is only one return
+ * point at the end (there is only one exception to this).
+ */
+ ast_channel_lock(chan);
if (chan->masq) {
if (ast_do_masquerade(chan)) {
ast_log(LOG_WARNING, "Failed to perform masquerade\n");
- f = NULL;
- } else
+ } else {
f = &ast_null_frame;
- ast_mutex_unlock(&chan->lock);
- return f;
+ }
+ goto done;
}
/* Stop if we're a zombie or need a soft hangup */
if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
if (chan->generator)
ast_deactivate_generator(chan);
- ast_mutex_unlock(&chan->lock);
- return NULL;
+ goto done;
}
prestate = chan->_state;
@@ -1881,19 +1841,21 @@
/* We have DTMF that has been deferred. Return it now */
chan->dtmff.frametype = AST_FRAME_DTMF;
chan->dtmff.subclass = chan->dtmfq[0];
- /* Drop first digit */
+ /* Drop first digit from the buffer */
memmove(chan->dtmfq, chan->dtmfq + 1, sizeof(chan->dtmfq) - 1);
- ast_mutex_unlock(&chan->lock);
- return &chan->dtmff;
+ f = &chan->dtmff;
+ goto done;
}
/* Read and ignore anything on the alertpipe, but read only
one sizeof(blah) per frame that we send from it */
- if (chan->alertpipe[0] > -1) {
+ if (chan->alertpipe[0] > -1)
read(chan->alertpipe[0], &blah, sizeof(blah));
- }
+
#ifdef ZAPTEL_OPTIMIZATIONS
if (chan->timingfd > -1 && chan->fdno == AST_TIMING_FD && ast_test_flag(chan, AST_FLAG_EXCEPTION)) {
+ int res;
+
ast_clear_flag(chan, AST_FLAG_EXCEPTION);
blah = -1;
/* IF we can't get event, assume it's an expired as-per the old interface */
@@ -1902,48 +1864,42 @@
blah = ZT_EVENT_TIMER_EXPIRED;
if (blah == ZT_EVENT_TIMER_PING) {
-#if 0
- ast_log(LOG_NOTICE, "Oooh, there's a PING!\n");
-#endif
if (!chan->readq || !chan->readq->next) {
/* Acknowledge PONG unless we need it again */
-#if 0
- ast_log(LOG_NOTICE, "Sending a PONG!\n");
-#endif
if (ioctl(chan->timingfd, ZT_TIMERPONG, &blah)) {
ast_log(LOG_WARNING, "Failed to pong timer on '%s': %s\n", chan->name, strerror(errno));
}
}
} else if (blah == ZT_EVENT_TIMER_EXPIRED) {
ioctl(chan->timingfd, ZT_TIMERACK, &blah);
- func = chan->timingfunc;
- data = chan->timingdata;
- ast_mutex_unlock(&chan->lock);
- if (func) {
-#if 0
- ast_log(LOG_DEBUG, "Calling private function\n");
-#endif
+ if (chan->timingfunc) {
+ /* save a copy of func/data before unlocking the channel */
+ int (*func)(void *) = chan->timingfunc;
+ void *data = chan->timingdata;
+ ast_channel_unlock(chan);
func(data);
} else {
blah = 0;
- ast_mutex_lock(&chan->lock);
ioctl(chan->timingfd, ZT_TIMERCONFIG, &blah);
chan->timingdata = NULL;
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
}
+ /* cannot 'goto done' because the channel is already unlocked */
return &ast_null_frame;
} else
ast_log(LOG_NOTICE, "No/unknown event '%d' on timer for '%s'?\n", blah, chan->name);
} else
#endif
- /* Check for AST_GENERATOR_FD if not null. If so, call generator with -1
- arguments now so it can do whatever it needs to. */
if (chan->fds[AST_GENERATOR_FD] > -1 && chan->fdno == AST_GENERATOR_FD) {
+ /* if the AST_GENERATOR_FD is set, call the generator with args
+ * set to -1 so it can do whatever it needs to.
+ */
void *tmp = chan->generatordata;
chan->generatordata = NULL; /* reset to let ast_write get through */
chan->generator->generate(chan, tmp, -1, -1);
chan->generatordata = tmp;
- return &ast_null_frame;
+ f = &ast_null_frame;
+ goto done;
}
/* Check for pending read queue */
@@ -1952,7 +1908,7 @@
chan->readq = f->next;
f->next = NULL;
/* Interpret hangup and return NULL */
- if ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP)) {
+ if (f->frametype == AST_FRAME_CONTROL && f->subclass == AST_CONTROL_HANGUP) {
ast_frfree(f);
f = NULL;
}
@@ -1967,12 +1923,10 @@
}
/* Clear the exception flag */
ast_clear_flag(chan, AST_FLAG_EXCEPTION);
- } else {
- if (chan->tech->read)
- f = chan->tech->read(chan);
- else
- ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
- }
+ } else if (chan->tech->read)
+ f = chan->tech->read(chan);
+ else
+ ast_log(LOG_WARNING, "No read routine on channel %s\n", chan->name);
}
if (f) {
@@ -2051,17 +2005,14 @@
}
}
- if (chan->readtrans) {
- if (!(f = ast_translate(chan->readtrans, f, 1)))
- f = &ast_null_frame;
- }
+ if (chan->readtrans && (f = ast_translate(chan->readtrans, f, 1)) == NULL)
+ f = &ast_null_frame;
/* Run generator sitting on the line if timing device not available
* and synchronous generation of outgoing frames is necessary */
if (chan->generatordata && !ast_internal_timing_enabled(chan)) {
- void *tmp;
+ void *tmp = chan->generatordata;
int res;
- int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples);
if (chan->timingfunc) {
if (option_debug > 1)
@@ -2069,10 +2020,8 @@
ast_settimeout(chan, 0, NULL, NULL);
}
- tmp = chan->generatordata;
- chan->generatordata = NULL;
- generate = chan->generator->generate;
- res = generate(chan, tmp, f->datalen, f->samples);
+ chan->generatordata = NULL; /* reset, to let writes go through */
+ res = chan->generator->generate(chan, tmp, f->datalen, f->samples);
chan->generatordata = tmp;
if (res) {
if (option_debug > 1)
@@ -2100,14 +2049,12 @@
}
/* High bit prints debugging */
- if (chan->fin & 0x80000000)
+ if (chan->fin & DEBUGCHAN_FLAG)
ast_frame_dump(chan->name, f, "<<");
- if ((chan->fin & 0x7fffffff) == 0x7fffffff)
- chan->fin &= 0x80000000;
- else
- chan->fin++;
+ chan->fin = FRAMECOUNT_INC(chan->fin);
+
+done:
ast_mutex_unlock(&chan->lock);
-
return f;
}
@@ -2133,21 +2080,23 @@
{
int res = -1;
- ast_mutex_lock(&chan->lock);
+ ast_channel_lock(chan);
/* Stop if we're a zombie or need a soft hangup */
if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
return -1;
}
if (chan->tech->indicate)
res = chan->tech->indicate(chan, condition);
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
if (!chan->tech->indicate || res) {
/*
* Device does not support (that) indication, lets fake
* it by doing our own tone generation. (PM2002)
*/
- if (condition >= 0) {
+ if (condition < 0)
+ ast_playtones_stop(chan);
+ else {
const struct tone_zone_sound *ts = NULL;
switch (condition) {
case AST_CONTROL_RINGING:
@@ -2180,7 +2129,6 @@
res = -1;
}
}
- else ast_playtones_stop(chan);
}
return res;
}
@@ -2318,34 +2266,31 @@
{
int res = -1;
struct ast_frame *f = NULL;
+
/* Stop if we're a zombie or need a soft hangup */
- ast_mutex_lock(&chan->lock);
- if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan)) {
- ast_mutex_unlock(&chan->lock);
- return -1;
- }
+ ast_channel_lock(chan);
+ if (ast_test_flag(chan, AST_FLAG_ZOMBIE) || ast_check_hangup(chan))
+ goto done;
+
/* Handle any pending masquerades */
- if (chan->masq) {
- if (ast_do_masquerade(chan)) {
- ast_log(LOG_WARNING, "Failed to perform masquerade\n");
- ast_mutex_unlock(&chan->lock);
- return -1;
- }
+ if (chan->masq && ast_do_masquerade(chan)) {
+ ast_log(LOG_WARNING, "Failed to perform masquerade\n");
+ goto done;
}
if (chan->masqr) {
- ast_mutex_unlock(&chan->lock);
- return 0;
+ res = 0; /* XXX explain, why 0 ? */
+ goto done;
}
if (chan->generatordata) {
if (ast_test_flag(chan, AST_FLAG_WRITE_INT))
ast_deactivate_generator(chan);
else {
- ast_mutex_unlock(&chan->lock);
- return 0;
+ res = 0; /* XXX explain, why 0 ? */
+ goto done;
}
}
/* High bit prints debugging */
- if (chan->fout & 0x80000000)
+ if (chan->fout & DEBUGCHAN_FLAG)
ast_frame_dump(chan->name, fr, ">>");
CHECK_BLOCKING(chan);
switch(fr->frametype) {
@@ -2354,98 +2299,90 @@
ast_log(LOG_WARNING, "Don't know how to handle control frames yet\n");
break;
case AST_FRAME_DTMF_BEGIN:
- if (chan->tech->send_digit_begin)
- res = chan->tech->send_digit_begin(chan, fr->subclass);
- else
- res = 0;
+ res = (chan->tech->send_digit_begin == NULL) ? 0 :
+ chan->tech->send_digit_begin(chan, fr->subclass);
break;
case AST_FRAME_DTMF_END:
- if (chan->tech->send_digit_end)
- res = chan->tech->send_digit_end(chan);
- else
- res = 0;
+ res = (chan->tech->send_digit_end == NULL) ? 0 :
+ chan->tech->send_digit_end(chan);
break;
case AST_FRAME_DTMF:
ast_clear_flag(chan, AST_FLAG_BLOCKING);
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
res = do_senddigit(chan,fr->subclass);
- ast_mutex_lock(&chan->lock);
+ ast_channel_lock(chan);
CHECK_BLOCKING(chan);
break;
case AST_FRAME_TEXT:
- if (chan->tech->send_text)
- res = chan->tech->send_text(chan, (char *) fr->data);
- else
- res = 0;
+ res = (chan->tech->send_text == NULL) ? 0 :
+ chan->tech->send_text(chan, (char *) fr->data);
break;
case AST_FRAME_HTML:
- if (chan->tech->send_html)
- res = chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
- else
- res = 0;
+ res = (chan->tech->send_html == NULL) ? 0 :
+ chan->tech->send_html(chan, fr->subclass, (char *) fr->data, fr->datalen);
break;
case AST_FRAME_VIDEO:
/* XXX Handle translation of video codecs one day XXX */
- if (chan->tech->write_video)
- res = chan->tech->write_video(chan, fr);
- else
- res = 0;
+ res = (chan->tech->write_video == NULL) ? 0 :
+ chan->tech->write_video(chan, fr);
break;
case AST_FRAME_VOICE:
- if (chan->tech->write) {
- /* Bypass translator if we're writing format in the raw write format. This
- allows mixing of native / non-native formats */
- if (fr->subclass == chan->rawwriteformat)
- f = fr;
- else
- f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
- if (f) {
- if (chan->spies)
- queue_frame_to_spies(chan, f, SPY_WRITE);
-
- if (chan->monitor && chan->monitor->write_stream) {
+ if (chan->tech->write == NULL)
+ break; /*! \todo XXX should return 0 maybe ? */
+
+ /* Bypass translator if we're writing format in the raw write format. This
+ allows mixing of native / non-native formats */
+ if (fr->subclass == chan->rawwriteformat)
+ f = fr;
+ else
+ f = (chan->writetrans) ? ast_translate(chan->writetrans, fr, 0) : fr;
+ if (f == NULL) {
+ res = 0;
+ } else {
+ if (chan->spies)
+ queue_frame_to_spies(chan, f, SPY_WRITE);
+
+ if (chan->monitor && chan->monitor->write_stream) {
+ /* XXX must explain this code */
#ifndef MONITOR_CONSTANT_DELAY
- int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
- if (jump >= 0) {
- if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
- ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
- chan->outsmpl += jump + 4 * f->samples;
- } else
- chan->outsmpl += f->samples;
+ int jump = chan->insmpl - chan->outsmpl - 4 * f->samples;
+ if (jump >= 0) {
+ if (ast_seekstream(chan->monitor->write_stream, jump + f->samples, SEEK_FORCECUR) == -1)
+ ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+ chan->outsmpl += jump + 4 * f->samples;
+ } else
+ chan->outsmpl += f->samples;
#else
- int jump = chan->insmpl - chan->outsmpl;
- if (jump - MONITOR_DELAY >= 0) {
- if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
- ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
- chan->outsmpl += jump;
- } else
- chan->outsmpl += f->samples;
+ int jump = chan->insmpl - chan->outsmpl;
+ if (jump - MONITOR_DELAY >= 0) {
+ if (ast_seekstream(chan->monitor->write_stream, jump - f->samples, SEEK_FORCECUR) == -1)
+ ast_log(LOG_WARNING, "Failed to perform seek in monitoring write stream, synchronization between the files may be broken\n");
+ chan->outsmpl += jump;
+ } else
+ chan->outsmpl += f->samples;
#endif
- if (chan->monitor->state == AST_MONITOR_RUNNING) {
- if (ast_writestream(chan->monitor->write_stream, f) < 0)
- ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
- }
+ if (chan->monitor->state == AST_MONITOR_RUNNING) {
+ if (ast_writestream(chan->monitor->write_stream, f) < 0)
+ ast_log(LOG_WARNING, "Failed to write data to channel monitor write stream\n");
}
-
- res = chan->tech->write(chan, f);
- } else
- res = 0;
- }
- }
-
- if (f && (f != fr))
+ }
+
+ res = chan->tech->write(chan, f);
+ }
+ break;
+ }
+
+ if (f && f != fr)
ast_frfree(f);
ast_clear_flag(chan, AST_FLAG_BLOCKING);
/* Consider a write failure to force a soft hangup */
if (res < 0)
chan->_softhangup |= AST_SOFTHANGUP_DEV;
else {
- if ((chan->fout & 0x7fffffff) == 0x7fffffff)
- chan->fout &= 0x80000000;
- else
- chan->fout++;
- }
- ast_mutex_unlock(&chan->lock);
+ chan->fout = FRAMECOUNT_INC(chan->fout);
+ }
+done:
+ ast_channel_unlock(chan);
return res;
}
@@ -2474,7 +2411,7 @@
}
/* Now we have a good choice for both. */
- ast_mutex_lock(&chan->lock);
+ ast_channel_lock(chan);
*rawformat = native;
/* User perspective is fmt */
*format = fmt;
@@ -2488,7 +2425,7 @@
else
/* writing */
*trans = ast_translator_build_path(*rawformat, *format);
- ast_mutex_unlock(&chan->lock);
+ ast_channel_unlock(chan);
if (option_debug)
ast_log(LOG_DEBUG, "Set channel %s to %s format %s\n", chan->name,
direction ? "write" : "read", ast_getformatname(fmt));
@@ -2509,101 +2446,100 @@
struct ast_channel *__ast_request_and_dial(const char *type, int format, void *data, int timeout, int *outstate, const char *cid_num, const char *cid_name, struct outgoing_helper *oh)
{
- int state = 0;
+ int dummy_outstate;
int cause = 0;
struct ast_channel *chan;
- struct ast_frame *f;
int res = 0;
+ if (outstate)
+ *outstate = 0;
+ else
+ outstate = &dummy_outstate; /* make outstate always a valid pointer */
+
chan = ast_request(type, format, data, &cause);
- if (chan) {
- if (oh) {
- if (oh->vars)
- ast_set_variables(chan, oh->vars);
- if (oh->cid_num && *oh->cid_num && oh->cid_name && *oh->cid_name)
- ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
- if (oh->parent_channel)
- ast_channel_inherit_variables(oh->parent_channel, chan);
- if (oh->account)
- ast_cdr_setaccount(chan, oh->account);
- }
- ast_set_callerid(chan, cid_num, cid_name, cid_num);
-
- if (!ast_call(chan, data, 0)) {
- res = 1; /* in case chan->_state is already AST_STATE_UP */
- while (timeout && (chan->_state != AST_STATE_UP)) {
- res = ast_waitfor(chan, timeout);
- if (res < 0) {
- /* Something not cool, or timed out */
+ if (!chan) {
+ ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
+ /* compute error and return */
+ if (cause == AST_CAUSE_BUSY)
+ *outstate = AST_CONTROL_BUSY;
+ else if (cause == AST_CAUSE_CONGESTION)
+ *outstate = AST_CONTROL_CONGESTION;
+ return NULL;
+ }
+
+ if (oh) {
+ if (oh->vars)
+ ast_set_variables(chan, oh->vars);
+ /* XXX why is this necessary, for the parent_channel perhaps ? */
+ if (!ast_strlen_zero(oh->cid_num) && !ast_strlen_zero(oh->cid_name))
+ ast_set_callerid(chan, oh->cid_num, oh->cid_name, oh->cid_num);
+ if (oh->parent_channel)
+ ast_channel_inherit_variables(oh->parent_channel, chan);
+ if (oh->account)
+ ast_cdr_setaccount(chan, oh->account);
+ }
+ ast_set_callerid(chan, cid_num, cid_name, cid_num);
+
+ if (ast_call(chan, data, 0)) { /* ast_call failed... */
+ ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
+ } else {
+ res = 1; /* mark success in case chan->_state is already AST_STATE_UP */
+ while (timeout && chan->_state != AST_STATE_UP) {
+ struct ast_frame *f;
+ res = ast_waitfor(chan, timeout);
+ if (res <= 0) /* error, timeout, or done */
+ break;
+ if (timeout > -1)
+ timeout = res;
+ f = ast_read(chan);
+ if (!f) {
+ *outstate = AST_CONTROL_HANGUP;
+ res = 0;
+ break;
+ }
+ if (f->frametype == AST_FRAME_CONTROL) {
+ switch (f->subclass) {
+ case AST_CONTROL_RINGING: /* record but keep going */
+ *outstate = f->subclass;
break;
+
+ case AST_CONTROL_BUSY:
+ case AST_CONTROL_CONGESTION:
+ case AST_CONTROL_ANSWER:
+ *outstate = f->subclass;
+ timeout = 0; /* trick to force exit from the while() */
+ break;
+
+ case AST_CONTROL_PROGRESS: /* Ignore */
+ case -1: /* Ignore -- just stopping indications */
+ break;
+
+ default:
+ ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
}
- /* If done, break out */
- if (!res)
- break;
- if (timeout > -1)
- timeout = res;
- f = ast_read(chan);
- if (!f) {
- state = AST_CONTROL_HANGUP;
- res = 0;
- break;
- }
- if (f->frametype == AST_FRAME_CONTROL) {
- if (f->subclass == AST_CONTROL_RINGING)
- state = AST_CONTROL_RINGING;
- else if ((f->subclass == AST_CONTROL_BUSY) || (f->subclass == AST_CONTROL_CONGESTION)) {
- state = f->subclass;
- ast_frfree(f);
- break;
- } else if (f->subclass == AST_CONTROL_ANSWER) {
- state = f->subclass;
- ast_frfree(f);
- break;
- } else if (f->subclass == AST_CONTROL_PROGRESS) {
- /* Ignore */
- } else if (f->subclass == -1) {
- /* Ignore -- just stopping indications */
- } else {
- ast_log(LOG_NOTICE, "Don't know what to do with control frame %d\n", f->subclass);
- }
- }
- ast_frfree(f);
}
- } else
- ast_log(LOG_NOTICE, "Unable to call channel %s/%s\n", type, (char *)data);
- } else {
- ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
- switch(cause) {
- case AST_CAUSE_BUSY:
- state = AST_CONTROL_BUSY;
- break;
- case AST_CAUSE_CONGESTION:
- state = AST_CONTROL_CONGESTION;
- break;
- }
- }
- if (chan) {
- /* Final fixups */
- if (oh) {
- if (oh->context && *oh->context)
- ast_copy_string(chan->context, oh->context, sizeof(chan->context));
- if (oh->exten && *oh->exten)
- ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
- if (oh->priority)
- chan->priority = oh->priority;
- }
- if (chan->_state == AST_STATE_UP)
- state = AST_CONTROL_ANSWER;
- }
- if (outstate)
- *outstate = state;
- if (chan && res <= 0) {
- if (!chan->cdr && (chan->cdr = ast_cdr_alloc())) {
+ ast_frfree(f);
+ }
+ }
+
+ /* Final fixups */
+ if (oh) {
+ if (!ast_strlen_zero(oh->context))
+ ast_copy_string(chan->context, oh->context, sizeof(chan->context));
+ if (!ast_strlen_zero(oh->exten))
+ ast_copy_string(chan->exten, oh->exten, sizeof(chan->exten));
+ if (oh->priority)
+ chan->priority = oh->priority;
+ }
+ if (chan->_state == AST_STATE_UP)
+ *outstate = AST_CONTROL_ANSWER;
+
+ if (res <= 0) {
+ if (!chan->cdr && (chan->cdr = ast_cdr_alloc()))
ast_cdr_init(chan->cdr, chan);
- }
if (chan->cdr) {
char tmp[256];
- snprintf(tmp, 256, "%s/%s", type, (char *)data);
+ snprintf(tmp, sizeof(tmp), "%s/%s", type, (char *)data);
ast_cdr_setapp(chan->cdr,"Dial",tmp);
ast_cdr_update(chan);
ast_cdr_start(chan->cdr);
@@ -2668,8 +2604,8 @@
"CallerIDName: %s\r\n"
"Uniqueid: %s\r\n",
c->name, ast_state2str(c->_state),
- c->cid.cid_num ? c->cid.cid_num : "<unknown>",
- c->cid.cid_name ? c->cid.cid_name : "<unknown>",
+ S_OR(c->cid.cid_num, "<unknown>"),
+ S_OR(c->cid.cid_name, "<unknown>"),
c->uniqueid);
}
return c;
@@ -2724,56 +2660,21 @@
int ast_readstring(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders)
{
- int pos=0;
+ return ast_readstring_full(c, s, len, timeout, ftimeout, enders, -1, -1);
+}
+
+int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
+{
+ int pos = 0; /* index in the buffer where we accumulate digits */
int to = ftimeout;
- int d;
-
- /* XXX Merge with full version? XXX */
+
/* Stop if we're a zombie or need a soft hangup */
if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
return -1;
if (!len)
return -1;
- do {
- if (c->stream) {
- d = ast_waitstream(c, AST_DIGIT_ANY);
- ast_stopstream(c);
- usleep(1000);
- if (!d)
- d = ast_waitfordigit(c, to);
- } else {
- d = ast_waitfordigit(c, to);
- }
- if (d < 0)
- return -1;
- if (d == 0) {
- s[pos]='\0';
- return 1;
- }
- if (!strchr(enders, d))
- s[pos++] = d;
- if (strchr(enders, d) || (pos >= len)) {
- s[pos]='\0';
- return 0;
- }
- to = timeout;
- } while(1);
- /* Never reached */
- return 0;
-}
-
-int ast_readstring_full(struct ast_channel *c, char *s, int len, int timeout, int ftimeout, char *enders, int audiofd, int ctrlfd)
-{
- int pos=0;
- int to = ftimeout;
- int d;
-
- /* Stop if we're a zombie or need a soft hangup */
- if (ast_test_flag(c, AST_FLAG_ZOMBIE) || ast_check_hangup(c))
- return -1;
- if (!len)
- return -1;
- do {
+ for (;;) {
+ int d;
if (c->stream) {
d = ast_waitstream_full(c, AST_DIGIT_ANY, audiofd, ctrlfd);
ast_stopstream(c);
@@ -2800,16 +2701,14 @@
return 0;
}
to = timeout;
- } while(1);
+ }
/* Never reached */
return 0;
}
int ast_channel_supports_html(struct ast_channel *chan)
{
- if (chan->tech->send_html)
- return 1;
- return 0;
+ return (chan->tech->send_html) ? 1 : 0;
}
int ast_channel_sendhtml(struct ast_channel *chan, int subclass, const char *data, int datalen)
@@ -2821,9 +2720,7 @@
int ast_channel_sendurl(struct ast_channel *chan, const char *url)
{
- if (chan->tech->send_html)
- return chan->tech->send_html(chan, AST_HTML_URL, url, strlen(url) + 1);
- return -1;
+ return ast_channel_sendhtml(chan, AST_HTML_URL, url, strlen(url) + 1);
}
int ast_channel_make_compatible(struct ast_channel *chan, struct ast_channel *peer)
@@ -2841,8 +2738,10 @@
/* if the best path is not 'pass through', then
transcoding is needed; if desired, force transcode path
- to use SLINEAR between channels */
- if ((src != dst) && ast_opt_transcode_via_slin)
+ to use SLINEAR between channels, but only if there is
+ no direct conversion available */
+ if ((src != dst) && ast_opt_transcode_via_slin &&
+ (ast_translate_path_steps(dst, src) != 1))
dst = AST_FORMAT_SLINEAR;
if (ast_set_read_format(chan, dst) < 0) {
ast_log(LOG_WARNING, "Unable to set read format on channel %s to %d\n", chan->name, dst);
@@ -2860,10 +2759,13 @@
[... 3240 lines stripped ...]
More information about the asterisk-commits
mailing list