Pass concept of status back, permit "leaveempty" to work with static agents who are not loggedon (bug #2719)

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@4106 65c4cc65-6c06-0410-ace0-fbb531ad65f3
1.2-netsec
Mark Spencer 21 years ago
parent 9efbc46301
commit 8a13712e45

@ -51,6 +51,7 @@ LOCAL_USER_DECL;
static int chanavail_exec(struct ast_channel *chan, void *data)
{
int res=-1;
int status;
struct localuser *u;
char info[512], tmp[512], *peers, *tech, *number, *rest, *cur;
struct ast_channel *tempchan;
@ -80,20 +81,24 @@ static int chanavail_exec(struct ast_channel *chan, void *data)
}
*number = '\0';
number++;
if ((tempchan = ast_request(tech, chan->nativeformats, number))) {
if ((tempchan = ast_request(tech, chan->nativeformats, number, &status))) {
pbx_builtin_setvar_helper(chan, "AVAILCHAN", tempchan->name);
/* Store the originally used channel too */
snprintf(tmp, sizeof(tmp), "%s/%s", tech, number);
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", tmp);
snprintf(tmp, sizeof(tmp), "%d", status);
pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
ast_hangup(tempchan);
tempchan = NULL;
res = 1;
break;
} else {
snprintf(tmp, sizeof(tmp), "%d", status);
pbx_builtin_setvar_helper(chan, "AVAILSTATUS", tmp);
}
cur = rest;
} while (cur);
}
if (res < 1) {
pbx_builtin_setvar_helper(chan, "AVAILCHAN", "");
pbx_builtin_setvar_helper(chan, "AVAILORIGCHAN", "");

@ -26,6 +26,7 @@
#include <asterisk/callerid.h>
#include <asterisk/utils.h>
#include <asterisk/app.h>
#include <asterisk/causes.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
@ -134,14 +135,32 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
#define AST_MAX_WATCHERS 256
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, int *sentringing, char *status, size_t statussize)
#define HANDLE_CAUSE(blah, bleh) do { \
switch(cause) { \
case AST_CAUSE_BUSY: \
if (bleh->cdr) \
ast_cdr_busy(bleh->cdr); \
numbusy++; \
case AST_CAUSE_CONGESTION: \
case AST_CAUSE_UNREGISTERED: \
if (bleh->cdr) \
ast_cdr_busy(bleh->cdr); \
numcongestion++; \
default: \
numnochan++; \
} \
} while(0)
static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localuser *outgoing, int *to, int *allowredir_in, int *allowredir_out, int *allowdisconnect_in, int *allowdisconnect_out, int *sentringing, char *status, size_t statussize, int busystart, int nochanstart, int congestionstart)
{
struct localuser *o;
int found;
int numlines;
int numbusy = 0;
int numcongestion = 0;
int numnochan = 0;
int numbusy = busystart;
int numcongestion = congestionstart;
int numnochan = nochanstart;
int cause;
int orig = *to;
struct ast_frame *f;
struct ast_channel *peer = NULL;
@ -227,11 +246,11 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
/* Setup parameters */
o->chan = ast_request(tech, in->nativeformats, stuff);
o->chan = ast_request(tech, in->nativeformats, stuff, &cause);
if (!o->chan) {
ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
o->stillgoing = 0;
numnochan++;
HANDLE_CAUSE(cause, in);
} else {
if (o->chan->cid.cid_num)
free(o->chan->cid.cid_num);
@ -317,9 +336,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
ast_hangup(o->chan);
o->chan = NULL;
o->stillgoing = 0;
if (in->cdr)
ast_cdr_busy(in->cdr);
numbusy++;
HANDLE_CAUSE(AST_CAUSE_BUSY, in);
break;
case AST_CONTROL_CONGESTION:
if (option_verbose > 2)
@ -328,9 +345,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in, struct localu
ast_hangup(o->chan);
o->chan = NULL;
o->stillgoing = 0;
if (in->cdr)
ast_cdr_busy(in->cdr);
numcongestion++;
HANDLE_CAUSE(AST_CAUSE_CONGESTION, in);
break;
case AST_CONTROL_RINGING:
if (option_verbose > 2)
@ -433,6 +448,10 @@ static int dial_exec(struct ast_channel *chan, void *data)
int privacy=0;
int announce=0;
int resetcdr=0;
int numbusy = 0;
int numcongestion = 0;
int numnochan = 0;
int cause;
char numsubst[AST_MAX_EXTENSION];
char restofit[AST_MAX_EXTENSION];
char *transfer = NULL;
@ -738,14 +757,11 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_log(LOG_DEBUG, "Dialing by extension %s\n", numsubst);
}
/* Request the peer */
tmp->chan = ast_request(tech, chan->nativeformats, numsubst);
tmp->chan = ast_request(tech, chan->nativeformats, numsubst, &cause);
if (!tmp->chan) {
/* If we can't, just go on to the next call */
ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", tech);
if (chan->cdr)
ast_cdr_busy(chan->cdr);
free(tmp);
cur = rest;
HANDLE_CAUSE(cause, chan);
continue;
}
if (!ast_strlen_zero(tmp->chan->call_forward)) {
@ -767,11 +783,10 @@ static int dial_exec(struct ast_channel *chan, void *data)
ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s/%s' (thanks to %s)\n", chan->name, tech, stuff, tmp->chan->name);
/* Setup parameters */
ast_hangup(tmp->chan);
tmp->chan = ast_request(tech, chan->nativeformats, stuff);
tmp->chan = ast_request(tech, chan->nativeformats, stuff, &cause);
if (!tmp->chan) {
ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
free(tmp);
cur = rest;
HANDLE_CAUSE(cause, chan);
continue;
}
}
@ -847,8 +862,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
else if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", numsubst);
ast_hangup(tmp->chan);
free(tmp);
cur = rest;
tmp->chan = NULL;
continue;
} else
if (option_verbose > 2)
@ -888,7 +902,7 @@ static int dial_exec(struct ast_channel *chan, void *data)
strncpy(status, "CHANUNAVAIL", sizeof(status) - 1);
time(&start_time);
peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, status, sizeof(status));
peer = wait_for_answer(chan, outgoing, &to, &allowredir_in, &allowredir_out, &allowdisconnect_in, &allowdisconnect_out, &sentringing, status, sizeof(status), numbusy, numnochan, numcongestion);
if (!peer) {
if (to)

@ -222,7 +222,7 @@ static struct ast_conference *build_conf(char *confno, char *pin, int make, int
strncpy(cnf->confno, confno, sizeof(cnf->confno) - 1);
strncpy(cnf->pin, pin, sizeof(cnf->pin) - 1);
cnf->markedusers = 0;
cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo");
cnf->chan = ast_request("zap", AST_FORMAT_ULAW, "pseudo", NULL);
if (cnf->chan) {
cnf->fd = cnf->chan->fds[0]; /* for use by conf_play() */
} else {

@ -45,6 +45,7 @@
#include <asterisk/config.h>
#include <asterisk/monitor.h>
#include <asterisk/utils.h>
#include <asterisk/causes.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
@ -145,6 +146,7 @@ struct localuser {
char tech[40];
int stillgoing;
int metric;
int oldstatus;
int allowredirect_in;
int allowredirect_out;
int ringbackonly;
@ -182,6 +184,7 @@ struct member {
int penalty; /* Are we a last resort? */
int calls; /* Number of calls serviced by this member */
int dynamic; /* Are we dynamically added? */
int status; /* Status of queue member */
time_t lastcall; /* When last successful call was hungup */
struct member *next; /* Next member */
};
@ -280,6 +283,26 @@ static inline void insert_entry(struct ast_call_queue *q,
new->opos = *pos;
}
static int has_no_members(struct ast_call_queue *q)
{
struct member *member;
int empty = 1;
member = q->members;
while(empty && member) {
switch(member->status) {
case AST_CAUSE_NOSUCHDRIVER:
case AST_CAUSE_UNREGISTERED:
/* Not logged on, etc */
break;
default:
/* Not empty */
empty = 0;
}
member = member->next;
}
return empty;
}
static int join_queue(char *queuename, struct queue_ent *qe)
{
struct ast_call_queue *q;
@ -293,7 +316,7 @@ static int join_queue(char *queuename, struct queue_ent *qe)
if (!strcasecmp(q->name, queuename)) {
/* This is our one */
ast_mutex_lock(&q->lock);
if ((q->members || q->joinempty) && (!q->maxlen || (q->count < q->maxlen))) {
if ((!has_no_members(q) || q->joinempty || !q->head) && (!q->maxlen || (q->count < q->maxlen))) {
/* There's space for us, put us at the right position inside
* the queue.
* Take into account the priority of the calling user */
@ -551,9 +574,29 @@ static void hanguptree(struct localuser *outgoing, struct ast_channel *exception
}
}
static int update_status(struct ast_call_queue *q, struct member *member, int status)
{
struct member *cur;
/* Since a reload could have taken place, we have to traverse the list to
be sure it's still valid */
ast_mutex_lock(&q->lock);
cur = q->members;
while(cur) {
if (member == cur) {
cur->status = status;
break;
}
cur = cur->next;
}
q->callscompleted++;
ast_mutex_unlock(&q->lock);
return 0;
}
static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
{
int res;
int status;
if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s/%s\n", tmp->tech, tmp->numsubst);
if (qe->chan->cdr)
@ -562,7 +605,7 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
return 0;
}
/* Request the peer */
tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst);
tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst, &status);
if (!tmp->chan) { /* If we can't, just go on to the next call */
#if 0
ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", cur->tech);
@ -570,8 +613,11 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
if (qe->chan->cdr)
ast_cdr_busy(qe->chan->cdr);
tmp->stillgoing = 0;
update_status(qe->parent, tmp->member, status);
return 0;
}
} else if (status != tmp->oldstatus)
update_status(qe->parent, tmp->member, status);
tmp->chan->appl = "AppQueue";
tmp->chan->data = "(Outgoing Line)";
tmp->chan->whentohangup = 0;
@ -728,6 +774,7 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
struct localuser *o;
int found;
int numlines;
int status;
int sentringing = 0;
int numbusies = 0;
int numnochan = 0;
@ -795,7 +842,9 @@ static struct localuser *wait_for_answer(struct queue_ent *qe, struct localuser
if (option_verbose > 2)
ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
/* Setup parameters */
o->chan = ast_request(tech, in->nativeformats, stuff);
o->chan = ast_request(tech, in->nativeformats, stuff, &status);
if (status != o->oldstatus)
update_status(qe->parent, o->member, status);
if (!o->chan) {
ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
o->stillgoing = 0;
@ -997,7 +1046,7 @@ static int wait_our_turn(struct queue_ent *qe, int ringing)
}
/* leave the queue if no agents, if enabled */
if (!(qe->parent->members) && qe->parent->leavewhenempty) {
if (has_no_members(qe->parent) && qe->parent->leavewhenempty) {
leave_queue(qe);
break;
}
@ -1163,6 +1212,7 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
tmp->member = cur; /* Never directly dereference! Could change on reload */
strncpy(tmp->tech, cur->tech, sizeof(tmp->tech)-1);
strncpy(tmp->numsubst, cur->loc, sizeof(tmp->numsubst)-1);
tmp->oldstatus = cur->status;
tmp->lastcall = cur->lastcall;
/* If we're dialing by extension, look at the extension to know what to dial */
if ((newnum = strstr(tmp->numsubst, "BYEXTENSION"))) {
@ -1728,6 +1778,7 @@ check_turns:
}
}
if (!res) {
int makeannouncement = 0;
for (;;) {
/* This is the wait loop for the head caller*/
/* To exit, they may get their call answered; */
@ -1740,15 +1791,12 @@ check_turns:
break;
}
/* leave the queue if no agents, if enabled */
if (!((qe.parent)->members) && (qe.parent)->leavewhenempty) {
leave_queue(&qe);
break;
if (makeannouncement) {
/* Make a position announcement, if enabled */
if (qe.parent->announcefrequency && !ringing)
say_position(&qe);
}
/* Make a position announcement, if enabled */
if (qe.parent->announcefrequency && !ringing)
say_position(&qe);
makeannouncement = 1;
/* Try calling all queue members for 'timeout' seconds */
res = try_calling(&qe, options, announceoverride, url, &go_on);
@ -1761,6 +1809,12 @@ check_turns:
break;
}
/* leave the queue if no agents, if enabled */
if (has_no_members(qe.parent) && (qe.parent->leavewhenempty)) {
res = 0;
break;
}
/* Leave if we have exceeded our queuetimeout */
if (qe.queuetimeout && ( (time(NULL) - qe.start) >= qe.queuetimeout) ) {
res = 0;
@ -2037,6 +2091,30 @@ static void reload_queues(void)
ast_mutex_unlock(&qlock);
}
static char *status2str(int status, char *buf, int buflen)
{
switch(status) {
case AST_CAUSE_BUSY:
strncpy(buf, "busy", buflen - 1);
break;
case AST_CAUSE_CONGESTION:
strncpy(buf, "congestion", buflen - 1);
break;
case AST_CAUSE_FAILURE:
strncpy(buf, "failure", buflen - 1);
break;
case AST_CAUSE_UNREGISTERED:
strncpy(buf, "unregistered", buflen - 1);
break;
case AST_CAUSE_NOSUCHDRIVER:
strncpy(buf, "nosuchdriver", buflen - 1);
break;
default:
snprintf(buf, buflen, "unknown status %d", status);
}
return buf;
}
static int __queues_show(int fd, int argc, char **argv, int queue_show)
{
struct ast_call_queue *q;
@ -2046,6 +2124,7 @@ static int __queues_show(int fd, int argc, char **argv, int queue_show)
time_t now;
char max[80] = "";
char calls[80] = "";
char tmpbuf[80] = "";
float sl = 0;
time(&now);
@ -2092,6 +2171,8 @@ static int __queues_show(int fd, int argc, char **argv, int queue_show)
max[0] = '\0';
if (mem->dynamic)
strncat(max, " (dynamic)", sizeof(max) - strlen(max) - 1);
if (mem->status)
snprintf(max + strlen(max), sizeof(max) - strlen(max), " (%s)", status2str(mem->status, tmpbuf, sizeof(tmpbuf)));
if (mem->calls) {
snprintf(calls, sizeof(calls), " has taken %d calls (last was %ld secs ago)",
mem->calls, (long)(time(NULL) - mem->lastcall));

@ -65,7 +65,7 @@ struct chanlist {
char type[80];
char description[80];
int capabilities;
struct ast_channel * (*requester)(const char *type, int format, void *data);
struct ast_channel * (*requester)(const char *type, int format, void *data, int *cause);
int (*devicestate)(void *data);
struct chanlist *next;
} *backends = NULL;
@ -154,13 +154,13 @@ void ast_channel_setwhentohangup(struct ast_channel *chan, time_t offset)
}
int ast_channel_register(const char *type, const char *description, int capabilities,
struct ast_channel *(*requester)(const char *type, int format, void *data))
struct ast_channel *(*requester)(const char *type, int format, void *data, int *cause))
{
return ast_channel_register_ex(type, description, capabilities, requester, NULL);
}
int ast_channel_register_ex(const char *type, const char *description, int capabilities,
struct ast_channel *(*requester)(const char *type, int format, void *data),
struct ast_channel *(*requester)(const char *type, int format, void *data, int *cause),
int (*devicestate)(void *data))
{
struct chanlist *chan, *last=NULL;
@ -1751,11 +1751,12 @@ int ast_set_read_format(struct ast_channel *chan, int fmts)
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 cause = 0;
struct ast_channel *chan;
struct ast_frame *f;
int res = 0;
char *variable;
chan = ast_request(type, format, data);
chan = ast_request(type, format, data, &cause);
if (chan) {
if (oh) {
char *tmp, *var;
@ -1815,9 +1816,18 @@ struct ast_channel *__ast_request_and_dial(const char *type, int format, void *d
ast_frfree(f);
}
} else
ast_log(LOG_NOTICE, "Unable to request channel %s/%s\n", type, (char *)data);
} 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) {
@ -1861,13 +1871,17 @@ struct ast_channel *ast_request_and_dial(const char *type, int format, void *dat
return __ast_request_and_dial(type, format, data, timeout, outstate, cidnum, cidname, NULL);
}
struct ast_channel *ast_request(const char *type, int format, void *data)
struct ast_channel *ast_request(const char *type, int format, void *data, int *cause)
{
struct chanlist *chan;
struct ast_channel *c = NULL;
int capabilities;
int fmt;
int res;
int foo;
if (!cause)
cause = &foo;
*cause = AST_CAUSE_NOTDEFINED;
if (ast_mutex_lock(&chlock)) {
ast_log(LOG_WARNING, "Unable to lock channel list\n");
return NULL;
@ -1885,7 +1899,7 @@ struct ast_channel *ast_request(const char *type, int format, void *data)
}
ast_mutex_unlock(&chlock);
if (chan->requester)
c = chan->requester(type, capabilities, data);
c = chan->requester(type, capabilities, data, cause);
if (c) {
if (c->_state == AST_STATE_DOWN) {
manager_event(EVENT_FLAG_CALL, "Newchannel",
@ -1901,8 +1915,10 @@ struct ast_channel *ast_request(const char *type, int format, void *data)
}
chan = chan->next;
}
if (!chan)
if (!chan) {
ast_log(LOG_WARNING, "No channel type registered for '%s'\n", type);
*cause = AST_CAUSE_NOSUCHDRIVER;
}
ast_mutex_unlock(&chlock);
return c;
}

@ -34,6 +34,7 @@
#include <asterisk/manager.h>
#include <asterisk/features.h>
#include <asterisk/utils.h>
#include <asterisk/causes.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
@ -1051,7 +1052,7 @@ static int check_beep(struct agent_pvt *newlyavailable, int needlock)
return res;
}
static struct ast_channel *agent_request(const char *type, int format, void *data)
static struct ast_channel *agent_request(const char *type, int format, void *data, int *cause)
{
struct agent_pvt *p;
struct ast_channel *chan = NULL;
@ -1113,7 +1114,7 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
chan = agent_new(p, AST_STATE_DOWN);
} else if (!p->owner && !ast_strlen_zero(p->loginchan)) {
/* Adjustable agent */
p->chan = ast_request("Local", format, p->loginchan);
p->chan = ast_request("Local", format, p->loginchan, cause);
if (p->chan)
chan = agent_new(p, AST_STATE_DOWN);
}
@ -1142,6 +1143,10 @@ static struct ast_channel *agent_request(const char *type, int format, void *dat
} else
ast_log(LOG_DEBUG, "Not creating place holder for '%s' since nobody logged in\n", s);
}
if (hasagent)
*cause = AST_CAUSE_BUSY;
else
*cause = AST_CAUSE_UNREGISTERED;
ast_mutex_unlock(&agentlock);
return chan;
}

@ -19,6 +19,7 @@
#include <asterisk/config.h>
#include <asterisk/cli.h>
#include <asterisk/utils.h>
#include <asterisk/causes.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@ -753,7 +754,7 @@ static struct ast_channel *alsa_new(struct chan_alsa_pvt *p, int state)
return tmp;
}
static struct ast_channel *alsa_request(const char *type, int format, void *data)
static struct ast_channel *alsa_request(const char *type, int format, void *data, int *cause)
{
int oldformat = format;
struct ast_channel *tmp=NULL;
@ -765,6 +766,7 @@ static struct ast_channel *alsa_request(const char *type, int format, void *data
ast_mutex_lock(&alsalock);
if (alsa.owner) {
ast_log(LOG_NOTICE, "Already have a call on the ALSA channel\n");
*cause = AST_CAUSE_BUSY;
} else {
tmp= alsa_new(&alsa, AST_STATE_DOWN);
if (!tmp) {

@ -66,6 +66,7 @@ extern "C" {
#include <asterisk/callerid.h>
#include <asterisk/cli.h>
#include <asterisk/dsp.h>
#include <asterisk/causes.h>
#ifdef __cplusplus
}
#endif
@ -948,7 +949,7 @@ static int create_addr(struct oh323_pvt *pvt, char *opeer)
return 0;
}
}
static struct ast_channel *oh323_request(const char *type, int format, void *data)
static struct ast_channel *oh323_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct oh323_pvt *pvt;

@ -35,6 +35,7 @@
#include <asterisk/musiconhold.h>
#include <asterisk/features.h>
#include <asterisk/utils.h>
#include <asterisk/causes.h>
#include <sys/mman.h>
#include <arpa/inet.h>
#include <dirent.h>
@ -6208,7 +6209,7 @@ static void free_context(struct iax2_context *con)
}
}
static struct ast_channel *iax2_request(const char *type, int format, void *data)
static struct ast_channel *iax2_request(const char *type, int format, void *data, int *cause)
{
int callno;
int res;
@ -6248,6 +6249,7 @@ static struct ast_channel *iax2_request(const char *type, int format, void *data
/* Populate our address from the given */
if (create_addr(&sin, &capability, &sendani, &maxtime, hostname, NULL, &trunk, &notransfer, &usejitterbuf, NULL, 0, NULL, 0, &found, NULL)) {
*cause = AST_CAUSE_UNREGISTERED;
return NULL;
}
if (portno) {
@ -6256,6 +6258,7 @@ static struct ast_channel *iax2_request(const char *type, int format, void *data
callno = find_callno(0, 0, &sin, NEW_FORCE, 1);
if (callno < 1) {
ast_log(LOG_WARNING, "Unable to create call\n");
*cause = AST_CAUSE_CONGESTION;
return NULL;
}
ast_mutex_lock(&iaxsl[callno]);

@ -462,7 +462,7 @@ static struct ast_channel *local_new(struct local_pvt *p, int state)
}
static struct ast_channel *local_request(const char *type, int format, void *data)
static struct ast_channel *local_request(const char *type, int format, void *data, int *cause)
{
struct local_pvt *p;
struct ast_channel *chan = NULL;

@ -72,6 +72,7 @@
#include <asterisk/app.h>
#include <asterisk/musiconhold.h>
#include <asterisk/utils.h>
#include <asterisk/causes.h>
#include <sys/socket.h>
#include <sys/ioctl.h>
#include <net/if.h>
@ -3342,7 +3343,7 @@ static int restart_monitor(void)
return 0;
}
static struct ast_channel *mgcp_request(const char *type, int format, void *data)
static struct ast_channel *mgcp_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct mgcp_subchannel *sub;
@ -3364,6 +3365,7 @@ static struct ast_channel *mgcp_request(const char *type, int format, void *data
sub = find_subchannel(tmp, 0, NULL);
if (!sub) {
ast_log(LOG_WARNING, "Unable to find MGCP endpoint '%s'\n", tmp);
*cause = AST_CAUSE_UNREGISTERED;
return NULL;
}
@ -3383,6 +3385,7 @@ static struct ast_channel *mgcp_request(const char *type, int format, void *data
transmit_notify_request(sub,"L/vmwi(-)");
}
}
*cause = AST_CAUSE_BUSY;
return NULL;
}
tmpc = mgcp_new(sub->owner ? sub->next : sub, AST_STATE_DOWN);

@ -773,7 +773,7 @@ static struct ast_modem_pvt *mkif(char *iface)
return tmp;
}
static struct ast_channel *modem_request(const char *type, int format, void *data)
static struct ast_channel *modem_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct ast_modem_pvt *p;

@ -232,7 +232,7 @@ static struct ast_channel *nbs_new(struct nbs_pvt *i, int state)
}
static struct ast_channel *nbs_request(const char *type, int format, void *data)
static struct ast_channel *nbs_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct nbs_pvt *p;

@ -26,6 +26,7 @@
#include <asterisk/config.h>
#include <asterisk/cli.h>
#include <asterisk/utils.h>
#include <asterisk/causes.h>
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
@ -745,7 +746,7 @@ static struct ast_channel *oss_new(struct chan_oss_pvt *p, int state)
return tmp;
}
static struct ast_channel *oss_request(const char *type, int format, void *data)
static struct ast_channel *oss_request(const char *type, int format, void *data, int *cause)
{
int oldformat = format;
struct ast_channel *tmp;
@ -756,6 +757,7 @@ static struct ast_channel *oss_request(const char *type, int format, void *data)
}
if (oss.owner) {
ast_log(LOG_NOTICE, "Already have a call on the OSS channel\n");
*cause = AST_CAUSE_BUSY;
return NULL;
}
tmp= oss_new(&oss, AST_STATE_DOWN);

@ -23,6 +23,7 @@
#include <asterisk/options.h>
#include <asterisk/utils.h>
#include <asterisk/callerid.h>
#include <asterisk/causes.h>
#include <sys/socket.h>
#include <sys/time.h>
#include <errno.h>
@ -1023,7 +1024,7 @@ static struct phone_pvt *mkif(char *iface, int mode, int txgain, int rxgain)
return tmp;
}
static struct ast_channel *phone_request(const char *type, int format, void *data)
static struct ast_channel *phone_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct phone_pvt *p;
@ -1047,7 +1048,8 @@ static struct ast_channel *phone_request(const char *type, int format, void *dat
if (!p->owner) {
tmp = phone_new(p, AST_STATE_DOWN, p->context);
break;
}
} else
*cause = AST_CAUSE_BUSY;
}
p = p->next;
}

