#include "asterisk.h"
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <string.h>
#include <stdio.h>
#include <sys/time.h>
#include <sys/signal.h>
#include <netinet/in.h>
#include "asterisk/lock.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/channel.h"
#include "asterisk/pbx.h"
#include "asterisk/options.h"
#include "asterisk/app.h"
#include "asterisk/linkedlists.h"
#include "asterisk/module.h"
#include "asterisk/translate.h"
#include "asterisk/say.h"
#include "asterisk/features.h"
#include "asterisk/musiconhold.h"
#include "asterisk/cli.h"
#include "asterisk/manager.h"
#include "asterisk/config.h"
#include "asterisk/monitor.h"
#include "asterisk/utils.h"
#include "asterisk/causes.h"
#include "asterisk/astdb.h"
#include "asterisk/devicestate.h"
#include "asterisk/stringfields.h"
#include "asterisk/astobj2.h"
#include "asterisk/global_datastores.h"
Include dependency graph for app_queue.c:

Go to the source code of this file.
Data Structures | |
| struct | call_queue |
| struct | callattempt |
| We define a custom "local user" structure because we use it not only for keeping track of what is in use but also for keeping track of who we're dialing. More... | |
| struct | member |
| struct | member_interface |
| struct | queue_ent |
| struct | queue_transfer_ds |
| struct | statechange |
| struct | strategy |
Defines | |
| #define | ANNOUNCEHOLDTIME_ALWAYS 1 |
| #define | ANNOUNCEHOLDTIME_ONCE 2 |
| #define | AST_MAX_WATCHERS 256 |
| #define | DEFAULT_RETRY 5 |
| #define | DEFAULT_TIMEOUT 15 |
| #define | MAX_PERIODIC_ANNOUNCEMENTS 10 |
| #define | PM_MAX_LEN 8192 |
| #define | QUEUE_EMPTY_NORMAL 1 |
| #define | QUEUE_EMPTY_STRICT 2 |
| #define | QUEUE_EVENT_VARIABLES 3 |
| #define | RECHECK 1 |
| #define | RES_EXISTS (-1) |
| #define | RES_NOSUCHQUEUE (-3) |
| #define | RES_NOT_DYNAMIC (-4) |
| #define | RES_OKAY 0 |
| #define | RES_OUTOFMEMORY (-2) |
Enumerations | |
| enum | { QUEUE_STRATEGY_RINGALL = 0, QUEUE_STRATEGY_ROUNDROBIN, QUEUE_STRATEGY_LEASTRECENT, QUEUE_STRATEGY_FEWESTCALLS, QUEUE_STRATEGY_RANDOM, QUEUE_STRATEGY_RRMEMORY } |
| enum | queue_member_status { QUEUE_NO_MEMBERS, QUEUE_NO_REACHABLE_MEMBERS, QUEUE_NORMAL } |
| enum | queue_result { QUEUE_UNKNOWN = 0, QUEUE_TIMEOUT = 1, QUEUE_JOINEMPTY = 2, QUEUE_LEAVEEMPTY = 3, QUEUE_JOINUNAVAIL = 4, QUEUE_LEAVEUNAVAIL = 5, QUEUE_FULL = 6 } |
Functions | |
| static int | __queues_show (struct mansession *s, int manager, int fd, int argc, char **argv) |
| static int | add_to_interfaces (const char *interface) |
| static int | add_to_queue (const char *queuename, const char *interface, const char *membername, int penalty, int paused, int dump) |
| static struct call_queue * | alloc_queue (const char *queuename) |
| static int | aqm_exec (struct ast_channel *chan, void *data) |
| static | AST_LIST_HEAD_STATIC (queues, call_queue) |
| static | AST_LIST_HEAD_STATIC (interfaces, member_interface) |
| AST_MODULE_INFO (ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT,"True Call Queueing",.load=load_module,.unload=unload_module,.reload=reload,) | |
| static int | attended_transfer_occurred (struct ast_channel *chan) |
| mechanism to tell if a queue caller was atxferred by a queue member. | |
| static int | calc_metric (struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp) |
| Calculate the metric of each member in the outgoing callattempts. | |
| static void | clear_and_free_interfaces (void) |
| static void | clear_queue (struct call_queue *q) |
| static int | compare_weight (struct call_queue *rq, struct member *member) |
| static char * | complete_queue (const char *line, const char *word, int pos, int state) |
| static char * | complete_queue_add_member (const char *line, const char *word, int pos, int state) |
| static char * | complete_queue_remove_member (const char *line, const char *word, int pos, int state) |
| static char * | complete_queue_show (const char *line, const char *word, int pos, int state) |
| static int | compress_char (const char c) |
| static struct member * | create_queue_member (const char *interface, const char *membername, int penalty, int paused) |
| allocate space for new queue member and set fields based on parameters passed | |
| static void | destroy_queue (struct call_queue *q) |
| static void * | device_state_thread (void *data) |
| Consumer of the statechange queue. | |
| static void | do_hang (struct callattempt *o) |
| common hangup actions | |
| static void | dump_queue_members (struct call_queue *pm_queue) |
| static struct callattempt * | find_best (struct callattempt *outgoing) |
| find the entry with the best metric, or NULL | |
| static struct call_queue * | find_queue_by_name_rt (const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config) |
| Reload a single queue via realtime. | |
| static void | free_members (struct call_queue *q, int all) |
| static enum queue_member_status | get_member_status (struct call_queue *q, int max_penalty) |
| Check if members are available. | |
| static int | handle_queue_add_member (int fd, int argc, char *argv[]) |
| static int | handle_queue_remove_member (int fd, int argc, char *argv[]) |
| static void * | handle_statechange (struct statechange *sc) |
| set a member's status based on device state of that member's interface | |
| static void | hangupcalls (struct callattempt *outgoing, struct ast_channel *exception) |
| static void | init_queue (struct call_queue *q) |
| static void | insert_entry (struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos) |
| Insert the 'new' entry after the 'prev' entry of queue 'q'. | |
| static char * | int2strat (int strategy) |
| static struct member * | interface_exists (struct call_queue *q, const char *interface) |
| static int | interface_exists_global (const char *interface) |
| static int | is_our_turn (struct queue_ent *qe) |
| Check if we should start attempting to call queue members. | |
| static int | join_queue (char *queuename, struct queue_ent *qe, enum queue_result *reason) |
| static void | leave_queue (struct queue_ent *qe) |
| static int | load_module (void) |
| static struct call_queue * | load_realtime_queue (const char *queuename) |
| static int | manager_add_queue_member (struct mansession *s, const struct message *m) |
| static int | manager_pause_queue_member (struct mansession *s, const struct message *m) |
| static int | manager_queues_show (struct mansession *s, const struct message *m) |
| static int | manager_queues_status (struct mansession *s, const struct message *m) |
| static int | manager_remove_queue_member (struct mansession *s, const struct message *m) |
| static int | member_cmp_fn (void *obj1, void *obj2, int flags) |
| static int | member_hash_fn (const void *obj, const int flags) |
| static void | monjoin_dep_warning (void) |
| static int | play_file (struct ast_channel *chan, char *filename) |
| static int | pqm_exec (struct ast_channel *chan, void *data) |
| static int | ql_exec (struct ast_channel *chan, void *data) |
| static int | queue_exec (struct ast_channel *chan, void *data) |
| The starting point for all queue calls. | |
| static int | queue_function_qac (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| static int | queue_function_queuememberlist (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| static int | queue_function_queuewaitingcount (struct ast_channel *chan, char *cmd, char *data, char *buf, size_t len) |
| static void | queue_set_param (struct call_queue *q, const char *param, const char *val, int linenum, int failunknown) |
| Configure a queue parameter. | |
| static int | queue_show (int fd, int argc, char **argv) |
| static void | queue_transfer_destroy (void *data) |
| static void | queue_transfer_fixup (void *data, struct ast_channel *old_chan, struct ast_channel *new_chan) |
| Log an attended transfer when a queue caller channel is masqueraded. | |
| static void | recalc_holdtime (struct queue_ent *qe, int newholdtime) |
| static void | record_abandoned (struct queue_ent *qe) |
| static int | reload (void) |
| static void | reload_queue_members (void) |
| static int | reload_queues (void) |
| static int | remove_from_interfaces (const char *interface) |
| static int | remove_from_queue (const char *queuename, const char *interface) |
| static int | ring_entry (struct queue_ent *qe, struct callattempt *tmp, int *busies) |
| Part 2 of ring_one. | |
| static int | ring_one (struct queue_ent *qe, struct callattempt *outgoing, int *busies) |
| Place a call to a queue member. | |
| static void | rna (int rnatime, struct queue_ent *qe, char *interface, char *membername) |
| RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. | |
| static int | rqm_exec (struct ast_channel *chan, void *data) |
| static void | rr_dep_warning (void) |
| static void | rt_handle_member_record (struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str) |
| static int | say_periodic_announcement (struct queue_ent *qe) |
| static int | say_position (struct queue_ent *qe) |
| static int | set_member_paused (const char *queuename, const char *interface, int paused) |
| static void | set_queue_result (struct ast_channel *chan, enum queue_result res) |
| sets the QUEUESTATUS channel variable | |
| static void | setup_transfer_datastore (struct queue_ent *qe, struct member *member, int starttime, int callcompletedinsl) |
| create a datastore for storing relevant info to log attended transfers in the queue_log | |
| static int | statechange_queue (const char *dev, int state, void *ign) |
| Producer of the statechange queue. | |
| static int | store_next (struct queue_ent *qe, struct callattempt *outgoing) |
| static int | strat2int (const char *strategy) |
| static int | try_calling (struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *tries, int *noption, const char *agi) |
| A large function which calls members, updates statistics, and bridges the caller and a member. | |
| static int | unload_module (void) |
| static int | update_queue (struct call_queue *q, struct member *member, int callcompletedinsl) |
| static int | update_realtime_member_field (struct member *mem, const char *queue_name, const char *field, const char *value) |
| static void | update_realtime_members (struct call_queue *q) |
| static int | update_status (const char *interface, const int status) |
| static int | upqm_exec (struct ast_channel *chan, void *data) |
| static int | valid_exit (struct queue_ent *qe, char digit) |
| static char * | vars2manager (struct ast_channel *chan, char *vars, size_t len) |
| static int | wait_a_bit (struct queue_ent *qe) |
| static struct callattempt * | wait_for_answer (struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed) |
| Wait for a member to answer the call. | |
| static int | wait_our_turn (struct queue_ent *qe, int ringing, enum queue_result *reason) |
| The waiting areas for callers who are not actively calling members. | |
Variables | |
| static char * | app = "Queue" |
| static char * | app_aqm = "AddQueueMember" |
| static char * | app_aqm_descrip |
| static char * | app_aqm_synopsis = "Dynamically adds queue members" |
| static char * | app_pqm = "PauseQueueMember" |
| static char * | app_pqm_descrip |
| static char * | app_pqm_synopsis = "Pauses a queue member" |
| static char * | app_ql = "QueueLog" |
| static char * | app_ql_descrip |
| static char * | app_ql_synopsis = "Writes to the queue_log" |
| static char * | app_rqm = "RemoveQueueMember" |
| static char * | app_rqm_descrip |
| static char * | app_rqm_synopsis = "Dynamically removes queue members" |
| static char * | app_upqm = "UnpauseQueueMember" |
| static char * | app_upqm_descrip |
| static char * | app_upqm_synopsis = "Unpauses a queue member" |
| static int | autofill_default = 0 |
| queues.conf [general] option | |
| static struct ast_cli_entry | cli_add_queue_member_deprecated |
| static struct ast_cli_entry | cli_queue [] |
| static struct ast_cli_entry | cli_remove_queue_member_deprecated |
| static struct ast_cli_entry | cli_show_queue_deprecated |
| static char * | descrip |
| struct { | |
| ast_cond_t cond | |
| ast_mutex_t lock | |
| unsigned int stop:1 | |
| pthread_t thread | |
| } | device_state |
| Data used by the device state thread. | |
| static int | montype_default = 0 |
| queues.conf [general] option | |
| static const char * | pm_family = "Queue/PersistentMembers" |
| Persistent Members astdb family. | |
| static char | qam_cmd_usage [] |
| static char | qrm_cmd_usage [] |
| static int | queue_persistent_members = 0 |
| queues.conf [general] option | |
| struct { | |
| enum queue_result id | |
| char * text | |
| } | queue_results [] |
| static char | queue_show_usage [] |
| static struct ast_datastore_info | queue_transfer_info |
| a datastore used to help correctly log attended transfers of queue callers | |
| static struct ast_custom_function | queueagentcount_function |
| static struct ast_custom_function | queuemembercount_function |
| static struct ast_custom_function | queuememberlist_function |
| static struct ast_custom_function | queuewaitingcount_function |
| static struct strategy | strategies [] |
| static char * | synopsis = "Queue a call for a call queue" |
| static int | use_weight = 0 |
| queues.conf per-queue weight option | |
These features added by David C. Troy <dave@toad.net>:
Added servicelevel statistic by Michiel Betel <michiel@betel.nl> Added Priority jumping code for adding and removing queue members by Jonathan Stanton <asterisk@doilooklikeicare.com>
Fixed to work with CVS as of 2004-02-25 and released as 1.07a by Matthew Enger <m.enger@xi.com.au>
Definition in file app_queue.c.
| #define ANNOUNCEHOLDTIME_ALWAYS 1 |
| #define ANNOUNCEHOLDTIME_ONCE 2 |
| #define AST_MAX_WATCHERS 256 |
Definition at line 2086 of file app_queue.c.
| #define DEFAULT_RETRY 5 |
| #define DEFAULT_TIMEOUT 15 |
| #define MAX_PERIODIC_ANNOUNCEMENTS 10 |
Definition at line 140 of file app_queue.c.
Referenced by init_queue(), queue_set_param(), and say_periodic_announcement().
| #define PM_MAX_LEN 8192 |
Definition at line 271 of file app_queue.c.
Referenced by dump_queue_members(), and reload_queue_members().
| #define QUEUE_EMPTY_NORMAL 1 |
| #define QUEUE_EMPTY_STRICT 2 |
Definition at line 378 of file app_queue.c.
Referenced by join_queue(), queue_exec(), queue_set_param(), and wait_our_turn().
| #define QUEUE_EVENT_VARIABLES 3 |
Definition at line 381 of file app_queue.c.
Referenced by queue_set_param(), ring_entry(), and try_calling().
| #define RECHECK 1 |
| #define RES_EXISTS (-1) |
Definition at line 143 of file app_queue.c.
Referenced by add_to_queue(), aqm_exec(), handle_queue_add_member(), handle_queue_remove_member(), manager_add_queue_member(), manager_remove_queue_member(), remove_from_queue(), and rqm_exec().
| #define RES_NOSUCHQUEUE (-3) |
Definition at line 145 of file app_queue.c.
Referenced by add_to_queue(), aqm_exec(), handle_queue_add_member(), handle_queue_remove_member(), manager_add_queue_member(), manager_remove_queue_member(), remove_from_queue(), and rqm_exec().
| #define RES_NOT_DYNAMIC (-4) |
Definition at line 146 of file app_queue.c.
Referenced by handle_queue_remove_member(), manager_remove_queue_member(), remove_from_queue(), and rqm_exec().
| #define RES_OKAY 0 |
Definition at line 142 of file app_queue.c.
Referenced by add_to_queue(), aqm_exec(), handle_queue_add_member(), handle_queue_remove_member(), manager_add_queue_member(), manager_remove_queue_member(), remove_from_queue(), and rqm_exec().
| #define RES_OUTOFMEMORY (-2) |
Definition at line 144 of file app_queue.c.
Referenced by add_to_queue(), aqm_exec(), handle_queue_add_member(), handle_queue_remove_member(), manager_add_queue_member(), manager_remove_queue_member(), and reload_queue_members().
| anonymous enum |
| QUEUE_STRATEGY_RINGALL | |
| QUEUE_STRATEGY_ROUNDROBIN | |
| QUEUE_STRATEGY_LEASTRECENT | |
| QUEUE_STRATEGY_FEWESTCALLS | |
| QUEUE_STRATEGY_RANDOM | |
| QUEUE_STRATEGY_RRMEMORY |
Definition at line 116 of file app_queue.c.
00116 { 00117 QUEUE_STRATEGY_RINGALL = 0, 00118 QUEUE_STRATEGY_ROUNDROBIN, 00119 QUEUE_STRATEGY_LEASTRECENT, 00120 QUEUE_STRATEGY_FEWESTCALLS, 00121 QUEUE_STRATEGY_RANDOM, 00122 QUEUE_STRATEGY_RRMEMORY 00123 };
| enum queue_member_status |
Definition at line 531 of file app_queue.c.
00531 { 00532 QUEUE_NO_MEMBERS, 00533 QUEUE_NO_REACHABLE_MEMBERS, 00534 QUEUE_NORMAL 00535 };
| enum queue_result |
| QUEUE_UNKNOWN | |
| QUEUE_TIMEOUT | |
| QUEUE_JOINEMPTY | |
| QUEUE_LEAVEEMPTY | |
| QUEUE_JOINUNAVAIL | |
| QUEUE_LEAVEUNAVAIL | |
| QUEUE_FULL |
Definition at line 285 of file app_queue.c.
00285 { 00286 QUEUE_UNKNOWN = 0, 00287 QUEUE_TIMEOUT = 1, 00288 QUEUE_JOINEMPTY = 2, 00289 QUEUE_LEAVEEMPTY = 3, 00290 QUEUE_JOINUNAVAIL = 4, 00291 QUEUE_LEAVEUNAVAIL = 5, 00292 QUEUE_FULL = 6, 00293 };
| static int __queues_show | ( | struct mansession * | s, | |
| int | manager, | |||
| int | fd, | |||
| int | argc, | |||
| char ** | argv | |||
| ) | [static] |
Definition at line 4453 of file app_queue.c.
References ao2_container_count(), ao2_iterator_init(), ao2_iterator_next(), ao2_ref(), ast_build_string(), ast_category_browse(), ast_check_realtime(), ast_cli(), ast_config_destroy(), AST_LIST_EMPTY, AST_LIST_LOCK, AST_LIST_NEXT, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_load_realtime_multientry(), ast_mutex_lock(), ast_mutex_unlock(), ast_strlen_zero(), astman_append(), member::calls, call_queue::callsabandoned, call_queue::callscompleted, call_queue::callscompletedinsl, queue_ent::chan, call_queue::count, devstate2str(), member::dynamic, call_queue::head, call_queue::holdtime, int2strat(), member::interface, member::lastcall, load_realtime_queue(), call_queue::lock, call_queue::maxlen, member::membername, call_queue::members, call_queue::name, queue_ent::next, member::paused, member::penalty, queue_ent::prio, queue_show(), member::realtime, RESULT_SHOWUSAGE, RESULT_SUCCESS, s, call_queue::servicelevel, queue_ent::start, member::status, call_queue::strategy, and call_queue::weight.
Referenced by manager_queues_show(), and queue_show().
04454 { 04455 struct call_queue *q; 04456 struct queue_ent *qe; 04457 struct member *mem; 04458 int pos, queue_show; 04459 time_t now; 04460 char max_buf[150]; 04461 char *max; 04462 size_t max_left; 04463 float sl = 0; 04464 char *term = manager ? "\r\n" : "\n"; 04465 struct ao2_iterator mem_iter; 04466 04467 time(&now); 04468 if (argc == 2) 04469 queue_show = 0; 04470 else if (argc == 3) 04471 queue_show = 1; 04472 else 04473 return RESULT_SHOWUSAGE; 04474 04475 /* We only want to load realtime queues when a specific queue is asked for. */ 04476 if (queue_show) { 04477 load_realtime_queue(argv[2]); 04478 } else if (ast_check_realtime("queues")) { 04479 struct ast_config *cfg = ast_load_realtime_multientry("queues", "name LIKE", "%", (char *) NULL); 04480 char *queuename; 04481 if (cfg) { 04482 for (queuename = ast_category_browse(cfg, NULL); !ast_strlen_zero(queuename); queuename = ast_category_browse(cfg, queuename)) { 04483 load_realtime_queue(queuename); 04484 } 04485 ast_config_destroy(cfg); 04486 } 04487 } 04488 04489 AST_LIST_LOCK(&queues); 04490 if (AST_LIST_EMPTY(&queues)) { 04491 AST_LIST_UNLOCK(&queues); 04492 if (queue_show) { 04493 if (s) 04494 astman_append(s, "No such queue: %s.%s",argv[2], term); 04495 else 04496 ast_cli(fd, "No such queue: %s.%s",argv[2], term); 04497 } else { 04498 if (s) 04499 astman_append(s, "No queues.%s", term); 04500 else 04501 ast_cli(fd, "No queues.%s", term); 04502 } 04503 return RESULT_SUCCESS; 04504 } 04505 AST_LIST_TRAVERSE(&queues, q, list) { 04506 ast_mutex_lock(&q->lock); 04507 if (queue_show) { 04508 if (strcasecmp(q->name, argv[2]) != 0) { 04509 ast_mutex_unlock(&q->lock); 04510 if (!AST_LIST_NEXT(q, list)) { 04511 ast_cli(fd, "No such queue: %s.%s",argv[2], term); 04512 break; 04513 } 04514 continue; 04515 } 04516 } 04517 max_buf[0] = '\0'; 04518 max = max_buf; 04519 max_left = sizeof(max_buf); 04520 if (q->maxlen) 04521 ast_build_string(&max, &max_left, "%d", q->maxlen); 04522 else 04523 ast_build_string(&max, &max_left, "unlimited"); 04524 sl = 0; 04525 if (q->callscompleted > 0) 04526 sl = 100 * ((float) q->callscompletedinsl / (float) q->callscompleted); 04527 if (s) 04528 astman_append(s, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s", 04529 q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight, 04530 q->callscompleted, q->callsabandoned,sl,q->servicelevel, term); 04531 else 04532 ast_cli(fd, "%-12.12s has %d calls (max %s) in '%s' strategy (%ds holdtime), W:%d, C:%d, A:%d, SL:%2.1f%% within %ds%s", 04533 q->name, q->count, max_buf, int2strat(q->strategy), q->holdtime, q->weight, q->callscompleted, q->callsabandoned,sl,q->servicelevel, term); 04534 if (ao2_container_count(q->members)) { 04535 if (s) 04536 astman_append(s, " Members: %s", term); 04537 else 04538 ast_cli(fd, " Members: %s", term); 04539 mem_iter = ao2_iterator_init(q->members, 0); 04540 while ((mem = ao2_iterator_next(&mem_iter))) { 04541 max_buf[0] = '\0'; 04542 max = max_buf; 04543 max_left = sizeof(max_buf); 04544 if (strcasecmp(mem->membername, mem->interface)) { 04545 ast_build_string(&max, &max_left, " (%s)", mem->interface); 04546 } 04547 if (mem->penalty) 04548 ast_build_string(&max, &max_left, " with penalty %d", mem->penalty); 04549 if (mem->dynamic) 04550 ast_build_string(&max, &max_left, " (dynamic)"); 04551 if (mem->realtime) 04552 ast_build_string(&max, &max_left, " (realtime)"); 04553 if (mem->paused) 04554 ast_build_string(&max, &max_left, " (paused)"); 04555 ast_build_string(&max, &max_left, " (%s)", devstate2str(mem->status)); 04556 if (mem->calls) { 04557 ast_build_string(&max, &max_left, " has taken %d calls (last was %ld secs ago)", 04558 mem->calls, (long) (time(NULL) - mem->lastcall)); 04559 } else 04560 ast_build_string(&max, &max_left, " has taken no calls yet"); 04561 if (s) 04562 astman_append(s, " %s%s%s", mem->membername, max_buf, term); 04563 else 04564 ast_cli(fd, " %s%s%s", mem->membername, max_buf, term); 04565 ao2_ref(mem, -1); 04566 } 04567 } else if (s) 04568 astman_append(s, " No Members%s", term); 04569 else 04570 ast_cli(fd, " No Members%s", term); 04571 if (q->head) { 04572 pos = 1; 04573 if (s) 04574 astman_append(s, " Callers: %s", term); 04575 else 04576 ast_cli(fd, " Callers: %s", term); 04577 for (qe = q->head; qe; qe = qe->next) { 04578 if (s) 04579 astman_append(s, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s", 04580 pos++, qe->chan->name, (long) (now - qe->start) / 60, 04581 (long) (now - qe->start) % 60, qe->prio, term); 04582 else 04583 ast_cli(fd, " %d. %s (wait: %ld:%2.2ld, prio: %d)%s", pos++, 04584 qe->chan->name, (long) (now - qe->start) / 60, 04585 (long) (now - qe->start) % 60, qe->prio, term); 04586 } 04587 } else if (s) 04588 astman_append(s, " No Callers%s", term); 04589 else 04590 ast_cli(fd, " No Callers%s", term); 04591 if (s) 04592 astman_append(s, "%s", term); 04593 else 04594 ast_cli(fd, "%s", term); 04595 ast_mutex_unlock(&q->lock); 04596 if (queue_show) 04597 break; 04598 } 04599 AST_LIST_UNLOCK(&queues); 04600 return RESULT_SUCCESS; 04601 }
| static int add_to_interfaces | ( | const char * | interface | ) | [static] |
Definition at line 872 of file app_queue.c.
References ast_calloc, AST_LIST_INSERT_HEAD, AST_LIST_LOCK, AST_LIST_TRAVERSE, AST_LIST_UNLOCK, ast_log(), member_interface::interface, LOG_DEBUG, and option_debug.
Referenced by add_to_queue(), reload_queues(), and rt_handle_member_record().
00873 { 00874 struct member_interface *curint; 00875 00876 AST_LIST_LOCK(&interfaces); 00877 AST_LIST_TRAVERSE(&interfaces, curint, list) { 00878 if (!strcasecmp(curint->interface, interface)) 00879 break; 00880 } 00881 00882 if (curint) { 00883 AST_LIST_UNLOCK(&interfaces); 00884 return 0; 00885 } 00886 00887 if (option_debug) 00888 ast_log(LOG_DEBUG, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface); 00889 00890 if ((curint = ast_calloc(1, sizeof(*curint)))) { 00891 ast_copy_string(curint->interface, interface, sizeof(curint->interface)); 00892 AST_LIST_INSERT_HEAD(&interfaces, curint, list); 00893 } 00894 AST_LIST_UNLOCK(&interfaces); 00895 00896 return 0; 00897 }
| static int add_to_queue | ( | const char * | queuename, | |
| const char * | interface, | |||
| const char * | membername, | |||
| int | penalty, | |||
| int | paused, | |||
| int | dump | |||
| ) | [static] |
Definition at line 3346 of file app_queue.c.
References add_to_interfaces(), ao2_ref(), AST_LIST_LOCK, AST_LIST_UNLOCK, ast_mutex_lock(), ast_mutex_unlock(), member::calls, create_queue_member(), dump_queue_members(), member::dynamic, EVENT_FLAG_AGENT, member::interface, interface_exists(), member::lastcall, load_realtime_queue(), call_queue::lock, manager_event(), call_queue::membercount, member::membername, call_queue::members, call_queue::name, member::paused, member::penalty, RES_EXISTS, RES_NOSUCHQUEUE, RES_OKAY, RES_OUTOFMEMORY, and member::status.
Referenced by aqm_exec(), handle_queue_add_member(), manager_add_queue_member(), and reload_queue_members().
03347 { 03348 struct call_queue *q; 03349 struct member *new_member, *old_member; 03350 int res = RES_NOSUCHQUEUE; 03351 03352 /* \note Ensure the appropriate realtime queue is loaded. Note that this 03353 * short-circuits if the queue is already in memory. */ 03354 if (!(q = load_realtime_queue(queuename))) 03355 return res; 03356 03357 AST_LIST_LOCK(&queues); 03358 03359 ast_mutex_lock(&q->lock); 03360 if ((old_member = interface_exists(q, interface)) == NULL) { 03361 add_to_interfaces(interface); 03362 if ((new_member = create_queue_member(interface, membername, penalty, paused))) { 03363 new_member->dynamic = 1; 03364 ao2_link(q->members, new_member); 03365 q->membercount++; 03366 manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded", 03367 "Queue: %s\r\n" 03368 "Location: %s\r\n" 03369 "MemberName: %s\r\n" 03370 "Membership: %s\r\n" 03371 "Penalty: %d\r\n" 03372 "CallsTaken: %d\r\n" 03373 "LastCall: %d\r\n" 03374 "Status: %d\r\n" 03375 "Paused: %d\r\n", 03376 q->