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"
96 /* Please read before modifying this file.
97 * There are three locks which are regularly used
98 * throughout this file, the queue list lock, the lock
99 * for each individual queue, and the interface list lock.
100 * Please be extra careful to always lock in the following order
102 * 2) individual queue lock
103 * 3) interface list lock
104 * This order has sort of "evolved" over the lifetime of this
105 * application, but it is now in place this way, so please adhere
111 QUEUE_STRATEGY_RINGALL = 0,
112 QUEUE_STRATEGY_LEASTRECENT,
113 QUEUE_STRATEGY_FEWESTCALLS,
114 QUEUE_STRATEGY_RANDOM,
115 QUEUE_STRATEGY_RRMEMORY,
116 QUEUE_STRATEGY_LINEAR,
117 QUEUE_STRATEGY_WRANDOM
120 static struct strategy {
124 { QUEUE_STRATEGY_RINGALL, "ringall" },
125 { QUEUE_STRATEGY_LEASTRECENT, "leastrecent" },
126 { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" },
127 { QUEUE_STRATEGY_RANDOM, "random" },
128 { QUEUE_STRATEGY_RRMEMORY, "rrmemory" },
129 { QUEUE_STRATEGY_LINEAR, "linear" },
130 { QUEUE_STRATEGY_WRANDOM, "wrandom"},
133 #define DEFAULT_RETRY 5
134 #define DEFAULT_TIMEOUT 15
135 #define RECHECK 1 /* Recheck every second to see we we're at the top yet */
136 #define MAX_PERIODIC_ANNOUNCEMENTS 10 /* The maximum periodic announcements we can have */
137 #define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 /* The minimum number of seconds between position announcements
138 The default value of 15 provides backwards compatibility */
139 #define MAX_QUEUE_BUCKETS 53
141 #define RES_OKAY 0 /* Action completed */
142 #define RES_EXISTS (-1) /* Entry already exists */
143 #define RES_OUTOFMEMORY (-2) /* Out of memory */
144 #define RES_NOSUCHQUEUE (-3) /* No such queue */
145 #define RES_NOT_DYNAMIC (-4) /* Member is not dynamic */
147 static char *app = "Queue";
149 static char *synopsis = "Queue a call for a call queue";
151 static char *descrip =
152 " Queue(queuename[,options[,URL][,announceoverride][,timeout][,AGI][,macro][,gosub][,rule]):\n"
153 "Queues an incoming call in a particular call queue as defined in queues.conf.\n"
154 "This application will return to the dialplan if the queue does not exist, or\n"
155 "any of the join options cause the caller to not enter the queue.\n"
156 "The option string may contain zero or more of the following characters:\n"
157 " 'c' -- continue in the dialplan if the callee hangs up.\n"
158 " 'd' -- data-quality (modem) call (minimum delay).\n"
159 " 'h' -- allow callee to hang up by pressing *.\n"
160 " 'H' -- allow caller to hang up by pressing *.\n"
161 " 'n' -- no retries on the timeout; will exit this application and \n"
162 " go to the next step.\n"
163 " 'i' -- ignore call forward requests from queue members and do nothing\n"
164 " when they are requested.\n"
165 " 'r' -- ring instead of playing MOH. Periodic Announcements are still made, if applicable.\n"
166 " 't' -- allow the called user to transfer the calling user.\n"
167 " 'T' -- allow the calling user to transfer the call.\n"
168 " 'w' -- allow the called user to write the conversation to disk via Monitor.\n"
169 " 'W' -- allow the calling user to write the conversation to disk via Monitor.\n"
170 " 'k' -- Allow the called party to enable parking of the call by sending\n"
171 " the DTMF sequence defined for call parking in features.conf.\n"
172 " 'K' -- Allow the calling party to enable parking of the call by sending\n"
173 " the DTMF sequence defined for call parking in features.conf.\n"
174 " 'x' -- allow the called user to write the conversation to disk via MixMonitor\n"
175 " 'X' -- allow the calling user to write the conversation to disk via MixMonitor\n"
177 " In addition to transferring the call, a call may be parked and then picked\n"
178 "up by another user.\n"
179 " The optional URL will be sent to the called party if the channel supports\n"
181 " The optional AGI parameter will setup an AGI script to be executed on the \n"
182 "calling party's channel once they are connected to a queue member.\n"
183 " The optional macro parameter will run a macro on the \n"
184 "calling party's channel once they are connected to a queue member.\n"
185 " The optional gosub parameter will run a gosub on the \n"
186 "calling party's channel once they are connected to a queue member.\n"
187 " The optional rule parameter will cause the queue's defaultrule to be\n"
188 "overridden by the rule specified.\n"
189 " The timeout will cause the queue to fail out after a specified number of\n"
190 "seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
191 " This application sets the following channel variable upon completion:\n"
192 " QUEUESTATUS The status of the call as a text string, one of\n"
193 " TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL | CONTINUE\n";
195 static char *app_aqm = "AddQueueMember" ;
196 static char *app_aqm_synopsis = "Dynamically adds queue members" ;
197 static char *app_aqm_descrip =
198 " AddQueueMember(queuename[,interface[,penalty[,options[,membername]]]]):\n"
199 "Dynamically adds interface to an existing queue.\n"
200 "If the interface is already in the queue it will return an error.\n"
201 " This application sets the following channel variable upon completion:\n"
202 " AQMSTATUS The status of the attempt to add a queue member as a \n"
203 " text string, one of\n"
204 " ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
205 "Example: AddQueueMember(techsupport,SIP/3000)\n"
208 static char *app_rqm = "RemoveQueueMember" ;
209 static char *app_rqm_synopsis = "Dynamically removes queue members" ;
210 static char *app_rqm_descrip =
211 " RemoveQueueMember(queuename[,interface[,options]]):\n"
212 "Dynamically removes interface to an existing queue\n"
213 "If the interface is NOT in the queue it will return an error.\n"
214 " This application sets the following channel variable upon completion:\n"
215 " RQMSTATUS The status of the attempt to remove a queue member as a\n"
216 " text string, one of\n"
217 " REMOVED | NOTINQUEUE | NOSUCHQUEUE \n"
218 "Example: RemoveQueueMember(techsupport,SIP/3000)\n"
221 static char *app_pqm = "PauseQueueMember" ;
222 static char *app_pqm_synopsis = "Pauses a queue member" ;
223 static char *app_pqm_descrip =
224 " PauseQueueMember([queuename],interface[,options[,reason]]):\n"
225 "Pauses (blocks calls for) a queue member.\n"
226 "The given interface will be paused in the given queue. This prevents\n"
227 "any calls from being sent from the queue to the interface until it is\n"
228 "unpaused with UnpauseQueueMember or the manager interface. If no\n"
229 "queuename is given, the interface is paused in every queue it is a\n"
230 "member of. The application will fail if the interface is not found.\n"
231 "The reason string is entirely optional and is used to add extra information\n"
232 "to the appropriate queue_log entries and manager events.\n"
233 " This application sets the following channel variable upon completion:\n"
234 " PQMSTATUS The status of the attempt to pause a queue member as a\n"
235 " text string, one of\n"
236 " PAUSED | NOTFOUND\n"
237 "Example: PauseQueueMember(,SIP/3000)\n";
239 static char *app_upqm = "UnpauseQueueMember" ;
240 static char *app_upqm_synopsis = "Unpauses a queue member" ;
241 static char *app_upqm_descrip =
242 " UnpauseQueueMember([queuename],interface[,options[,reason]]):\n"
243 "Unpauses (resumes calls to) a queue member.\n"
244 "This is the counterpart to PauseQueueMember and operates exactly the\n"
245 "same way, except it unpauses instead of pausing the given interface.\n"
246 "The reason string is entirely optional and is used to add extra information\n"
247 "to the appropriate queue_log entries and manager events.\n"
248 " This application sets the following channel variable upon completion:\n"
249 " UPQMSTATUS The status of the attempt to unpause a queue \n"
250 " member as a text string, one of\n"
251 " UNPAUSED | NOTFOUND\n"
252 "Example: UnpauseQueueMember(,SIP/3000)\n";
254 static char *app_ql = "QueueLog" ;
255 static char *app_ql_synopsis = "Writes to the queue_log" ;
256 static char *app_ql_descrip =
257 " QueueLog(queuename,uniqueid,agent,event[,additionalinfo]):\n"
258 "Allows you to write your own events into the queue log\n"
259 "Example: QueueLog(101,${UNIQUEID},${AGENT},WENTONBREAK,600)\n";
261 /*! \brief Persistent Members astdb family */
262 static const char *pm_family = "Queue/PersistentMembers";
263 /* The maximum length of each persistent member queue database entry */
264 #define PM_MAX_LEN 8192
266 /*! \brief queues.conf [general] option */
267 static int queue_keep_stats = 0;
269 /*! \brief queues.conf [general] option */
270 static int queue_persistent_members = 0;
272 /*! \brief queues.conf per-queue weight option */
273 static int use_weight = 0;
275 /*! \brief queues.conf [general] option */
276 static int autofill_default = 0;
278 /*! \brief queues.conf [general] option */
279 static int montype_default = 0;
281 /*! \brief queues.conf [general] option */
282 static int shared_lastcall = 0;
284 /*! \brief Subscription to device state change events */
285 static struct ast_event_sub *device_state_sub;
287 /*! \brief queues.conf [general] option */
288 static int update_cdr = 0;
294 QUEUE_LEAVEEMPTY = 3,
295 QUEUE_JOINUNAVAIL = 4,
296 QUEUE_LEAVEUNAVAIL = 5,
302 enum queue_result id;
304 } queue_results[] = {
305 { QUEUE_UNKNOWN, "UNKNOWN" },
306 { QUEUE_TIMEOUT, "TIMEOUT" },
307 { QUEUE_JOINEMPTY,"JOINEMPTY" },
308 { QUEUE_LEAVEEMPTY, "LEAVEEMPTY" },
309 { QUEUE_JOINUNAVAIL, "JOINUNAVAIL" },
310 { QUEUE_LEAVEUNAVAIL, "LEAVEUNAVAIL" },
311 { QUEUE_FULL, "FULL" },
312 { QUEUE_CONTINUE, "CONTINUE" },
315 /*! \brief We define a custom "local user" structure because we
316 use it not only for keeping track of what is in use but
317 also for keeping track of who we're dialing.
319 There are two "links" defined in this structure, q_next and call_next.
320 q_next links ALL defined callattempt structures into a linked list. call_next is
321 a link which allows for a subset of the callattempts to be traversed. This subset
322 is used in wait_for_answer so that irrelevant callattempts are not traversed. This
323 also is helpful so that queue logs are always accurate in the case where a call to
324 a member times out, especially if using the ringall strategy. */
327 struct callattempt *q_next;
328 struct callattempt *call_next;
329 struct ast_channel *chan;
335 struct call_queue *lastqueue;
336 struct member *member;
341 struct call_queue *parent; /*!< What queue is our parent */
342 char moh[80]; /*!< Name of musiconhold to be used */
343 char announce[80]; /*!< Announcement to play for member when call is answered */
344 char context[AST_MAX_CONTEXT]; /*!< Context when user exits queue */
345 char digits[AST_MAX_EXTENSION]; /*!< Digits entered while in queue */
346 int valid_digits; /*!< Digits entered correspond to valid extension. Exited */
347 int pos; /*!< Where we are in the queue */
348 int prio; /*!< Our priority */
349 int last_pos_said; /*!< Last position we told the user */
350 time_t last_periodic_announce_time; /*!< The last time we played a periodic announcement */
351 int last_periodic_announce_sound; /*!< The last periodic announcement we made */
352 time_t last_pos; /*!< Last time we told the user their position */
353 int opos; /*!< Where we started in the queue */
354 int handled; /*!< Whether our call was handled */
355 int pending; /*!< Non-zero if we are attempting to call a member */
356 int max_penalty; /*!< Limit the members that can take this call to this penalty or lower */
357 int min_penalty; /*!< Limit the members that can take this call to this penalty or higher */
358 int linpos; /*!< If using linear strategy, what position are we at? */
359 int linwrapped; /*!< Is the linpos wrapped? */
360 time_t start; /*!< When we started holding */
361 time_t expire; /*!< When this entry should expire (time out of queue) */
362 struct ast_channel *chan; /*!< Our channel */
363 AST_LIST_HEAD_NOLOCK(,penalty_rule) qe_rules; /*!< Local copy of the queue's penalty rules */
364 struct penalty_rule *pr; /*!< Pointer to the next penalty rule to implement */
365 struct queue_ent *next; /*!< The next queue entry */
369 char interface[80]; /*!< Technology/Location to dial to reach this member*/
370 char state_interface[80]; /*!< Technology/Location from which to read devicestate changes */
371 char membername[80]; /*!< Member name to use in queue logs */
372 int penalty; /*!< Are we a last resort? */
373 int calls; /*!< Number of calls serviced by this member */
374 int dynamic; /*!< Are we dynamically added? */
375 int realtime; /*!< Is this member realtime? */
376 int status; /*!< Status of queue member */
377 int paused; /*!< Are we paused (not accepting calls)? */
378 time_t lastcall; /*!< When last successful call was hungup */
379 struct call_queue *lastqueue; /*!< Last queue we received a call */
380 unsigned int dead:1; /*!< Used to detect members deleted in realtime */
381 unsigned int delme:1; /*!< Flag to delete entry on reload */
384 struct member_interface {
386 AST_LIST_ENTRY(member_interface) list; /*!< Next call queue */
389 static AST_LIST_HEAD_STATIC(interfaces, member_interface);
391 /* values used in multi-bit flags in call_queue */
392 #define QUEUE_EMPTY_NORMAL 1
393 #define QUEUE_EMPTY_STRICT 2
394 #define QUEUE_EMPTY_LOOSE 3
395 #define ANNOUNCEHOLDTIME_ALWAYS 1
396 #define ANNOUNCEHOLDTIME_ONCE 2
397 #define QUEUE_EVENT_VARIABLES 3
399 struct penalty_rule {
400 int time; /*!< Number of seconds that need to pass before applying this rule */
401 int max_value; /*!< The amount specified in the penalty rule for max penalty */
402 int min_value; /*!< The amount specified in the penalty rule for min penalty */
403 int max_relative; /*!< Is the max adjustment relative? 1 for relative, 0 for absolute */
404 int min_relative; /*!< Is the min adjustment relative? 1 for relative, 0 for absolute */
405 AST_LIST_ENTRY(penalty_rule) list; /*!< Next penalty_rule */
409 AST_DECLARE_STRING_FIELDS(
411 AST_STRING_FIELD(name);
412 /*! Music on Hold class */
413 AST_STRING_FIELD(moh);
414 /*! Announcement to play when call is answered */
415 AST_STRING_FIELD(announce);
417 AST_STRING_FIELD(context);
418 /*! Macro to run upon member connection */
419 AST_STRING_FIELD(membermacro);
420 /*! Gosub to run upon member connection */
421 AST_STRING_FIELD(membergosub);
422 /*! Default rule to use if none specified in call to Queue() */
423 AST_STRING_FIELD(defaultrule);
424 /*! Sound file: "Your call is now first in line" (def. queue-youarenext) */
425 AST_STRING_FIELD(sound_next);
426 /*! Sound file: "There are currently" (def. queue-thereare) */
427 AST_STRING_FIELD(sound_thereare);
428 /*! Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting) */
429 AST_STRING_FIELD(sound_calls);
430 /*! Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
431 AST_STRING_FIELD(sound_holdtime);
432 /*! Sound file: "minutes." (def. queue-minutes) */
433 AST_STRING_FIELD(sound_minutes);
434 /*! Sound file: "less-than" (def. queue-lessthan) */
435 AST_STRING_FIELD(sound_lessthan);
436 /*! Sound file: "seconds." (def. queue-seconds) */
437 AST_STRING_FIELD(sound_seconds);
438 /*! Sound file: "Thank you for your patience." (def. queue-thankyou) */
439 AST_STRING_FIELD(sound_thanks);
440 /*! Sound file: Custom announce for caller, no default */
441 AST_STRING_FIELD(sound_callerannounce);
442 /*! Sound file: "Hold time" (def. queue-reporthold) */
443 AST_STRING_FIELD(sound_reporthold);
445 /*! Sound files: Custom announce, no default */
446 struct ast_str *sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS];
448 unsigned int joinempty:2;
449 unsigned int eventwhencalled:2;
450 unsigned int leavewhenempty:2;
451 unsigned int ringinuse:1;
452 unsigned int setinterfacevar:1;
453 unsigned int setqueuevar:1;
454 unsigned int setqueueentryvar:1;
455 unsigned int reportholdtime:1;
456 unsigned int wrapped:1;
457 unsigned int timeoutrestart:1;
458 unsigned int announceholdtime:2;
459 unsigned int announceposition:1;
461 unsigned int maskmemberstatus:1;
462 unsigned int realtime:1;
463 unsigned int found:1;
464 int announcefrequency; /*!< How often to announce their position */
465 int minannouncefrequency; /*!< The minimum number of seconds between position announcements (def. 15) */
466 int periodicannouncefrequency; /*!< How often to play periodic announcement */
467 int roundingseconds; /*!< How many seconds do we round to? */
468 int holdtime; /*!< Current avg holdtime, based on recursive boxcar filter */
469 int callscompleted; /*!< Number of queue calls completed */
470 int callsabandoned; /*!< Number of queue calls abandoned */
471 int servicelevel; /*!< seconds setting for servicelevel*/
472 int callscompletedinsl; /*!< Number of calls answered with servicelevel*/
473 char monfmt[8]; /*!< Format to use when recording calls */
474 int montype; /*!< Monitor type Monitor vs. MixMonitor */
475 int count; /*!< How many entries */
476 int maxlen; /*!< Max number of entries */
477 int wrapuptime; /*!< Wrapup Time */
479 int retry; /*!< Retry calling everyone after this amount of time */
480 int timeout; /*!< How long to wait for an answer */
481 int weight; /*!< Respective weight */
482 int autopause; /*!< Auto pause queue members if they fail to answer */
484 /* Queue strategy things */
485 int rrpos; /*!< Round Robin - position */
486 int memberdelay; /*!< Seconds to delay connecting member to caller */
487 int autofill; /*!< Ignore the head call status and ring an available agent */
489 struct ao2_container *members; /*!< Head of the list of members */
491 * \brief Number of members _logged in_
492 * \note There will be members in the members container that are not logged
493 * in, so this can not simply be replaced with ao2_container_count().
496 struct queue_ent *head; /*!< Head of the list of callers */
497 AST_LIST_ENTRY(call_queue) list; /*!< Next call queue */
498 AST_LIST_HEAD_NOLOCK(, penalty_rule) rules; /*!< The list of penalty rules to invoke */
503 AST_LIST_HEAD_NOLOCK(,penalty_rule) rules;
504 AST_LIST_ENTRY(rule_list) list;
507 AST_LIST_HEAD_STATIC(rule_lists, rule_list);
509 static struct ao2_container *queues;
511 static void update_realtime_members(struct call_queue *q);
512 static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused);
514 /*! \brief sets the QUEUESTATUS channel variable */
515 static void set_queue_result(struct ast_channel *chan, enum queue_result res)
519 for (i = 0; i < sizeof(queue_results) / sizeof(queue_results[0]); i++) {
520 if (queue_results[i].id == res) {
521 pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
527 static char *int2strat(int strategy)
531 for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
532 if (strategy == strategies[x].strategy)
533 return strategies[x].name;
539 static int strat2int(const char *strategy)
543 for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
544 if (!strcasecmp(strategy, strategies[x].name))
545 return strategies[x].strategy;
551 static int queue_hash_cb(const void *obj, const int flags)
553 const struct call_queue *q = obj;
554 return ast_str_hash(q->name);
557 static int queue_cmp_cb(void *obj, void *arg, int flags)
559 struct call_queue *q = obj, *q2 = arg;
560 return !strcasecmp(q->name, q2->name) ? CMP_MATCH : 0;
563 static inline struct call_queue *queue_ref(struct call_queue *q)
569 static inline struct call_queue *queue_unref(struct call_queue *q)
575 static void set_queue_variables(struct queue_ent *qe)
578 char interfacevar[256]="";
581 if (qe->parent->setqueuevar) {
583 if (qe->parent->callscompleted > 0)
584 sl = 100 * ((float) qe->parent->callscompletedinsl / (float) qe->parent->callscompleted);
586 snprintf(interfacevar,sizeof(interfacevar),
587 "QUEUENAME=%s|QUEUEMAX=%d|QUEUESTRATEGY=%s|QUEUECALLS=%d|QUEUEHOLDTIME=%d|QUEUECOMPLETED=%d|QUEUEABANDONED=%d|QUEUESRVLEVEL=%d|QUEUESRVLEVELPERF=%2.1f",
588 qe->parent->name, qe->parent->maxlen, int2strat(qe->parent->strategy), qe->parent->count, qe->parent->holdtime, qe->parent->callscompleted,
589 qe->parent->callsabandoned, qe->parent->servicelevel, sl);
591 pbx_builtin_setvar(qe->chan, interfacevar);
595 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
596 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
598 struct queue_ent *cur;
615 enum queue_member_status {
617 QUEUE_NO_REACHABLE_MEMBERS,
618 QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
622 /*! \brief Check if members are available
624 * This function checks to see if members are available to be called. If any member
625 * is available, the function immediately returns QUEUE_NORMAL. If no members are available,
626 * the appropriate reason why is returned
628 static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty, int min_penalty)
630 struct member *member;
631 struct ao2_iterator mem_iter;
632 enum queue_member_status result = QUEUE_NO_MEMBERS;
635 mem_iter = ao2_iterator_init(q->members, 0);
636 for (; (member = ao2_iterator_next(&mem_iter)); ao2_ref(member, -1)) {
637 if ((max_penalty && (member->penalty > max_penalty)) || (min_penalty && (member->penalty < min_penalty)))
640 switch (member->status) {
641 case AST_DEVICE_INVALID:
644 case AST_DEVICE_UNAVAILABLE:
645 if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)
646 result = QUEUE_NO_REACHABLE_MEMBERS;
649 if (member->paused) {
650 result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
665 AST_LIST_ENTRY(statechange) entry;
669 /*! \brief set a member's status based on device state of that member's state_interface*/
670 static void *handle_statechange(struct statechange *sc)
672 struct call_queue *q;
674 struct ao2_iterator mem_iter;
675 struct member_interface *curint;
676 struct ao2_iterator queue_iter;
680 technology = ast_strdupa(sc->dev);
681 loc = strchr(technology, '/');
688 AST_LIST_LOCK(&interfaces);
689 AST_LIST_TRAVERSE(&interfaces, curint, list) {
692 interface = ast_strdupa(curint->interface);
693 if ((slash_pos = strchr(interface, '/')))
694 if ((slash_pos = strchr(slash_pos + 1, '/')))
697 if (!strcasecmp(interface, sc->dev))
700 AST_LIST_UNLOCK(&interfaces);
703 ast_debug(3, "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));
707 ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
708 queue_iter = ao2_iterator_init(queues, 0);
709 while ((q = ao2_iterator_next(&queue_iter))) {
711 mem_iter = ao2_iterator_init(q->members, 0);
712 while ((cur = ao2_iterator_next(&mem_iter))) {
715 interface = ast_strdupa(cur->state_interface);
716 if ((slash_pos = strchr(interface, '/')))
717 if ((slash_pos = strchr(slash_pos + 1, '/')))
720 if (strcasecmp(sc->dev, interface)) {
725 if (cur->status != sc->state) {
726 cur->status = sc->state;
727 if (q->maskmemberstatus) {
732 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
742 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static",
743 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
755 * \brief Data used by the device state thread
758 /*! Set to 1 to stop the thread */
760 /*! The device state monitoring thread */
762 /*! Lock for the state change queue */
764 /*! Condition for the state change queue */
766 /*! Queue of state changes */
767 AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
769 .thread = AST_PTHREADT_NULL,
772 /*! \brief Consumer of the statechange queue */
773 static void *device_state_thread(void *data)
775 struct statechange *sc = NULL;
777 while (!device_state.stop) {
778 ast_mutex_lock(&device_state.lock);
779 if (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
780 ast_cond_wait(&device_state.cond, &device_state.lock);
781 sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry);
783 ast_mutex_unlock(&device_state.lock);
785 /* Check to see if we were woken up to see the request to stop */
786 if (device_state.stop)
792 handle_statechange(sc);
801 while ((sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry)))
806 /*! \brief Producer of the statechange queue */
807 static int statechange_queue(const char *dev, enum ast_device_state state)
809 struct statechange *sc;
811 if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
815 strcpy(sc->dev, dev);
817 ast_mutex_lock(&device_state.lock);
818 AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
819 ast_cond_signal(&device_state.cond);
820 ast_mutex_unlock(&device_state.lock);
824 static void device_state_cb(const struct ast_event *event, void *unused)
826 enum ast_device_state state;
829 state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
830 device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
832 if (ast_strlen_zero(device)) {
833 ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
837 statechange_queue(device, state);
840 /*! \brief allocate space for new queue member and set fields based on parameters passed */
841 static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface)
845 if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
846 cur->penalty = penalty;
847 cur->paused = paused;
848 ast_copy_string(cur->interface, interface, sizeof(cur->interface));
849 if (!ast_strlen_zero(state_interface))
850 ast_copy_string(cur->state_interface, state_interface, sizeof(cur->state_interface));
852 ast_copy_string(cur->state_interface, interface, sizeof(cur->state_interface));
853 if (!ast_strlen_zero(membername))
854 ast_copy_string(cur->membername, membername, sizeof(cur->membername));
856 ast_copy_string(cur->membername, interface, sizeof(cur->membername));
857 if (!strchr(cur->interface, '/'))
858 ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
859 cur->status = ast_device_state(cur->state_interface);
866 static int compress_char(const char c)
876 static int member_hash_fn(const void *obj, const int flags)
878 const struct member *mem = obj;
879 const char *chname = strchr(mem->interface, '/');
882 chname = mem->interface;
883 for (i = 0; i < 5 && chname[i]; i++)
884 ret += compress_char(chname[i]) << (i * 6);
888 static int member_cmp_fn(void *obj1, void *obj2, int flags)
890 struct member *mem1 = obj1, *mem2 = obj2;
891 return strcasecmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
894 static void init_queue(struct call_queue *q)
897 struct penalty_rule *pr_iter;
900 q->retry = DEFAULT_RETRY;
903 q->announcefrequency = 0;
904 q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
905 q->announceholdtime = 0;
906 q->announceholdtime = 1;
907 q->roundingseconds = 0; /* Default - don't announce seconds */
910 q->setinterfacevar = 0;
912 q->setqueueentryvar = 0;
913 q->autofill = autofill_default;
914 q->montype = montype_default;
916 q->reportholdtime = 0;
920 q->leavewhenempty = 0;
922 q->maskmemberstatus = 0;
923 q->eventwhencalled = 0;
925 q->timeoutrestart = 0;
926 q->periodicannouncefrequency = 0;
928 if (q->strategy == QUEUE_STRATEGY_LINEAR)
929 /* linear strategy depends on order, so we have to place all members in a single bucket */
930 q->members = ao2_container_alloc(1, member_hash_fn, member_cmp_fn);
932 q->members = ao2_container_alloc(37, member_hash_fn, member_cmp_fn);
937 ast_string_field_set(q, sound_next, "queue-youarenext");
938 ast_string_field_set(q, sound_thereare, "queue-thereare");
939 ast_string_field_set(q, sound_calls, "queue-callswaiting");
940 ast_string_field_set(q, sound_holdtime, "queue-holdtime");
941 ast_string_field_set(q, sound_minutes, "queue-minutes");
942 ast_string_field_set(q, sound_seconds, "queue-seconds");
943 ast_string_field_set(q, sound_thanks, "queue-thankyou");
944 ast_string_field_set(q, sound_lessthan, "queue-less-than");
945 ast_string_field_set(q, sound_reporthold, "queue-reporthold");
947 if ((q->sound_periodicannounce[0] = ast_str_create(32)))
948 ast_str_set(&q->sound_periodicannounce[0], 0, "queue-periodic-announce");
950 for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
951 if (q->sound_periodicannounce[i])
952 ast_str_set(&q->sound_periodicannounce[i], 0, "%s", "");
955 while ((pr_iter = AST_LIST_REMOVE_HEAD(&q->rules,list)))
959 static void clear_queue(struct call_queue *q)
962 q->callscompleted = 0;
963 q->callsabandoned = 0;
964 q->callscompletedinsl = 0;
968 static int add_to_interfaces(const char *interface)
970 struct member_interface *curint;
972 AST_LIST_LOCK(&interfaces);
973 AST_LIST_TRAVERSE(&interfaces, curint, list) {
974 if (!strcasecmp(curint->interface, interface))
979 AST_LIST_UNLOCK(&interfaces);
983 ast_debug(1, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
985 if ((curint = ast_calloc(1, sizeof(*curint)))) {
986 ast_copy_string(curint->interface, interface, sizeof(curint->interface));
987 AST_LIST_INSERT_HEAD(&interfaces, curint, list);
989 AST_LIST_UNLOCK(&interfaces);
994 static int interface_exists_global(const char *interface)
996 struct call_queue *q;
997 struct member *mem, tmpmem;
998 struct ao2_iterator queue_iter, mem_iter;
1001 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1002 queue_iter = ao2_iterator_init(queues, 0);
1003 while ((q = ao2_iterator_next(&queue_iter))) {
1005 mem_iter = ao2_iterator_init(q->members, 0);
1006 while ((mem = ao2_iterator_next(&mem_iter))) {
1007 if (!strcasecmp(mem->state_interface, interface)) {
1020 static int remove_from_interfaces(const char *interface)
1022 struct member_interface *curint;
1024 if (interface_exists_global(interface))
1027 AST_LIST_LOCK(&interfaces);
1028 AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
1029 if (!strcasecmp(curint->interface, interface)) {
1030 ast_debug(1, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
1031 AST_LIST_REMOVE_CURRENT(&interfaces, list);
1036 AST_LIST_TRAVERSE_SAFE_END;
1037 AST_LIST_UNLOCK(&interfaces);
1042 static void clear_and_free_interfaces(void)
1044 struct member_interface *curint;
1046 AST_LIST_LOCK(&interfaces);
1047 while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
1049 AST_LIST_UNLOCK(&interfaces);
1052 /*Note: call this with the rule_lists locked */
1053 static int insert_penaltychange (const char *list_name, const char *content, const int linenum)
1055 char *timestr, *maxstr, *minstr, *contentdup;
1056 struct penalty_rule *rule = NULL, *rule_iter;
1057 struct rule_list *rl_iter;
1058 int time, inserted = 0;
1060 if (!(rule = ast_calloc(1, sizeof(*rule)))) {
1061 ast_log(LOG_ERROR, "Cannot allocate memory for penaltychange rule at line %d!\n", linenum);
1065 contentdup = ast_strdupa(content);
1067 if (!(maxstr = strchr(contentdup, ','))) {
1068 ast_log(LOG_WARNING, "Improperly formatted penaltychange rule at line %d. Ignoring.\n", linenum);
1074 timestr = contentdup;
1076 if ((time = atoi(timestr)) < 0) {
1077 ast_log(LOG_WARNING, "Improper time parameter specified for penaltychange rule at line %d. Ignoring.\n", linenum);
1084 if ((minstr = strchr(maxstr,',')))
1087 /* The last check will evaluate true if either no penalty change is indicated for a given rule
1088 * OR if a min penalty change is indicated but no max penalty change is */
1089 if (*maxstr == '+' || *maxstr == '-' || *maxstr == '\0') {
1090 rule->max_relative = 1;
1093 rule->max_value = atoi(maxstr);
1095 if (!ast_strlen_zero(minstr)) {
1096 if (*minstr == '+' || *minstr == '-')
1097 rule->min_relative = 1;
1098 rule->min_value = atoi(minstr);
1099 } else /*there was no minimum specified, so assume this means no change*/
1100 rule->min_relative = 1;
1102 /*We have the rule made, now we need to insert it where it belongs*/
1103 AST_LIST_TRAVERSE(&rule_lists, rl_iter, list){
1104 if (strcasecmp(rl_iter->name, list_name))
1107 AST_LIST_TRAVERSE_SAFE_BEGIN(&rl_iter->rules, rule_iter, list) {
1108 if (rule->time < rule_iter->time) {
1109 AST_LIST_INSERT_BEFORE_CURRENT(rule, list);
1114 AST_LIST_TRAVERSE_SAFE_END;
1117 AST_LIST_INSERT_TAIL(&rl_iter->rules, rule, list);
1124 /*! \brief Configure a queue parameter.
1126 For error reporting, line number is passed for .conf static configuration.
1127 For Realtime queues, linenum is -1.
1128 The failunknown flag is set for config files (and static realtime) to show
1129 errors for unknown parameters. It is cleared for dynamic realtime to allow
1130 extra fields in the tables. */
1131 static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
1133 if (!strcasecmp(param, "musicclass") ||
1134 !strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
1135 ast_string_field_set(q, moh, val);
1136 } else if (!strcasecmp(param, "announce")) {
1137 ast_string_field_set(q, announce, val);
1138 } else if (!strcasecmp(param, "context")) {
1139 ast_string_field_set(q, context, val);
1140 } else if (!strcasecmp(param, "timeout")) {
1141 q->timeout = atoi(val);
1143 q->timeout = DEFAULT_TIMEOUT;
1144 } else if (!strcasecmp(param, "ringinuse")) {
1145 q->ringinuse = ast_true(val);
1146 } else if (!strcasecmp(param, "setinterfacevar")) {
1147 q->setinterfacevar = ast_true(val);
1148 } else if (!strcasecmp(param, "setqueuevar")) {
1149 q->setqueuevar = ast_true(val);
1150 } else if (!strcasecmp(param, "setqueueentryvar")) {
1151 q->setqueueentryvar = ast_true(val);
1152 } else if (!strcasecmp(param, "monitor-format")) {
1153 ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
1154 } else if (!strcasecmp(param, "membermacro")) {
1155 ast_string_field_set(q, membermacro, val);
1156 } else if (!strcasecmp(param, "membergosub")) {
1157 ast_string_field_set(q, membergosub, val);
1158 } else if (!strcasecmp(param, "queue-youarenext")) {
1159 ast_string_field_set(q, sound_next, val);
1160 } else if (!strcasecmp(param, "queue-thereare")) {
1161 ast_string_field_set(q, sound_thereare, val);
1162 } else if (!strcasecmp(param, "queue-callswaiting")) {
1163 ast_string_field_set(q, sound_calls, val);
1164 } else if (!strcasecmp(param, "queue-holdtime")) {
1165 ast_string_field_set(q, sound_holdtime, val);
1166 } else if (!strcasecmp(param, "queue-minutes")) {
1167 ast_string_field_set(q, sound_minutes, val);
1168 } else if (!strcasecmp(param, "queue-seconds")) {
1169 ast_string_field_set(q, sound_seconds, val);
1170 } else if (!strcasecmp(param, "queue-lessthan")) {
1171 ast_string_field_set(q, sound_lessthan, val);
1172 } else if (!strcasecmp(param, "queue-thankyou")) {
1173 ast_string_field_set(q, sound_thanks, val);
1174 } else if (!strcasecmp(param, "queue-callerannounce")) {
1175 ast_string_field_set(q, sound_callerannounce, val);
1176 } else if (!strcasecmp(param, "queue-reporthold")) {
1177 ast_string_field_set(q, sound_reporthold, val);
1178 } else if (!strcasecmp(param, "announce-frequency")) {
1179 q->announcefrequency = atoi(val);
1180 } else if (!strcasecmp(param, "min-announce-frequency")) {
1181 q->minannouncefrequency = atoi(val);
1182 ast_debug(1, "%s=%s for queue '%s'\n", param, val, q->name);
1183 } else if (!strcasecmp(param, "announce-round-seconds")) {
1184 q->roundingseconds = atoi(val);
1185 /* Rounding to any other values just doesn't make sense... */
1186 if (!(q->roundingseconds == 0 || q->roundingseconds == 1 || q->roundingseconds == 5 || q->roundingseconds == 10
1187 || q->roundingseconds == 15 || q->roundingseconds == 20 || q->roundingseconds == 30)) {
1189 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1190 "using 0 instead for queue '%s' at line %d of queues.conf\n",
1191 val, param, q->name, linenum);
1193 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1194 "using 0 instead for queue '%s'\n", val, param, q->name);
1196 q->roundingseconds=0;
1198 } else if (!strcasecmp(param, "announce-holdtime")) {
1199 if (!strcasecmp(val, "once"))
1200 q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
1201 else if (ast_true(val))
1202 q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
1204 q->announceholdtime = 0;
1205 } else if (!strcasecmp(param, "announce-position")) {
1206 q->announceposition = ast_true(val);
1207 } else if (!strcasecmp(param, "periodic-announce")) {
1208 if (strchr(val, ',')) {
1209 char *s, *buf = ast_strdupa(val);
1212 while ((s = strsep(&buf, ",|"))) {
1213 if (!q->sound_periodicannounce[i])
1214 q->sound_periodicannounce[i] = ast_str_create(16);
1215 ast_str_set(&q->sound_periodicannounce[i], 0, s);
1217 if (i == MAX_PERIODIC_ANNOUNCEMENTS)
1221 ast_str_set(&q->sound_periodicannounce[0], 0, val);
1223 } else if (!strcasecmp(param, "periodic-announce-frequency")) {
1224 q->periodicannouncefrequency = atoi(val);
1225 } else if (!strcasecmp(param, "retry")) {
1226 q->retry = atoi(val);
1228 q->retry = DEFAULT_RETRY;
1229 } else if (!strcasecmp(param, "wrapuptime")) {
1230 q->wrapuptime = atoi(val);
1231 } else if (!strcasecmp(param, "autofill")) {
1232 q->autofill = ast_true(val);
1233 } else if (!strcasecmp(param, "monitor-type")) {
1234 if (!strcasecmp(val, "mixmonitor"))
1236 } else if (!strcasecmp(param, "autopause")) {
1237 q->autopause = ast_true(val);
1238 } else if (!strcasecmp(param, "maxlen")) {
1239 q->maxlen = atoi(val);
1242 } else if (!strcasecmp(param, "servicelevel")) {
1243 q->servicelevel= atoi(val);
1244 } else if (!strcasecmp(param, "strategy")) {
1245 /* We already have set this, no need to do it again */
1247 } else if (!strcasecmp(param, "joinempty")) {
1248 if (!strcasecmp(val, "loose"))
1249 q->joinempty = QUEUE_EMPTY_LOOSE;
1250 else if (!strcasecmp(val, "strict"))
1251 q->joinempty = QUEUE_EMPTY_STRICT;
1252 else if (ast_true(val))
1253 q->joinempty = QUEUE_EMPTY_NORMAL;
1256 } else if (!strcasecmp(param, "leavewhenempty")) {
1257 if (!strcasecmp(val, "loose"))
1258 q->leavewhenempty = QUEUE_EMPTY_LOOSE;
1259 else if (!strcasecmp(val, "strict"))
1260 q->leavewhenempty = QUEUE_EMPTY_STRICT;
1261 else if (ast_true(val))
1262 q->leavewhenempty = QUEUE_EMPTY_NORMAL;
1264 q->leavewhenempty = 0;
1265 } else if (!strcasecmp(param, "eventmemberstatus")) {
1266 q->maskmemberstatus = !ast_true(val);
1267 } else if (!strcasecmp(param, "eventwhencalled")) {
1268 if (!strcasecmp(val, "vars")) {
1269 q->eventwhencalled = QUEUE_EVENT_VARIABLES;
1271 q->eventwhencalled = ast_true(val) ? 1 : 0;
1273 } else if (!strcasecmp(param, "reportholdtime")) {
1274 q->reportholdtime = ast_true(val);
1275 } else if (!strcasecmp(param, "memberdelay")) {
1276 q->memberdelay = atoi(val);
1277 } else if (!strcasecmp(param, "weight")) {
1278 q->weight = atoi(val);
1281 /* With Realtime queues, if the last queue using weights is deleted in realtime,
1282 we will not see any effect on use_weight until next reload. */
1283 } else if (!strcasecmp(param, "timeoutrestart")) {
1284 q->timeoutrestart = ast_true(val);
1285 } else if (!strcasecmp(param, "defaultrule")) {
1286 ast_string_field_set(q, defaultrule, val);
1287 } else if (failunknown) {
1289 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
1290 q->name, param, linenum);
1292 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
1297 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)
1299 struct member *m, tmpmem;
1304 penalty = atoi(penalty_str);
1310 paused = atoi(paused_str);
1315 /* Find the member, or the place to put a new one. */
1316 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1317 m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
1319 /* Create a new one if not found, else update penalty */
1321 if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
1324 add_to_interfaces(m->state_interface);
1325 ao2_link(q->members, m);
1331 m->dead = 0; /* Do not delete this one. */
1334 if (strcasecmp(state_interface, m->state_interface)) {
1335 remove_from_interfaces(m->state_interface);
1336 ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface));
1337 add_to_interfaces(m->state_interface);
1339 m->penalty = penalty;
1344 static void free_members(struct call_queue *q, int all)
1346 /* Free non-dynamic members */
1348 struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
1350 while ((cur = ao2_iterator_next(&mem_iter))) {
1351 if (all || !cur->dynamic) {
1352 ao2_unlink(q->members, cur);
1353 remove_from_interfaces(cur->state_interface);
1360 static void destroy_queue(void *obj)
1362 struct call_queue *q = obj;
1365 ast_debug(0, "Queue destructor called for queue '%s'!\n", q->name);
1368 ast_string_field_free_memory(q);
1369 for (i = 0; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
1370 if (q->sound_periodicannounce[i])
1371 free(q->sound_periodicannounce[i]);
1373 ao2_ref(q->members, -1);
1376 static struct call_queue *alloc_queue(const char *queuename)
1378 struct call_queue *q;
1380 if ((q = ao2_alloc(sizeof(*q), destroy_queue))) {
1381 if (ast_string_field_init(q, 64)) {
1385 ast_string_field_set(q, name, queuename);
1390 /*!\brief Reload a single queue via realtime.
1391 \return Return the queue, or NULL if it doesn't exist.
1392 \note Should be called with the global qlock locked. */
1393 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
1395 struct ast_variable *v;
1396 struct call_queue *q, tmpq = {
1400 struct ao2_iterator mem_iter;
1401 char *interface = NULL;
1402 const char *tmp_name;
1404 char tmpbuf[64]; /* Must be longer than the longest queue param name. */
1406 /* Static queues override realtime. */
1407 if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
1415 ast_log(LOG_WARNING, "Static queue '%s' already exists. Not loading from realtime\n", q->name);
1421 } else if (!member_config)
1422 /* Not found in the list, and it's not realtime ... */
1425 /* Check if queue is defined in realtime. */
1427 /* Delete queue from in-core list if it has been deleted in realtime. */
1429 /*! \note Hmm, can't seem to distinguish a DB failure from a not
1430 found condition... So we might delete an in-core queue
1431 in case of DB failure. */
1432 ast_debug(1, "Queue %s not found in realtime.\n", queuename);
1435 /* Delete if unused (else will be deleted when last caller leaves). */
1436 ao2_unlink(queues, q);
1443 /* Create a new queue if an in-core entry does not exist yet. */
1445 struct ast_variable *tmpvar = NULL;
1446 if (!(q = alloc_queue(queuename)))
1451 /*Before we initialize the queue, we need to set the strategy, so that linear strategy
1452 * will allocate the members properly
1454 for (tmpvar = queue_vars; tmpvar; tmpvar = tmpvar->next) {
1455 if (!strcasecmp(tmpvar->name, "strategy")) {
1456 q->strategy = strat2int(tmpvar->value);
1457 if (q->strategy < 0) {
1458 ast_log(LOG_WARNING, "'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
1459 tmpvar->value, q->name);
1460 q->strategy = QUEUE_STRATEGY_RINGALL;
1465 /* We traversed all variables and didn't find a strategy */
1467 q->strategy = QUEUE_STRATEGY_RINGALL;
1468 init_queue(q); /* Ensure defaults for all parameters not set explicitly. */
1469 ao2_link(queues, q);
1470 ast_variables_destroy(tmpvar);
1473 memset(tmpbuf, 0, sizeof(tmpbuf));
1474 for (v = queue_vars; v; v = v->next) {
1475 /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
1476 if ((tmp = strchr(v->name, '_'))) {
1477 ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
1480 while ((tmp = strchr(tmp, '_')))
1484 queue_set_param(q, tmp_name, v->value, -1, 0);
1487 /* Temporarily set realtime members dead so we can detect deleted ones.
1488 * Also set the membercount correctly for realtime*/
1489 mem_iter = ao2_iterator_init(q->members, 0);
1490 while ((m = ao2_iterator_next(&mem_iter))) {
1497 while ((interface = ast_category_browse(member_config, interface))) {
1498 rt_handle_member_record(q, interface,
1499 S_OR(ast_variable_retrieve(member_config, interface, "membername"),interface),
1500 ast_variable_retrieve(member_config, interface, "penalty"),
1501 ast_variable_retrieve(member_config, interface, "paused"),
1502 S_OR(ast_variable_retrieve(member_config, interface, "state_interface"),interface));
1505 /* Delete all realtime members that have been deleted in DB. */
1506 mem_iter = ao2_iterator_init(q->members, 0);
1507 while ((m = ao2_iterator_next(&mem_iter))) {
1509 ao2_unlink(q->members, m);
1510 remove_from_interfaces(m->state_interface);
1521 static struct call_queue *load_realtime_queue(const char *queuename)
1523 struct ast_variable *queue_vars;
1524 struct ast_config *member_config = NULL;
1525 struct call_queue *q = NULL, tmpq = {
1529 /* Find the queue in the in-core list first. */
1530 q = ao2_find(queues, &tmpq, OBJ_POINTER);
1532 if (!q || q->realtime) {
1533 /*! \note Load from realtime before taking the global qlock, to avoid blocking all
1534 queue operations while waiting for the DB.
1536 This will be two separate database transactions, so we might
1537 see queue parameters as they were before another process
1538 changed the queue and member list as it was after the change.
1539 Thus we might see an empty member list when a queue is
1540 deleted. In practise, this is unlikely to cause a problem. */
1542 queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
1544 member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
1545 if (!member_config) {
1546 ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
1547 ast_variables_destroy(queue_vars);
1553 q = find_queue_by_name_rt(queuename, queue_vars, member_config);
1555 ast_config_destroy(member_config);
1557 ast_variables_destroy(queue_vars);
1561 update_realtime_members(q);
1566 static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
1568 struct ast_variable *var;
1571 if (!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL)))
1574 if (!strcmp(var->name, "uniqueid"))
1578 if (var && !ast_strlen_zero(var->value)) {
1579 if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
1585 static void update_realtime_members(struct call_queue *q)
1587 struct ast_config *member_config = NULL;
1589 char *interface = NULL;
1590 struct ao2_iterator mem_iter;
1592 if (!(member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL))) {
1593 /*This queue doesn't have realtime members*/
1594 ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
1600 /* Temporarily set realtime members dead so we can detect deleted ones.*/
1601 mem_iter = ao2_iterator_init(q->members, 0);
1602 while ((m = ao2_iterator_next(&mem_iter))) {
1608 while ((interface = ast_category_browse(member_config, interface))) {
1609 rt_handle_member_record(q, interface,
1610 S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
1611 ast_variable_retrieve(member_config, interface, "penalty"),
1612 ast_variable_retrieve(member_config, interface, "paused"),
1613 S_OR(ast_variable_retrieve(member_config, interface, "state_interface"), interface));
1616 /* Delete all realtime members that have been deleted in DB. */
1617 mem_iter = ao2_iterator_init(q->members, 0);
1618 while ((m = ao2_iterator_next(&mem_iter))) {
1620 ao2_unlink(q->members, m);
1621 remove_from_interfaces(m->state_interface);
1627 ast_config_destroy(member_config);
1630 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
1632 struct call_queue *q;
1633 struct queue_ent *cur, *prev = NULL;
1637 enum queue_member_status stat;
1639 if (!(q = load_realtime_queue(queuename)))
1645 /* This is our one */
1646 stat = get_member_status(q, qe->max_penalty, qe->min_penalty);
1647 if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
1648 *reason = QUEUE_JOINEMPTY;
1649 else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
1650 *reason = QUEUE_JOINUNAVAIL;
1651 else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
1652 *reason = QUEUE_JOINUNAVAIL;
1653 else if (q->maxlen && (q->count >= q->maxlen))
1654 *reason = QUEUE_FULL;
1656 /* There's space for us, put us at the right position inside
1658 * Take into account the priority of the calling user */
1663 /* We have higher priority than the current user, enter
1664 * before him, after all the other users with priority
1665 * higher or equal to our priority. */
1666 if ((!inserted) && (qe->prio > cur->prio)) {
1667 insert_entry(q, prev, qe, &pos);
1674 /* No luck, join at the end of the queue */
1676 insert_entry(q, prev, qe, &pos);
1677 ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
1678 ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
1679 ast_copy_string(qe->context, q->context, sizeof(qe->context));
1682 manager_event(EVENT_FLAG_CALL, "Join",
1683 "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
1685 S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
1686 S_OR(qe->chan->cid.cid_name, "unknown"),
1687 q->name, qe->pos, q->count, qe->chan->uniqueid );
1688 ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
1696 static int play_file(struct ast_channel *chan, const char *filename)
1700 ast_stopstream(chan);
1702 res = ast_streamfile(chan, filename, chan->language);
1704 res = ast_waitstream(chan, AST_DIGIT_ANY);
1706 ast_stopstream(chan);
1711 static int valid_exit(struct queue_ent *qe, char digit)
1713 int digitlen = strlen(qe->digits);
1715 /* Prevent possible buffer overflow */
1716 if (digitlen < sizeof(qe->digits) - 2) {
1717 qe->digits[digitlen] = digit;
1718 qe->digits[digitlen + 1] = '\0';
1720 qe->digits[0] = '\0';
1724 /* If there's no context to goto, short-circuit */
1725 if (ast_strlen_zero(qe->context))
1728 /* If the extension is bad, then reset the digits to blank */
1729 if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
1730 qe->digits[0] = '\0';
1734 /* We have an exact match */
1735 if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
1736 qe->valid_digits = 1;
1737 /* Return 1 on a successful goto */
1744 static int say_position(struct queue_ent *qe, int ringing)
1746 int res = 0, avgholdmins, avgholdsecs;
1749 /* Let minannouncefrequency seconds pass between the start of each position announcement */
1751 if ((now - qe->last_pos) < qe->parent->minannouncefrequency)
1754 /* If either our position has changed, or we are over the freq timer, say position */
1755 if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
1759 ast_indicate(qe->chan,-1);
1761 ast_moh_stop(qe->chan);
1763 if (qe->parent->announceposition) {
1764 /* Say we're next, if we are */
1766 res = play_file(qe->chan, qe->parent->sound_next);
1772 res = play_file(qe->chan, qe->parent->sound_thereare);
1775 res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, NULL); /* Needs gender */
1778 res = play_file(qe->chan, qe->parent->sound_calls);
1783 /* Round hold time to nearest minute */
1784 avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
1786 /* If they have specified a rounding then round the seconds as well */
1787 if (qe->parent->roundingseconds) {
1788 avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
1789 avgholdsecs *= qe->parent->roundingseconds;
1794 ast_verb(3, "Hold time for %s is %d minutes %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
1796 /* If the hold time is >1 min, if it's enabled, and if it's not
1797 supposed to be only once and we have already said it, say it */
1798 if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
1799 (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
1800 res = play_file(qe->chan, qe->parent->sound_holdtime);
1804 if (avgholdmins > 0) {
1805 if (avgholdmins < 2) {
1806 res = play_file(qe->chan, qe->parent->sound_lessthan);
1810 res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
1814 res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
1819 res = play_file(qe->chan, qe->parent->sound_minutes);
1823 if (avgholdsecs>0) {
1824 res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
1828 res = play_file(qe->chan, qe->parent->sound_seconds);
1836 if (qe->parent->announceposition) {
1837 ast_verb(3, "Told %s in %s their queue position (which was %d)\n",
1838 qe->chan->name, qe->parent->name, qe->pos);
1840 res = play_file(qe->chan, qe->parent->sound_thanks);
1843 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
1846 /* Set our last_pos indicators */
1848 qe->last_pos_said = qe->pos;
1850 /* Don't restart music on hold if we're about to exit the caller from the queue */
1853 ast_indicate(qe->chan, AST_CONTROL_RINGING);
1855 ast_moh_start(qe->chan, qe->moh, NULL);
1860 static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
1864 /* Calculate holdtime using a recursive boxcar filter */
1865 /* Thanks to SRT for this contribution */
1866 /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
1868 ao2_lock(qe->parent);
1869 oldvalue = qe->parent->holdtime;
1870 qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
1871 ao2_unlock(qe->parent);
1875 static void leave_queue(struct queue_ent *qe)
1877 struct call_queue *q;
1878 struct queue_ent *cur, *prev = NULL;
1879 struct penalty_rule *pr_iter;
1882 if (!(q = qe->parent))
1888 for (cur = q->head; cur; cur = cur->next) {
1892 /* Take us out of the queue */
1893 manager_event(EVENT_FLAG_CALL, "Leave",
1894 "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
1895 qe->chan->name, q->name, q->count, qe->chan->uniqueid);
1896 ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
1897 /* Take us out of the queue */
1899 prev->next = cur->next;
1901 q->head = cur->next;
1902 /* Free penalty rules */
1903 while ((pr_iter = AST_LIST_REMOVE_HEAD(&qe->qe_rules, list)))
1906 /* Renumber the people after us in the queue based on a new count */
1913 /*If the queue is a realtime queue, check to see if it's still defined in real time*/
1915 if (!ast_load_realtime("queues", "name", q->name, NULL))
1920 /* It's dead and nobody is in it, so kill it */
1921 ao2_unlink(queues, q);
1927 /* Hang up a list of outgoing calls */
1928 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
1930 struct callattempt *oo;
1933 /* Hangup any existing lines we have open */
1934 if (outgoing->chan && (outgoing->chan != exception))
1935 ast_hangup(outgoing->chan);
1937 outgoing = outgoing->q_next;
1939 ao2_ref(oo->member, -1);
1944 static int update_status(struct call_queue *q, struct member *member, int status)
1947 struct ao2_iterator mem_iter;
1949 /* Since a reload could have taken place, we have to traverse the list to
1950 be sure it's still valid */
1952 mem_iter = ao2_iterator_init(q->members, 0);
1953 while ((cur = ao2_iterator_next(&mem_iter))) {
1954 if (member != cur) {
1959 cur->status = status;
1960 if (!q->maskmemberstatus) {
1961 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
1964 "MemberName: %s\r\n"
1965 "Membership: %s\r\n"
1967 "CallsTaken: %d\r\n"
1971 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime": "static",
1972 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
1980 static int update_dial_status(struct call_queue *q, struct member *member, int status)
1982 if (status == AST_CAUSE_BUSY)
1983 status = AST_DEVICE_BUSY;
1984 else if (status == AST_CAUSE_UNREGISTERED)
1985 status = AST_DEVICE_UNAVAILABLE;
1986 else if (status == AST_CAUSE_NOSUCHDRIVER)
1987 status = AST_DEVICE_INVALID;
1989 status = AST_DEVICE_UNKNOWN;
1990 return update_status(q, member, status);
1993 /* traverse all defined queues which have calls waiting and contain this member
1994 return 0 if no other queue has precedence (higher weight) or 1 if found */
1995 static int compare_weight(struct call_queue *rq, struct member *member)
1997 struct call_queue *q;
2000 struct ao2_iterator queue_iter;
2002 /* &qlock and &rq->lock already set by try_calling()
2003 * to solve deadlock */
2004 queue_iter = ao2_iterator_init(queues, 0);
2005 while ((q = ao2_iterator_next(&queue_iter))) {
2006 if (q == rq) { /* don't check myself, could deadlock */
2011 if (q->count && q->members) {
2012 if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
2013 ast_debug(1, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
2014 if (q->weight > rq->weight) {
2015 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);
2031 /*! \brief common hangup actions */
2032 static void do_hang(struct callattempt *o)
2035 ast_hangup(o->chan);
2039 static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
2041 struct ast_str *buf = ast_str_alloca(len + 1);
2044 if (pbx_builtin_serialize_variables(chan, &buf)) {
2047 /* convert "\n" to "\nVariable: " */
2048 strcpy(vars, "Variable: ");
2051 for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
2054 if (tmp[i + 1] == '\0')
2056 if (tmp[i] == '\n') {
2060 ast_copy_string(&(vars[j]), "Variable: ", len - j);
2070 /* there are no channel variables; leave it blank */
2076 /*! \brief Part 2 of ring_one
2078 * Does error checking before attempting to request a channel and call a member. This
2079 * function is only called from ring_one
2081 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
2088 /* on entry here, we know that tmp->chan == NULL */
2089 if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
2090 (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
2091 ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
2092 (tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
2094 ast_cdr_busy(qe->chan->cdr);
2095 tmp->stillgoing = 0;
2100 if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
2101 ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
2103 ast_cdr_busy(qe->chan->cdr);
2104 tmp->stillgoing = 0;
2108 if (tmp->member->paused) {
2109 ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
2111 ast_cdr_busy(qe->chan->cdr);
2112 tmp->stillgoing = 0;
2115 if (use_weight && compare_weight(qe->parent,tmp->member)) {
2116 ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
2118 ast_cdr_busy(qe->chan->cdr);
2119 tmp->stillgoing = 0;
2124 ast_copy_string(tech, tmp->interface, sizeof(tech));
2125 if ((location = strchr(tech, '/')))
2130 /* Request the peer */
2131 tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
2132 if (!tmp->chan) { /* If we can't, just go on to the next call */
2134 ast_cdr_busy(qe->chan->cdr);
2135 tmp->stillgoing = 0;
2136 update_dial_status(qe->parent, tmp->member, status);
2138 ao2_lock(qe->parent);
2139 qe->parent->rrpos++;
2141 ao2_unlock(qe->parent);
2146 } else if (status != tmp->oldstatus)
2147 update_dial_status(qe->parent, tmp->member, status);
2149 tmp->chan->appl = "AppQueue";
2150 tmp->chan->data = "(Outgoing Line)";
2151 tmp->chan->whentohangup = 0;
2152 if (tmp->chan->cid.cid_num)
2153 ast_free(tmp->chan->cid.cid_num);
2154 tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
2155 if (tmp->chan->cid.cid_name)
2156 ast_free(tmp->chan->cid.cid_name);
2157 tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
2158 if (tmp->chan->cid.cid_ani)
2159 ast_free(tmp->chan->cid.cid_ani);
2160 tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
2162 /* Inherit specially named variables from parent channel */
2163 ast_channel_inherit_variables(qe->chan, tmp->chan);
2165 /* Presense of ADSI CPE on outgoing channel follows ours */
2166 tmp->chan->adsicpe = qe->chan->adsicpe;
2168 /* Inherit context and extension */
2169 if (!ast_strlen_zero(qe->chan->macrocontext))
2170 ast_copy_string(tmp->chan->dialcontext, qe->chan->macrocontext, sizeof(tmp->chan->dialcontext));
2172 ast_copy_string(tmp->chan->dialcontext, qe->chan->context, sizeof(tmp->chan->dialcontext));
2173 if (!ast_strlen_zero(qe->chan->macroexten))
2174 ast_copy_string(tmp->chan->exten, qe->chan->macroexten, sizeof(tmp->chan->exten));
2176 ast_copy_string(tmp->chan->exten, qe->chan->exten, sizeof(tmp->chan->exten));
2178 /* Place the call, but don't wait on the answer */
2179 if ((res = ast_call(tmp->chan, location, 0))) {
2180 /* Again, keep going even if there's an error */
2181 ast_debug(1, "ast call on peer returned %d\n", res);
2182 ast_verb(3, "Couldn't call %s\n", tmp->interface);
2186 } else if (qe->parent->eventwhencalled) {
2189 manager_event(EVENT_FLAG_AGENT, "AgentCalled",
2191 "AgentCalled: %s\r\n"
2193 "ChannelCalling: %s\r\n"
2194 "DestinationChannel: %s\r\n"
2195 "CallerIDNum: %s\r\n"
2196 "CallerIDName: %s\r\n"
2202 qe->parent->name, tmp->interface, tmp->member->membername, qe->chan->name, tmp->chan->name,
2203 tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
2204 tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
2205 qe->chan->context, qe->chan->exten, qe->chan->priority, qe->chan->uniqueid,
2206 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2207 ast_verb(3, "Called %s\n", tmp->interface);
2213 /*! \brief find the entry with the best metric, or NULL */
2214 static struct callattempt *find_best(struct callattempt *outgoing)
2216 struct callattempt *best = NULL, *cur;
2218 for (cur = outgoing; cur; cur = cur->q_next) {
2219 if (cur->stillgoing && /* Not already done */
2220 !cur->chan && /* Isn't already going */
2221 (!best || cur->metric < best->metric)) { /* We haven't found one yet, or it's better */
2229 /*! \brief Place a call to a queue member
2231 * Once metrics have been calculated for each member, this function is used
2232 * to place a call to the appropriate member (or members). The low-level
2233 * channel-handling and error detection is handled in ring_entry
2235 * Returns 1 if a member was called successfully, 0 otherwise
2237 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
2242 struct callattempt *best = find_best(outgoing);
2244 ast_debug(1, "Nobody left to try ringing in queue\n");
2247 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2248 struct callattempt *cur;
2249 /* Ring everyone who shares this best metric (for ringall) */
2250 for (cur = outgoing; cur; cur = cur->q_next) {
2251 if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
2252 ast_debug(1, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
2253 ret |= ring_entry(qe, cur, busies);
2257 /* Ring just the best channel */
2258 ast_debug(1, "Trying '%s' with metric %d\n", best->interface, best->metric);
2259 ret = ring_entry(qe, best, busies);
2266 static int store_next_rr(struct queue_ent *qe, struct callattempt *outgoing)
2268 struct callattempt *best = find_best(outgoing);
2271 /* Ring just the best channel */
2272 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2273 qe->parent->rrpos = best->metric % 1000;
2275 /* Just increment rrpos */
2276 if (qe->parent->wrapped) {
2277 /* No more channels, start over */
2278 qe->parent->rrpos = 0;
2280 /* Prioritize next entry */
2281 qe->parent->rrpos++;
2284 qe->parent->wrapped = 0;
2289 static int store_next_lin(struct queue_ent *qe, struct callattempt *outgoing)
2291 struct callattempt *best = find_best(outgoing);
2294 /* Ring just the best channel */
2295 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2296 qe->linpos = best->metric % 1000;
2298 /* Just increment rrpos */
2299 if (qe->linwrapped) {
2300 /* No more channels, start over */
2303 /* Prioritize next entry */
2312 static int say_periodic_announcement(struct queue_ent *qe, int ringing)
2317 /* Get the current time */
2320 /* Check to see if it is time to announce */
2321 if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
2324 /* Stop the music on hold so we can play our own file */
2326 ast_indicate(qe->chan,-1);
2328 ast_moh_stop(qe->chan);
2330 ast_verb(3, "Playing periodic announcement\n");
2332 /* Check to make sure we have a sound file. If not, reset to the first sound file */
2333 if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS ||
2334 !qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound] ||
2335 ast_strlen_zero(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str)) {
2336 qe->last_periodic_announce_sound = 0;
2339 /* play the announcement */
2340 res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str);
2342 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
2345 /* Resume Music on Hold if the caller is going to stay in the queue */
2348 ast_indicate(qe->chan, AST_CONTROL_RINGING);
2350 ast_moh_start(qe->chan, qe->moh, NULL);
2353 /* update last_periodic_announce_time */
2354 qe->last_periodic_announce_time = now;
2356 /* Update the current periodic announcement to the next announcement */
2357 qe->last_periodic_announce_sound++;
2362 static void record_abandoned(struct queue_ent *qe)
2364 ao2_lock(qe->parent);
2365 set_queue_variables(qe);
2366 manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
2370 "OriginalPosition: %d\r\n"
2372 qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
2374 qe->parent->callsabandoned++;
2375 ao2_unlock(qe->parent);
2378 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
2379 static void rna(int rnatime, struct queue_ent *qe, char *interface, char *membername)
2381 ast_verb(3, "Nobody picked up in %d ms\n", rnatime);
2382 ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
2383 if (qe->parent->autopause) {
2384 if (!set_member_paused(qe->parent->name, interface, "Auto-Pause", 1)) {
2385 ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
2387 ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
2393 #define AST_MAX_WATCHERS 256
2394 /*! \brief Wait for a member to answer the call
2396 * \param[in] qe the queue_ent corresponding to the caller in the queue
2397 * \param[in] outgoing the list of callattempts. Relevant ones will have their chan and stillgoing parameters non-zero
2398 * \param[in] to the amount of time (in milliseconds) to wait for a response
2399 * \param[out] digit if a user presses a digit to exit the queue, this is the digit the caller pressed
2400 * \param[in] prebusies number of busy members calculated prior to calling wait_for_answer
2401 * \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
2402 * \param[in] forwardsallowed used to detect if we should allow call forwarding, based on the 'i' option to Queue()
2404 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
2406 const char *queue = qe->parent->name;
2407 struct callattempt *o, *start = NULL, *prev = NULL;
2409 int numbusies = prebusies;
2413 struct ast_frame *f;
2414 struct callattempt *peer = NULL;
2415 struct ast_channel *winner;
2416 struct ast_channel *in = qe->chan;
2418 char membername[80] = "";
2422 struct callattempt *epollo;
2425 starttime = (long) time(NULL);
2427 for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2429 ast_poll_channel_add(in, epollo->chan);
2433 while (*to && !peer) {
2434 int numlines, retry, pos = 1;
2435 struct ast_channel *watchers[AST_MAX_WATCHERS];
2439 for (retry = 0; retry < 2; retry++) {
2441 for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
2442 if (o->stillgoing) { /* Keep track of important channels */
2445 watchers[pos++] = o->chan;
2449 prev->call_next = o;
2455 if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
2456 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
2458 /* On "ringall" strategy we only move to the next penalty level
2459 when *all* ringing phones are done in the current penalty level */
2460 ring_one(qe, outgoing, &numbusies);
2463 if (pos == 1 /* not found */) {
2464 if (numlines == (numbusies + numnochan)) {
2465 ast_debug(1, "Everyone is busy at this time\n");
2467 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
2472 winner = ast_waitfor_n(watchers, pos, to);
2473 for (o = start; o; o = o->call_next) {
2474 if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) {
2476 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2479 } else if (o->chan && (o->chan == winner)) {
2481 ast_copy_string(on, o->member->interface, sizeof(on));
2482 ast_copy_string(membername, o->member->membername, sizeof(membername));
2484 if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
2485 ast_verb(3, "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
2490 } else if (!ast_strlen_zero(o->chan->call_forward)) {
2495 ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
2496 if ((stuff = strchr(tmpchan, '/'))) {
2500 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
2504 /* Before processing channel, go ahead and check for forwarding */
2505 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
2506 /* Setup parameters */
2507 o->chan = ast_request(tech, in->nativeformats, stuff, &status);
2508 if (status != o->oldstatus)
2509 update_dial_status(qe->parent, o->member, status);
2511 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
2515 ast_channel_inherit_variables(in, o->chan);
2516 ast_channel_datastore_inherit(in, o->chan);
2517 if (o->chan->cid.cid_num)
2518 ast_free(o->chan->cid.cid_num);
2519 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
2521 if (o->chan->cid.cid_name)
2522 ast_free(o->chan->cid.cid_name);
2523 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
2525 ast_string_field_set(o->chan, accountcode, in->accountcode);
2526 o->chan->cdrflags = in->cdrflags;
2528 if (in->cid.cid_ani) {
2529 if (o->chan->cid.cid_ani)
2530 ast_free(o->chan->cid.cid_ani);
2531 o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
2533 if (o->chan->cid.cid_rdnis)
2534 ast_free(o->chan->cid.cid_rdnis);
2535 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
2536 if (ast_call(o->chan, tmpchan, 0)) {
2537 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
2542 /* Hangup the original channel now, in case we needed it */
2546 f = ast_read(winner);
2548 if (f->frametype == AST_FRAME_CONTROL) {
2549 switch (f->subclass) {
2550 case AST_CONTROL_ANSWER:
2551 /* This is our guy if someone answered. */
2553 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2557 case AST_CONTROL_BUSY:
2558 ast_verb(3, "%s is busy\n", o->chan->name);
2560 ast_cdr_busy(in->cdr);
2562 endtime = (long) time(NULL);
2563 endtime -= starttime;
2564 rna(endtime*1000, qe, on, membername);
2565 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2566 if (qe->parent->timeoutrestart)
2568 ring_one(qe, outgoing, &numbusies);
2572 case AST_CONTROL_CONGESTION:
2573 ast_verb(3, "%s is circuit-busy\n", o->chan->name);
2575 ast_cdr_busy(in->cdr);
2576 endtime = (long) time(NULL);
2577 endtime -= starttime;
2578 rna(endtime*1000, qe, on, membername);
2580 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2581 if (qe->parent->timeoutrestart)
2583 ring_one(qe, outgoing, &numbusies);
2587 case AST_CONTROL_RINGING:
2588 ast_verb(3, "%s is ringing\n", o->chan->name);
2590 case AST_CONTROL_OFFHOOK:
2591 /* Ignore going off hook */
2594 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
2599 endtime = (long) time(NULL) - starttime;
2600 rna(endtime * 1000, qe, on, membername);
2602 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2603 if (qe->parent->timeoutrestart)
2605 ring_one(qe, outgoing, &numbusies);
2612 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2620 if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2621 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
2626 if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
2627 ast_verb(3, "User pressed digit: %c\n", f->subclass);
2629 *digit = f->subclass;
2636 for (o = start; o; o = o->call_next)
2637 rna(orig, qe, o->interface, o->member->membername);
2642 for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2644 ast_poll_channel_del(in, epollo->chan);
2650 /*! \brief Check if we should start attempting to call queue members
2652 * The behavior of this function is dependent first on whether autofill is enabled
2653 * and second on whether the ring strategy is ringall. If autofill is not enabled,
2654 * then return true if we're the head of the queue. If autofill is enabled, then
2655 * we count the available members and see if the number of available members is enough
2656 * that given our position in the queue, we would theoretically be able to connect to
2657 * one of those available members
2659 static int is_our_turn(struct queue_ent *qe)
2661 struct queue_ent *ch;
2667 if (!qe->parent->autofill) {
2668 /* Atomically read the parent head -- does not need a lock */
2669 ch = qe->parent->head;
2670 /* If we are now at the top of the head, break out */
2672 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2675 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2680 /* This needs a lock. How many members are available to be served? */
2681 ao2_lock(qe->parent);
2683 ch = qe->parent->head;
2685 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2686 ast_debug(1, "Even though there may be multiple members available, the strategy is ringall so only the head call is allowed in\n");
2689 struct ao2_iterator mem_iter = ao2_iterator_init(qe->parent->members, 0);
2690 while ((cur = ao2_iterator_next(&mem_iter))) {
2691 switch (cur->status) {
2692 case AST_DEVICE_NOT_INUSE:
2693 case AST_DEVICE_UNKNOWN:
2702 ast_debug(1, "There are %d available members.\n", avl);
2704 while ((idx < avl) && (ch) && (ch != qe)) {
2710 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2711 if (ch && idx < avl) {
2712 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2715 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2719 ao2_unlock(qe->parent);
2724 static void update_qe_rule(struct queue_ent *qe)
2726 int max_penalty = qe->pr->max_relative ? qe->max_penalty + qe->pr->max_value : qe->pr->max_value;
2727 int min_penalty = qe->pr->min_relative ? qe->min_penalty + qe->pr->min_value : qe->pr->min_value;
2728 char max_penalty_str[20], min_penalty_str[20];
2729 /* a relative change to the penalty could put it below 0 */
2730 if (max_penalty < 0)
2732 if (min_penalty < 0)
2734 if (min_penalty > max_penalty)
2735 min_penalty = max_penalty;
2736 snprintf(max_penalty_str, sizeof(max_penalty_str) - 1, "%d", max_penalty);
2737 snprintf(min_penalty_str, sizeof(min_penalty_str) - 1, "%d", min_penalty);
2738 pbx_builtin_setvar_helper(qe->chan, "QUEUE_MAX_PENALTY", max_penalty_str);
2739 pbx_builtin_setvar_helper(qe->chan, "QUEUE_MIN_PENALTY", min_penalty_str);
2740 qe->max_penalty = max_penalty;
2741 qe->min_penalty = min_penalty;
2742 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);
2743 qe->pr = AST_LIST_NEXT(qe->pr, list);
2746 /*! \brief The waiting areas for callers who are not actively calling members
2748 * This function is one large loop. This function will return if a caller
2749 * either exits the queue or it becomes that caller's turn to attempt calling
2750 * queue members. Inside the loop, we service the caller with periodic announcements,
2751 * holdtime announcements, etc. as configured in queues.conf
2753 * \retval 0 if the caller's turn has arrived
2754 * \retval -1 if the caller should exit the queue.
2756 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2760 /* This is the holding pen for callers 2 through maxlen */
2762 enum queue_member_status stat;
2764 if (is_our_turn(qe))
2767 /* If we have timed out, break out */
2768 if (qe->expire && (time(NULL) > qe->expire)) {
2769 *reason = QUEUE_TIMEOUT;
2773 stat = get_member_status(qe->parent, qe->max_penalty, qe->min_penalty);
2775 /* leave the queue if no agents, if enabled */
2776 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2777 *reason = QUEUE_LEAVEEMPTY;
2778 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2783 /* leave the queue if no reachable agents, if enabled */
2784 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
2785 *reason = QUEUE_LEAVEUNAVAIL;
2786 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2790 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2791 *reason = QUEUE_LEAVEUNAVAIL;
2792 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2797 /* Make a position announcement, if enabled */
2798 if (qe->parent->announcefrequency &&
2799 (res = say_position(qe,ringing)))
2802 /* Make a periodic announcement, if enabled */
2803 if (qe->parent->periodicannouncefrequency &&
2804 (res = say_periodic_announcement(qe,ringing)))
2807 /* see if we need to move to the next penalty level for this queue */
2808 while (qe->pr && ((time(NULL) - qe->start) > qe->pr->time)) {
2812 /* Wait a second before checking again */
2813 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
2814 if (res > 0 && !valid_exit(qe, res))
2824 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
2827 struct call_queue *qtmp;
2828 struct ao2_iterator queue_iter;
2830 if (shared_lastcall) {
2831 queue_iter = ao2_iterator_init(queues, 0);
2832 while ((qtmp = ao2_iterator_next(&queue_iter))) {
2834 if ((mem = ao2_find(qtmp->members, member, OBJ_POINTER))) {
2835 time(&mem->lastcall);
2845 time(&member->lastcall);
2847 member->lastqueue = q;
2851 q->callscompleted++;
2852 if (callcompletedinsl)
2853 q->callscompletedinsl++;
2858 /*! \brief Calculate the metric of each member in the outgoing callattempts
2860 * A numeric metric is given to each member depending on the ring strategy used
2861 * by the queue. Members with lower metrics will be called before members with
2864 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2866 if ((qe->max_penalty && (mem->penalty > qe->max_penalty)) || (qe->min_penalty && (mem->penalty < qe->min_penalty)))
2869 switch (q->strategy) {
2870 case QUEUE_STRATEGY_RINGALL:
2871 /* Everyone equal, except for penalty */
2872 tmp->metric = mem->penalty * 1000000;
2874 case QUEUE_STRATEGY_LINEAR:
2875 if (pos < qe->linpos) {
2876 tmp->metric = 1000 + pos;
2878 if (pos > qe->linpos)
2879 /* Indicate there is another priority */
2883 tmp->metric += mem->penalty * 1000000;
2885 case QUEUE_STRATEGY_RRMEMORY:
2886 if (pos < q->rrpos) {
2887 tmp->metric = 1000 + pos;
2890 /* Indicate there is another priority */
2894 tmp->metric += mem->penalty * 1000000;
2896 case QUEUE_STRATEGY_RANDOM:
2897 tmp->metric = ast_random() % 1000;
2898 tmp->metric += mem->penalty * 1000000;
2900 case QUEUE_STRATEGY_WRANDOM:
2901 tmp->metric = ast_random() % ((1 + mem->penalty) * 1000);
2903 case QUEUE_STRATEGY_FEWESTCALLS:
2904 tmp->metric = mem->calls;
2905 tmp->metric += mem->penalty * 1000000;
2907 case QUEUE_STRATEGY_LEASTRECENT:
2911 tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2912 tmp->metric += mem->penalty * 1000000;
2915 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2921 enum agent_complete_reason {
2927 static void send_agent_complete(const struct queue_ent *qe, const char *queuename,
2928 const struct ast_channel *peer, const struct member *member, time_t callstart,
2929 char *vars, size_t vars_len, enum agent_complete_reason rsn)
2931 const char *reason = NULL; /* silence dumb compilers */
2933 if (!qe->parent->eventwhencalled)
2944 reason = "transfer";
2948 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2953 "MemberName: %s\r\n"
2958 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2959 (long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
2960 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
2962 /*! \brief A large function which calls members, updates statistics, and bridges the caller and a member
2964 * Here is the process of this function
2965 * 1. Process any options passed to the Queue() application. Options here mean the third argument to Queue()
2966 * 2. Iterate trough the members of the queue, creating a callattempt corresponding to each member. During this
2967 * iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
2968 * member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
2969 * during each iteration, we call calc_metric to determine which members should be rung when.
2970 * 3. Call ring_one to place a call to the appropriate member(s)
2971 * 4. Call wait_for_answer to wait for an answer. If no one answers, return.
2972 * 5. Take care of any holdtime announcements, member delays, or other options which occur after a call has been answered.
2973 * 6. Start the monitor or mixmonitor if the option is set
2974 * 7. Remove the caller from the queue to allow other callers to advance
2975 * 8. Bridge the call.
2976 * 9. Do any post processing after the call has disconnected.
2978 * \param[in] qe the queue_ent structure which corresponds to the caller attempting to reach members
2979 * \param[in] options the options passed as the third parameter to the Queue() application
2980 * \param[in] url the url passed as the fourth parameter to the Queue() application
2981 * \param[in,out] tries the number of times we have tried calling queue members
2982 * \param[out] noption set if the call to Queue() has the 'n' option set.
2983 * \param[in] agi the agi passed as the fifth parameter to the Queue() application
2984 * \param[in] macro the macro passed as the sixth parameter to the Queue() application
2985 * \param[in] gosub the gosub passed as the seventh parameter to the Queue() application
2986 * \param[in] ringing 1 if the 'r' option is set, otherwise 0
2988 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)
2991 struct callattempt *outgoing = NULL; /* the list of calls we are building */
2993 char oldexten[AST_MAX_EXTENSION]="";
2994 char oldcontext[AST_MAX_CONTEXT]="";
2995 char queuename[256]="";
2996 char interfacevar[256]="";
2997 struct ast_channel *peer;
2998 struct ast_channel *which;
2999 struct callattempt *lpeer;
3000 struct member *member;
3001 struct ast_app *app;
3002 int res = 0, bridge = 0;
3005 char *announce = NULL;
3008 time_t now = time(NULL);
3009 struct ast_bridge_config bridge_config;
3010 char nondataquality = 1;
3011 char *agiexec = NULL;
3012 char *macroexec = NULL;
3013 char *gosubexec = NULL;
3015 const char *monitorfilename;
3016 const char *monitor_exec;
3017 const char *monitor_options;
3018 char tmpid[256], tmpid2[256];
3019 char meid[1024], meid2[1024];
3020 char mixmonargs[1512];
3021 struct ast_app *mixmonapp = NULL;
3024 int forwardsallowed = 1;
3025 int callcompletedinsl;
3026 struct ao2_iterator memi;
3027 struct ast_datastore *datastore;
3029 ast_channel_lock(qe->chan);
3030 datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
3031 ast_channel_unlock(qe->chan);
3033 memset(&bridge_config, 0, sizeof(bridge_config));
3038 for (; options && *options; options++)
3041 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
3044 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
3047 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
3050 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
3056 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
3059 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
3062 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_PARKCALL);
3065 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_PARKCALL);
3068 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_LINEAR)
3071 *tries = qe->parent->membercount;
3075 forwardsallowed = 0;
3078 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMIXMON);
3081 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMIXMON);
3086 /* Hold the lock while we setup the outgoing calls */
3089 ao2_lock(qe->parent);
3090 ast_debug(1, "%s is trying to call a queue member.\n",
3092 ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
3093 if (!ast_strlen_zero(qe->announce))
3094 announce = qe->announce;
3095 if (!ast_strlen_zero(announceoverride))
3096 announce = announceoverride;
3098 memi = ao2_iterator_init(qe->parent->members, 0);
3099 while ((cur = ao2_iterator_next(&memi))) {
3100 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
3101 struct ast_dialed_interface *di;
3102 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
3105 ao2_unlock(qe->parent);
3111 if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
3113 ao2_unlock(qe->parent);
3119 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
3120 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
3122 ao2_unlock(&qe->parent);
3128 datastore->data = dialed_interfaces;
3129 AST_LIST_HEAD_INIT(dialed_interfaces);
3131 ast_channel_lock(qe->chan);
3132 ast_channel_datastore_add(qe->chan, datastore);
3133 ast_channel_unlock(qe->chan);
3135 dialed_interfaces = datastore->data;
3137 AST_LIST_LOCK(dialed_interfaces);
3138 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
3139 if (!strcasecmp(cur->interface, di->interface)) {
3140 ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n",
3145 AST_LIST_UNLOCK(dialed_interfaces);
3152 /* It is always ok to dial a Local interface. We only keep track of
3153 * which "real" interfaces have been dialed. The Local channel will
3154 * inherit this list so that if it ends up dialing a real interface,
3155 * it won't call one that has already been called. */
3156 if (strncasecmp(cur->interface, "Local/", 6)) {
3157 if (!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) {
3159 ao2_unlock(qe->parent);
3165 strcpy(di->interface, cur->interface);
3167 AST_LIST_LOCK(dialed_interfaces);
3168 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
3169 AST_LIST_UNLOCK(dialed_interfaces);
3172 tmp->stillgoing = -1;
3174 tmp->oldstatus = cur->status;
3175 tmp->lastcall = cur->lastcall;
3176 tmp->lastqueue = cur->lastqueue;
3177 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
3178 /* Special case: If we ring everyone, go ahead and ring them, otherwise
3179 just calculate their metric for the appropriate strategy */
3180 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
3181 /* Put them in the list of outgoing thingies... We're ready now.
3182 XXX If we're forcibly removed, these outgoing calls won't get
3184 tmp->q_next = outgoing;
3186 /* If this line is up, don't try anybody else */
3187 if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
3194 if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
3195 to = (qe->expire - now) * 1000;
3197 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
3200 ring_one(qe, outgoing, &numbusies);
3201 ao2_unlock(qe->parent);
3204 lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
3206 ast_channel_datastore_remove(qe->chan, datastore);
3207 ast_channel_datastore_free(datastore);
3209 ao2_lock(qe->parent);
3210 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
3211 store_next_rr(qe, outgoing);
3213 if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) {
3214 store_next_lin(qe, outgoing);
3216 ao2_unlock(qe->parent);
3217 peer = lpeer ? lpeer->chan : NULL;
3221 /* Must gotten hung up */
3224 /* User exited by pressing a digit */
3228 ast_debug(1, "%s: Nobody answered.\n", qe->chan->name);
3229 } else { /* peer is valid */
3230 /* Ah ha! Someone answered within the desired timeframe. Of course after this
3231 we will always return with -1 so that it is hung up properly after the
3234 if (!strcmp(qe->chan->tech->type, "Zap"))
3235 ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
3236 if (!strcmp(peer->tech->type, "Zap"))
3237 ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
3238 /* Update parameters for the queue */
3240 recalc_holdtime(qe, (now - qe->start));
3241 ao2_lock(qe->parent);
3242 callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
3243 ao2_unlock(qe->parent);
3244 member = lpeer->member;
3245 /* Increment the refcount for this member, since we're going to be using it for awhile in here. */
3247 hangupcalls(outgoing, peer);
3249 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
3252 res2 = ast_autoservice_start(qe->chan);
3254 if (qe->parent->memberdelay) {
3255 ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
3256 res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
3258 if (!res2 && announce) {
3259 play_file(peer, announce);
3261 if (!res2 && qe->parent->reportholdtime) {
3262 if (!play_file(peer, qe->parent->sound_reporthold)) {
3266 holdtime = abs((now - qe->start) / 60);
3268 play_file(peer, qe->parent->sound_lessthan);
3269 ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
3271 ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
3272 play_file(peer, qe->parent->sound_minutes);
3276 res2 |= ast_autoservice_stop(qe->chan);
3277 if (ast_check_hangup(peer)) {
3278 /* Agent must have hung up */
3279 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
3280 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
3281 record_abandoned(qe);
3282 if (qe->parent->eventwhencalled)
3283 manager_event(EVENT_FLAG_AGENT, "AgentDump",
3288 "MemberName: %s\r\n"
3290 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
3291 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
3293 ao2_ref(member, -1);
3296 /* Caller must have hung up just before being connected*/
3297 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
3298 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
3299 record_abandoned(qe);
3301 ao2_ref(member, -1);
3305 /* Stop music on hold */
3307 ast_indicate(qe->chan,-1);
3309 ast_moh_stop(qe->chan);
3310 /* If appropriate, log that we have a destination channel */
3312 ast_cdr_setdestchan(qe->chan->cdr, peer->name);
3313 /* Make sure channels are compatible */
3314 res = ast_channel_make_compatible(qe->chan, peer);
3316 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
3317 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
3318 record_abandoned(qe);
3320 ao2_ref(member, -1);
3324 /* Play announcement to the caller telling it's his turn if defined */
3325 if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
3326 if (play_file(qe->chan, qe->parent->sound_callerannounce))
3327 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
3330 ao2_lock(qe->parent);
3331 /* if setinterfacevar is defined, make member variables available to the channel */
3332 /* use pbx_builtin_setvar to set a load of variables with one call */
3333 if (qe->parent->setinterfacevar) {
3334 snprintf(interfacevar,sizeof(interfacevar), "MEMBERINTERFACE=%s|MEMBERNAME=%s|MEMBERCALLS=%d|MEMBERLASTCALL=%ld|MEMBERPENALTY=%d|MEMBERDYNAMIC=%d|MEMBERREALTIME=%d",
3335 member->interface, member->membername, member->calls, (long)member->lastcall, member->penalty, member->dynamic, member->realtime);
3336 pbx_builtin_setvar(qe->chan, interfacevar);
3339 /* if setqueueentryvar is defined, make queue entry (i.e. the caller) variables available to the channel */
3340 /* use pbx_builtin_setvar to set a load of variables with one call */
3341 if (qe->parent->setqueueentryvar) {
3342 snprintf(interfacevar,sizeof(interfacevar), "QEHOLDTIME=%ld|QEORIGINALPOS=%d",
3343 (long) time(NULL) - qe->start, qe->opos);
3344 pbx_builtin_setvar(qe->chan, interfacevar);
3347 /* try to set queue variables if configured to do so*/
3348 set_queue_variables(qe);
3349 ao2_unlock(qe->parent);
3351 /* Begin Monitoring */
3352 if (qe->parent->monfmt && *qe->parent->monfmt) {
3353 if (!qe->parent->montype) {
3354 ast_debug(1, "Starting Monitor as requested.\n");
3355 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
3356 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
3360 if (monitorfilename)
3361 ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT);
3362 else if (qe->chan->cdr)
3363 ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1, X_REC_IN | X_REC_OUT);
3365 /* Last ditch effort -- no CDR, make up something */
3366 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
3367 ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT);
3370 ast_debug(1, "Starting MixMonitor as requested.\n");
3371 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
3372 if (!monitorfilename) {
3374 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid));
3376 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
3378 const char *m = monitorfilename;
3379 for (p = tmpid2; p < tmpid2 + sizeof(tmpid2) - 1; p++, m++) {
3382 if (*(m + 1) == '{')