@ -7946,7 +7946,7 @@ static int sip_devicestate(void *data)
/*--- sip_request: PBX interface function -build SIP pvt structure ---*/
/* SIP calls initiated by the PBX arrive here */
static struct ast_channel *sip_request(const char *type, int format, void *data)
static struct ast_channel *sip_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct sip_pvt *p;
@ -7990,6 +7990,7 @@ static struct ast_channel *sip_request(const char *type, int format, void *data)
p->capability = global_capability;
if (create_addr(p, host)) {
*cause = AST_CAUSE_UNREGISTERED;
sip_destroy(p);
return NULL;
}

@ -2489,7 +2489,7 @@ static int restart_monitor(void)
return 0;
}
static struct ast_channel *skinny_request(const char *type, int format, void *data)
static struct ast_channel *skinny_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct skinny_subchannel *sub;

@ -2115,7 +2115,7 @@ static struct ast_channel *vpb_new(struct vpb_pvt *me, int state, char *context)
return tmp;
}
static struct ast_channel *vpb_request(const char *type, int format, void *data)
static struct ast_channel *vpb_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
struct vpb_pvt *p;

@ -6732,7 +6732,7 @@ static int pri_find_empty_chan(struct zt_pri *pri, int backwards)
}
#endif
static struct ast_channel *zt_request(const char *type, int format, void *data)
static struct ast_channel *zt_request(const char *type, int format, void *data, int *cause)
{
int oldformat;
int groupmatch = 0;
@ -6945,21 +6945,8 @@ next:
}
ast_mutex_unlock(lock);
restart_monitor();
if (!tmp) {
if (busy && (channelmatch != CHAN_PSEUDO)) {
tmp = zt_request("Zap", format, "pseudo");
if (tmp) {
char newname[80];
ast_mutex_lock(&tmp->lock);
snprintf(newname, sizeof(newname), "Zap/%s-busy-%d", (char *)data, rand());
ast_change_name(tmp, newname);
ast_setstate(tmp, AST_STATE_BUSY);
ast_mutex_unlock(&tmp->lock);
}
} else if (busy) {
ast_log(LOG_WARNING, "Whoa, the pseudo was busy somehow!\n");
}
}
if (callwait || (!tmp && busy))
*cause = AST_CAUSE_BUSY;
return tmp;
}
@ -7200,6 +7187,7 @@ static void *pri_dchannel(void *vpri)
time_t t;
int i, which=-1;
int numdchans;
int cause=0;
struct zt_pvt *crv;
pthread_t threadid;
pthread_attr_t attr;
@ -7277,7 +7265,7 @@ static void *pri_dchannel(void *vpri)
(tv.tv_usec - lastidle.tv_usec) / 1000) > 1000) {
/* Don't create a new idle call more than once per second */
snprintf(idlen, sizeof(idlen), "%d/%s", pri->pvts[nextidle]->channel, pri->idledial);
idle = zt_request("Zap", AST_FORMAT_ULAW, idlen);
idle = zt_request("Zap", AST_FORMAT_ULAW, idlen, &cause);
if (idle) {
pri->pvts[nextidle]->isidlecall = 1;
if (ast_pthread_create(&p, NULL, do_idle_thread, idle)) {

@ -66,6 +66,8 @@
#define AST_CAUSE_NORMAL AST_CAUSE_NORMAL_CLEARING
#define AST_CAUSE_NOANSWER AST_CAUSE_NO_ANSWER
#define AST_CAUSE_CONGESTION AST_CAUSE_NORMAL_CIRCUIT_CONGESTION
#define AST_CAUSE_UNREGISTERED AST_CAUSE_NO_ROUTE_DESTINATION
#define AST_CAUSE_NOTDEFINED 0
#define AST_CAUSE_NOSUCHDRIVER AST_CAUSE_CHAN_NOT_IMPLEMENTED
#endif

@ -377,7 +377,7 @@ struct outgoing_helper {
* by the low level module
* Returns an ast_channel on success, NULL on failure.
*/
struct ast_channel *ast_request(const char *type, int format, void *data);
struct ast_channel *ast_request(const char *type, int format, void *data, int *status);
//! Search the Channels by Name
/*!
@ -427,11 +427,11 @@ struct ast_channel *__ast_request_and_dial(const char *type, int format, void *d
* Returns 0 on success, -1 on failure.
*/
int ast_channel_register(const char *type, const char *description, int capabilities,
struct ast_channel* (*requester)(const char *type, int format, void *data));
struct ast_channel* (*requester)(const char *type, int format, void *data, int *cause));
/* Same like the upper function but with support for devicestate */
int ast_channel_register_ex(const char *type, const char *description, int capabilities,
struct ast_channel *(*requester)(const char *type, int format, void *data),
struct ast_channel *(*requester)(const char *type, int format, void *data, int *cause),
int (*devicestate)(void *data));
//! Unregister a channel class

Loading…
Cancel
Save