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 const 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: "minute." (def. queue-minute) */
435 AST_STRING_FIELD(sound_minute);
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 < ARRAY_LEN(queue_results); i++) {
520 if (queue_results[i].id == res) {
521 pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
527 static const char *int2strat(int strategy)
531 for (x = 0; x < ARRAY_LEN(strategies); x++) {
532 if (strategy == strategies[x].strategy)
533 return strategies[x].name;
539 static int strat2int(const char *strategy)
543 for (x = 0; x < ARRAY_LEN(strategies); 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)
577 char interfacevar[256]="";
580 if (qe->parent->setqueuevar) {
582 if (qe->parent->callscompleted > 0)
583 sl = 100 * ((float) qe->parent->callscompletedinsl / (float) qe->parent->callscompleted);
585 snprintf(interfacevar, sizeof(interfacevar),
586 "QUEUENAME=%s|QUEUEMAX=%d|QUEUESTRATEGY=%s|QUEUECALLS=%d|QUEUEHOLDTIME=%d|QUEUECOMPLETED=%d|QUEUEABANDONED=%d|QUEUESRVLEVEL=%d|QUEUESRVLEVELPERF=%2.1f",
587 qe->parent->name, qe->parent->maxlen, int2strat(qe->parent->strategy), qe->parent->count, qe->parent->holdtime, qe->parent->callscompleted,
588 qe->parent->callsabandoned, qe->parent->servicelevel, sl);
590 pbx_builtin_setvar(qe->chan, interfacevar);
594 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
595 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
597 struct queue_ent *cur;
614 enum queue_member_status {
616 QUEUE_NO_REACHABLE_MEMBERS,
617 QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
621 /*! \brief Check if members are available
623 * This function checks to see if members are available to be called. If any member
624 * is available, the function immediately returns QUEUE_NORMAL. If no members are available,
625 * the appropriate reason why is returned
627 static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty, int min_penalty)
629 struct member *member;
630 struct ao2_iterator mem_iter;
631 enum queue_member_status result = QUEUE_NO_MEMBERS;
634 mem_iter = ao2_iterator_init(q->members, 0);
635 for (; (member = ao2_iterator_next(&mem_iter)); ao2_ref(member, -1)) {
636 if ((max_penalty && (member->penalty > max_penalty)) || (min_penalty && (member->penalty < min_penalty)))
639 switch (member->status) {
640 case AST_DEVICE_INVALID:
643 case AST_DEVICE_UNAVAILABLE:
644 if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)
645 result = QUEUE_NO_REACHABLE_MEMBERS;
648 if (member->paused) {
649 result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
664 AST_LIST_ENTRY(statechange) entry;
668 /*! \brief set a member's status based on device state of that member's state_interface*/
669 static void *handle_statechange(struct statechange *sc)
671 struct call_queue *q;
673 struct ao2_iterator mem_iter;
674 struct member_interface *curint;
675 struct ao2_iterator queue_iter;
679 technology = ast_strdupa(sc->dev);
680 loc = strchr(technology, '/');
687 AST_LIST_LOCK(&interfaces);
688 AST_LIST_TRAVERSE(&interfaces, curint, list) {
691 interface = ast_strdupa(curint->interface);
692 if ((slash_pos = strchr(interface, '/')))
693 if ((slash_pos = strchr(slash_pos + 1, '/')))
696 if (!strcasecmp(interface, sc->dev))
699 AST_LIST_UNLOCK(&interfaces);
702 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));
706 ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
707 queue_iter = ao2_iterator_init(queues, 0);
708 while ((q = ao2_iterator_next(&queue_iter))) {
710 mem_iter = ao2_iterator_init(q->members, 0);
711 while ((cur = ao2_iterator_next(&mem_iter))) {
714 interface = ast_strdupa(cur->state_interface);
715 if ((slash_pos = strchr(interface, '/')))
716 if ((slash_pos = strchr(slash_pos + 1, '/')))
719 if (strcasecmp(sc->dev, interface)) {
724 if (cur->status != sc->state) {
725 cur->status = sc->state;
726 if (q->maskmemberstatus) {
731 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
741 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static",
742 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
754 * \brief Data used by the device state thread
757 /*! Set to 1 to stop the thread */
759 /*! The device state monitoring thread */
761 /*! Lock for the state change queue */
763 /*! Condition for the state change queue */
765 /*! Queue of state changes */
766 AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
768 .thread = AST_PTHREADT_NULL,
771 /*! \brief Consumer of the statechange queue */
772 static void *device_state_thread(void *data)
774 struct statechange *sc = NULL;
776 while (!device_state.stop) {
777 ast_mutex_lock(&device_state.lock);
778 if (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
779 ast_cond_wait(&device_state.cond, &device_state.lock);
780 sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry);
782 ast_mutex_unlock(&device_state.lock);
784 /* Check to see if we were woken up to see the request to stop */
785 if (device_state.stop)
791 handle_statechange(sc);
800 while ((sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry)))
805 /*! \brief Producer of the statechange queue */
806 static int statechange_queue(const char *dev, enum ast_device_state state)
808 struct statechange *sc;
810 if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
814 strcpy(sc->dev, dev);
816 ast_mutex_lock(&device_state.lock);
817 AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
818 ast_cond_signal(&device_state.cond);
819 ast_mutex_unlock(&device_state.lock);
823 static void device_state_cb(const struct ast_event *event, void *unused)
825 enum ast_device_state state;
828 state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
829 device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
831 if (ast_strlen_zero(device)) {
832 ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
836 statechange_queue(device, state);
839 /*! \brief allocate space for new queue member and set fields based on parameters passed */
840 static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused, const char *state_interface)
844 if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
845 cur->penalty = penalty;
846 cur->paused = paused;
847 ast_copy_string(cur->interface, interface, sizeof(cur->interface));
848 if (!ast_strlen_zero(state_interface))
849 ast_copy_string(cur->state_interface, state_interface, sizeof(cur->state_interface));
851 ast_copy_string(cur->state_interface, interface, sizeof(cur->state_interface));
852 if (!ast_strlen_zero(membername))
853 ast_copy_string(cur->membername, membername, sizeof(cur->membername));
855 ast_copy_string(cur->membername, interface, sizeof(cur->membername));
856 if (!strchr(cur->interface, '/'))
857 ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
858 cur->status = ast_device_state(cur->state_interface);
865 static int compress_char(const char c)
875 static int member_hash_fn(const void *obj, const int flags)
877 const struct member *mem = obj;
878 const char *chname = strchr(mem->interface, '/');
881 chname = mem->interface;
882 for (i = 0; i < 5 && chname[i]; i++)
883 ret += compress_char(chname[i]) << (i * 6);
887 static int member_cmp_fn(void *obj1, void *obj2, int flags)
889 struct member *mem1 = obj1, *mem2 = obj2;
890 return strcasecmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
893 static void init_queue(struct call_queue *q)
896 struct penalty_rule *pr_iter;
899 q->retry = DEFAULT_RETRY;
902 q->announcefrequency = 0;
903 q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
904 q->announceholdtime = 0;
905 q->announceholdtime = 1;
906 q->roundingseconds = 0; /* Default - don't announce seconds */
909 q->setinterfacevar = 0;
911 q->setqueueentryvar = 0;
912 q->autofill = autofill_default;
913 q->montype = montype_default;
915 q->reportholdtime = 0;
919 q->leavewhenempty = 0;
921 q->maskmemberstatus = 0;
922 q->eventwhencalled = 0;
924 q->timeoutrestart = 0;
925 q->periodicannouncefrequency = 0;
927 if (q->strategy == QUEUE_STRATEGY_LINEAR)
928 /* linear strategy depends on order, so we have to place all members in a single bucket */
929 q->members = ao2_container_alloc(1, member_hash_fn, member_cmp_fn);
931 q->members = ao2_container_alloc(37, member_hash_fn, member_cmp_fn);
936 ast_string_field_set(q, sound_next, "queue-youarenext");
937 ast_string_field_set(q, sound_thereare, "queue-thereare");
938 ast_string_field_set(q, sound_calls, "queue-callswaiting");
939 ast_string_field_set(q, sound_holdtime, "queue-holdtime");
940 ast_string_field_set(q, sound_minutes, "queue-minutes");
941 ast_string_field_set(q, sound_minute, "queue-minute");
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_reporthold, "queue-reporthold");
946 if ((q->sound_periodicannounce[0] = ast_str_create(32)))
947 ast_str_set(&q->sound_periodicannounce[0], 0, "queue-periodic-announce");
949 for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
950 if (q->sound_periodicannounce[i])
951 ast_str_set(&q->sound_periodicannounce[i], 0, "%s", "");
954 while ((pr_iter = AST_LIST_REMOVE_HEAD(&q->rules,list)))
958 static void clear_queue(struct call_queue *q)
961 q->callscompleted = 0;
962 q->callsabandoned = 0;
963 q->callscompletedinsl = 0;
967 static int add_to_interfaces(const char *interface)
969 struct member_interface *curint;
971 AST_LIST_LOCK(&interfaces);
972 AST_LIST_TRAVERSE(&interfaces, curint, list) {
973 if (!strcasecmp(curint->interface, interface))
978 AST_LIST_UNLOCK(&interfaces);
982 ast_debug(1, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
984 if ((curint = ast_calloc(1, sizeof(*curint)))) {
985 ast_copy_string(curint->interface, interface, sizeof(curint->interface));
986 AST_LIST_INSERT_HEAD(&interfaces, curint, list);
988 AST_LIST_UNLOCK(&interfaces);
993 static int interface_exists_global(const char *interface)
995 struct call_queue *q;
996 struct member *mem, tmpmem;
997 struct ao2_iterator queue_iter, mem_iter;
1000 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1001 queue_iter = ao2_iterator_init(queues, 0);
1002 while ((q = ao2_iterator_next(&queue_iter))) {
1004 mem_iter = ao2_iterator_init(q->members, 0);
1005 while ((mem = ao2_iterator_next(&mem_iter))) {
1006 if (!strcasecmp(mem->state_interface, interface)) {
1019 static int remove_from_interfaces(const char *interface)
1021 struct member_interface *curint;
1023 if (interface_exists_global(interface))
1026 AST_LIST_LOCK(&interfaces);
1027 AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
1028 if (!strcasecmp(curint->interface, interface)) {
1029 ast_debug(1, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
1030 AST_LIST_REMOVE_CURRENT(list);
1035 AST_LIST_TRAVERSE_SAFE_END;
1036 AST_LIST_UNLOCK(&interfaces);
1041 static void clear_and_free_interfaces(void)
1043 struct member_interface *curint;
1045 AST_LIST_LOCK(&interfaces);
1046 while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
1048 AST_LIST_UNLOCK(&interfaces);
1051 /*Note: call this with the rule_lists locked */
1052 static int insert_penaltychange (const char *list_name, const char *content, const int linenum)
1054 char *timestr, *maxstr, *minstr, *contentdup;
1055 struct penalty_rule *rule = NULL, *rule_iter;
1056 struct rule_list *rl_iter;
1057 int time, inserted = 0;
1059 if (!(rule = ast_calloc(1, sizeof(*rule)))) {
1060 ast_log(LOG_ERROR, "Cannot allocate memory for penaltychange rule at line %d!\n", linenum);
1064 contentdup = ast_strdupa(content);
1066 if (!(maxstr = strchr(contentdup, ','))) {
1067 ast_log(LOG_WARNING, "Improperly formatted penaltychange rule at line %d. Ignoring.\n", linenum);
1073 timestr = contentdup;
1075 if ((time = atoi(timestr)) < 0) {
1076 ast_log(LOG_WARNING, "Improper time parameter specified for penaltychange rule at line %d. Ignoring.\n", linenum);
1083 if ((minstr = strchr(maxstr,',')))
1086 /* The last check will evaluate true if either no penalty change is indicated for a given rule
1087 * OR if a min penalty change is indicated but no max penalty change is */
1088 if (*maxstr == '+' || *maxstr == '-' || *maxstr == '\0') {
1089 rule->max_relative = 1;
1092 rule->max_value = atoi(maxstr);
1094 if (!ast_strlen_zero(minstr)) {
1095 if (*minstr == '+' || *minstr == '-')
1096 rule->min_relative = 1;
1097 rule->min_value = atoi(minstr);
1098 } else /*there was no minimum specified, so assume this means no change*/
1099 rule->min_relative = 1;
1101 /*We have the rule made, now we need to insert it where it belongs*/
1102 AST_LIST_TRAVERSE(&rule_lists, rl_iter, list){
1103 if (strcasecmp(rl_iter->name, list_name))
1106 AST_LIST_TRAVERSE_SAFE_BEGIN(&rl_iter->rules, rule_iter, list) {
1107 if (rule->time < rule_iter->time) {
1108 AST_LIST_INSERT_BEFORE_CURRENT(rule, list);
1113 AST_LIST_TRAVERSE_SAFE_END;
1116 AST_LIST_INSERT_TAIL(&rl_iter->rules, rule, list);
1123 /*! \brief Configure a queue parameter.
1125 For error reporting, line number is passed for .conf static configuration.
1126 For Realtime queues, linenum is -1.
1127 The failunknown flag is set for config files (and static realtime) to show
1128 errors for unknown parameters. It is cleared for dynamic realtime to allow
1129 extra fields in the tables. */
1130 static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
1132 if (!strcasecmp(param, "musicclass") ||
1133 !strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
1134 ast_string_field_set(q, moh, val);
1135 } else if (!strcasecmp(param, "announce")) {
1136 ast_string_field_set(q, announce, val);
1137 } else if (!strcasecmp(param, "context")) {
1138 ast_string_field_set(q, context, val);
1139 } else if (!strcasecmp(param, "timeout")) {
1140 q->timeout = atoi(val);
1142 q->timeout = DEFAULT_TIMEOUT;
1143 } else if (!strcasecmp(param, "ringinuse")) {
1144 q->ringinuse = ast_true(val);
1145 } else if (!strcasecmp(param, "setinterfacevar")) {
1146 q->setinterfacevar = ast_true(val);
1147 } else if (!strcasecmp(param, "setqueuevar")) {
1148 q->setqueuevar = ast_true(val);
1149 } else if (!strcasecmp(param, "setqueueentryvar")) {
1150 q->setqueueentryvar = ast_true(val);
1151 } else if (!strcasecmp(param, "monitor-format")) {
1152 ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
1153 } else if (!strcasecmp(param, "membermacro")) {
1154 ast_string_field_set(q, membermacro, val);
1155 } else if (!strcasecmp(param, "membergosub")) {
1156 ast_string_field_set(q, membergosub, val);
1157 } else if (!strcasecmp(param, "queue-youarenext")) {
1158 ast_string_field_set(q, sound_next, val);
1159 } else if (!strcasecmp(param, "queue-thereare")) {
1160 ast_string_field_set(q, sound_thereare, val);
1161 } else if (!strcasecmp(param, "queue-callswaiting")) {
1162 ast_string_field_set(q, sound_calls, val);
1163 } else if (!strcasecmp(param, "queue-holdtime")) {
1164 ast_string_field_set(q, sound_holdtime, val);
1165 } else if (!strcasecmp(param, "queue-minutes")) {
1166 ast_string_field_set(q, sound_minutes, val);
1167 } else if (!strcasecmp(param, "queue-minute")) {
1168 ast_string_field_set(q, sound_minute, val);
1169 } else if (!strcasecmp(param, "queue-seconds")) {
1170 ast_string_field_set(q, sound_seconds, val);
1171 } else if (!strcasecmp(param, "queue-thankyou")) {
1172 ast_string_field_set(q, sound_thanks, val);
1173 } else if (!strcasecmp(param, "queue-callerannounce")) {
1174 ast_string_field_set(q, sound_callerannounce, val);
1175 } else if (!strcasecmp(param, "queue-reporthold")) {
1176 ast_string_field_set(q, sound_reporthold, val);
1177 } else if (!strcasecmp(param, "announce-frequency")) {
1178 q->announcefrequency = atoi(val);
1179 } else if (!strcasecmp(param, "min-announce-frequency")) {
1180 q->minannouncefrequency = atoi(val);
1181 ast_debug(1, "%s=%s for queue '%s'\n", param, val, q->name);
1182 } else if (!strcasecmp(param, "announce-round-seconds")) {
1183 q->roundingseconds = atoi(val);
1184 /* Rounding to any other values just doesn't make sense... */
1185 if (!(q->roundingseconds == 0 || q->roundingseconds == 5 || q->roundingseconds == 10
1186 || q->roundingseconds == 15 || q->roundingseconds == 20 || q->roundingseconds == 30)) {
1188 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1189 "using 0 instead for queue '%s' at line %d of queues.conf\n",
1190 val, param, q->name, linenum);
1192 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1193 "using 0 instead for queue '%s'\n", val, param, q->name);
1195 q->roundingseconds=0;
1197 } else if (!strcasecmp(param, "announce-holdtime")) {
1198 if (!strcasecmp(val, "once"))
1199 q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
1200 else if (ast_true(val))
1201 q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
1203 q->announceholdtime = 0;
1204 } else if (!strcasecmp(param, "announce-position")) {
1205 q->announceposition = ast_true(val);
1206 } else if (!strcasecmp(param, "periodic-announce")) {
1207 if (strchr(val, ',')) {
1208 char *s, *buf = ast_strdupa(val);
1211 while ((s = strsep(&buf, ",|"))) {
1212 if (!q->sound_periodicannounce[i])
1213 q->sound_periodicannounce[i] = ast_str_create(16);
1214 ast_str_set(&q->sound_periodicannounce[i], 0, s);
1216 if (i == MAX_PERIODIC_ANNOUNCEMENTS)
1220 ast_str_set(&q->sound_periodicannounce[0], 0, val);
1222 } else if (!strcasecmp(param, "periodic-announce-frequency")) {
1223 q->periodicannouncefrequency = atoi(val);
1224 } else if (!strcasecmp(param, "retry")) {
1225 q->retry = atoi(val);
1227 q->retry = DEFAULT_RETRY;
1228 } else if (!strcasecmp(param, "wrapuptime")) {
1229 q->wrapuptime = atoi(val);
1230 } else if (!strcasecmp(param, "autofill")) {
1231 q->autofill = ast_true(val);
1232 } else if (!strcasecmp(param, "monitor-type")) {
1233 if (!strcasecmp(val, "mixmonitor"))
1235 } else if (!strcasecmp(param, "autopause")) {
1236 q->autopause = ast_true(val);
1237 } else if (!strcasecmp(param, "maxlen")) {
1238 q->maxlen = atoi(val);
1241 } else if (!strcasecmp(param, "servicelevel")) {
1242 q->servicelevel= atoi(val);
1243 } else if (!strcasecmp(param, "strategy")) {
1244 /* We already have set this, no need to do it again */
1246 } else if (!strcasecmp(param, "joinempty")) {
1247 if (!strcasecmp(val, "loose"))
1248 q->joinempty = QUEUE_EMPTY_LOOSE;
1249 else if (!strcasecmp(val, "strict"))
1250 q->joinempty = QUEUE_EMPTY_STRICT;
1251 else if (ast_true(val))
1252 q->joinempty = QUEUE_EMPTY_NORMAL;
1255 } else if (!strcasecmp(param, "leavewhenempty")) {
1256 if (!strcasecmp(val, "loose"))
1257 q->leavewhenempty = QUEUE_EMPTY_LOOSE;
1258 else if (!strcasecmp(val, "strict"))
1259 q->leavewhenempty = QUEUE_EMPTY_STRICT;
1260 else if (ast_true(val))
1261 q->leavewhenempty = QUEUE_EMPTY_NORMAL;
1263 q->leavewhenempty = 0;
1264 } else if (!strcasecmp(param, "eventmemberstatus")) {
1265 q->maskmemberstatus = !ast_true(val);
1266 } else if (!strcasecmp(param, "eventwhencalled")) {
1267 if (!strcasecmp(val, "vars")) {
1268 q->eventwhencalled = QUEUE_EVENT_VARIABLES;
1270 q->eventwhencalled = ast_true(val) ? 1 : 0;
1272 } else if (!strcasecmp(param, "reportholdtime")) {
1273 q->reportholdtime = ast_true(val);
1274 } else if (!strcasecmp(param, "memberdelay")) {
1275 q->memberdelay = atoi(val);
1276 } else if (!strcasecmp(param, "weight")) {
1277 q->weight = atoi(val);
1280 /* With Realtime queues, if the last queue using weights is deleted in realtime,
1281 we will not see any effect on use_weight until next reload. */
1282 } else if (!strcasecmp(param, "timeoutrestart")) {
1283 q->timeoutrestart = ast_true(val);
1284 } else if (!strcasecmp(param, "defaultrule")) {
1285 ast_string_field_set(q, defaultrule, val);
1286 } else if (failunknown) {
1288 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
1289 q->name, param, linenum);
1291 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
1296 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)
1298 struct member *m, tmpmem;
1303 penalty = atoi(penalty_str);
1309 paused = atoi(paused_str);
1314 /* Find the member, or the place to put a new one. */
1315 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1316 m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
1318 /* Create a new one if not found, else update penalty */
1320 if ((m = create_queue_member(interface, membername, penalty, paused, state_interface))) {
1323 add_to_interfaces(m->state_interface);
1324 ao2_link(q->members, m);
1330 m->dead = 0; /* Do not delete this one. */
1333 if (strcasecmp(state_interface, m->state_interface)) {
1334 remove_from_interfaces(m->state_interface);
1335 ast_copy_string(m->state_interface, state_interface, sizeof(m->state_interface));
1336 add_to_interfaces(m->state_interface);
1338 m->penalty = penalty;
1343 static void free_members(struct call_queue *q, int all)
1345 /* Free non-dynamic members */
1347 struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
1349 while ((cur = ao2_iterator_next(&mem_iter))) {
1350 if (all || !cur->dynamic) {
1351 ao2_unlink(q->members, cur);
1352 remove_from_interfaces(cur->state_interface);
1359 static void destroy_queue(void *obj)
1361 struct call_queue *q = obj;
1364 ast_debug(0, "Queue destructor called for queue '%s'!\n", q->name);
1367 ast_string_field_free_memory(q);
1368 for (i = 0; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
1369 if (q->sound_periodicannounce[i])
1370 free(q->sound_periodicannounce[i]);
1372 ao2_ref(q->members, -1);
1375 static struct call_queue *alloc_queue(const char *queuename)
1377 struct call_queue *q;
1379 if ((q = ao2_alloc(sizeof(*q), destroy_queue))) {
1380 if (ast_string_field_init(q, 64)) {
1384 ast_string_field_set(q, name, queuename);
1389 /*!\brief Reload a single queue via realtime.
1390 \return Return the queue, or NULL if it doesn't exist.
1391 \note Should be called with the global qlock locked. */
1392 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
1394 struct ast_variable *v;
1395 struct call_queue *q, tmpq = {
1399 struct ao2_iterator mem_iter;
1400 char *interface = NULL;
1401 const char *tmp_name;
1403 char tmpbuf[64]; /* Must be longer than the longest queue param name. */
1405 /* Static queues override realtime. */
1406 if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
1414 ast_log(LOG_WARNING, "Static queue '%s' already exists. Not loading from realtime\n", q->name);
1420 } else if (!member_config)
1421 /* Not found in the list, and it's not realtime ... */
1424 /* Check if queue is defined in realtime. */
1426 /* Delete queue from in-core list if it has been deleted in realtime. */
1428 /*! \note Hmm, can't seem to distinguish a DB failure from a not
1429 found condition... So we might delete an in-core queue
1430 in case of DB failure. */
1431 ast_debug(1, "Queue %s not found in realtime.\n", queuename);
1434 /* Delete if unused (else will be deleted when last caller leaves). */
1435 ao2_unlink(queues, q);
1442 /* Create a new queue if an in-core entry does not exist yet. */
1444 struct ast_variable *tmpvar = NULL;
1445 if (!(q = alloc_queue(queuename)))
1450 /*Before we initialize the queue, we need to set the strategy, so that linear strategy
1451 * will allocate the members properly
1453 for (tmpvar = queue_vars; tmpvar; tmpvar = tmpvar->next) {
1454 if (!strcasecmp(tmpvar->name, "strategy")) {
1455 q->strategy = strat2int(tmpvar->value);
1456 if (q->strategy < 0) {
1457 ast_log(LOG_WARNING, "'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
1458 tmpvar->value, q->name);
1459 q->strategy = QUEUE_STRATEGY_RINGALL;
1464 /* We traversed all variables and didn't find a strategy */
1466 q->strategy = QUEUE_STRATEGY_RINGALL;
1467 init_queue(q); /* Ensure defaults for all parameters not set explicitly. */
1468 ao2_link(queues, q);
1469 ast_variables_destroy(tmpvar);
1472 memset(tmpbuf, 0, sizeof(tmpbuf));
1473 for (v = queue_vars; v; v = v->next) {
1474 /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
1475 if ((tmp = strchr(v->name, '_'))) {
1476 ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
1479 while ((tmp = strchr(tmp, '_')))
1483 queue_set_param(q, tmp_name, v->value, -1, 0);
1486 /* Temporarily set realtime members dead so we can detect deleted ones.
1487 * Also set the membercount correctly for realtime*/
1488 mem_iter = ao2_iterator_init(q->members, 0);
1489 while ((m = ao2_iterator_next(&mem_iter))) {
1496 while ((interface = ast_category_browse(member_config, interface))) {
1497 rt_handle_member_record(q, interface,
1498 S_OR(ast_variable_retrieve(member_config, interface, "membername"),interface),
1499 ast_variable_retrieve(member_config, interface, "penalty"),
1500 ast_variable_retrieve(member_config, interface, "paused"),
1501 S_OR(ast_variable_retrieve(member_config, interface, "state_interface"),interface));
1504 /* Delete all realtime members that have been deleted in DB. */
1505 mem_iter = ao2_iterator_init(q->members, 0);
1506 while ((m = ao2_iterator_next(&mem_iter))) {
1508 ao2_unlink(q->members, m);
1509 remove_from_interfaces(m->state_interface);
1520 static struct call_queue *load_realtime_queue(const char *queuename)
1522 struct ast_variable *queue_vars;
1523 struct ast_config *member_config = NULL;
1524 struct call_queue *q = NULL, tmpq = {
1528 /* Find the queue in the in-core list first. */
1529 q = ao2_find(queues, &tmpq, OBJ_POINTER);
1531 if (!q || q->realtime) {
1532 /*! \note Load from realtime before taking the global qlock, to avoid blocking all
1533 queue operations while waiting for the DB.
1535 This will be two separate database transactions, so we might
1536 see queue parameters as they were before another process
1537 changed the queue and member list as it was after the change.
1538 Thus we might see an empty member list when a queue is
1539 deleted. In practise, this is unlikely to cause a problem. */
1541 queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
1543 member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
1544 if (!member_config) {
1545 ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
1546 ast_variables_destroy(queue_vars);
1552 q = find_queue_by_name_rt(queuename, queue_vars, member_config);
1554 ast_config_destroy(member_config);
1556 ast_variables_destroy(queue_vars);
1560 update_realtime_members(q);
1565 static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
1567 struct ast_variable *var;
1570 if (!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL)))
1573 if (!strcmp(var->name, "uniqueid"))
1577 if (var && !ast_strlen_zero(var->value)) {
1578 if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
1584 static void update_realtime_members(struct call_queue *q)
1586 struct ast_config *member_config = NULL;
1588 char *interface = NULL;
1589 struct ao2_iterator mem_iter;
1591 if (!(member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL))) {
1592 /*This queue doesn't have realtime members*/
1593 ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
1599 /* Temporarily set realtime members dead so we can detect deleted ones.*/
1600 mem_iter = ao2_iterator_init(q->members, 0);
1601 while ((m = ao2_iterator_next(&mem_iter))) {
1607 while ((interface = ast_category_browse(member_config, interface))) {
1608 rt_handle_member_record(q, interface,
1609 S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
1610 ast_variable_retrieve(member_config, interface, "penalty"),
1611 ast_variable_retrieve(member_config, interface, "paused"),
1612 S_OR(ast_variable_retrieve(member_config, interface, "state_interface"), interface));
1615 /* Delete all realtime members that have been deleted in DB. */
1616 mem_iter = ao2_iterator_init(q->members, 0);
1617 while ((m = ao2_iterator_next(&mem_iter))) {
1619 ao2_unlink(q->members, m);
1620 remove_from_interfaces(m->state_interface);
1626 ast_config_destroy(member_config);
1629 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
1631 struct call_queue *q;
1632 struct queue_ent *cur, *prev = NULL;
1636 enum queue_member_status stat;
1638 if (!(q = load_realtime_queue(queuename)))
1644 /* This is our one */
1645 stat = get_member_status(q, qe->max_penalty, qe->min_penalty);
1646 if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
1647 *reason = QUEUE_JOINEMPTY;
1648 else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
1649 *reason = QUEUE_JOINUNAVAIL;
1650 else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
1651 *reason = QUEUE_JOINUNAVAIL;
1652 else if (q->maxlen && (q->count >= q->maxlen))
1653 *reason = QUEUE_FULL;
1655 /* There's space for us, put us at the right position inside
1657 * Take into account the priority of the calling user */
1662 /* We have higher priority than the current user, enter
1663 * before him, after all the other users with priority
1664 * higher or equal to our priority. */
1665 if ((!inserted) && (qe->prio > cur->prio)) {
1666 insert_entry(q, prev, qe, &pos);
1673 /* No luck, join at the end of the queue */
1675 insert_entry(q, prev, qe, &pos);
1676 ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
1677 ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
1678 ast_copy_string(qe->context, q->context, sizeof(qe->context));
1681 manager_event(EVENT_FLAG_CALL, "Join",
1682 "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
1684 S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
1685 S_OR(qe->chan->cid.cid_name, "unknown"),
1686 q->name, qe->pos, q->count, qe->chan->uniqueid );
1687 ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
1695 static int play_file(struct ast_channel *chan, const char *filename)
1699 ast_stopstream(chan);
1701 res = ast_streamfile(chan, filename, chan->language);
1703 res = ast_waitstream(chan, AST_DIGIT_ANY);
1705 ast_stopstream(chan);
1710 static int valid_exit(struct queue_ent *qe, char digit)
1712 int digitlen = strlen(qe->digits);
1714 /* Prevent possible buffer overflow */
1715 if (digitlen < sizeof(qe->digits) - 2) {
1716 qe->digits[digitlen] = digit;
1717 qe->digits[digitlen + 1] = '\0';
1719 qe->digits[0] = '\0';
1723 /* If there's no context to goto, short-circuit */
1724 if (ast_strlen_zero(qe->context))
1727 /* If the extension is bad, then reset the digits to blank */
1728 if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
1729 qe->digits[0] = '\0';
1733 /* We have an exact match */
1734 if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
1735 qe->valid_digits = 1;
1736 /* Return 1 on a successful goto */
1743 static int say_position(struct queue_ent *qe, int ringing)
1745 int res = 0, avgholdmins, avgholdsecs;
1748 /* Let minannouncefrequency seconds pass between the start of each position announcement */
1750 if ((now - qe->last_pos) < qe->parent->minannouncefrequency)
1753 /* If either our position has changed, or we are over the freq timer, say position */
1754 if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
1758 ast_indicate(qe->chan,-1);
1760 ast_moh_stop(qe->chan);
1762 if (qe->parent->announceposition) {
1763 /* Say we're next, if we are */
1765 res = play_file(qe->chan, qe->parent->sound_next);
1771 res = play_file(qe->chan, qe->parent->sound_thereare);
1774 res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, NULL); /* Needs gender */
1777 res = play_file(qe->chan, qe->parent->sound_calls);
1782 /* Round hold time to nearest minute */
1783 avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
1785 /* If they have specified a rounding then round the seconds as well */
1786 if (qe->parent->roundingseconds) {
1787 avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
1788 avgholdsecs *= qe->parent->roundingseconds;
1793 ast_verb(3, "Hold time for %s is %d minute(s) %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
1795 /* If the hold time is >1 min, if it's enabled, and if it's not
1796 supposed to be only once and we have already said it, say it */
1797 if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
1798 (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
1799 res = play_file(qe->chan, qe->parent->sound_holdtime);
1803 if (avgholdmins > 1) {
1804 res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
1808 if (avgholdmins == 1) {
1809 res = play_file(qe->chan, qe->parent->sound_minute);
1813 res = play_file(qe->chan, qe->parent->sound_minutes);
1818 if (avgholdsecs > 1) {
1819 res = ast_say_number(qe->chan, avgholdmins > 1 ? avgholdsecs : avgholdmins * 60 + avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
1823 res = play_file(qe->chan, qe->parent->sound_seconds);
1831 if (qe->parent->announceposition) {
1832 ast_verb(3, "Told %s in %s their queue position (which was %d)\n",
1833 qe->chan->name, qe->parent->name, qe->pos);
1835 res = play_file(qe->chan, qe->parent->sound_thanks);
1838 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
1841 /* Set our last_pos indicators */
1843 qe->last_pos_said = qe->pos;
1845 /* Don't restart music on hold if we're about to exit the caller from the queue */
1848 ast_indicate(qe->chan, AST_CONTROL_RINGING);
1850 ast_moh_start(qe->chan, qe->moh, NULL);
1855 static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
1859 /* Calculate holdtime using a recursive boxcar filter */
1860 /* Thanks to SRT for this contribution */
1861 /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
1863 ao2_lock(qe->parent);
1864 oldvalue = qe->parent->holdtime;
1865 qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
1866 ao2_unlock(qe->parent);
1870 static void leave_queue(struct queue_ent *qe)
1872 struct call_queue *q;
1873 struct queue_ent *cur, *prev = NULL;
1874 struct penalty_rule *pr_iter;
1877 if (!(q = qe->parent))
1883 for (cur = q->head; cur; cur = cur->next) {
1887 /* Take us out of the queue */
1888 manager_event(EVENT_FLAG_CALL, "Leave",
1889 "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
1890 qe->chan->name, q->name, q->count, qe->chan->uniqueid);
1891 ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
1892 /* Take us out of the queue */
1894 prev->next = cur->next;
1896 q->head = cur->next;
1897 /* Free penalty rules */
1898 while ((pr_iter = AST_LIST_REMOVE_HEAD(&qe->qe_rules, list)))
1901 /* Renumber the people after us in the queue based on a new count */
1908 /*If the queue is a realtime queue, check to see if it's still defined in real time*/
1910 if (!ast_load_realtime("queues", "name", q->name, NULL))
1915 /* It's dead and nobody is in it, so kill it */
1916 ao2_unlink(queues, q);
1917 /* unref the container's reference to the queue */
1920 /* unref the explicit ref earlier in the function */
1924 /* Hang up a list of outgoing calls */
1925 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
1927 struct callattempt *oo;
1930 /* Hangup any existing lines we have open */
1931 if (outgoing->chan && (outgoing->chan != exception))
1932 ast_hangup(outgoing->chan);
1934 outgoing = outgoing->q_next;
1936 ao2_ref(oo->member, -1);
1941 static int update_status(struct call_queue *q, struct member *member, int status)
1944 struct ao2_iterator mem_iter;
1946 /* Since a reload could have taken place, we have to traverse the list to
1947 be sure it's still valid */
1949 mem_iter = ao2_iterator_init(q->members, 0);
1950 while ((cur = ao2_iterator_next(&mem_iter))) {
1951 if (member != cur) {
1956 cur->status = status;
1957 if (!q->maskmemberstatus) {
1958 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
1961 "MemberName: %s\r\n"
1962 "Membership: %s\r\n"
1964 "CallsTaken: %d\r\n"
1968 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime": "static",
1969 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
1977 static int update_dial_status(struct call_queue *q, struct member *member, int status)
1979 if (status == AST_CAUSE_BUSY)
1980 status = AST_DEVICE_BUSY;
1981 else if (status == AST_CAUSE_UNREGISTERED)
1982 status = AST_DEVICE_UNAVAILABLE;
1983 else if (status == AST_CAUSE_NOSUCHDRIVER)
1984 status = AST_DEVICE_INVALID;
1986 status = AST_DEVICE_UNKNOWN;
1987 return update_status(q, member, status);
1990 /* traverse all defined queues which have calls waiting and contain this member
1991 return 0 if no other queue has precedence (higher weight) or 1 if found */
1992 static int compare_weight(struct call_queue *rq, struct member *member)
1994 struct call_queue *q;
1997 struct ao2_iterator queue_iter;
1999 /* &qlock and &rq->lock already set by try_calling()
2000 * to solve deadlock */
2001 queue_iter = ao2_iterator_init(queues, 0);
2002 while ((q = ao2_iterator_next(&queue_iter))) {
2003 if (q == rq) { /* don't check myself, could deadlock */
2008 if (q->count && q->members) {
2009 if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
2010 ast_debug(1, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
2011 if (q->weight > rq->weight) {
2012 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);
2028 /*! \brief common hangup actions */
2029 static void do_hang(struct callattempt *o)
2032 ast_hangup(o->chan);
2036 static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
2038 struct ast_str *buf = ast_str_alloca(len + 1);
2041 if (pbx_builtin_serialize_variables(chan, &buf)) {
2044 /* convert "\n" to "\nVariable: " */
2045 strcpy(vars, "Variable: ");
2048 for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
2051 if (tmp[i + 1] == '\0')
2053 if (tmp[i] == '\n') {
2057 ast_copy_string(&(vars[j]), "Variable: ", len - j);
2067 /* there are no channel variables; leave it blank */
2073 /*! \brief Part 2 of ring_one
2075 * Does error checking before attempting to request a channel and call a member. This
2076 * function is only called from ring_one
2078 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
2085 /* on entry here, we know that tmp->chan == NULL */
2086 if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
2087 (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
2088 ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
2089 (tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
2091 ast_cdr_busy(qe->chan->cdr);
2092 tmp->stillgoing = 0;
2097 if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
2098 ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
2100 ast_cdr_busy(qe->chan->cdr);
2101 tmp->stillgoing = 0;
2105 if (tmp->member->paused) {
2106 ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
2108 ast_cdr_busy(qe->chan->cdr);
2109 tmp->stillgoing = 0;
2112 if (use_weight && compare_weight(qe->parent,tmp->member)) {
2113 ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
2115 ast_cdr_busy(qe->chan->cdr);
2116 tmp->stillgoing = 0;
2121 ast_copy_string(tech, tmp->interface, sizeof(tech));
2122 if ((location = strchr(tech, '/')))
2127 /* Request the peer */
2128 tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
2129 if (!tmp->chan) { /* If we can't, just go on to the next call */
2131 ast_cdr_busy(qe->chan->cdr);
2132 tmp->stillgoing = 0;
2133 update_dial_status(qe->parent, tmp->member, status);
2135 ao2_lock(qe->parent);
2136 qe->parent->rrpos++;
2138 ao2_unlock(qe->parent);
2143 } else if (status != tmp->oldstatus)
2144 update_dial_status(qe->parent, tmp->member, status);
2146 tmp->chan->appl = "AppQueue";
2147 tmp->chan->data = "(Outgoing Line)";
2148 tmp->chan->whentohangup = 0;
2149 if (tmp->chan->cid.cid_num)
2150 ast_free(tmp->chan->cid.cid_num);
2151 tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
2152 if (tmp->chan->cid.cid_name)
2153 ast_free(tmp->chan->cid.cid_name);
2154 tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
2155 if (tmp->chan->cid.cid_ani)
2156 ast_free(tmp->chan->cid.cid_ani);
2157 tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
2159 /* Inherit specially named variables from parent channel */
2160 ast_channel_inherit_variables(qe->chan, tmp->chan);
2162 /* Presense of ADSI CPE on outgoing channel follows ours */
2163 tmp->chan->adsicpe = qe->chan->adsicpe;
2165 /* Inherit context and extension */
2166 if (!ast_strlen_zero(qe->chan->macrocontext))
2167 ast_copy_string(tmp->chan->dialcontext, qe->chan->macrocontext, sizeof(tmp->chan->dialcontext));
2169 ast_copy_string(tmp->chan->dialcontext, qe->chan->context, sizeof(tmp->chan->dialcontext));
2170 if (!ast_strlen_zero(qe->chan->macroexten))
2171 ast_copy_string(tmp->chan->exten, qe->chan->macroexten, sizeof(tmp->chan->exten));
2173 ast_copy_string(tmp->chan->exten, qe->chan->exten, sizeof(tmp->chan->exten));
2175 /* Place the call, but don't wait on the answer */
2176 if ((res = ast_call(tmp->chan, location, 0))) {
2177 /* Again, keep going even if there's an error */
2178 ast_debug(1, "ast call on peer returned %d\n", res);
2179 ast_verb(3, "Couldn't call %s\n", tmp->interface);
2183 } else if (qe->parent->eventwhencalled) {
2186 manager_event(EVENT_FLAG_AGENT, "AgentCalled",
2188 "AgentCalled: %s\r\n"
2190 "ChannelCalling: %s\r\n"
2191 "DestinationChannel: %s\r\n"
2192 "CallerIDNum: %s\r\n"
2193 "CallerIDName: %s\r\n"
2199 qe->parent->name, tmp->interface, tmp->member->membername, qe->chan->name, tmp->chan->name,
2200 tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
2201 tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
2202 qe->chan->context, qe->chan->exten, qe->chan->priority, qe->chan->uniqueid,
2203 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2204 ast_verb(3, "Called %s\n", tmp->interface);
2210 /*! \brief find the entry with the best metric, or NULL */
2211 static struct callattempt *find_best(struct callattempt *outgoing)
2213 struct callattempt *best = NULL, *cur;
2215 for (cur = outgoing; cur; cur = cur->q_next) {
2216 if (cur->stillgoing && /* Not already done */
2217 !cur->chan && /* Isn't already going */
2218 (!best || cur->metric < best->metric)) { /* We haven't found one yet, or it's better */
2226 /*! \brief Place a call to a queue member
2228 * Once metrics have been calculated for each member, this function is used
2229 * to place a call to the appropriate member (or members). The low-level
2230 * channel-handling and error detection is handled in ring_entry
2232 * Returns 1 if a member was called successfully, 0 otherwise
2234 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
2239 struct callattempt *best = find_best(outgoing);
2241 ast_debug(1, "Nobody left to try ringing in queue\n");
2244 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2245 struct callattempt *cur;
2246 /* Ring everyone who shares this best metric (for ringall) */
2247 for (cur = outgoing; cur; cur = cur->q_next) {
2248 if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
2249 ast_debug(1, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
2250 ret |= ring_entry(qe, cur, busies);
2254 /* Ring just the best channel */
2255 ast_debug(1, "Trying '%s' with metric %d\n", best->interface, best->metric);
2256 ret = ring_entry(qe, best, busies);
2263 static int store_next_rr(struct queue_ent *qe, struct callattempt *outgoing)
2265 struct callattempt *best = find_best(outgoing);
2268 /* Ring just the best channel */
2269 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2270 qe->parent->rrpos = best->metric % 1000;
2272 /* Just increment rrpos */
2273 if (qe->parent->wrapped) {
2274 /* No more channels, start over */
2275 qe->parent->rrpos = 0;
2277 /* Prioritize next entry */
2278 qe->parent->rrpos++;
2281 qe->parent->wrapped = 0;
2286 static int store_next_lin(struct queue_ent *qe, struct callattempt *outgoing)
2288 struct callattempt *best = find_best(outgoing);
2291 /* Ring just the best channel */
2292 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2293 qe->linpos = best->metric % 1000;
2295 /* Just increment rrpos */
2296 if (qe->linwrapped) {
2297 /* No more channels, start over */
2300 /* Prioritize next entry */
2309 static int say_periodic_announcement(struct queue_ent *qe, int ringing)
2314 /* Get the current time */
2317 /* Check to see if it is time to announce */
2318 if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
2321 /* Stop the music on hold so we can play our own file */
2323 ast_indicate(qe->chan,-1);
2325 ast_moh_stop(qe->chan);
2327 ast_verb(3, "Playing periodic announcement\n");
2329 /* Check to make sure we have a sound file. If not, reset to the first sound file */
2330 if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS ||
2331 !qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound] ||
2332 ast_strlen_zero(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str)) {
2333 qe->last_periodic_announce_sound = 0;
2336 /* play the announcement */
2337 res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str);
2339 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
2342 /* Resume Music on Hold if the caller is going to stay in the queue */
2345 ast_indicate(qe->chan, AST_CONTROL_RINGING);
2347 ast_moh_start(qe->chan, qe->moh, NULL);
2350 /* update last_periodic_announce_time */
2351 qe->last_periodic_announce_time = now;
2353 /* Update the current periodic announcement to the next announcement */
2354 qe->last_periodic_announce_sound++;
2359 static void record_abandoned(struct queue_ent *qe)
2361 ao2_lock(qe->parent);
2362 set_queue_variables(qe);
2363 manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
2367 "OriginalPosition: %d\r\n"
2369 qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
2371 qe->parent->callsabandoned++;
2372 ao2_unlock(qe->parent);
2375 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
2376 static void rna(int rnatime, struct queue_ent *qe, char *interface, char *membername)
2378 ast_verb(3, "Nobody picked up in %d ms\n", rnatime);
2379 ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
2380 if (qe->parent->autopause) {
2381 if (!set_member_paused(qe->parent->name, interface, "Auto-Pause", 1)) {
2382 ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
2384 ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
2390 #define AST_MAX_WATCHERS 256
2391 /*! \brief Wait for a member to answer the call
2393 * \param[in] qe the queue_ent corresponding to the caller in the queue
2394 * \param[in] outgoing the list of callattempts. Relevant ones will have their chan and stillgoing parameters non-zero
2395 * \param[in] to the amount of time (in milliseconds) to wait for a response
2396 * \param[out] digit if a user presses a digit to exit the queue, this is the digit the caller pressed
2397 * \param[in] prebusies number of busy members calculated prior to calling wait_for_answer
2398 * \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
2399 * \param[in] forwardsallowed used to detect if we should allow call forwarding, based on the 'i' option to Queue()
2401 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
2403 const char *queue = qe->parent->name;
2404 struct callattempt *o, *start = NULL, *prev = NULL;
2406 int numbusies = prebusies;
2410 struct ast_frame *f;
2411 struct callattempt *peer = NULL;
2412 struct ast_channel *winner;
2413 struct ast_channel *in = qe->chan;
2415 char membername[80] = "";
2419 struct callattempt *epollo;
2422 starttime = (long) time(NULL);
2424 for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2426 ast_poll_channel_add(in, epollo->chan);
2430 while (*to && !peer) {
2431 int numlines, retry, pos = 1;
2432 struct ast_channel *watchers[AST_MAX_WATCHERS];
2436 for (retry = 0; retry < 2; retry++) {
2438 for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
2439 if (o->stillgoing) { /* Keep track of important channels */
2442 watchers[pos++] = o->chan;
2446 prev->call_next = o;
2452 if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
2453 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
2455 /* On "ringall" strategy we only move to the next penalty level
2456 when *all* ringing phones are done in the current penalty level */
2457 ring_one(qe, outgoing, &numbusies);
2460 if (pos == 1 /* not found */) {
2461 if (numlines == (numbusies + numnochan)) {
2462 ast_debug(1, "Everyone is busy at this time\n");
2464 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
2469 winner = ast_waitfor_n(watchers, pos, to);
2470 for (o = start; o; o = o->call_next) {
2471 if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) {
2473 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2476 } else if (o->chan && (o->chan == winner)) {
2478 ast_copy_string(on, o->member->interface, sizeof(on));
2479 ast_copy_string(membername, o->member->membername, sizeof(membername));
2481 if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
2482 ast_verb(3, "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
2487 } else if (!ast_strlen_zero(o->chan->call_forward)) {
2492 ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
2493 if ((stuff = strchr(tmpchan, '/'))) {
2497 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
2501 /* Before processing channel, go ahead and check for forwarding */
2502 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
2503 /* Setup parameters */
2504 o->chan = ast_request(tech, in->nativeformats, stuff, &status);
2505 if (status != o->oldstatus)
2506 update_dial_status(qe->parent, o->member, status);
2508 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
2512 ast_channel_inherit_variables(in, o->chan);
2513 ast_channel_datastore_inherit(in, o->chan);
2514 if (o->chan->cid.cid_num)
2515 ast_free(o->chan->cid.cid_num);
2516 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
2518 if (o->chan->cid.cid_name)
2519 ast_free(o->chan->cid.cid_name);
2520 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
2522 ast_string_field_set(o->chan, accountcode, in->accountcode);
2523 o->chan->cdrflags = in->cdrflags;
2525 if (in->cid.cid_ani) {
2526 if (o->chan->cid.cid_ani)
2527 ast_free(o->chan->cid.cid_ani);
2528 o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
2530 if (o->chan->cid.cid_rdnis)
2531 ast_free(o->chan->cid.cid_rdnis);
2532 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
2533 if (ast_call(o->chan, tmpchan, 0)) {
2534 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
2539 /* Hangup the original channel now, in case we needed it */
2543 f = ast_read(winner);
2545 if (f->frametype == AST_FRAME_CONTROL) {
2546 switch (f->subclass) {
2547 case AST_CONTROL_ANSWER:
2548 /* This is our guy if someone answered. */
2550 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2554 case AST_CONTROL_BUSY:
2555 ast_verb(3, "%s is busy\n", o->chan->name);
2557 ast_cdr_busy(in->cdr);
2559 endtime = (long) time(NULL);
2560 endtime -= starttime;
2561 rna(endtime*1000, qe, on, membername);
2562 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2563 if (qe->parent->timeoutrestart)
2565 ring_one(qe, outgoing, &numbusies);
2569 case AST_CONTROL_CONGESTION:
2570 ast_verb(3, "%s is circuit-busy\n", o->chan->name);
2572 ast_cdr_busy(in->cdr);
2573 endtime = (long) time(NULL);
2574 endtime -= starttime;
2575 rna(endtime*1000, qe, on, membername);
2577 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2578 if (qe->parent->timeoutrestart)
2580 ring_one(qe, outgoing, &numbusies);
2584 case AST_CONTROL_RINGING:
2585 ast_verb(3, "%s is ringing\n", o->chan->name);
2587 case AST_CONTROL_OFFHOOK:
2588 /* Ignore going off hook */
2591 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
2596 endtime = (long) time(NULL) - starttime;
2597 rna(endtime * 1000, qe, on, membername);
2599 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2600 if (qe->parent->timeoutrestart)
2602 ring_one(qe, outgoing, &numbusies);
2609 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2617 if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2618 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
2623 if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
2624 ast_verb(3, "User pressed digit: %c\n", f->subclass);
2626 *digit = f->subclass;
2633 for (o = start; o; o = o->call_next)
2634 rna(orig, qe, o->interface, o->member->membername);
2639 for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2641 ast_poll_channel_del(in, epollo->chan);
2647 /*! \brief Check if we should start attempting to call queue members
2649 * The behavior of this function is dependent first on whether autofill is enabled
2650 * and second on whether the ring strategy is ringall. If autofill is not enabled,
2651 * then return true if we're the head of the queue. If autofill is enabled, then
2652 * we count the available members and see if the number of available members is enough
2653 * that given our position in the queue, we would theoretically be able to connect to
2654 * one of those available members
2656 static int is_our_turn(struct queue_ent *qe)
2658 struct queue_ent *ch;
2664 if (!qe->parent->autofill) {
2665 /* Atomically read the parent head -- does not need a lock */
2666 ch = qe->parent->head;
2667 /* If we are now at the top of the head, break out */
2669 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2672 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2677 /* This needs a lock. How many members are available to be served? */
2678 ao2_lock(qe->parent);
2680 ch = qe->parent->head;
2682 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2683 ast_debug(1, "Even though there may be multiple members available, the strategy is ringall so only the head call is allowed in\n");
2686 struct ao2_iterator mem_iter = ao2_iterator_init(qe->parent->members, 0);
2687 while ((cur = ao2_iterator_next(&mem_iter))) {
2688 switch (cur->status) {
2689 case AST_DEVICE_INUSE:
2690 if (!qe->parent->ringinuse)
2692 /* else fall through */
2693 case AST_DEVICE_NOT_INUSE:
2694 case AST_DEVICE_UNKNOWN:
2703 ast_debug(1, "There are %d available members.\n", avl);
2705 while ((idx < avl) && (ch) && (ch != qe)) {
2711 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2712 if (ch && idx < avl) {
2713 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2716 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2720 ao2_unlock(qe->parent);
2725 static void update_qe_rule(struct queue_ent *qe)
2727 int max_penalty = qe->pr->max_relative ? qe->max_penalty + qe->pr->max_value : qe->pr->max_value;
2728 int min_penalty = qe->pr->min_relative ? qe->min_penalty + qe->pr->min_value : qe->pr->min_value;
2729 char max_penalty_str[20], min_penalty_str[20];
2730 /* a relative change to the penalty could put it below 0 */
2731 if (max_penalty < 0)
2733 if (min_penalty < 0)
2735 if (min_penalty > max_penalty)
2736 min_penalty = max_penalty;
2737 snprintf(max_penalty_str, sizeof(max_penalty_str), "%d", max_penalty);
2738 snprintf(min_penalty_str, sizeof(min_penalty_str), "%d", min_penalty);
2739 pbx_builtin_setvar_helper(qe->chan, "QUEUE_MAX_PENALTY", max_penalty_str);
2740 pbx_builtin_setvar_helper(qe->chan, "QUEUE_MIN_PENALTY", min_penalty_str);
2741 qe->max_penalty = max_penalty;
2742 qe->min_penalty = min_penalty;
2743 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);
2744 qe->pr = AST_LIST_NEXT(qe->pr, list);
2747 /*! \brief The waiting areas for callers who are not actively calling members
2749 * This function is one large loop. This function will return if a caller
2750 * either exits the queue or it becomes that caller's turn to attempt calling
2751 * queue members. Inside the loop, we service the caller with periodic announcements,
2752 * holdtime announcements, etc. as configured in queues.conf
2754 * \retval 0 if the caller's turn has arrived
2755 * \retval -1 if the caller should exit the queue.
2757 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2761 /* This is the holding pen for callers 2 through maxlen */
2763 enum queue_member_status stat;
2765 if (is_our_turn(qe))
2768 /* If we have timed out, break out */
2769 if (qe->expire && (time(NULL) > qe->expire)) {
2770 *reason = QUEUE_TIMEOUT;
2774 stat = get_member_status(qe->parent, qe->max_penalty, qe->min_penalty);
2776 /* leave the queue if no agents, if enabled */
2777 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2778 *reason = QUEUE_LEAVEEMPTY;
2779 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2784 /* leave the queue if no reachable agents, if enabled */
2785 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
2786 *reason = QUEUE_LEAVEUNAVAIL;
2787 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2791 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2792 *reason = QUEUE_LEAVEUNAVAIL;
2793 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2798 /* Make a position announcement, if enabled */
2799 if (qe->parent->announcefrequency &&
2800 (res = say_position(qe,ringing)))
2803 /* Make a periodic announcement, if enabled */
2804 if (qe->parent->periodicannouncefrequency &&
2805 (res = say_periodic_announcement(qe,ringing)))
2808 /* see if we need to move to the next penalty level for this queue */
2809 while (qe->pr && ((time(NULL) - qe->start) > qe->pr->time)) {
2813 /* Wait a second before checking again */
2814 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
2815 if (res > 0 && !valid_exit(qe, res))
2825 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
2828 struct call_queue *qtmp;
2829 struct ao2_iterator queue_iter;
2831 if (shared_lastcall) {
2832 queue_iter = ao2_iterator_init(queues, 0);
2833 while ((qtmp = ao2_iterator_next(&queue_iter))) {
2835 if ((mem = ao2_find(qtmp->members, member, OBJ_POINTER))) {
2836 time(&mem->lastcall);
2846 time(&member->lastcall);
2848 member->lastqueue = q;
2852 q->callscompleted++;
2853 if (callcompletedinsl)
2854 q->callscompletedinsl++;
2859 /*! \brief Calculate the metric of each member in the outgoing callattempts
2861 * A numeric metric is given to each member depending on the ring strategy used
2862 * by the queue. Members with lower metrics will be called before members with
2865 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2867 if ((qe->max_penalty && (mem->penalty > qe->max_penalty)) || (qe->min_penalty && (mem->penalty < qe->min_penalty)))
2870 switch (q->strategy) {
2871 case QUEUE_STRATEGY_RINGALL:
2872 /* Everyone equal, except for penalty */
2873 tmp->metric = mem->penalty * 1000000;
2875 case QUEUE_STRATEGY_LINEAR:
2876 if (pos < qe->linpos) {
2877 tmp->metric = 1000 + pos;
2879 if (pos > qe->linpos)
2880 /* Indicate there is another priority */
2884 tmp->metric += mem->penalty * 1000000;
2886 case QUEUE_STRATEGY_RRMEMORY:
2887 if (pos < q->rrpos) {
2888 tmp->metric = 1000 + pos;
2891 /* Indicate there is another priority */
2895 tmp->metric += mem->penalty * 1000000;
2897 case QUEUE_STRATEGY_RANDOM:
2898 tmp->metric = ast_random() % 1000;
2899 tmp->metric += mem->penalty * 1000000;
2901 case QUEUE_STRATEGY_WRANDOM:
2902 tmp->metric = ast_random() % ((1 + mem->penalty) * 1000);
2904 case QUEUE_STRATEGY_FEWESTCALLS:
2905 tmp->metric = mem->calls;
2906 tmp->metric += mem->penalty * 1000000;
2908 case QUEUE_STRATEGY_LEASTRECENT:
2912 tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2913 tmp->metric += mem->penalty * 1000000;
2916 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2922 enum agent_complete_reason {
2928 static void send_agent_complete(const struct queue_ent *qe, const char *queuename,
2929 const struct ast_channel *peer, const struct member *member, time_t callstart,
2930 char *vars, size_t vars_len, enum agent_complete_reason rsn)
2932 const char *reason = NULL; /* silence dumb compilers */
2934 if (!qe->parent->eventwhencalled)
2945 reason = "transfer";
2949 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2954 "MemberName: %s\r\n"
2959 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2960 (long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
2961 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
2963 /*! \brief A large function which calls members, updates statistics, and bridges the caller and a member
2965 * Here is the process of this function
2966 * 1. Process any options passed to the Queue() application. Options here mean the third argument to Queue()
2967 * 2. Iterate trough the members of the queue, creating a callattempt corresponding to each member. During this
2968 * iteration, we also check the dialed_interfaces datastore to see if we have already attempted calling this
2969 * member. If we have, we do not create a callattempt. This is in place to prevent call forwarding loops. Also
2970 * during each iteration, we call calc_metric to determine which members should be rung when.
2971 * 3. Call ring_one to place a call to the appropriate member(s)
2972 * 4. Call wait_for_answer to wait for an answer. If no one answers, return.
2973 * 5. Take care of any holdtime announcements, member delays, or other options which occur after a call has been answered.
2974 * 6. Start the monitor or mixmonitor if the option is set
2975 * 7. Remove the caller from the queue to allow other callers to advance
2976 * 8. Bridge the call.
2977 * 9. Do any post processing after the call has disconnected.
2979 * \param[in] qe the queue_ent structure which corresponds to the caller attempting to reach members
2980 * \param[in] options the options passed as the third parameter to the Queue() application
2981 * \param[in] announceoverride filename to play to user when waiting
2982 * \param[in] url the url passed as the fourth parameter to the Queue() application
2983 * \param[in,out] tries the number of times we have tried calling queue members
2984 * \param[out] noption set if the call to Queue() has the 'n' option set.
2985 * \param[in] agi the agi passed as the fifth parameter to the Queue() application
2986 * \param[in] macro the macro passed as the sixth parameter to the Queue() application
2987 * \param[in] gosub the gosub passed as the seventh parameter to the Queue() application
2988 * \param[in] ringing 1 if the 'r' option is set, otherwise 0
2990 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)
2993 struct callattempt *outgoing = NULL; /* the list of calls we are building */
2995 char oldexten[AST_MAX_EXTENSION]="";
2996 char oldcontext[AST_MAX_CONTEXT]="";
2997 char queuename[256]="";
2998 char interfacevar[256]="";
2999 struct ast_channel *peer;
3000 struct ast_channel *which;
3001 struct callattempt *lpeer;
3002 struct member *member;
3003 struct ast_app *app;
3004 int res = 0, bridge = 0;
3007 char *announce = NULL;
3010 time_t now = time(NULL);
3011 struct ast_bridge_config bridge_config;
3012 char nondataquality = 1;
3013 char *agiexec = NULL;
3014 char *macroexec = NULL;
3015 char *gosubexec = NULL;
3017 const char *monitorfilename;
3018 const char *monitor_exec;
3019 const char *monitor_options;
3020 char tmpid[256], tmpid2[256];
3021 char meid[1024], meid2[1024];
3022 char mixmonargs[1512];
3023 struct ast_app *mixmonapp = NULL;
3026 int forwardsallowed = 1;
3027 int callcompletedinsl;
3028 struct ao2_iterator memi;
3029 struct ast_datastore *datastore;
3031 ast_channel_lock(qe->chan);
3032 datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
3033 ast_channel_unlock(qe->chan);
3035 memset(&bridge_config, 0, sizeof(bridge_config));
3040 for (; options && *options; options++)
3043 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
3046 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
3049 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
3052 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
3058 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
3061 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
3064 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_PARKCALL);
3067 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_PARKCALL);
3070 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_LINEAR)
3073 *tries = qe->parent->membercount;
3077 forwardsallowed = 0;
3080 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMIXMON);
3083 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMIXMON);
3088 /* Hold the lock while we setup the outgoing calls */
3091 ao2_lock(qe->parent);
3092 ast_debug(1, "%s is trying to call a queue member.\n",
3094 ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
3095 if (!ast_strlen_zero(qe->announce))
3096 announce = qe->announce;
3097 if (!ast_strlen_zero(announceoverride))
3098 announce = announceoverride;
3100 memi = ao2_iterator_init(qe->parent->members, 0);
3101 while ((cur = ao2_iterator_next(&memi))) {
3102 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
3103 struct ast_dialed_interface *di;
3104 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
3107 ao2_unlock(qe->parent);
3113 if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
3115 ao2_unlock(qe->parent);
3121 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
3122 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
3124 ao2_unlock(&qe->parent);
3130 datastore->data = dialed_interfaces;
3131 AST_LIST_HEAD_INIT(dialed_interfaces);
3133 ast_channel_lock(qe->chan);
3134 ast_channel_datastore_add(qe->chan, datastore);
3135 ast_channel_unlock(qe->chan);
3137 dialed_interfaces = datastore->data;
3139 AST_LIST_LOCK(dialed_interfaces);
3140 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
3141 if (!strcasecmp(cur->interface, di->interface)) {
3142 ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n",
3147 AST_LIST_UNLOCK(dialed_interfaces);
3154 /* It is always ok to dial a Local interface. We only keep track of
3155 * which "real" interfaces have been dialed. The Local channel will
3156 * inherit this list so that if it ends up dialing a real interface,
3157 * it won't call one that has already been called. */
3158 if (strncasecmp(cur->interface, "Local/", 6)) {
3159 if (!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) {
3161 ao2_unlock(qe->parent);
3167 strcpy(di->interface, cur->interface);
3169 AST_LIST_LOCK(dialed_interfaces);
3170 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
3171 AST_LIST_UNLOCK(dialed_interfaces);
3174 tmp->stillgoing = -1;
3176 tmp->oldstatus = cur->status;
3177 tmp->lastcall = cur->lastcall;
3178 tmp->lastqueue = cur->lastqueue;
3179 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
3180 /* Special case: If we ring everyone, go ahead and ring them, otherwise
3181 just calculate their metric for the appropriate strategy */
3182 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
3183 /* Put them in the list of outgoing thingies... We're ready now.
3184 XXX If we're forcibly removed, these outgoing calls won't get
3186 tmp->q_next = outgoing;
3188 /* If this line is up, don't try anybody else */
3189 if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
3196 if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
3197 to = (qe->expire - now) * 1000;
3199 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
3202 ring_one(qe, outgoing, &numbusies);
3203 ao2_unlock(qe->parent);
3206 lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
3208 ast_channel_datastore_remove(qe->chan, datastore);
3209 ast_channel_datastore_free(datastore);
3211 ao2_lock(qe->parent);
3212 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
3213 store_next_rr(qe, outgoing);
3215 if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) {
3216 store_next_lin(qe, outgoing);
3218 ao2_unlock(qe->parent);
3219 peer = lpeer ? lpeer->chan : NULL;
3223 /* Must gotten hung up */
3226 /* User exited by pressing a digit */
3230 ast_debug(1, "%s: Nobody answered.\n", qe->chan->name);
3231 } else { /* peer is valid */
3232 /* Ah ha! Someone answered within the desired timeframe. Of course after this
3233 we will always return with -1 so that it is hung up properly after the
3236 if (!strcmp(qe->chan->tech->type, "Zap"))
3237 ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
3238 if (!strcmp(peer->tech->type, "Zap"))
3239 ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
3240 /* Update parameters for the queue */
3242 recalc_holdtime(qe, (now - qe->start));
3243 ao2_lock(qe->parent);
3244 callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
3245 ao2_unlock(qe->parent);
3246 member = lpeer->member;
3247 /* Increment the refcount for this member, since we're going to be using it for awhile in here. */
3249 hangupcalls(outgoing, peer);
3251 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
3254 res2 = ast_autoservice_start(qe->chan);
3256 if (qe->parent->memberdelay) {
3257 ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
3258 res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
3260 if (!res2 && announce) {
3261 play_file(peer, announce);
3263 if (!res2 && qe->parent->reportholdtime) {
3264 if (!play_file(peer, qe->parent->sound_reporthold)) {
3265 int holdtime, holdtimesecs;
3268 holdtime = abs((now - qe->start) / 60);
3269 holdtimesecs = abs((now - qe->start));
3270 if (holdtime == 1) {
3271 ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
3272 play_file(peer, qe->parent->sound_minute);
3274 ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
3275 play_file(peer, qe->parent->sound_minutes);
3277 if (holdtimesecs > 1) {
3278 ast_say_number(peer, holdtimesecs, AST_DIGIT_ANY, peer->language, NULL);
3279 play_file(peer, qe->parent->sound_seconds);
3284 res2 |= ast_autoservice_stop(qe->chan);
3285 if (ast_check_hangup(peer)) {
3286 /* Agent must have hung up */
3287 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
3288 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
3289 record_abandoned(qe);
3290 if (qe->parent->eventwhencalled)
3291 manager_event(EVENT_FLAG_AGENT, "AgentDump",
3296 "MemberName: %s\r\n"
3298 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
3299 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
3301 ao2_ref(member, -1);
3304 /* Caller must have hung up just before being connected*/
3305 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
3306 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
3307 record_abandoned(qe);
3309 ao2_ref(member, -1);
3313 /* Stop music on hold */
3315 ast_indicate(qe->chan,-1);
3317 ast_moh_stop(qe->chan);
3318 /* If appropriate, log that we have a destination channel */
3320 ast_cdr_setdestchan(qe->chan->cdr, peer->name);
3321 /* Make sure channels are compatible */
3322 res = ast_channel_make_compatible(qe->chan, peer);
3324 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
3325 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
3326 record_abandoned(qe);
3328 ao2_ref(member, -1);
3332 /* Play announcement to the caller telling it's his turn if defined */
3333 if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
3334 if (play_file(qe->chan, qe->parent->sound_callerannounce))
3335 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
3338 ao2_lock(qe->parent);
3339 /* if setinterfacevar is defined, make member variables available to the channel */
3340 /* use pbx_builtin_setvar to set a load of variables with one call */
3341 if (qe->parent->setinterfacevar) {
3342 snprintf(interfacevar, sizeof(interfacevar), "MEMBERINTERFACE=%s|MEMBERNAME=%s|MEMBERCALLS=%d|MEMBERLASTCALL=%ld|MEMBERPENALTY=%d|MEMBERDYNAMIC=%d|MEMBERREALTIME=%d",
3343 member->interface, member->membername, member->calls, (long)member->lastcall, member->penalty, member->dynamic, member->realtime);
3344 pbx_builtin_setvar(qe->chan, interfacevar);
3347 /* if setqueueentryvar is defined, make queue entry (i.e. the caller) variables available to the channel */
3348 /* use pbx_builtin_setvar to set a load of variables with one call */
3349 if (qe->parent->setqueueentryvar) {
3350 snprintf(interfacevar, sizeof(interfacevar), "QEHOLDTIME=%ld|QEORIGINALPOS=%d",
3351 (long) time(NULL) - qe->start, qe->opos);
3352 pbx_builtin_setvar(qe->chan, interfacevar);
3355 /* try to set queue variables if configured to do so*/
3356 set_queue_variables(qe);
3357 ao2_unlock(qe->parent);
3359 /* Begin Monitoring */
3360 if (qe->parent->monfmt && *qe->parent->monfmt) {
3361 if (!qe->parent->montype) {
3362 ast_debug(1, "Starting Monitor as requested.\n");
3363 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
3364 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
3368 if (monitorfilename)
3369 ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT);
3370 else if (qe->chan->cdr)
3371 ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1, X_REC_IN | X_REC_OUT);
3373 /* Last ditch effort -- no CDR, make up something */
3374 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
3375 ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT);
3378 ast_debug(1, "Starting MixMonitor as requested.\n");
3379 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
3380 if (!monitorfilename) {
3382 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid));
3384 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
3386 const char *m = monitorfilename;