2 * Asterisk -- An open source telephony toolkit.
4 * Copyright (C) 1999 - 2006, Digium, Inc.
6 * Mark Spencer <markster@digium.com>
8 * See http://www.asterisk.org for more information about
9 * the Asterisk project. Please do not directly contact
10 * any of the maintainers of this project for assistance;
11 * the project provides a web site, mailing lists and IRC
12 * channels for your use.
14 * This program is free software, distributed under the terms of
15 * the GNU General Public License Version 2. See the LICENSE file
16 * at the top of the source tree.
21 * \brief True call queues with optional send URL on answer
23 * \author Mark Spencer <markster@digium.com>
25 * \arg Config in \ref Config_qu queues.conf
27 * \par Development notes
28 * \note 2004-11-25: Persistent Dynamic Members added by:
29 * NetNation Communications (www.netnation.com)
30 * Kevin Lindsay <kevinl@netnation.com>
32 * Each dynamic agent in each queue is now stored in the astdb.
33 * When asterisk is restarted, each agent will be automatically
34 * readded into their recorded queues. This feature can be
35 * configured with the 'persistent_members=<1|0>' setting in the
36 * '[general]' category in queues.conf. The default is on.
38 * \note 2004-06-04: Priorities in queues added by inAccess Networks (work funded by Hellas On Line (HOL) www.hol.gr).
40 * \note These features added by David C. Troy <dave@toad.net>:
41 * - Per-queue holdtime calculation
42 * - Estimated holdtime announcement
43 * - Position announcement
44 * - Abandoned/completed call counters
45 * - Failout timer passed as optional app parameter
46 * - Optional monitoring of calls, started when call is answered
48 * Patch Version 1.07 2003-12-24 01
50 * Added servicelevel statistic by Michiel Betel <michiel@betel.nl>
51 * Added Priority jumping code for adding and removing queue members by Jonathan Stanton <asterisk@doilooklikeicare.com>
53 * Fixed to work with CVS as of 2004-02-25 and released as 1.07a
54 * by Matthew Enger <m.enger@xi.com.au>
56 * \ingroup applications
60 <depend>res_monitor</depend>
65 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
68 #include <sys/signal.h>
69 #include <netinet/in.h>
71 #include "asterisk/lock.h"
72 #include "asterisk/file.h"
73 #include "asterisk/channel.h"
74 #include "asterisk/pbx.h"
75 #include "asterisk/app.h"
76 #include "asterisk/linkedlists.h"
77 #include "asterisk/module.h"
78 #include "asterisk/translate.h"
79 #include "asterisk/say.h"
80 #include "asterisk/features.h"
81 #include "asterisk/musiconhold.h"
82 #include "asterisk/cli.h"
83 #include "asterisk/manager.h"
84 #include "asterisk/config.h"
85 #include "asterisk/monitor.h"
86 #include "asterisk/utils.h"
87 #include "asterisk/causes.h"
88 #include "asterisk/astdb.h"
89 #include "asterisk/devicestate.h"
90 #include "asterisk/stringfields.h"
91 #include "asterisk/event.h"
92 #include "asterisk/astobj2.h"
93 #include "asterisk/strings.h"
94 #include "asterisk/global_datastores.h"
97 * \par Please read before modifying this file.
98 * There are three locks which are regularly used
99 * throughout this file, the queue list lock, the lock
100 * for each individual queue, and the interface list lock.
101 * Please be extra careful to always lock in the following order
103 * 2) individual queue lock
104 * 3) interface list lock
105 * This order has sort of "evolved" over the lifetime of this
106 * application, but it is now in place this way, so please adhere
112 QUEUE_STRATEGY_RINGALL = 0,
113 QUEUE_STRATEGY_LEASTRECENT,
114 QUEUE_STRATEGY_FEWESTCALLS,
115 QUEUE_STRATEGY_RANDOM,
116 QUEUE_STRATEGY_RRMEMORY,
117 QUEUE_STRATEGY_LINEAR,
118 QUEUE_STRATEGY_WRANDOM
121 static const struct strategy {
125 { QUEUE_STRATEGY_RINGALL, "ringall" },
126 { QUEUE_STRATEGY_LEASTRECENT, "leastrecent" },
127 { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" },
128 { QUEUE_STRATEGY_RANDOM, "random" },
129 { QUEUE_STRATEGY_RRMEMORY, "rrmemory" },
130 { QUEUE_STRATEGY_LINEAR, "linear" },
131 { QUEUE_STRATEGY_WRANDOM, "wrandom"},
134 #define DEFAULT_RETRY 5
135 #define DEFAULT_TIMEOUT 15
136 #define RECHECK 1 /*!< Recheck every second to see we we're at the top yet */
137 #define MAX_PERIODIC_ANNOUNCEMENTS 10 /*!< The maximum periodic announcements we can have */
138 #define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 /*!< The minimum number of seconds between position announcements
139 The default value of 15 provides backwards compatibility */
140 #define MAX_QUEUE_BUCKETS 53
142 #define RES_OKAY 0 /*!< Action completed */
143 #define RES_EXISTS (-1) /*!< Entry already exists */
144 #define RES_OUTOFMEMORY (-2) /*!< Out of memory */
145 #define RES_NOSUCHQUEUE (-3) /*!< No such queue */
146 #define RES_NOT_DYNAMIC (-4) /*!< Member is not dynamic */
148 static char *app = "Queue";
150 static char *synopsis = "Queue a call for a call queue";
152 static char *descrip =
153 " Queue(queuename[,options[,URL][,announceoverride][,timeout][,AGI][,macro][,gosub][,rule]):\n"
154 "Queues an incoming call in a particular call queue as defined in queues.conf.\n"
155 "This application will return to the dialplan if the queue does not exist, or\n"
156 "any of the join options cause the caller to not enter the queue.\n"
157 "The option string may contain zero or more of the following characters:\n"
158 " 'c' -- continue in the dialplan if the callee hangs up.\n"
159 " 'd' -- data-quality (modem) call (minimum delay).\n"
160 " 'h' -- allow callee to hang up by pressing *.\n"
161 " 'H' -- allow caller to hang up by pressing *.\n"
162 " 'n' -- no retries on the timeout; will exit this application and \n"
163 " go to the next step.\n"
164 " 'i' -- ignore call forward requests from queue members and do nothing\n"
165 " when they are requested.\n"
166 " 'r' -- ring instead of playing MOH. Periodic Announcements are still made, if applicable.\n"
167 " 't' -- allow the called user to transfer the calling user.\n"
168 " 'T' -- allow the calling user to transfer the call.\n"
169 " 'w' -- allow the called user to write the conversation to disk via Monitor.\n"
170 " 'W' -- allow the calling user to write the conversation to disk via Monitor.\n"
171 " 'k' -- Allow the called party to enable parking of the call by sending\n"
172 " the DTMF sequence defined for call parking in features.conf.\n"
173 " 'K' -- Allow the calling party to enable parking of the call by sending\n"
174 " the DTMF sequence defined for call parking in features.conf.\n"
175 " 'x' -- allow the called user to write the conversation to disk via MixMonitor\n"
176 " 'X' -- allow the calling user to write the conversation to disk via MixMonitor\n"
178 " In addition to transferring the call, a call may be parked and then picked\n"
179 "up by another user.\n"
180 " The optional URL will be sent to the called party if the channel supports\n"
182 " The optional AGI parameter will setup an AGI script to be executed on the \n"
183 "calling party's channel once they are connected to a queue member.\n"
184 " The optional macro parameter will run a macro on the \n"
185 "calling party's channel once they are connected to a queue member.\n"
186 " The optional gosub parameter will run a gosub on the \n"
187 "calling party's channel once they are connected to a queue member.\n"
188 " The optional rule parameter will cause the queue's defaultrule to be\n"
189 "overridden by the rule specified.\n"
190 " The timeout will cause the queue to fail out after a specified number of\n"
191 "seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
192 " This application sets the following channel variable upon completion:\n"
193 " QUEUESTATUS The status of the call as a text string, one of\n"
194 " TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL | CONTINUE\n";
196 static char *app_aqm = "AddQueueMember" ;
197 static char *app_aqm_synopsis = "Dynamically adds queue members" ;
198 static char *app_aqm_descrip =
199 " AddQueueMember(queuename[,interface[,penalty[,options[,membername]]]]):\n"
200 "Dynamically adds interface to an existing queue.\n"
201 "If the interface is already in the queue it will return an error.\n"
202 " This application sets the following channel variable upon completion:\n"
203 " AQMSTATUS The status of the attempt to add a queue member as a \n"
204 " text string, one of\n"
205 " ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
206 "Example: AddQueueMember(techsupport,SIP/3000)\n"
209 static char *app_rqm = "RemoveQueueMember" ;
210 static char *app_rqm_synopsis = "Dynamically removes queue members" ;
211 static char *app_rqm_descrip =
212 " RemoveQueueMember(queuename[,interface[,options]]):\n"
213 "Dynamically removes interface to an existing queue\n"
214 "If the interface is NOT in the queue it will return an error.\n"
215 " This application sets the following channel variable upon completion:\n"
216 " RQMSTATUS The status of the attempt to remove a queue member as a\n"
217 " text string, one of\n"
218 " REMOVED | NOTINQUEUE | NOSUCHQUEUE \n"
219 "Example: RemoveQueueMember(techsupport,SIP/3000)\n"
222 static char *app_pqm = "PauseQueueMember" ;
223 static char *app_pqm_synopsis = "Pauses a queue member" ;
224 static char *app_pqm_descrip =
225 " PauseQueueMember([queuename],interface[,options[,reason]]):\n"
226 "Pauses (blocks calls for) a queue member.\n"
227 "The given interface will be paused in the given queue. This prevents\n"
228 "any calls from being sent from the queue to the interface until it is\n"
229 "unpaused with UnpauseQueueMember or the manager interface. If no\n"
230 "queuename is given, the interface is paused in every queue it is a\n"
231 "member of. The application will fail if the interface is not found.\n"
232 "The reason string is entirely optional and is used to add extra information\n"
233 "to the appropriate queue_log entries and manager events.\n"
234 " This application sets the following channel variable upon completion:\n"
235 " PQMSTATUS The status of the attempt to pause a queue member as a\n"
236 " text string, one of\n"
237 " PAUSED | NOTFOUND\n"
238 "Example: PauseQueueMember(,SIP/3000)\n";
240 static char *app_upqm = "UnpauseQueueMember" ;
241 static char *app_upqm_synopsis = "Unpauses a queue member" ;
242 static char *app_upqm_descrip =
243 " UnpauseQueueMember([queuename],interface[,options[,reason]]):\n"
244 "Unpauses (resumes calls to) a queue member.\n"
245 "This is the counterpart to PauseQueueMember and operates exactly the\n"
246 "same way, except it unpauses instead of pausing the given interface.\n"
247 "The reason string is entirely optional and is used to add extra information\n"
248 "to the appropriate queue_log entries and manager events.\n"
249 " This application sets the following channel variable upon completion:\n"
250 " UPQMSTATUS The status of the attempt to unpause a queue \n"
251 " member as a text string, one of\n"
252 " UNPAUSED | NOTFOUND\n"
253 "Example: UnpauseQueueMember(,SIP/3000)\n";
255 static char *app_ql = "QueueLog" ;
256 static char *app_ql_synopsis = "Writes to the queue_log" ;
257 static char *app_ql_descrip =
258 " QueueLog(queuename,uniqueid,agent,event[,additionalinfo]):\n"
259 "Allows you to write your own events into the queue log\n"
260 "Example: QueueLog(101,${UNIQUEID},${AGENT},WENTONBREAK,600)\n";
262 /*! \brief Persistent Members astdb family */
263 static const char *pm_family = "Queue/PersistentMembers";
264 /* The maximum length of each persistent member queue database entry */
265 #define PM_MAX_LEN 8192
267 /*! \brief queues.conf [general] option */
268 static int queue_keep_stats = 0;
270 /*! \brief queues.conf [general] option */
271 static int queue_persistent_members = 0;
273 /*! \brief queues.conf per-queue weight option */
274 static int use_weight = 0;
276 /*! \brief queues.conf [general] option */
277 static int autofill_default = 0;
279 /*! \brief queues.conf [general] option */
280 static int montype_default = 0;
282 /*! \brief queues.conf [general] option */
283 static int shared_lastcall = 0;
285 /*! \brief Subscription to device state change events */
286 static struct ast_event_sub *device_state_sub;
288 /*! \brief queues.conf [general] option */
289 static int update_cdr = 0;
295 QUEUE_LEAVEEMPTY = 3,
296 QUEUE_JOINUNAVAIL = 4,
297 QUEUE_LEAVEUNAVAIL = 5,
303 enum queue_result id;
305 } queue_results[] = {
306 { QUEUE_UNKNOWN, "UNKNOWN" },
307 { QUEUE_TIMEOUT, "TIMEOUT" },
308 { QUEUE_JOINEMPTY,"JOINEMPTY" },
309 { QUEUE_LEAVEEMPTY, "LEAVEEMPTY" },
310 { QUEUE_JOINUNAVAIL, "JOINUNAVAIL" },
311 { QUEUE_LEAVEUNAVAIL, "LEAVEUNAVAIL" },
312 { QUEUE_FULL, "FULL" },
313 { QUEUE_CONTINUE, "CONTINUE" },
316 /*! \brief We define a custom "local user" structure because we
317 * use it not only for keeping track of what is in use but
318 * also for keeping track of who we're dialing.
320 * There are two "links" defined in this structure, q_next and call_next.
321 * q_next links ALL defined callattempt structures into a linked list. call_next is
322 * a link which allows for a subset of the callattempts to be traversed. This subset
323 * is used in wait_for_answer so that irrelevant callattempts are not traversed. This
324 * also is helpful so that queue logs are always accurate in the case where a call to
325 * a member times out, especially if using the ringall strategy.
329 struct callattempt *q_next;
330 struct callattempt *call_next;
331 struct ast_channel *chan;
337 struct call_queue *lastqueue;
338 struct member *member;
343 struct call_queue *parent; /*!< What queue is our parent */
344 char moh[80]; /*!< Name of musiconhold to be used */
345 char announce[80]; /*!< Announcement to play for member when call is answered */
346 char context[AST_MAX_CONTEXT]; /*!< Context when user exits queue */
347 char digits[AST_MAX_EXTENSION]; /*!< Digits entered while in queue */
348 int valid_digits; /*!< Digits entered correspond to valid extension. Exited */
349 int pos; /*!< Where we are in the queue */
350 int prio; /*!< Our priority */
351 int last_pos_said; /*!< Last position we told the user */
352 time_t last_periodic_announce_time; /*!< The last time we played a periodic announcement */
353 int last_periodic_announce_sound; /*!< The last periodic announcement we made */
354 time_t last_pos; /*!< Last time we told the user their position */
355 int opos; /*!< Where we started in the queue */
356 int handled; /*!< Whether our call was handled */
357 int pending; /*!< Non-zero if we are attempting to call a member */
358 int max_penalty; /*!< Limit the members that can take this call to this penalty or lower */
359 int min_penalty; /*!< Limit the members that can take this call to this penalty or higher */
360 int linpos; /*!< If using linear strategy, what position are we at? */
361 int linwrapped; /*!< Is the linpos wrapped? */
362 time_t start; /*!< When we started holding */
363 time_t expire; /*!< When this entry should expire (time out of queue) */
364 struct ast_channel *chan; /*!< Our channel */
365 AST_LIST_HEAD_NOLOCK(,penalty_rule) qe_rules; /*!< Local copy of the queue's penalty rules */
366 struct penalty_rule *pr; /*!< Pointer to the next penalty rule to implement */
367 struct queue_ent *next; /*!< The next queue entry */
371 char interface[80]; /*!< Technology/Location to dial to reach this member*/
372 char state_interface[80]; /*!< Technology/Location from which to read devicestate changes */
373 char membername[80]; /*!< Member name to use in queue logs */
374 int penalty; /*!< Are we a last resort? */
375 int calls; /*!< Number of calls serviced by this member */
376 int dynamic; /*!< Are we dynamically added? */
377 int realtime; /*!< Is this member realtime? */
378 int status; /*!< Status of queue member */
379 int paused; /*!< Are we paused (not accepting calls)? */
380 time_t lastcall; /*!< When last successful call was hungup */
381 struct call_queue *lastqueue; /*!< Last queue we received a call */
382 unsigned int dead:1; /*!< Used to detect members deleted in realtime */
383 unsigned int delme:1; /*!< Flag to delete entry on reload */
386 struct member_interface {
388 AST_LIST_ENTRY(member_interface) list; /*!< Next call queue */
391 static AST_LIST_HEAD_STATIC(interfaces, member_interface);
393 /* values used in multi-bit flags in call_queue */
394 #define QUEUE_EMPTY_NORMAL 1
395 #define QUEUE_EMPTY_STRICT 2
396 #define QUEUE_EMPTY_LOOSE 3
397 #define ANNOUNCEHOLDTIME_ALWAYS 1
398 #define ANNOUNCEHOLDTIME_ONCE 2
399 #define QUEUE_EVENT_VARIABLES 3
401 struct penalty_rule {
402 int time; /*!< Number of seconds that need to pass before applying this rule */
403 int max_value; /*!< The amount specified in the penalty rule for max penalty */
404 int min_value; /*!< The amount specified in the penalty rule for min penalty */
405 int max_relative; /*!< Is the max adjustment relative? 1 for relative, 0 for absolute */
406 int min_relative; /*!< Is the min adjustment relative? 1 for relative, 0 for absolute */
407 AST_LIST_ENTRY(penalty_rule) list; /*!< Next penalty_rule */
411 AST_DECLARE_STRING_FIELDS(
413 AST_STRING_FIELD(name);
414 /*! Music on Hold class */
415 AST_STRING_FIELD(moh);
416 /*! Announcement to play when call is answered */
417 AST_STRING_FIELD(announce);
419 AST_STRING_FIELD(context);
420 /*! Macro to run upon member connection */
421 AST_STRING_FIELD(membermacro);
422 /*! Gosub to run upon member connection */
423 AST_STRING_FIELD(membergosub);
424 /*! Default rule to use if none specified in call to Queue() */
425 AST_STRING_FIELD(defaultrule);
426 /*! Sound file: "Your call is now first in line" (def. queue-youarenext) */
427 AST_STRING_FIELD(sound_next);
428 /*! Sound file: "There are currently" (def. queue-thereare) */
429 AST_STRING_FIELD(sound_thereare);
430 /*! Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting) */
431 AST_STRING_FIELD(sound_calls);
432 /*! Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
433 AST_STRING_FIELD(sound_holdtime);
434 /*! Sound file: "minutes." (def. queue-minutes) */
435 AST_STRING_FIELD(sound_minutes);
436 /*! Sound file: "minute." (def. queue-minute) */
437 AST_STRING_FIELD(sound_minute);
438 /*! Sound file: "seconds." (def. queue-seconds) */
439 AST_STRING_FIELD(sound_seconds);
440 /*! Sound file: "Thank you for your patience." (def. queue-thankyou) */
441 AST_STRING_FIELD(sound_thanks);
442 /*! Sound file: Custom announce for caller, no default */
443 AST_STRING_FIELD(sound_callerannounce);
444 /*! Sound file: "Hold time" (def. queue-reporthold) */
445 AST_STRING_FIELD(sound_reporthold);
447 /*! Sound files: Custom announce, no default */
448 struct ast_str *sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS];
450 unsigned int joinempty:2;
451 unsigned int eventwhencalled:2;
452 unsigned int leavewhenempty:2;
453 unsigned int ringinuse:1;
454 unsigned int setinterfacevar:1;
455 unsigned int setqueuevar:1;
456 unsigned int setqueueentryvar:1;
457 unsigned int reportholdtime:1;
458 unsigned int wrapped:1;
459 unsigned int timeoutrestart:1;
460 unsigned int announceholdtime:2;
461 unsigned int announceposition:1;
463 unsigned int maskmemberstatus:1;
464 unsigned int realtime:1;
465 unsigned int found:1;
466 int announcefrequency; /*!< How often to announce their position */
467 int minannouncefrequency; /*!< The minimum number of seconds between position announcements (def. 15) */
468 int periodicannouncefrequency; /*!< How often to play periodic announcement */
469 int numperiodicannounce; /*!< The number of periodic announcements configured */
470 int randomperiodicannounce; /*!< Are periodic announcments randomly chosen */
471 int roundingseconds; /*!< How many seconds do we round to? */
472 int holdtime; /*!< Current avg holdtime, based on recursive boxcar filter */
473 int callscompleted; /*!< Number of queue calls completed */
474 int callsabandoned; /*!< Number of queue calls abandoned */
475 int servicelevel; /*!< seconds setting for servicelevel*/
476 int callscompletedinsl; /*!< Number of calls answered with servicelevel*/
477 char monfmt[8]; /*!< Format to use when recording calls */
478 int montype; /*!< Monitor type Monitor vs. MixMonitor */
479 int count; /*!< How many entries */
480 int maxlen; /*!< Max number of entries */
481 int wrapuptime; /*!< Wrapup Time */
483 int retry; /*!< Retry calling everyone after this amount of time */
484 int timeout; /*!< How long to wait for an answer */
485 int weight; /*!< Respective weight */
486 int autopause; /*!< Auto pause queue members if they fail to answer */
488 /* Queue strategy things */
489 int rrpos; /*!< Round Robin - position */
490 int memberdelay; /*!< Seconds to delay connecting member to caller */
491 int autofill; /*!< Ignore the head call status and ring an available agent */
493 struct ao2_container *members; /*!< Head of the list of members */
495 * \brief Number of members _logged in_
496 * \note There will be members in the members container that are not logged
497 * in, so this can not simply be replaced with ao2_container_count().
500 struct queue_ent *head; /*!< Head of the list of callers */
501 AST_LIST_ENTRY(call_queue) list; /*!< Next call queue */
502 AST_LIST_HEAD_NOLOCK(, penalty_rule) rules; /*!< The list of penalty rules to invoke */
507 AST_LIST_HEAD_NOLOCK(,penalty_rule) rules;
508 AST_LIST_ENTRY(rule_list) list;
511 AST_LIST_HEAD_STATIC(rule_lists, rule_list);
513 static struct ao2_container *queues;
515 static void update_realtime_members(struct call_queue *q);
516 static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused);
518 /*! \brief sets the QUEUESTATUS channel variable */
519 static void set_queue_result(struct ast_channel *chan, enum queue_result res)
523 for (i = 0; i < ARRAY_LEN(queue_results); i++) {
524 if (queue_results[i].id == res) {
525 pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
531 static const char *int2strat(int strategy)
535 for (x = 0; x < ARRAY_LEN(strategies); x++) {
536 if (strategy == strategies[x].strategy)
537 return strategies[x].name;
543 static int strat2int(const char *strategy)
547 for (x = 0; x < ARRAY_LEN(strategies); x++) {
548 if (!strcasecmp(strategy, strategies[x].name))
549 return strategies[x].strategy;
555 static int queue_hash_cb(const void *obj, const int flags)
557 const struct call_queue *q = obj;
558 return ast_str_hash(q->name);
561 static int queue_cmp_cb(void *obj, void *arg, int flags)
563 struct call_queue *q = obj, *q2 = arg;
564 return !strcasecmp(q->name, q2->name) ? CMP_MATCH : 0;
567 static inline struct call_queue *queue_ref(struct call_queue *q)
573 static inline struct call_queue *queue_unref(struct call_queue *q)
579 /*! \brief Set variables of queue */
580 static void set_queue_variables(struct queue_ent *qe)
582 char interfacevar[256]="";
585 if (qe->parent->setqueuevar) {
587 if (qe->parent->callscompleted > 0)
588 sl = 100 * ((float) qe->parent->callscompletedinsl / (float) qe->parent->callscompleted);
590 snprintf(interfacevar, sizeof(interfacevar),
591 "QUEUENAME=%s|QUEUEMAX=%d|QUEUESTRATEGY=%s|QUEUECALLS=%d|QUEUEHOLDTIME=%d|QUEUECOMPLETED=%d|QUEUEABANDONED=%d|QUEUESRVLEVEL=%d|QUEUESRVLEVELPERF=%2.1f",
592 qe->parent->name, qe->parent->maxlen, int2strat(qe->parent->strategy), qe->parent->count, qe->parent->holdtime, qe->parent->callscompleted,
593 qe->parent->callsabandoned, qe->parent->servicelevel, sl);
595 pbx_builtin_setvar(qe->chan, interfacevar);
599 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
600 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
602 struct queue_ent *cur;
619 enum queue_member_status {
621 QUEUE_NO_REACHABLE_MEMBERS,
622 QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
626 /*! \brief Check if members are available
628 * This function checks to see if members are available to be called. If any member
629 * is available, the function immediately returns QUEUE_NORMAL. If no members are available,
630 * the appropriate reason why is returned
632 static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty, int min_penalty)
634 struct member *member;
635 struct ao2_iterator mem_iter;
636 enum queue_member_status result = QUEUE_NO_MEMBERS;
639 mem_iter = ao2_iterator_init(q->members, 0);
640 for (; (member = ao2_iterator_next(&mem_iter)); ao2_ref(member, -1)) {
641 if ((max_penalty && (member->penalty > max_penalty)) || (min_penalty && (member->penalty < min_penalty)))
644 switch (member->status) {
645 case AST_DEVICE_INVALID:
648 case AST_DEVICE_UNAVAILABLE:
649 if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)
650 result = QUEUE_NO_REACHABLE_MEMBERS;
653 if (member->paused) {
654 result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
669 AST_LIST_ENTRY(statechange) entry;
674 /*! \brief set a member's status based on device state of that member's state_interface.
676 * Lock interface list find sc, iterate through each queues queue_member list for member to
677 * update state inside queues
679 static int update_status(const char *interface, const int status)
682 struct ao2_iterator mem_iter, queue_iter;
683 struct call_queue *q;
685 queue_iter = ao2_iterator_init(queues, 0);
686 while ((q = ao2_iterator_next(&queue_iter))) {
688 mem_iter = ao2_iterator_init(q->members, 0);
689 while ((cur = ao2_iterator_next(&mem_iter))) {
692 tmp_interface = ast_strdupa(cur->state_interface);
693 if ((slash_pos = strchr(interface, '/')))
694 if ((slash_pos = strchr(slash_pos + 1, '/')))
697 if (strcasecmp(interface, tmp_interface)) {
702 if (cur->status != status) {
703 cur->status = status;
704 if (q->maskmemberstatus) {
709 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
719 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static",
720 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
731 /*! \brief set a member's status based on device state of that member's interface*/
732 static void *handle_statechange(struct statechange *sc)
734 struct member_interface *curint;
738 technology = ast_strdupa(sc->dev);
739 loc = strchr(technology, '/');
746 AST_LIST_LOCK(&interfaces);
747 AST_LIST_TRAVERSE(&interfaces, curint, list) {
750 interface = ast_strdupa(curint->interface);
751 if ((slash_pos = strchr(interface, '/')))
752 if ((slash_pos = strchr(slash_pos + 1, '/')))
755 if (!strcasecmp(interface, sc->dev))
758 AST_LIST_UNLOCK(&interfaces);
761 if (option_debug > 2)
762 ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state));
767 ast_log(LOG_DEBUG, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
769 update_status(sc->dev, sc->state);
774 /*! \brief Data used by the device state thread */
776 /*! Set to 1 to stop the thread */
778 /*! The device state monitoring thread */
780 /*! Lock for the state change queue */
782 /*! Condition for the state change queue */
784 /*! Queue of state changes */
785 AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
787 .thread = AST_PTHREADT_NULL,
790 /*! \brief Consumer of the statechange queue */
791 static void *device_state_thread(void *data)
793 struct statechange *sc = NULL;
795 while (!device_state.stop) {
796 ast_mutex_lock(&device_state.lock);
797 if (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
798 ast_cond_wait(&device_state.cond, &device_state.lock);
799 sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry);
801 ast_mutex_unlock(&device_state.lock);
803 /* Check to see if we were woken up to see the request to stop */
804 if (device_state.stop)
810 handle_statechange(sc);
819 while ((sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry)))
825 /*! \brief Producer of the statechange queue */
826 static int statechange_queue(const char *dev, enum ast_device_state state)
828 struct statechange *sc;
830 if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
834 strcpy(sc->dev, dev);
836 ast_mutex_lock(&device_state.lock);
837 AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
838 ast_cond_signal(&device_state.cond);
839 ast_mutex_unlock(&device_state.lock);
844 static void device_state_cb(const struct ast_event *event, void *unused)
846 enum ast_device_state state;
849 state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
850 device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
852 if (ast_strlen_zero(device)) {
853 ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
857 statechange_queue(device, state);
860 /*! \brief allocate space for new queue member and set fields based on parameters passed */
861 static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface)
865 if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
866 cur->penalty = penalty;
867 cur->paused = paused;
868 ast_copy_string(cur->interface, interface, sizeof(cur->interface));
869 if (!ast_strlen_zero(state_interface))
870 ast_copy_string(cur->state_interface, state_interface, sizeof(cur->state_interface));
872 ast_copy_string(cur->state_interface, interface, sizeof(cur->state_interface));
873 if (!ast_strlen_zero(membername))
874 ast_copy_string(cur->membername, membername, sizeof(cur->membername));
876 ast_copy_string(cur->membername, interface, sizeof(cur->membername));
877 if (!strchr(cur->interface, '/'))
878 ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
879 cur->status = ast_device_state(cur->state_interface);
886 static int compress_char(const char c)
896 static int member_hash_fn(const void *obj, const int flags)
898 const struct member *mem = obj;
899 const char *chname = strchr(mem->interface, '/');
902 chname = mem->interface;
903 for (i = 0; i < 5 && chname[i]; i++)
904 ret += compress_char(chname[i]) << (i * 6);
908 static int member_cmp_fn(void *obj1, void *obj2, int flags)
910 struct member *mem1 = obj1, *mem2 = obj2;
911 return strcasecmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
915 * \brief Initialize Queue default values.
916 * \note the queue's lock must be held before executing this function
918 static void init_queue(struct call_queue *q)
921 struct penalty_rule *pr_iter;
924 q->retry = DEFAULT_RETRY;
927 q->announcefrequency = 0;
928 q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
929 q->announceholdtime = 0;
930 q->announceholdtime = 1;
931 q->roundingseconds = 0; /* Default - don't announce seconds */
934 q->setinterfacevar = 0;
936 q->setqueueentryvar = 0;
937 q->autofill = autofill_default;
938 q->montype = montype_default;
940 q->reportholdtime = 0;
944 q->leavewhenempty = 0;
946 q->maskmemberstatus = 0;
947 q->eventwhencalled = 0;
949 q->timeoutrestart = 0;
950 q->periodicannouncefrequency = 0;
951 q->randomperiodicannounce = 0;
952 q->numperiodicannounce = 0;
954 if (q->strategy == QUEUE_STRATEGY_LINEAR)
955 /* linear strategy depends on order, so we have to place all members in a single bucket */
956 q->members = ao2_container_alloc(1, member_hash_fn, member_cmp_fn);
958 q->members = ao2_container_alloc(37, member_hash_fn, member_cmp_fn);
963 ast_string_field_set(q, sound_next, "queue-youarenext");
964 ast_string_field_set(q, sound_thereare, "queue-thereare");
965 ast_string_field_set(q, sound_calls, "queue-callswaiting");
966 ast_string_field_set(q, sound_holdtime, "queue-holdtime");
967 ast_string_field_set(q, sound_minutes, "queue-minutes");
968 ast_string_field_set(q, sound_minute, "queue-minute");
969 ast_string_field_set(q, sound_seconds, "queue-seconds");
970 ast_string_field_set(q, sound_thanks, "queue-thankyou");
971 ast_string_field_set(q, sound_reporthold, "queue-reporthold");
973 if ((q->sound_periodicannounce[0] = ast_str_create(32)))
974 ast_str_set(&q->sound_periodicannounce[0], 0, "queue-periodic-announce");
976 for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
977 if (q->sound_periodicannounce[i])
978 ast_str_set(&q->sound_periodicannounce[i], 0, "%s", "");
981 while ((pr_iter = AST_LIST_REMOVE_HEAD(&q->rules,list)))
985 static void clear_queue(struct call_queue *q)
988 q->callscompleted = 0;
989 q->callsabandoned = 0;
990 q->callscompletedinsl = 0;
994 static int add_to_interfaces(const char *interface)
996 struct member_interface *curint;
998 AST_LIST_LOCK(&interfaces);
999 AST_LIST_TRAVERSE(&interfaces, curint, list) {
1000 if (!strcasecmp(curint->interface, interface))
1005 AST_LIST_UNLOCK(&interfaces);
1009 ast_debug(1, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
1011 if ((curint = ast_calloc(1, sizeof(*curint)))) {
1012 ast_copy_string(curint->interface, interface, sizeof(curint->interface));
1013 AST_LIST_INSERT_HEAD(&interfaces, curint, list);
1015 AST_LIST_UNLOCK(&interfaces);
1020 static int interface_exists_global(const char *interface)
1022 struct call_queue *q;
1023 struct member *mem, tmpmem;
1024 struct ao2_iterator queue_iter, mem_iter;
1027 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1028 queue_iter = ao2_iterator_init(queues, 0);
1029 while ((q = ao2_iterator_next(&queue_iter))) {
1031 mem_iter = ao2_iterator_init(q->members, 0);
1032 while ((mem = ao2_iterator_next(&mem_iter))) {
1033 if (!strcasecmp(mem->state_interface, interface)) {
1046 static int remove_from_interfaces(const char *interface)
1048 struct member_interface *curint;
1050 if (interface_exists_global(interface))
1053 AST_LIST_LOCK(&interfaces);
1054 AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
1055 if (!strcasecmp(curint->interface, interface)) {
1056 ast_debug(1, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
1057 AST_LIST_REMOVE_CURRENT(list);
1062 AST_LIST_TRAVERSE_SAFE_END;
1063 AST_LIST_UNLOCK(&interfaces);
1068 static void clear_and_free_interfaces(void)
1070 struct member_interface *curint;
1072 AST_LIST_LOCK(&interfaces);
1073 while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
1075 AST_LIST_UNLOCK(&interfaces);
1079 * \brief Change queue penalty by adding rule.
1081 * Check rule for errors with time or fomatting, see if rule is relative to rest
1082 * of queue, iterate list of rules to find correct insertion point, insert and return.
1083 * \retval -1 on failure
1084 * \retval 0 on success
1085 * \note Call this with the rule_lists locked
1087 static int insert_penaltychange (const char *list_name, const char *content, const int linenum)
1089 char *timestr, *maxstr, *minstr, *contentdup;
1090 struct penalty_rule *rule = NULL, *rule_iter;
1091 struct rule_list *rl_iter;
1092 int time, inserted = 0;
1094 if (!(rule = ast_calloc(1, sizeof(*rule)))) {
1095 ast_log(LOG_ERROR, "Cannot allocate memory for penaltychange rule at line %d!\n", linenum);
1099 contentdup = ast_strdupa(content);
1101 if (!(maxstr = strchr(contentdup, ','))) {
1102 ast_log(LOG_WARNING, "Improperly formatted penaltychange rule at line %d. Ignoring.\n", linenum);
1108 timestr = contentdup;
1110 if ((time = atoi(timestr)) < 0) {
1111 ast_log(LOG_WARNING, "Improper time parameter specified for penaltychange rule at line %d. Ignoring.\n", linenum);
1118 if ((minstr = strchr(maxstr,',')))
1121 /* The last check will evaluate true if either no penalty change is indicated for a given rule
1122 * OR if a min penalty change is indicated but no max penalty change is */
1123 if (*maxstr == '+' || *maxstr == '-' || *maxstr == '\0') {
1124 rule->max_relative = 1;
1127 rule->max_value = atoi(maxstr);
1129 if (!ast_strlen_zero(minstr)) {
1130 if (*minstr == '+' || *minstr == '-')
1131 rule->min_relative = 1;
1132 rule->min_value = atoi(minstr);
1133 } else /*there was no minimum specified, so assume this means no change*/
1134 rule->min_relative = 1;
1136 /*We have the rule made, now we need to insert it where it belongs*/
1137 AST_LIST_TRAVERSE(&rule_lists, rl_iter, list){
1138 if (strcasecmp(rl_iter->name, list_name))
1141 AST_LIST_TRAVERSE_SAFE_BEGIN(&rl_iter->rules, rule_iter, list) {
1142 if (rule->time < rule_iter->time) {
1143 AST_LIST_INSERT_BEFORE_CURRENT(rule, list);
1148 AST_LIST_TRAVERSE_SAFE_END;
1151 AST_LIST_INSERT_TAIL(&rl_iter->rules, rule, list);
1158 /*! \brief Configure a queue parameter.
1160 * The failunknown flag is set for config files (and static realtime) to show
1161 * errors for unknown parameters. It is cleared for dynamic realtime to allow
1162 * extra fields in the tables.
1163 * \note For error reporting, line number is passed for .conf static configuration,
1164 * for Realtime queues, linenum is -1.
1166 static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
1168 if (!strcasecmp(param, "musicclass") ||
1169 !strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
1170 ast_string_field_set(q, moh, val);
1171 } else if (!strcasecmp(param, "announce")) {
1172 ast_string_field_set(q, announce, val);
1173 } else if (!strcasecmp(param, "context")) {
1174 ast_string_field_set(q, context, val);
1175 } else if (!strcasecmp(param, "timeout")) {
1176 q->timeout = atoi(val);
1178 q->timeout = DEFAULT_TIMEOUT;
1179 } else if (!strcasecmp(param, "ringinuse")) {
1180 q->ringinuse = ast_true(val);
1181 } else if (!strcasecmp(param, "setinterfacevar")) {
1182 q->setinterfacevar = ast_true(val);
1183 } else if (!strcasecmp(param, "setqueuevar")) {
1184 q->setqueuevar = ast_true(val);
1185 } else if (!strcasecmp(param, "setqueueentryvar")) {
1186 q->setqueueentryvar = ast_true(val);
1187 } else if (!strcasecmp(param, "monitor-format")) {
1188 ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
1189 } else if (!strcasecmp(param, "membermacro")) {
1190 ast_string_field_set(q, membermacro, val);
1191 } else if (!strcasecmp(param, "membergosub")) {
1192 ast_string_field_set(q, membergosub, val);
1193 } else if (!strcasecmp(param, "queue-youarenext")) {
1194 ast_string_field_set(q, sound_next, val);
1195 } else if (!strcasecmp(param, "queue-thereare")) {
1196 ast_string_field_set(q, sound_thereare, val);
1197 } else if (!strcasecmp(param, "queue-callswaiting")) {
1198 ast_string_field_set(q, sound_calls, val);
1199 } else if (!strcasecmp(param, "queue-holdtime")) {
1200 ast_string_field_set(q, sound_holdtime, val);
1201 } else if (!strcasecmp(param, "queue-minutes")) {
1202 ast_string_field_set(q, sound_minutes, val);
1203 } else if (!strcasecmp(param, "queue-minute")) {
1204 ast_string_field_set(q, sound_minute, val);
1205 } else if (!strcasecmp(param, "queue-seconds")) {
1206 ast_string_field_set(q, sound_seconds, val);
1207 } else if (!strcasecmp(param, "queue-thankyou")) {
1208 ast_string_field_set(q, sound_thanks, val);
1209 } else if (!strcasecmp(param, "queue-callerannounce")) {
1210 ast_string_field_set(q, sound_callerannounce, val);
1211 } else if (!strcasecmp(param, "queue-reporthold")) {
1212 ast_string_field_set(q, sound_reporthold, val);
1213 } else if (!strcasecmp(param, "announce-frequency")) {
1214 q->announcefrequency = atoi(val);
1215 } else if (!strcasecmp(param, "min-announce-frequency")) {
1216 q->minannouncefrequency = atoi(val);
1217 ast_debug(1, "%s=%s for queue '%s'\n", param, val, q->name);
1218 } else if (!strcasecmp(param, "announce-round-seconds")) {
1219 q->roundingseconds = atoi(val);
1220 /* Rounding to any other values just doesn't make sense... */
1221 if (!(q->roundingseconds == 0 || q->roundingseconds == 5 || q->roundingseconds == 10
1222 || q->roundingseconds == 15 || q->roundingseconds == 20 || q->roundingseconds == 30)) {
1224 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1225 "using 0 instead for queue '%s' at line %d of queues.conf\n",
1226 val, param, q->name, linenum);
1228 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1229 "using 0 instead for queue '%s'\n", val, param, q->name);
1231 q->roundingseconds=0;
1233 } else if (!strcasecmp(param, "announce-holdtime")) {
1234 if (!strcasecmp(val, "once"))
1235 q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
1236 else if (ast_true(val))
1237 q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
1239 q->announceholdtime = 0;
1240 } else if (!strcasecmp(param, "announce-position")) {
1241 q->announceposition = ast_true(val);
1242 } else if (!strcasecmp(param, "periodic-announce")) {
1243 if (strchr(val, ',')) {
1244 char *s, *buf = ast_strdupa(val);
1247 while ((s = strsep(&buf, ",|"))) {
1248 if (!q->sound_periodicannounce[i])
1249 q->sound_periodicannounce[i] = ast_str_create(16);
1250 ast_str_set(&q->sound_periodicannounce[i], 0, "%s", s);
1252 if (i == MAX_PERIODIC_ANNOUNCEMENTS)
1255 q->numperiodicannounce = i;
1257 ast_str_set(&q->sound_periodicannounce[0], 0, "%s", val);
1258 q->numperiodicannounce = 1;
1260 } else if (!strcasecmp(param, "periodic-announce-frequency")) {
1261 q->periodicannouncefrequency = atoi(val);
1262 } else if (!strcasecmp(param, "random-periodic-announce")) {
1263 q->randomperiodicannounce = ast_true(val);
1264 } else if (!strcasecmp(param, "retry")) {
1265 q->retry = atoi(val);
1267 q->retry = DEFAULT_RETRY;
1268 } else if (!strcasecmp(param, "wrapuptime")) {
1269 q->wrapuptime = atoi(val);
1270 } else if (!strcasecmp(param, "autofill")) {
1271 q->autofill = ast_true(val);
1272 } else if (!strcasecmp(param, "monitor-type")) {
1273 if (!strcasecmp(val, "mixmonitor"))
1275 } else if (!strcasecmp(param, "autopause")) {
1276 q->autopause = ast_true(val);
1277 } else if (!strcasecmp(param, "maxlen")) {
1278 q->maxlen = atoi(val);
1281 } else if (!strcasecmp(param, "servicelevel")) {
1282 q->servicelevel= atoi(val);
1283 } else if (!strcasecmp(param, "strategy")) {
1284 /* We already have set this, no need to do it again */
1286 } else if (!strcasecmp(param, "joinempty")) {
1287 if (!strcasecmp(val, "loose"))
1288 q->joinempty = QUEUE_EMPTY_LOOSE;
1289 else if (!strcasecmp(val, "strict"))
1290 q->joinempty = QUEUE_EMPTY_STRICT;
1291 else if (ast_true(val))
1292 q->joinempty = QUEUE_EMPTY_NORMAL;
1295 } else if (!strcasecmp(param, "leavewhenempty")) {
1296 if (!strcasecmp(val, "loose"))
1297 q->leavewhenempty = QUEUE_EMPTY_LOOSE;
1298 else if (!strcasecmp(val, "strict"))
1299 q->leavewhenempty = QUEUE_EMPTY_STRICT;
1300 else if (ast_true(val))
1301 q->leavewhenempty = QUEUE_EMPTY_NORMAL;
1303 q->leavewhenempty = 0;
1304 } else if (!strcasecmp(param, "eventmemberstatus")) {
1305 q->maskmemberstatus = !ast_true(val);
1306 } else if (!strcasecmp(param, "eventwhencalled")) {
1307 if (!strcasecmp(val, "vars")) {
1308 q->eventwhencalled = QUEUE_EVENT_VARIABLES;
1310 q->eventwhencalled = ast_true(val) ? 1 : 0;
1312 } else if (!strcasecmp(param, "reportholdtime")) {
1313 q->reportholdtime = ast_true(val);
1314 } else if (!strcasecmp(param, "memberdelay")) {
1315 q->memberdelay = atoi(val);
1316 } else if (!strcasecmp(param, "weight")) {
1317 q->weight = atoi(val);
1320 /* With Realtime queues, if the last queue using weights is deleted in realtime,
1321 we will not see any effect on use_weight until next reload. */
1322 } else if (!strcasecmp(param, "timeoutrestart")) {
1323 q->timeoutrestart = ast_true(val);
1324 } else if (!strcasecmp(param, "defaultrule")) {
1325 ast_string_field_set(q, defaultrule, val);
1326 } else if (failunknown) {
1328 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
1329 q->name, param, linenum);
1331 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
1337 * \brief Find rt member record to update otherwise create one.
1339 * Search for member in queue, if found update penalty/paused state,
1340 * if no memeber exists create one flag it as a RT member and add to queue member list.
1342 static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str, const char* state_interface)
1344 struct member *m, tmpmem;
1349 penalty = atoi(penalty_str);
1355 paused = atoi(paused_str);
1360 /* Find the member, or the place to put a new one. */
1361 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1362 m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
1364 /* Create a new one if not found, else update penalty */
1366 if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
1369 add_to_interfaces(m->state_interface);
1370 ao2_link(q->members, m);
1376 m->dead = 0; /* Do not delete this one. */
1379 if (strcasecmp(state_interface, m->state_interface)) {
1380 remove_from_interfaces(m->state_interface);
1381 ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface));
1382 add_to_interfaces(m->state_interface);
1384 m->penalty = penalty;
1389 /*! \brief Iterate through queue's member list and delete them */
1390 static void free_members(struct call_queue *q, int all)
1392 /* Free non-dynamic members */
1394 struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
1396 while ((cur = ao2_iterator_next(&mem_iter))) {
1397 if (all || !cur->dynamic) {
1398 ao2_unlink(q->members, cur);
1399 remove_from_interfaces(cur->state_interface);
1406 /*! \brief Free queue's member list then its string fields */
1407 static void destroy_queue(void *obj)
1409 struct call_queue *q = obj;
1412 ast_debug(0, "Queue destructor called for queue '%s'!\n", q->name);
1415 ast_string_field_free_memory(q);
1416 for (i = 0; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
1417 if (q->sound_periodicannounce[i])
1418 free(q->sound_periodicannounce[i]);
1420 ao2_ref(q->members, -1);
1423 static struct call_queue *alloc_queue(const char *queuename)
1425 struct call_queue *q;
1427 if ((q = ao2_alloc(sizeof(*q), destroy_queue))) {
1428 if (ast_string_field_init(q, 64)) {
1432 ast_string_field_set(q, name, queuename);
1438 * \brief Reload a single queue via realtime.
1440 * Check for statically defined queue first, check if deleted RT queue,
1441 * check for new RT queue, if queue vars are not defined init them with defaults.
1442 * reload RT queue vars, set RT queue members dead and reload them, return finished queue.
1443 * \retval the queue,
1444 * \retval NULL if it doesn't exist.
1445 * \note Should be called with the "queues" container locked.
1447 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
1449 struct ast_variable *v;
1450 struct call_queue *q, tmpq = {
1454 struct ao2_iterator mem_iter;
1455 char *interface = NULL;
1456 const char *tmp_name;
1458 char tmpbuf[64]; /* Must be longer than the longest queue param name. */
1460 /* Static queues override realtime. */
1461 if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
1469 ast_log(LOG_WARNING, "Static queue '%s' already exists. Not loading from realtime\n", q->name);
1475 } else if (!member_config)
1476 /* Not found in the list, and it's not realtime ... */
1479 /* Check if queue is defined in realtime. */
1481 /* Delete queue from in-core list if it has been deleted in realtime. */
1483 /*! \note Hmm, can't seem to distinguish a DB failure from a not
1484 found condition... So we might delete an in-core queue
1485 in case of DB failure. */
1486 ast_debug(1, "Queue %s not found in realtime.\n", queuename);
1489 /* Delete if unused (else will be deleted when last caller leaves). */
1490 ao2_unlink(queues, q);
1497 /* Create a new queue if an in-core entry does not exist yet. */
1499 struct ast_variable *tmpvar = NULL;
1500 if (!(q = alloc_queue(queuename)))
1505 /*Before we initialize the queue, we need to set the strategy, so that linear strategy
1506 * will allocate the members properly
1508 for (tmpvar = queue_vars; tmpvar; tmpvar = tmpvar->next) {
1509 if (!strcasecmp(tmpvar->name, "strategy")) {
1510 q->strategy = strat2int(tmpvar->value);
1511 if (q->strategy < 0) {
1512 ast_log(LOG_WARNING, "'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
1513 tmpvar->value, q->name);
1514 q->strategy = QUEUE_STRATEGY_RINGALL;
1519 /* We traversed all variables and didn't find a strategy */
1521 q->strategy = QUEUE_STRATEGY_RINGALL;
1522 init_queue(q); /* Ensure defaults for all parameters not set explicitly. */
1523 ao2_link(queues, q);
1524 ast_variables_destroy(tmpvar);
1527 memset(tmpbuf, 0, sizeof(tmpbuf));
1528 for (v = queue_vars; v; v = v->next) {
1529 /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
1530 if ((tmp = strchr(v->name, '_'))) {
1531 ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
1534 while ((tmp = strchr(tmp, '_')))
1538 queue_set_param(q, tmp_name, v->value, -1, 0);
1541 /* Temporarily set realtime members dead so we can detect deleted ones.
1542 * Also set the membercount correctly for realtime*/
1543 mem_iter = ao2_iterator_init(q->members, 0);
1544 while ((m = ao2_iterator_next(&mem_iter))) {
1551 while ((interface = ast_category_browse(member_config, interface))) {
1552 rt_handle_member_record(q, interface,
1553 S_OR(ast_variable_retrieve(member_config, interface, "membername"),interface),
1554 ast_variable_retrieve(member_config, interface, "penalty"),
1555 ast_variable_retrieve(member_config, interface, "paused"),
1556 S_OR(ast_variable_retrieve(member_config, interface, "state_interface"),interface));
1559 /* Delete all realtime members that have been deleted in DB. */
1560 mem_iter = ao2_iterator_init(q->members, 0);
1561 while ((m = ao2_iterator_next(&mem_iter))) {
1563 ao2_unlink(q->members, m);
1564 remove_from_interfaces(m->state_interface);
1575 static struct call_queue *load_realtime_queue(const char *queuename)
1577 struct ast_variable *queue_vars;
1578 struct ast_config *member_config = NULL;
1579 struct call_queue *q = NULL, tmpq = {
1583 /* Find the queue in the in-core list first. */
1584 q = ao2_find(queues, &tmpq, OBJ_POINTER);
1586 if (!q || q->realtime) {
1587 /*! \note Load from realtime before taking the "queues" container lock, to avoid blocking all
1588 queue operations while waiting for the DB.
1590 This will be two separate database transactions, so we might
1591 see queue parameters as they were before another process
1592 changed the queue and member list as it was after the change.
1593 Thus we might see an empty member list when a queue is
1594 deleted. In practise, this is unlikely to cause a problem. */
1596 queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
1598 member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
1599 if (!member_config) {
1600 ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
1601 ast_variables_destroy(queue_vars);
1607 q = find_queue_by_name_rt(queuename, queue_vars, member_config);
1609 ast_config_destroy(member_config);
1611 ast_variables_destroy(queue_vars);
1615 update_realtime_members(q);
1620 static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
1622 struct ast_variable *var;
1625 if (!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL)))
1628 if (!strcmp(var->name, "uniqueid"))
1632 if (var && !ast_strlen_zero(var->value)) {
1633 if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
1639 static void update_realtime_members(struct call_queue *q)
1641 struct ast_config *member_config = NULL;
1643 char *interface = NULL;
1644 struct ao2_iterator mem_iter;
1646 if (!(member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL))) {
1647 /*This queue doesn't have realtime members*/
1648 ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
1654 /* Temporarily set realtime members dead so we can detect deleted ones.*/
1655 mem_iter = ao2_iterator_init(q->members, 0);
1656 while ((m = ao2_iterator_next(&mem_iter))) {
1662 while ((interface = ast_category_browse(member_config, interface))) {
1663 rt_handle_member_record(q, interface,
1664 S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
1665 ast_variable_retrieve(member_config, interface, "penalty"),
1666 ast_variable_retrieve(member_config, interface, "paused"),
1667 S_OR(ast_variable_retrieve(member_config, interface, "state_interface"), interface));
1670 /* Delete all realtime members that have been deleted in DB. */
1671 mem_iter = ao2_iterator_init(q->members, 0);
1672 while ((m = ao2_iterator_next(&mem_iter))) {
1674 ao2_unlink(q->members, m);
1675 remove_from_interfaces(m->state_interface);
1681 ast_config_destroy(member_config);
1684 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
1686 struct call_queue *q;
1687 struct queue_ent *cur, *prev = NULL;
1691 enum queue_member_status stat;
1693 if (!(q = load_realtime_queue(queuename)))
1699 /* This is our one */
1700 stat = get_member_status(q, qe->max_penalty, qe->min_penalty);
1701 if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
1702 *reason = QUEUE_JOINEMPTY;
1703 else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
1704 *reason = QUEUE_JOINUNAVAIL;
1705 else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
1706 *reason = QUEUE_JOINUNAVAIL;
1707 else if (q->maxlen && (q->count >= q->maxlen))
1708 *reason = QUEUE_FULL;
1710 /* There's space for us, put us at the right position inside
1712 * Take into account the priority of the calling user */
1717 /* We have higher priority than the current user, enter
1718 * before him, after all the other users with priority
1719 * higher or equal to our priority. */
1720 if ((!inserted) && (qe->prio > cur->prio)) {
1721 insert_entry(q, prev, qe, &pos);
1728 /* No luck, join at the end of the queue */
1730 insert_entry(q, prev, qe, &pos);
1731 ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
1732 ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
1733 ast_copy_string(qe->context, q->context, sizeof(qe->context));
1736 manager_event(EVENT_FLAG_CALL, "Join",
1737 "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
1739 S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
1740 S_OR(qe->chan->cid.cid_name, "unknown"),
1741 q->name, qe->pos, q->count, qe->chan->uniqueid );
1742 ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
1750 static int play_file(struct ast_channel *chan, const char *filename)
1754 ast_stopstream(chan);
1756 res = ast_streamfile(chan, filename, chan->language);
1758 res = ast_waitstream(chan, AST_DIGIT_ANY);
1760 ast_stopstream(chan);
1766 * \brief Check for valid exit from queue via goto
1767 * \retval 0 if failure
1768 * \retval 1 if successful
1770 static int valid_exit(struct queue_ent *qe, char digit)
1772 int digitlen = strlen(qe->digits);
1774 /* Prevent possible buffer overflow */
1775 if (digitlen < sizeof(qe->digits) - 2) {
1776 qe->digits[digitlen] = digit;
1777 qe->digits[digitlen + 1] = '\0';
1779 qe->digits[0] = '\0';
1783 /* If there's no context to goto, short-circuit */
1784 if (ast_strlen_zero(qe->context))
1787 /* If the extension is bad, then reset the digits to blank */
1788 if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
1789 qe->digits[0] = '\0';
1793 /* We have an exact match */
1794 if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
1795 qe->valid_digits = 1;
1796 /* Return 1 on a successful goto */
1803 static int say_position(struct queue_ent *qe, int ringing)
1805 int res = 0, avgholdmins, avgholdsecs;
1808 /* Let minannouncefrequency seconds pass between the start of each position announcement */
1810 if ((now - qe->last_pos) < qe->parent->minannouncefrequency)
1813 /* If either our position has changed, or we are over the freq timer, say position */
1814 if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
1818 ast_indicate(qe->chan,-1);
1820 ast_moh_stop(qe->chan);
1822 if (qe->parent->announceposition) {
1823 /* Say we're next, if we are */
1825 res = play_file(qe->chan, qe->parent->sound_next);
1831 res = play_file(qe->chan, qe->parent->sound_thereare);
1834 res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, NULL); /* Needs gender */
1837 res = play_file(qe->chan, qe->parent->sound_calls);
1842 /* Round hold time to nearest minute */
1843 avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
1845 /* If they have specified a rounding then round the seconds as well */
1846 if (qe->parent->roundingseconds) {
1847 avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
1848 avgholdsecs *= qe->parent->roundingseconds;
1853 ast_verb(3, "Hold time for %s is %d minute(s) %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
1855 /* If the hold time is >1 min, if it's enabled, and if it's not
1856 supposed to be only once and we have already said it, say it */
1857 if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
1858 (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
1859 res = play_file(qe->chan, qe->parent->sound_holdtime);
1863 if (avgholdmins > 1) {
1864 res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
1868 if (avgholdmins == 1) {
1869 res = play_file(qe->chan, qe->parent->sound_minute);
1873 res = play_file(qe->chan, qe->parent->sound_minutes);
1878 if (avgholdsecs > 1) {
1879 res = ast_say_number(qe->chan, avgholdmins > 1 ? avgholdsecs : avgholdmins * 60 + avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
1883 res = play_file(qe->chan, qe->parent->sound_seconds);
1891 if (qe->parent->announceposition) {
1892 ast_verb(3, "Told %s in %s their queue position (which was %d)\n",
1893 qe->chan->name, qe->parent->name, qe->pos);
1895 res = play_file(qe->chan, qe->parent->sound_thanks);
1898 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
1901 /* Set our last_pos indicators */
1903 qe->last_pos_said = qe->pos;
1905 /* Don't restart music on hold if we're about to exit the caller from the queue */
1908 ast_indicate(qe->chan, AST_CONTROL_RINGING);
1910 ast_moh_start(qe->chan, qe->moh, NULL);
1915 static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
1919 /* Calculate holdtime using a recursive boxcar filter */
1920 /* Thanks to SRT for this contribution */
1921 /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
1923 ao2_lock(qe->parent);
1924 oldvalue = qe->parent->holdtime;
1925 qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
1926 ao2_unlock(qe->parent);
1929 /*! \brief Caller leaving queue.
1931 * Search the queue to find the leaving client, if found remove from queue
1932 * create manager event, move others up the queue.
1934 static void leave_queue(struct queue_ent *qe)
1936 struct call_queue *q;
1937 struct queue_ent *cur, *prev = NULL;
1938 struct penalty_rule *pr_iter;
1941 if (!(q = qe->parent))
1947 for (cur = q->head; cur; cur = cur->next) {
1951 /* Take us out of the queue */
1952 manager_event(EVENT_FLAG_CALL, "Leave",
1953 "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
1954 qe->chan->name, q->name, q->count, qe->chan->uniqueid);
1955 ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
1956 /* Take us out of the queue */
1958 prev->next = cur->next;
1960 q->head = cur->next;
1961 /* Free penalty rules */
1962 while ((pr_iter = AST_LIST_REMOVE_HEAD(&qe->qe_rules, list)))
1965 /* Renumber the people after us in the queue based on a new count */
1972 /*If the queue is a realtime queue, check to see if it's still defined in real time*/
1974 if (!ast_load_realtime("queues", "name", q->name, NULL))
1979 /* It's dead and nobody is in it, so kill it */
1980 ao2_unlink(queues, q);
1981 /* unref the container's reference to the queue */
1984 /* unref the explicit ref earlier in the function */
1988 /*! \brief Hang up a list of outgoing calls */
1989 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
1991 struct callattempt *oo;
1994 /* Hangup any existing lines we have open */
1995 if (outgoing->chan && (outgoing->chan != exception))
1996 ast_hangup(outgoing->chan);
1998 outgoing = outgoing->q_next;
2000 ao2_ref(oo->member, -1);
2006 * \brief traverse all defined queues which have calls waiting and contain this member
2007 * \retval 0 if no other queue has precedence (higher weight)
2008 * \retval 1 if found
2010 static int compare_weight(struct call_queue *rq, struct member *member)
2012 struct call_queue *q;
2015 struct ao2_iterator queue_iter;
2017 /* q's lock and rq's lock already set by try_calling()
2018 * to solve deadlock */
2019 queue_iter = ao2_iterator_init(queues, 0);
2020 while ((q = ao2_iterator_next(&queue_iter))) {
2021 if (q == rq) { /* don't check myself, could deadlock */
2026 if (q->count && q->members) {
2027 if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
2028 ast_debug(1, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
2029 if (q->weight > rq->weight) {
2030 ast_debug(1, "Queue '%s' (weight %d, calls %d) is preferred over '%s' (weight %d, calls %d)\n", q->name, q->weight, q->count, rq->name, rq->weight, rq->count);
2046 /*! \brief common hangup actions */
2047 static void do_hang(struct callattempt *o)
2050 ast_hangup(o->chan);
2054 /*! \brief convert "\n" to "\nVariable: " ready for manager to use */
2055 static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
2057 struct ast_str *buf = ast_str_alloca(len + 1);
2060 if (pbx_builtin_serialize_variables(chan, &buf)) {
2063 /* convert "\n" to "\nVariable: " */
2064 strcpy(vars, "Variable: ");
2067 for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
2070 if (tmp[i + 1] == '\0')
2072 if (tmp[i] == '\n') {
2076 ast_copy_string(&(vars[j]), "Variable: ", len - j);
2086 /* there are no channel variables; leave it blank */
2093 * \brief Part 2 of ring_one
2095 * Does error checking before attempting to request a channel and call a member.
2096 * This function is only called from ring_one().
2097 * Failure can occur if:
2100 * - Wrapup time not expired
2101 * - Priority by another queue
2103 * \retval 1 on success to reach a free agent
2104 * \retval 0 on failure to get agent.
2106 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
2113 /* on entry here, we know that tmp->chan == NULL */
2114 if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
2115 (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
2116 ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
2117 (tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
2119 ast_cdr_busy(qe->chan->cdr);
2120 tmp->stillgoing = 0;
2125 if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
2126 ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
2128 ast_cdr_busy(qe->chan->cdr);
2129 tmp->stillgoing = 0;
2133 if (tmp->member->paused) {
2134 ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
2136 ast_cdr_busy(qe->chan->cdr);
2137 tmp->stillgoing = 0;
2140 if (use_weight && compare_weight(qe->parent,tmp->member)) {
2141 ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
2143 ast_cdr_busy(qe->chan->cdr);
2144 tmp->stillgoing = 0;
2149 ast_copy_string(tech, tmp->interface, sizeof(tech));
2150 if ((location = strchr(tech, '/')))
2155 /* Request the peer */
2156 tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
2157 if (!tmp->chan) { /* If we can't, just go on to the next call */
2159 ast_cdr_busy(qe->chan->cdr);
2160 tmp->stillgoing = 0;
2162 update_status(tmp->member->state_interface, ast_device_state(tmp->member->state_interface));
2164 ao2_lock(qe->parent);
2165 qe->parent->rrpos++;
2167 ao2_unlock(qe->parent);
2174 tmp->chan->appl = "AppQueue";
2175 tmp->chan->data = "(Outgoing Line)";
2176 tmp->chan->whentohangup = 0;
2177 if (tmp->chan->cid.cid_num)
2178 ast_free(tmp->chan->cid.cid_num);
2179 tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
2180 if (tmp->chan->cid.cid_name)
2181 ast_free(tmp->chan->cid.cid_name);
2182 tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
2183 if (tmp->chan->cid.cid_ani)
2184 ast_free(tmp->chan->cid.cid_ani);
2185 tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
2187 /* Inherit specially named variables from parent channel */
2188 ast_channel_inherit_variables(qe->chan, tmp->chan);
2190 /* Presense of ADSI CPE on outgoing channel follows ours */
2191 tmp->chan->adsicpe = qe->chan->adsicpe;
2193 /* Inherit context and extension */
2194 if (!ast_strlen_zero(qe->chan->macrocontext))
2195 ast_copy_string(tmp->chan->dialcontext, qe->chan->macrocontext, sizeof(tmp->chan->dialcontext));
2197 ast_copy_string(tmp->chan->dialcontext, qe->chan->context, sizeof(tmp->chan->dialcontext));
2198 if (!ast_strlen_zero(qe->chan->macroexten))
2199 ast_copy_string(tmp->chan->exten, qe->chan->macroexten, sizeof(tmp->chan->exten));
2201 ast_copy_string(tmp->chan->exten, qe->chan->exten, sizeof(tmp->chan->exten));
2203 /* Place the call, but don't wait on the answer */
2204 if ((res = ast_call(tmp->chan, location, 0))) {
2205 /* Again, keep going even if there's an error */
2206 ast_debug(1, "ast call on peer returned %d\n", res);
2207 ast_verb(3, "Couldn't call %s\n", tmp->interface);
2211 } else if (qe->parent->eventwhencalled) {
2214 manager_event(EVENT_FLAG_AGENT, "AgentCalled",
2216 "AgentCalled: %s\r\n"
2218 "ChannelCalling: %s\r\n"
2219 "DestinationChannel: %s\r\n"
2220 "CallerIDNum: %s\r\n"
2221 "CallerIDName: %s\r\n"
2227 qe->parent->name, tmp->interface, tmp->member->membername, qe->chan->name, tmp->chan->name,
2228 tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
2229 tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
2230 qe->chan->context, qe->chan->exten, qe->chan->priority, qe->chan->uniqueid,
2231 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2232 ast_verb(3, "Called %s\n", tmp->interface);
2238 /*! \brief find the entry with the best metric, or NULL */
2239 static struct callattempt *find_best(struct callattempt *outgoing)
2241 struct callattempt *best = NULL, *cur;
2243 for (cur = outgoing; cur; cur = cur->q_next) {
2244 if (cur->stillgoing && /* Not already done */
2245 !cur->chan && /* Isn't already going */
2246 (!best || cur->metric < best->metric)) { /* We haven't found one yet, or it's better */
2255 * \brief Place a call to a queue member.
2257 * Once metrics have been calculated for each member, this function is used
2258 * to place a call to the appropriate member (or members). The low-level
2259 * channel-handling and error detection is handled in ring_entry
2261 * \retval 1 if a member was called successfully
2262 * \retval 0 otherwise
2264 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
2269 struct callattempt *best = find_best(outgoing);
2271 ast_debug(1, "Nobody left to try ringing in queue\n");
2274 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2275 struct callattempt *cur;
2276 /* Ring everyone who shares this best metric (for ringall) */
2277 for (cur = outgoing; cur; cur = cur->q_next) {
2278 if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
2279 ast_debug(1, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
2280 ret |= ring_entry(qe, cur, busies);
2284 /* Ring just the best channel */
2285 ast_debug(1, "Trying '%s' with metric %d\n", best->interface, best->metric);
2286 ret = ring_entry(qe, best, busies);
2293 /*! \brief Search for best metric and add to Round Robbin queue */
2294 static int store_next_rr(struct queue_ent *qe, struct callattempt *outgoing)
2296 struct callattempt *best = find_best(outgoing);
2299 /* Ring just the best channel */
2300 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2301 qe->parent->rrpos = best->metric % 1000;
2303 /* Just increment rrpos */
2304 if (qe->parent->wrapped) {
2305 /* No more channels, start over */
2306 qe->parent->rrpos = 0;
2308 /* Prioritize next entry */
2309 qe->parent->rrpos++;
2312 qe->parent->wrapped = 0;
2317 /*! \brief Search for best metric and add to Linear queue */
2318 static int store_next_lin(struct queue_ent *qe, struct callattempt *outgoing)
2320 struct callattempt *best = find_best(outgoing);
2323 /* Ring just the best channel */
2324 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2325 qe->linpos = best->metric % 1000;
2327 /* Just increment rrpos */
2328 if (qe->linwrapped) {
2329 /* No more channels, start over */
2332 /* Prioritize next entry */
2341 /*! \brief Playback announcement to queued members if peroid has elapsed */
2342 static int say_periodic_announcement(struct queue_ent *qe, int ringing)
2347 /* Get the current time */
2350 /* Check to see if it is time to announce */
2351 if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
2354 /* Stop the music on hold so we can play our own file */
2356 ast_indicate(qe->chan,-1);
2358 ast_moh_stop(qe->chan);
2360 ast_verb(3, "Playing periodic announcement\n");
2362 if (qe->parent->randomperiodicannounce) {
2363 qe->last_periodic_announce_sound = ((unsigned long) ast_random()) % qe->parent->numperiodicannounce;
2364 } else if (qe->last_periodic_announce_sound >= qe->parent->numperiodicannounce ||
2365 ast_strlen_zero(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str)) {
2366 qe->last_periodic_announce_sound = 0;
2369 /* play the announcement */
2370 res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str);
2372 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
2375 /* Resume Music on Hold if the caller is going to stay in the queue */
2378 ast_indicate(qe->chan, AST_CONTROL_RINGING);
2380 ast_moh_start(qe->chan, qe->moh, NULL);
2383 /* update last_periodic_announce_time */
2384 qe->last_periodic_announce_time = now;
2386 /* Update the current periodic announcement to the next announcement */
2387 if (!qe->parent->randomperiodicannounce) {
2388 qe->last_periodic_announce_sound++;
2394 /*! \brief Record that a caller gave up on waiting in queue */
2395 static void record_abandoned(struct queue_ent *qe)
2397 ao2_lock(qe->parent);
2398 set_queue_variables(qe);
2399 manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
2403 "OriginalPosition: %d\r\n"
2405 qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
2407 qe->parent->callsabandoned++;
2408 ao2_unlock(qe->parent);
2411 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
2412 static void rna(int rnatime, struct queue_ent *qe, char *interface, char *membername)
2414 ast_verb(3, "Nobody picked up in %d ms\n", rnatime);
2415 ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
2416 if (qe->parent->autopause) {
2417 if (!set_member_paused(qe->parent->name, interface, "Auto-Pause", 1)) {
2418 ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
2420 ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
2426 #define AST_MAX_WATCHERS 256
2427 /*! \brief Wait for a member to answer the call
2429 * \param[in] qe the queue_ent corresponding to the caller in the queue
2430 * \param[in] outgoing the list of callattempts. Relevant ones will have their chan and stillgoing parameters non-zero
2431 * \param[in] to the amount of time (in milliseconds) to wait for a response
2432 * \param[out] digit if a user presses a digit to exit the queue, this is the digit the caller pressed
2433 * \param[in] prebusies number of busy members calculated prior to calling wait_for_answer
2434 * \param[in] caller_disconnect if the 'H' option is used when calling Queue(), this is used to detect if the caller pressed * to disconnect the call
2435 * \param[in] forwardsallowed used to detect if we should allow call forwarding, based on the 'i' option to Queue()
2437 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
2439 const char *queue = qe->parent->name;
2440 struct callattempt *o, *start = NULL, *prev = NULL;
2442 int numbusies = prebusies;
2446 struct ast_frame *f;
2447 struct callattempt *peer = NULL;
2448 struct ast_channel *winner;
2449 struct ast_channel *in = qe->chan;
2451 char membername[80] = "";
2455 struct callattempt *epollo;
2458 starttime = (long) time(NULL);
2460 for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2462 ast_poll_channel_add(in, epollo->chan);
2466 while (*to && !peer) {
2467 int numlines, retry, pos = 1;
2468 struct ast_channel *watchers[AST_MAX_WATCHERS];
2472 for (retry = 0; retry < 2; retry++) {
2474 for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
2475 if (o->stillgoing) { /* Keep track of important channels */
2478 watchers[pos++] = o->chan;
2482 prev->call_next = o;
2488 if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
2489 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
2491 /* On "ringall" strategy we only move to the next penalty level
2492 when *all* ringing phones are done in the current penalty level */
2493 ring_one(qe, outgoing, &numbusies);
2496 if (pos == 1 /* not found */) {
2497 if (numlines == (numbusies + numnochan)) {
2498 ast_debug(1, "Everyone is busy at this time\n");
2500 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
2505 winner = ast_waitfor_n(watchers, pos, to);
2506 for (o = start; o; o = o->call_next) {
2507 if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) {
2509 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2512 } else if (o->chan && (o->chan == winner)) {
2514 ast_copy_string(on, o->member->interface, sizeof(on));
2515 ast_copy_string(membername, o->member->membername, sizeof(membername));
2517 if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
2518 ast_verb(3, "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
2523 } else if (!ast_strlen_zero(o->chan->call_forward)) {
2528 ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
2529 if ((stuff = strchr(tmpchan, '/'))) {
2533 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
2537 /* Before processing channel, go ahead and check for forwarding */
2538 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
2539 /* Setup parameters */
2540 o->chan = ast_request(tech, in->nativeformats, stuff, &status);
2542 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
2546 ast_channel_inherit_variables(in, o->chan);
2547 ast_channel_datastore_inherit(in, o->chan);
2548 if (o->chan->cid.cid_num)
2549 ast_free(o->chan->cid.cid_num);
2550 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
2552 if (o->chan->cid.cid_name)
2553 ast_free(o->chan->cid.cid_name);
2554 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
2556 ast_string_field_set(o->chan, accountcode, in->accountcode);
2557 o->chan->cdrflags = in->cdrflags;
2559 if (in->cid.cid_ani) {
2560 if (o->chan->cid.cid_ani)
2561 ast_free(o->chan->cid.cid_ani);
2562 o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
2564 if (o->chan->cid.cid_rdnis)
2565 ast_free(o->chan->cid.cid_rdnis);
2566 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
2567 if (ast_call(o->chan, tmpchan, 0)) {
2568 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
2573 /* Hangup the original channel now, in case we needed it */
2577 f = ast_read(winner);
2579 if (f->frametype == AST_FRAME_CONTROL) {
2580 switch (f->subclass) {
2581 case AST_CONTROL_ANSWER:
2582 /* This is our guy if someone answered. */
2584 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2588 case AST_CONTROL_BUSY:
2589 ast_verb(3, "%s is busy\n", o->chan->name);
2591 ast_cdr_busy(in->cdr);
2593 endtime = (long) time(NULL);
2594 endtime -= starttime;
2595 rna(endtime*1000, qe, on, membername);
2596 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2597 if (qe->parent->timeoutrestart)
2599 ring_one(qe, outgoing, &numbusies);
2603 case AST_CONTROL_CONGESTION:
2604 ast_verb(3, "%s is circuit-busy\n", o->chan->name);
2606 ast_cdr_busy(in->cdr);
2607 endtime = (long) time(NULL);
2608 endtime -= starttime;
2609 rna(endtime*1000, qe, on, membername);
2611 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2612 if (qe->parent->timeoutrestart)
2614 ring_one(qe, outgoing, &numbusies);
2618 case AST_CONTROL_RINGING:
2619 ast_verb(3, "%s is ringing\n", o->chan->name);
2621 case AST_CONTROL_OFFHOOK:
2622 /* Ignore going off hook */
2625 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
2630 endtime = (long) time(NULL) - starttime;
2631 rna(endtime * 1000, qe, on, membername);
2633 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2634 if (qe->parent->timeoutrestart)
2636 ring_one(qe, outgoing, &numbusies);
2643 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2651 if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2652 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
2657 if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
2658 ast_verb(3, "User pressed digit: %c\n", f->subclass);
2660 *digit = f->subclass;
2667 for (o = start; o; o = o->call_next)
2668 rna(orig, qe, o->interface, o->member->membername);
2673 for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2675 ast_poll_channel_del(in, epollo->chan);
2683 * \brief Check if we should start attempting to call queue members.
2685 * The behavior of this function is dependent first on whether autofill is enabled
2686 * and second on whether the ring strategy is ringall. If autofill is not enabled,
2687 * then return true if we're the head of the queue. If autofill is enabled, then
2688 * we count the available members and see if the number of available members is enough
2689 * that given our position in the queue, we would theoretically be able to connect to
2690 * one of those available members
2692 static int is_our_turn(struct queue_ent *qe)
2694 struct queue_ent *ch;
2700 if (!qe->parent->autofill) {
2701 /* Atomically read the parent head -- does not need a lock */
2702 ch = qe->parent->head;
2703 /* If we are now at the top of the head, break out */
2705 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2708 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2713 /* This needs a lock. How many members are available to be served? */
2714 ao2_lock(qe->parent);
2716 ch = qe->parent->head;
2718 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2719 ast_debug(1, "Even though there may be multiple members available, the strategy is ringall so only the head call is allowed in\n");
2722 struct ao2_iterator mem_iter = ao2_iterator_init(qe->parent->members, 0);
2723 while ((cur = ao2_iterator_next(&mem_iter))) {
2724 switch (cur->status) {
2725 case AST_DEVICE_INUSE:
2726 if (!qe->parent->ringinuse)
2728 /* else fall through */
2729 case AST_DEVICE_NOT_INUSE:
2730 case AST_DEVICE_UNKNOWN:
2739 ast_debug(1, "There are %d available members.\n", avl);
2741 while ((idx < avl) && (ch) && (ch != qe)) {
2747 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2748 if (ch && idx < avl) {
2749 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2752 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2756 ao2_unlock(qe->parent);
2763 * \brief update rules for queues
2765 * Calculate min/max penalties making sure if relative they stay within bounds.
2766 * Update queues penalty and set dialplan vars, goto next list entry.
2768 static void update_qe_rule(struct queue_ent *qe)
2770 int max_penalty = qe->pr->max_relative ? qe->max_penalty + qe->pr->max_value : qe->pr->max_value;
2771 int min_penalty = qe->pr->min_relative ? qe->min_penalty + qe->pr->min_value : qe->pr->min_value;
2772 char max_penalty_str[20], min_penalty_str[20];
2773 /* a relative change to the penalty could put it below 0 */
2774 if (max_penalty < 0)
2776 if (min_penalty < 0)
2778 if (min_penalty > max_penalty)
2779 min_penalty = max_penalty;
2780 snprintf(max_penalty_str, sizeof(max_penalty_str), "%d", max_penalty);
2781 snprintf(min_penalty_str, sizeof(min_penalty_str), "%d", min_penalty);
2782 pbx_builtin_setvar_helper(qe->chan, "QUEUE_MAX_PENALTY", max_penalty_str);
2783 pbx_builtin_setvar_helper(qe->chan, "QUEUE_MIN_PENALTY", min_penalty_str);
2784 qe->max_penalty = max_penalty;
2785 qe->min_penalty = min_penalty;
2786 ast_debug(3, "Setting max penalty to %d and min penalty to %d for caller %s since %d seconds have elapsed\n", qe->max_penalty, qe->min_penalty, qe->chan->name, qe->pr->time);
2787 qe->pr = AST_LIST_NEXT(qe->pr, list);
2790 /*! \brief The waiting areas for callers who are not actively calling members
2792 * This function is one large loop. This function will return if a caller
2793 * either exits the queue or it becomes that caller's turn to attempt calling
2794 * queue members. Inside the loop, we service the caller with periodic announcements,
2795 * holdtime announcements, etc. as configured in queues.conf
2797 * \retval 0 if the caller's turn has arrived
2798 * \retval -1 if the caller should exit the queue.
2800 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2804 /* This is the holding pen for callers 2 through maxlen */
2806 enum queue_member_status stat;
2808 if (is_our_turn(qe))
2811 /* If we have timed out, break out */
2812 if (qe->expire && (time(NULL) > qe->expire)) {
2813 *reason = QUEUE_TIMEOUT;
2817 stat = get_member_status(qe->parent, qe->max_penalty, qe->min_penalty);
2819 /* leave the queue if no agents, if enabled */
2820 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2821 *reason = QUEUE_LEAVEEMPTY;
2822 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2827 /* leave the queue if no reachable agents, if enabled */
2828 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
2829 *reason = QUEUE_LEAVEUNAVAIL;
2830 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2834 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2835 *reason = QUEUE_LEAVEUNAVAIL;
2836 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2841 /* Make a position announcement, if enabled */
2842 if (qe->parent->announcefrequency &&
2843 (res = say_position(qe,ringing)))
2846 /* Make a periodic announcement, if enabled */
2847 if (qe->parent->periodicannouncefrequency &&
2848 (res = say_periodic_announcement(qe,ringing)))
2851 /* see if we need to move to the next penalty level for this queue */
2852 while (qe->pr && ((time(NULL) - qe->start) > qe->pr->time)) {
2856 /* Wait a second before checking again */
2857 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
2858 if (res > 0 && !valid_exit(qe, res))
2869 * \brief update the queue status
2872 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
2875 struct call_queue *qtmp;
2876 struct ao2_iterator queue_iter;
2878 if (shared_lastcall) {
2879 queue_iter = ao2_iterator_init(queues, 0);
2880 while ((qtmp = ao2_iterator_next(&queue_iter))) {
2882 if ((mem = ao2_find(qtmp->members, member, OBJ_POINTER))) {
2883 time(&mem->lastcall);
2893 time(&member->lastcall);
2895 member->lastqueue = q;
2899 q->callscompleted++;
2900 if (callcompletedinsl)
2901 q->callscompletedinsl++;
2906 /*! \brief Calculate the metric of each member in the outgoing callattempts
2908 * A numeric metric is given to each member depending on the ring strategy used
2909 * by the queue. Members with lower metrics will be called before members with
2911 * \retval -1 if penalties are exceeded
2912 * \retval 0 otherwise
2914 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2916 if ((qe->max_penalty && (mem->penalty > qe->max_penalty)) || (qe->min_penalty && (mem->penalty < qe->min_penalty)))
2919 switch (q->strategy) {
2920 case QUEUE_STRATEGY_RINGALL:
2921 /* Everyone equal, except for penalty */
2922 tmp->metric = mem->penalty * 1000000;
2924 case QUEUE_STRATEGY_LINEAR:
2925 if (pos < qe->linpos) {
2926 tmp->metric = 1000 + pos;
2928 if (pos > qe->linpos)
2929 /* Indicate there is another priority */
2933 tmp->metric += mem->penalty * 1000000;
2935 case QUEUE_STRATEGY_RRMEMORY:
2936 if (pos < q->rrpos) {
2937 tmp->metric = 1000 + pos;
2940 /* Indicate there is another priority */
2944 tmp->metric += mem->penalty * 1000000;
2946 case QUEUE_STRATEGY_RANDOM:
2947 tmp->metric = ast_random() % 1000;
2948 tmp->metric += mem->penalty * 1000000;
2950 case QUEUE_STRATEGY_WRANDOM:
2951 tmp->metric = ast_random() % ((1 + mem->penalty) * 1000);
2953 case QUEUE_STRATEGY_FEWESTCALLS:
2954 tmp->metric = mem->calls;
2955 tmp->metric += mem->penalty * 1000000;
2957 case QUEUE_STRATEGY_LEASTRECENT:
2961 tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2962 tmp->metric += mem->penalty * 1000000;
2965 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2971 enum agent_complete_reason {
2977 /*! \brief Send out AMI message with member call completion status information */
2978 static void send_agent_complete(const struct queue_ent *qe, const char *queuename,
2979 const struct ast_channel *peer, const struct member *member, time_t callstart,
2980 char *vars, size_t vars_len, enum agent_complete_reason rsn)
2982 const char *reason = NULL; /* silence dumb compilers */
2984 if (!qe->parent->eventwhencalled)
2995 reason = "transfer";
2999 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
3004 "MemberName: %s\r\n"
3009 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
3010 (long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
3011 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
3014 /*! \brief A large function which calls members, updates statistics, and bridges the caller and a member
3016 * Here is the process of this function
3017 * 1. Process any options passed to the Queue() application. Options here mean the third argument to Queue()
3018 * 2. Iterate trough the members of the queue, creating a callattempt corresponding to each member. During this
3019 * iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
3020 * member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
3021 * during each iteration, we call calc_metric to determine which members should be rung when.
3022 * 3. Call ring_one to place a call to the appropriate member(s)
3023 * 4. Call wait_for_answer to wait for an answer. If no one answers, return.
3024 * 5. Take care of any holdtime announcements, member delays, or other options which occur after a call has been answered.
3025 * 6. Start the monitor or mixmonitor if the option is set
3026 * 7. Remove the caller from the queue to allow other callers to advance
3027 * 8. Bridge the call.
3028 * 9. Do any post processing after the call has disconnected.
3030 * \param[in] qe the queue_ent structure which corresponds to the caller attempting to reach members
3031 * \param[in] options the options passed as the third parameter to the Queue() application
3032 * \param[in] announceoverride filename to play to user when waiting
3033 * \param[in] url the url passed as the fourth parameter to the Queue() application
3034 * \param[in,out] tries the number of times we have tried calling queue members
3035 * \param[out] noption set if the call to Queue() has the 'n' option set.
3036 * \param[in] agi the agi passed as the fifth parameter to the Queue() application
3037 * \param[in] macro the macro passed as the sixth parameter to the Queue() application
3038 * \param[in] gosub the gosub passed as the seventh parameter to the Queue() application
3039 * \param[in] ringing 1 if the 'r' option is set, otherwise 0
3041 static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *tries, int *noption, const char *agi, const char *macro, const char *gosub, int ringing)
3044 struct callattempt *outgoing = NULL; /* the list of calls we are building */
3046 char oldexten[AST_MAX_EXTENSION]="";
3047 char oldcontext[AST_MAX_CONTEXT]="";
3048 char queuename[256]="";
3049 char interfacevar[256]="";
3050 struct ast_channel *peer;
3051 struct ast_channel *which;
3052 struct callattempt *lpeer;
3053 struct member *member;
3054 struct ast_app *app;
3055 int res = 0, bridge = 0;
3058 char *announce = NULL;
3061 time_t now = time(NULL);
3062 struct ast_bridge_config bridge_config;
3063 char nondataquality = 1;
3064 char *agiexec = NULL;
3065 char *macroexec = NULL;
3066 char *gosubexec = NULL;
3068 const char *monitorfilename;
3069 const char *monitor_exec;
3070 const char *monitor_options;
3071 char tmpid[256], tmpid2[256];
3072 char meid[1024], meid2[1024];
3073 char mixmonargs[1512];
3074 struct ast_app *mixmonapp = NULL;
3077 int forwardsallowed = 1;
3078 int callcompletedinsl;
3079 struct ao2_iterator memi;
3080 struct ast_datastore *datastore;
3082 ast_channel_lock(qe->chan);
3083 datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
3084 ast_channel_unlock(qe->chan);
3086 memset(&bridge_config, 0, sizeof(bridge_config));
3091 for (; options && *options; options++)
3094 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
3097 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
3100 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
3103 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
3109 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
3112 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
3115 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_PARKCALL);
3118 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_PARKCALL);
3121 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_LINEAR)
3124 *tries = qe->parent->membercount;
3128 forwardsallowed = 0;
3131 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMIXMON);
3134 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMIXMON);
3139 /* Hold the lock while we setup the outgoing calls */
3142 ao2_lock(qe->parent);
3143 ast_debug(1, "%s is trying to call a queue member.\n",
3145 ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
3146 if (!ast_strlen_zero(qe->announce))
3147 announce = qe->announce;
3148 if (!ast_strlen_zero(announceoverride))
3149 announce = announceoverride;
3151 memi = ao2_iterator_init(qe->parent->members, 0);
3152 while ((cur = ao2_iterator_next(&memi))) {
3153 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
3154 struct ast_dialed_interface *di;
3155 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
3158 ao2_unlock(qe->parent);
3164 if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
3166 ao2_unlock(qe->parent);
3172 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
3173 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
3175 ao2_unlock(&qe->parent);
3181 datastore->data = dialed_interfaces;
3182 AST_LIST_HEAD_INIT(dialed_interfaces);
3184 ast_channel_lock(qe->chan);
3185 ast_channel_datastore_add(qe->chan, datastore);
3186 ast_channel_unlock(qe->chan);
3188 dialed_interfaces = datastore->data;
3190 AST_LIST_LOCK(dialed_interfaces);
3191 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
3192 if (!strcasecmp(cur->interface, di->interface)) {
3193 ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n",
3198 AST_LIST_UNLOCK(dialed_interfaces);
3205 /* It is always ok to dial a Local interface. We only keep track of
3206 * which "real" interfaces have been dialed. The Local channel will
3207 * inherit this list so that if it ends up dialing a real interface,
3208 * it won't call one that has already been called. */
3209 if (strncasecmp(cur->interface, "Local/", 6)) {
3210 if (!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) {
3212 ao2_unlock(qe->parent);
3218 strcpy(di->interface, cur->interface);
3220 AST_LIST_LOCK(dialed_interfaces);
3221 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
3222 AST_LIST_UNLOCK(dialed_interfaces);
3225 tmp->stillgoing = -1;
3227 tmp->oldstatus = cur->status;
3228 tmp->lastcall = cur->lastcall;
3229 tmp->lastqueue = cur->lastqueue;
3230 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
3231 /* Special case: If we ring everyone, go ahead and ring them, otherwise
3232 just calculate their metric for the appropriate strategy */
3233 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
3234 /* Put them in the list of outgoing thingies... We're ready now.
3235 XXX If we're forcibly removed, these outgoing calls won't get
3237 tmp->q_next = outgoing;
3239 /* If this line is up, don't try anybody else */
3240 if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
3247 if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
3248 to = (qe->expire - now) * 1000;
3250 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
3253 ao2_unlock(qe->parent);
3254 ring_one(qe, outgoing, &numbusies);
3257 lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
3259 ast_channel_datastore_remove(qe->chan, datastore);
3260 ast_channel_datastore_free(datastore);
3262 ao2_lock(qe->parent);
3263 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
3264 store_next_rr(qe, outgoing);
3266 if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) {
3267 store_next_lin(qe, outgoing);
3269 ao2_unlock(qe->parent);
3270 peer = lpeer ? lpeer->chan : NULL;
3274 /* Must gotten hung up */
3277 /* User exited by pressing a digit */
3281 ast_debug(1, "%s: Nobody answered.\n", qe->chan->name);
3282 } else { /* peer is valid */
3283 /* Ah ha! Someone answered within the desired timeframe. Of course after this
3284 we will always return with -1 so that it is hung up properly after the
3287 if (!strcmp(qe->chan->tech->type, "Zap"))
3288 ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
3289 if (!strcmp(peer->tech->type, "Zap"))
3290 ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
3291 /* Update parameters for the queue */
3293 recalc_holdtime(qe, (now - qe->start));
3294 ao2_lock(qe->parent);
3295 callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
3296 ao2_unlock(qe->parent);
3297 member = lpeer->member;
3298 /* Increment the refcount for this member, since we're going to be using it for awhile in here. */
3300 hangupcalls(outgoing, peer);
3302 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
3305 res2 = ast_autoservice_start(qe->chan);
3307 if (qe->parent->memberdelay) {
3308 ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
3309 res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
3311 if (!res2 && announce) {
3312 play_file(peer, announce);
3314 if (!res2 && qe->parent->reportholdtime) {
3315 if (!play_file(peer, qe->parent->sound_reporthold)) {
3316 int holdtime, holdtimesecs;
3319 holdtime = abs((now - qe->start) / 60);
3320 holdtimesecs = abs((now - qe->start));
3321 if (holdtime == 1) {
3322 ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
3323 play_file(peer, qe->parent->sound_minute);
3325 ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
3326 play_file(peer, qe->parent->sound_minutes);
3328 if (holdtimesecs > 1) {
3329 ast_say_number(peer, holdtimesecs, AST_DIGIT_ANY, peer->language, NULL);
3330 play_file(peer, qe->parent->sound_seconds);
3335 res2 |= ast_autoservice_stop(qe->chan);
3336 if (ast_check_hangup(peer)) {
3337 /* Agent must have hung up */
3338 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
3339 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
3340 record_abandoned(qe);
3341 if (qe->parent->eventwhencalled)
3342 manager_event(EVENT_FLAG_AGENT, "AgentDump",
3347 "MemberName: %s\r\n"
3349 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
3350 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
3352 ao2_ref(member, -1);
3355 /* Caller must have hung up just before being connected*/
3356 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
3357 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
3358 record_abandoned(qe);
3360 ao2_ref(member, -1);
3364 /* Stop music on hold */
3366 ast_indicate(qe->chan,-1);
3368 ast_moh_stop(qe->chan);
3369 /* If appropriate, log that we have a destination channel */
3371 ast_cdr_setdestchan(qe->chan->cdr, peer->name);
3372 /* Make sure channels are compatible */
3373 res = ast_channel_make_compatible(qe->chan, peer);
3375 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
3376 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
3377 record_abandoned(qe);
3379 ao2_ref(member, -1);
3383 /* Play announcement to the caller telling it's his turn if defined */
3384 if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
3385 if (play_file(qe->chan, qe->parent->sound_callerannounce))
3386 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
3389 ao2_lock(qe->parent);
3390 /* if setinterfacevar is defined, make member variables available to the channel */
3391 /* use pbx_builtin_setvar to set a load of variables with one call */
3392 if (qe->parent->setinterfacevar) {
3393 snprintf(interfacevar, sizeof(interfacevar), "MEMBERINTERFACE=%s|MEMBERNAME=%s|MEMBERCALLS=%d|MEMBERLASTCALL=%ld|MEMBERPENALTY=%d|MEMBERDYNAMIC=%d|MEMBERREALTIME=%d",
3394 member->interface, member->membername, member->calls, (long)member->lastcall, member->penalty, member->dynamic, member->realtime);
3395 pbx_builtin_setvar(qe->chan, interfacevar);
3398 /* if setqueueentryvar is defined, make queue entry (i.e. the caller) variables available to the channel */
3399 /* use pbx_builtin_setvar to set a load of variables with one call */
3400 if (qe->parent->setqueueentryvar) {
3401 snprintf(interfacevar, sizeof(interfacevar), "QEHOLDTIME=%ld|QEORIGINALPOS=%d",
3402 (long) time(NULL) - qe->start, qe->opos);
3403 pbx_builtin_setvar(qe->chan, interfacevar);
3406 /* try to set queue variables if configured to do so*/
3407 set_queue_variables(qe);
3408 ao2_unlock(qe->parent);
3410 /* Begin Monitoring */
3411 if (qe->parent->monfmt && *qe->parent->monfmt) {
3412 if (!qe->parent->montype) {
3413 ast_debug(1, "Starting Monitor as requested.\n");
3414 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
3415 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
3419 if (monitorfilename)