|
|
@ -160,8 +160,7 @@ static int queue_persistent_members = 0;
|
|
|
|
|
|
|
|
|
|
|
|
struct localuser {
|
|
|
|
struct localuser {
|
|
|
|
struct ast_channel *chan;
|
|
|
|
struct ast_channel *chan;
|
|
|
|
char numsubst[256];
|
|
|
|
char interface[256];
|
|
|
|
char tech[40];
|
|
|
|
|
|
|
|
int stillgoing;
|
|
|
|
int stillgoing;
|
|
|
|
int metric;
|
|
|
|
int metric;
|
|
|
|
int oldstatus;
|
|
|
|
int oldstatus;
|
|
|
@ -197,8 +196,7 @@ struct queue_ent {
|
|
|
|
};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
struct member {
|
|
|
|
struct member {
|
|
|
|
char tech[80]; /* Technology */
|
|
|
|
char interface[80]; /* Technology/Location */
|
|
|
|
char loc[256]; /* Location */
|
|
|
|
|
|
|
|
int penalty; /* Are we a last resort? */
|
|
|
|
int penalty; /* Are we a last resort? */
|
|
|
|
int calls; /* Number of calls serviced by this member */
|
|
|
|
int calls; /* Number of calls serviced by this member */
|
|
|
|
int dynamic; /* Are we dynamically added? */
|
|
|
|
int dynamic; /* Are we dynamically added? */
|
|
|
@ -348,18 +346,18 @@ static void *changethread(void *data)
|
|
|
|
ast_mutex_lock(&q->lock);
|
|
|
|
ast_mutex_lock(&q->lock);
|
|
|
|
cur = q->members;
|
|
|
|
cur = q->members;
|
|
|
|
while(cur) {
|
|
|
|
while(cur) {
|
|
|
|
if (!strcasecmp(sc->dev, cur->tech) && !strcmp(loc, cur->loc)) {
|
|
|
|
if (!strcasecmp(sc->dev, cur->interface)) {
|
|
|
|
if (cur->status != sc->state) {
|
|
|
|
if (cur->status != sc->state) {
|
|
|
|
cur->status = sc->state;
|
|
|
|
cur->status = sc->state;
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Location: %s/%s\r\n"
|
|
|
|
"Location: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
|
"LastCall: %ld\r\n"
|
|
|
|
"LastCall: %ld\r\n"
|
|
|
|
"Status: %d\r\n",
|
|
|
|
"Status: %d\r\n",
|
|
|
|
q->name, cur->tech, cur->loc, cur->dynamic ? "dynamic" : "static",
|
|
|
|
q->name, cur->interface, cur->dynamic ? "dynamic" : "static",
|
|
|
|
cur->penalty, cur->calls, cur->lastcall, cur->status);
|
|
|
|
cur->penalty, cur->calls, cur->lastcall, cur->status);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -677,13 +675,13 @@ static int update_status(struct ast_call_queue *q, struct member *member, int st
|
|
|
|
cur->status = status;
|
|
|
|
cur->status = status;
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Location: %s/%s\r\n"
|
|
|
|
"Location: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
|
"LastCall: %ld\r\n"
|
|
|
|
"LastCall: %ld\r\n"
|
|
|
|
"Status: %d\r\n",
|
|
|
|
"Status: %d\r\n",
|
|
|
|
q->name, cur->tech, cur->loc, cur->dynamic ? "dynamic" : "static",
|
|
|
|
q->name, cur->interface, cur->dynamic ? "dynamic" : "static",
|
|
|
|
cur->penalty, cur->calls, cur->lastcall, cur->status);
|
|
|
|
cur->penalty, cur->calls, cur->lastcall, cur->status);
|
|
|
|
break;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -711,15 +709,25 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
int res;
|
|
|
|
int res;
|
|
|
|
int status;
|
|
|
|
int status;
|
|
|
|
|
|
|
|
char tech[256];
|
|
|
|
|
|
|
|
char *location;
|
|
|
|
|
|
|
|
|
|
|
|
if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
|
|
|
|
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);
|
|
|
|
ast_log(LOG_DEBUG, "Wrapuptime not yet expired for %s\n", tmp->interface);
|
|
|
|
if (qe->chan->cdr)
|
|
|
|
if (qe->chan->cdr)
|
|
|
|
ast_cdr_busy(qe->chan->cdr);
|
|
|
|
ast_cdr_busy(qe->chan->cdr);
|
|
|
|
tmp->stillgoing = 0;
|
|
|
|
tmp->stillgoing = 0;
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
strncpy(tech, tmp->interface, sizeof(tech) - 1);
|
|
|
|
|
|
|
|
if ((location = strchr(tech, '/')))
|
|
|
|
|
|
|
|
*location++ = '\0';
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
location = "";
|
|
|
|
|
|
|
|
|
|
|
|
/* Request the peer */
|
|
|
|
/* Request the peer */
|
|
|
|
tmp->chan = ast_request(tmp->tech, qe->chan->nativeformats, tmp->numsubst, &status);
|
|
|
|
tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
|
|
|
|
if (!tmp->chan) { /* If we can't, just go on to the next call */
|
|
|
|
if (!tmp->chan) { /* If we can't, just go on to the next call */
|
|
|
|
#if 0
|
|
|
|
#if 0
|
|
|
|
ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", cur->tech);
|
|
|
|
ast_log(LOG_NOTICE, "Unable to create channel of type '%s'\n", cur->tech);
|
|
|
@ -753,13 +761,13 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
|
|
|
|
/* Presense of ADSI CPE on outgoing channel follows ours */
|
|
|
|
/* Presense of ADSI CPE on outgoing channel follows ours */
|
|
|
|
tmp->chan->adsicpe = qe->chan->adsicpe;
|
|
|
|
tmp->chan->adsicpe = qe->chan->adsicpe;
|
|
|
|
/* Place the call, but don't wait on the answer */
|
|
|
|
/* Place the call, but don't wait on the answer */
|
|
|
|
res = ast_call(tmp->chan, tmp->numsubst, 0);
|
|
|
|
res = ast_call(tmp->chan, location, 0);
|
|
|
|
if (res) {
|
|
|
|
if (res) {
|
|
|
|
/* Again, keep going even if there's an error */
|
|
|
|
/* Again, keep going even if there's an error */
|
|
|
|
if (option_debug)
|
|
|
|
if (option_debug)
|
|
|
|
ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
|
|
|
|
ast_log(LOG_DEBUG, "ast call on peer returned %d\n", res);
|
|
|
|
else if (option_verbose > 2)
|
|
|
|
else if (option_verbose > 2)
|
|
|
|
ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->numsubst);
|
|
|
|
ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->interface);
|
|
|
|
ast_hangup(tmp->chan);
|
|
|
|
ast_hangup(tmp->chan);
|
|
|
|
tmp->chan = NULL;
|
|
|
|
tmp->chan = NULL;
|
|
|
|
tmp->stillgoing = 0;
|
|
|
|
tmp->stillgoing = 0;
|
|
|
@ -767,20 +775,20 @@ static int ring_entry(struct queue_ent *qe, struct localuser *tmp)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
if (qe->parent->eventwhencalled) {
|
|
|
|
if (qe->parent->eventwhencalled) {
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "AgentCalled",
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "AgentCalled",
|
|
|
|
"AgentCalled: %s/%s\r\n"
|
|
|
|
"AgentCalled: %s\r\n"
|
|
|
|
"ChannelCalling: %s\r\n"
|
|
|
|
"ChannelCalling: %s\r\n"
|
|
|
|
"CallerID: %s\r\n"
|
|
|
|
"CallerID: %s\r\n"
|
|
|
|
"CallerIDName: %s\r\n"
|
|
|
|
"CallerIDName: %s\r\n"
|
|
|
|
"Context: %s\r\n"
|
|
|
|
"Context: %s\r\n"
|
|
|
|
"Extension: %s\r\n"
|
|
|
|
"Extension: %s\r\n"
|
|
|
|
"Priority: %d\r\n",
|
|
|
|
"Priority: %d\r\n",
|
|
|
|
tmp->tech, tmp->numsubst, qe->chan->name,
|
|
|
|
tmp->interface, qe->chan->name,
|
|
|
|
tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
|
|
|
|
tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
|
|
|
|
tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
|
|
|
|
tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
|
|
|
|
qe->chan->context, qe->chan->exten, qe->chan->priority);
|
|
|
|
qe->chan->context, qe->chan->exten, qe->chan->priority);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (option_verbose > 2)
|
|
|
|
if (option_verbose > 2)
|
|
|
|
ast_verbose(VERBOSE_PREFIX_3 "Called %s/%s\n", tmp->tech, tmp->numsubst);
|
|
|
|
ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -808,7 +816,7 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
|
|
|
|
cur = outgoing;
|
|
|
|
cur = outgoing;
|
|
|
|
while(cur) {
|
|
|
|
while(cur) {
|
|
|
|
if (cur->stillgoing && !cur->chan && (cur->metric == bestmetric)) {
|
|
|
|
if (cur->stillgoing && !cur->chan && (cur->metric == bestmetric)) {
|
|
|
|
ast_log(LOG_DEBUG, "(Parallel) Trying '%s/%s' with metric %d\n", cur->tech, cur->numsubst, cur->metric);
|
|
|
|
ast_log(LOG_DEBUG, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
|
|
|
|
ring_entry(qe, cur);
|
|
|
|
ring_entry(qe, cur);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
cur = cur->next;
|
|
|
|
cur = cur->next;
|
|
|
@ -816,8 +824,7 @@ static int ring_one(struct queue_ent *qe, struct localuser *outgoing)
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
/* Ring just the best channel */
|
|
|
|
/* Ring just the best channel */
|
|
|
|
if (option_debug)
|
|
|
|
if (option_debug)
|
|
|
|
ast_log(LOG_DEBUG, "Trying '%s/%s' with metric %d\n",
|
|
|
|
ast_log(LOG_DEBUG, "Trying '%s' with metric %d\n", best->interface, best->metric);
|
|
|
|
best->tech, best->numsubst, best->metric);
|
|
|
|
|
|
|
|
ring_entry(qe, best);
|
|
|
|
ring_entry(qe, best);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
@ -848,7 +855,7 @@ static int store_next(struct queue_ent *qe, struct localuser *outgoing)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (best) {
|
|
|
|
if (best) {
|
|
|
|
/* Ring just the best channel */
|
|
|
|
/* Ring just the best channel */
|
|
|
|
ast_log(LOG_DEBUG, "Next is '%s/%s' with metric %d\n", best->tech, best->numsubst, best->metric);
|
|
|
|
ast_log(LOG_DEBUG, "Next is '%s' with metric %d\n", best->interface, best->metric);
|
|
|
|
qe->parent->rrpos = best->metric % 1000;
|
|
|
|
qe->parent->rrpos = best->metric % 1000;
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
/* Just increment rrpos */
|
|
|
|
/* Just increment rrpos */
|
|
|
@ -1320,16 +1327,16 @@ static int try_calling(struct queue_ent *qe, char *options, char *announceoverri
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tmp->member = cur; /* Never directly dereference! Could change on reload */
|
|
|
|
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->oldstatus = cur->status;
|
|
|
|
tmp->lastcall = cur->lastcall;
|
|
|
|
tmp->lastcall = cur->lastcall;
|
|
|
|
|
|
|
|
strncpy(tmp->interface, cur->interface, sizeof(tmp->interface)-1);
|
|
|
|
/* If we're dialing by extension, look at the extension to know what to dial */
|
|
|
|
/* If we're dialing by extension, look at the extension to know what to dial */
|
|
|
|
if ((newnum = strstr(tmp->numsubst, "BYEXTENSION"))) {
|
|
|
|
if ((newnum = strstr(tmp->interface, "/BYEXTENSION"))) {
|
|
|
|
strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit)-1);
|
|
|
|
newnum++;
|
|
|
|
snprintf(newnum, sizeof(tmp->numsubst) - (newnum - tmp->numsubst), "%s%s", qe->chan->exten,restofit);
|
|
|
|
strncpy(restofit, newnum + strlen("BYEXTENSION"), sizeof(restofit) - 1);
|
|
|
|
|
|
|
|
snprintf(newnum, sizeof(tmp->interface) - (newnum - tmp->interface), "%s%s", qe->chan->exten, restofit);
|
|
|
|
if (option_debug)
|
|
|
|
if (option_debug)
|
|
|
|
ast_log(LOG_DEBUG, "Dialing by extension %s\n", tmp->numsubst);
|
|
|
|
ast_log(LOG_DEBUG, "Dialing by extension %s\n", tmp->interface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
/* Special case: If we ring everyone, go ahead and ring them, otherwise
|
|
|
|
/* Special case: If we ring everyone, go ahead and ring them, otherwise
|
|
|
|
just calculate their metric for the appropriate strategy */
|
|
|
|
just calculate their metric for the appropriate strategy */
|
|
|
@ -1504,36 +1511,22 @@ static int wait_a_bit(struct queue_ent *qe)
|
|
|
|
|
|
|
|
|
|
|
|
/* [PHM 06/26/03] */
|
|
|
|
/* [PHM 06/26/03] */
|
|
|
|
|
|
|
|
|
|
|
|
static struct member * interface_exists( struct ast_call_queue * q, char * interface )
|
|
|
|
static struct member * interface_exists(struct ast_call_queue *q, char *interface)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct member * ret = NULL ;
|
|
|
|
|
|
|
|
struct member *mem;
|
|
|
|
struct member *mem;
|
|
|
|
char buf[500] ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if( q != NULL )
|
|
|
|
|
|
|
|
{
|
|
|
|
|
|
|
|
mem = q->members ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
while( mem != NULL ) {
|
|
|
|
if (q)
|
|
|
|
snprintf( buf, sizeof(buf), "%s/%s", mem->tech, mem->loc);
|
|
|
|
for (mem = q->members; mem; mem = mem->next)
|
|
|
|
|
|
|
|
if (!strcmp(interface, mem->interface))
|
|
|
|
if( strcmp( buf, interface ) == 0 ) {
|
|
|
|
return mem;
|
|
|
|
ret = mem ;
|
|
|
|
|
|
|
|
break ;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
else
|
|
|
|
|
|
|
|
mem = mem->next ;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
return( ret ) ;
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static struct member * create_queue_node( char * interface, int penalty )
|
|
|
|
static struct member *create_queue_node(char *interface, int penalty)
|
|
|
|
{
|
|
|
|
{
|
|
|
|
struct member * cur ;
|
|
|
|
struct member *cur;
|
|
|
|
char * tmp ;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/* Add a new member */
|
|
|
|
/* Add a new member */
|
|
|
|
|
|
|
|
|
|
|
@ -1542,18 +1535,13 @@ static struct member * create_queue_node( char * interface, int penalty )
|
|
|
|
if (cur) {
|
|
|
|
if (cur) {
|
|
|
|
memset(cur, 0, sizeof(struct member));
|
|
|
|
memset(cur, 0, sizeof(struct member));
|
|
|
|
cur->penalty = penalty;
|
|
|
|
cur->penalty = penalty;
|
|
|
|
strncpy(cur->tech, interface, sizeof(cur->tech) - 1);
|
|
|
|
strncpy(cur->interface, interface, sizeof(cur->interface) - 1);
|
|
|
|
if ((tmp = strchr(cur->tech, '/')))
|
|
|
|
if (!strchr(cur->interface, '/'))
|
|
|
|
*tmp = '\0';
|
|
|
|
|
|
|
|
if ((tmp = strchr(interface, '/'))) {
|
|
|
|
|
|
|
|
tmp++;
|
|
|
|
|
|
|
|
strncpy(cur->loc, tmp, sizeof(cur->loc) - 1);
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
|
|
|
|
ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
|
|
|
|
cur->status = ast_device_state(interface);
|
|
|
|
cur->status = ast_device_state(interface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
return( cur ) ;
|
|
|
|
return cur;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/* Dump all members in a specific queue to the databse
|
|
|
|
/* Dump all members in a specific queue to the databse
|
|
|
@ -1575,7 +1563,7 @@ static void dump_queue_members(struct ast_call_queue *pm_queue)
|
|
|
|
while (cur_member) {
|
|
|
|
while (cur_member) {
|
|
|
|
if (cur_member->dynamic) {
|
|
|
|
if (cur_member->dynamic) {
|
|
|
|
value_len = strlen(value);
|
|
|
|
value_len = strlen(value);
|
|
|
|
res = snprintf(value+value_len, sizeof(value)-value_len, "%s/%s;%d;", cur_member->tech, cur_member->loc, cur_member->penalty);
|
|
|
|
res = snprintf(value+value_len, sizeof(value)-value_len, "%s;%d;", cur_member->interface, cur_member->penalty);
|
|
|
|
if (res != strlen(value + value_len)) {
|
|
|
|
if (res != strlen(value + value_len)) {
|
|
|
|
ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
|
|
|
|
ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
|
|
|
|
break;
|
|
|
|
break;
|
|
|
@ -1621,8 +1609,8 @@ static int remove_from_queue(char *queuename, char *interface)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Location: %s/%s\r\n",
|
|
|
|
"Location: %s\r\n",
|
|
|
|
q->name, last_member->tech, last_member->loc);
|
|
|
|
q->name, last_member->interface);
|
|
|
|
free(last_member);
|
|
|
|
free(last_member);
|
|
|
|
|
|
|
|
|
|
|
|
if (queue_persistent_members)
|
|
|
|
if (queue_persistent_members)
|
|
|
@ -1660,13 +1648,13 @@ static int add_to_queue(char *queuename, char *interface, int penalty)
|
|
|
|
q->members = new_member;
|
|
|
|
q->members = new_member;
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
|
|
|
|
manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Location: %s/%s\r\n"
|
|
|
|
"Location: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
|
"LastCall: %ld\r\n"
|
|
|
|
"LastCall: %ld\r\n"
|
|
|
|
"Status: %d\r\n",
|
|
|
|
"Status: %d\r\n",
|
|
|
|
q->name, new_member->tech, new_member->loc, new_member->dynamic ? "dynamic" : "static",
|
|
|
|
q->name, new_member->interface, new_member->dynamic ? "dynamic" : "static",
|
|
|
|
new_member->penalty, new_member->calls, new_member->lastcall, new_member->status);
|
|
|
|
new_member->penalty, new_member->calls, new_member->lastcall, new_member->status);
|
|
|
|
|
|
|
|
|
|
|
|
if (queue_persistent_members)
|
|
|
|
if (queue_persistent_members)
|
|
|
@ -2203,22 +2191,15 @@ static void reload_queues(void)
|
|
|
|
cur = malloc(sizeof(struct member));
|
|
|
|
cur = malloc(sizeof(struct member));
|
|
|
|
if (cur) {
|
|
|
|
if (cur) {
|
|
|
|
memset(cur, 0, sizeof(struct member));
|
|
|
|
memset(cur, 0, sizeof(struct member));
|
|
|
|
strncpy(cur->tech, var->value, sizeof(cur->tech) - 1);
|
|
|
|
strncpy(cur->interface, var->value, sizeof(cur->interface) - 1);
|
|
|
|
if ((tmp = strchr(cur->tech, ','))) {
|
|
|
|
if ((tmp = strchr(cur->interface, ','))) {
|
|
|
|
*tmp = '\0';
|
|
|
|
*tmp = '\0';
|
|
|
|
tmp++;
|
|
|
|
tmp++;
|
|
|
|
cur->penalty = atoi(tmp);
|
|
|
|
cur->penalty = atoi(tmp);
|
|
|
|
if (cur->penalty < 0)
|
|
|
|
if (cur->penalty < 0)
|
|
|
|
cur->penalty = 0;
|
|
|
|
cur->penalty = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if ((tmp = strchr(cur->tech, '/')))
|
|
|
|
if (!strchr(cur->interface, '/'))
|
|
|
|
*tmp = '\0';
|
|
|
|
|
|
|
|
if ((tmp = strchr(var->value, '/'))) {
|
|
|
|
|
|
|
|
tmp++;
|
|
|
|
|
|
|
|
strncpy(cur->loc, tmp, sizeof(cur->loc) - 1);
|
|
|
|
|
|
|
|
if ((tmp = strchr(cur->loc, ',')))
|
|
|
|
|
|
|
|
*tmp = '\0';
|
|
|
|
|
|
|
|
} else
|
|
|
|
|
|
|
|
ast_log(LOG_WARNING, "No location at line %d of queue.conf\n", var->lineno);
|
|
|
|
ast_log(LOG_WARNING, "No location at line %d of queue.conf\n", var->lineno);
|
|
|
|
if (prev)
|
|
|
|
if (prev)
|
|
|
|
prev->next = cur;
|
|
|
|
prev->next = cur;
|
|
|
@ -2331,13 +2312,8 @@ static void reload_queues(void)
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
ast_log(LOG_WARNING, "XXX Leaking a little memory :( XXX\n");
|
|
|
|
ast_log(LOG_WARNING, "XXX Leaking a little memory :( XXX\n");
|
|
|
|
} else {
|
|
|
|
} else {
|
|
|
|
char tmp[256];
|
|
|
|
for (cur = q->members; cur; cur = cur->next)
|
|
|
|
cur = q->members;
|
|
|
|
cur->status = ast_device_state(cur->interface);
|
|
|
|
while(cur) {
|
|
|
|
|
|
|
|
snprintf(tmp, sizeof(tmp), "%s/%s", cur->tech, cur->loc);
|
|
|
|
|
|
|
|
cur->status = ast_device_state(tmp);
|
|
|
|
|
|
|
|
cur = cur->next;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ql = q;
|
|
|
|
ql = q;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
q = qn;
|
|
|
|
q = qn;
|
|
|
@ -2435,7 +2411,7 @@ static int __queues_show(int fd, int argc, char **argv, int queue_show)
|
|
|
|
mem->calls, (long)(time(NULL) - mem->lastcall));
|
|
|
|
mem->calls, (long)(time(NULL) - mem->lastcall));
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
strncpy(calls, " has taken no calls yet", sizeof(calls) - 1);
|
|
|
|
strncpy(calls, " has taken no calls yet", sizeof(calls) - 1);
|
|
|
|
ast_cli(fd, " %s/%s%s%s\n", mem->tech, mem->loc, max, calls);
|
|
|
|
ast_cli(fd, " %s%s%s\n", mem->interface, max, calls);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else
|
|
|
|
} else
|
|
|
|
ast_cli(fd, " No Members\n");
|
|
|
|
ast_cli(fd, " No Members\n");
|
|
|
@ -2533,7 +2509,7 @@ static int manager_queues_status( struct mansession *s, struct message *m )
|
|
|
|
for (mem = q->members; mem; mem = mem->next)
|
|
|
|
for (mem = q->members; mem; mem = mem->next)
|
|
|
|
ast_cli(s->fd, "Event: QueueMember\r\n"
|
|
|
|
ast_cli(s->fd, "Event: QueueMember\r\n"
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Queue: %s\r\n"
|
|
|
|
"Location: %s/%s\r\n"
|
|
|
|
"Location: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Membership: %s\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"Penalty: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
|
"CallsTaken: %d\r\n"
|
|
|
@ -2541,7 +2517,7 @@ static int manager_queues_status( struct mansession *s, struct message *m )
|
|
|
|
"Status: %d\r\n"
|
|
|
|
"Status: %d\r\n"
|
|
|
|
"%s"
|
|
|
|
"%s"
|
|
|
|
"\r\n",
|
|
|
|
"\r\n",
|
|
|
|
q->name, mem->tech, mem->loc, mem->dynamic ? "dynamic" : "static",
|
|
|
|
q->name, mem->interface, mem->dynamic ? "dynamic" : "static",
|
|
|
|
mem->penalty, mem->calls, mem->lastcall, mem->status, idText);
|
|
|
|
mem->penalty, mem->calls, mem->lastcall, mem->status, idText);
|
|
|
|
|
|
|
|
|
|
|
|
/* List Queue Entries */
|
|
|
|
/* List Queue Entries */
|
|
|
@ -2782,14 +2758,8 @@ static char *complete_remove_queue_member(char *line, char *word, int pos, int s
|
|
|
|
ast_mutex_lock(&q->lock);
|
|
|
|
ast_mutex_lock(&q->lock);
|
|
|
|
for (m = q->members ; m ; m = m->next) {
|
|
|
|
for (m = q->members ; m ; m = m->next) {
|
|
|
|
if (++which > state) {
|
|
|
|
if (++which > state) {
|
|
|
|
char *tmp = malloc(strlen(m->tech) + strlen(m->loc) + 2);
|
|
|
|
|
|
|
|
if (tmp) {
|
|
|
|
|
|
|
|
sprintf(tmp, "%s/%s", m->tech, m->loc);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
ast_log(LOG_ERROR, "Out of memory\n");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
ast_mutex_unlock(&q->lock);
|
|
|
|
ast_mutex_unlock(&q->lock);
|
|
|
|
return tmp;
|
|
|
|
return strdup(m->interface);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast_mutex_unlock(&q->lock);
|
|
|
|
ast_mutex_unlock(&q->lock);
|
|
|
|