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
61 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
64 #include <sys/signal.h>
65 #include <netinet/in.h>
67 #include "asterisk/lock.h"
68 #include "asterisk/file.h"
69 #include "asterisk/channel.h"
70 #include "asterisk/pbx.h"
71 #include "asterisk/app.h"
72 #include "asterisk/linkedlists.h"
73 #include "asterisk/module.h"
74 #include "asterisk/translate.h"
75 #include "asterisk/say.h"
76 #include "asterisk/features.h"
77 #include "asterisk/musiconhold.h"
78 #include "asterisk/cli.h"
79 #include "asterisk/manager.h"
80 #include "asterisk/config.h"
81 #include "asterisk/monitor.h"
82 #include "asterisk/utils.h"
83 #include "asterisk/causes.h"
84 #include "asterisk/astdb.h"
85 #include "asterisk/devicestate.h"
86 #include "asterisk/stringfields.h"
87 #include "asterisk/event.h"
88 #include "asterisk/astobj2.h"
89 #include "asterisk/strings.h"
90 #include "asterisk/global_datastores.h"
93 QUEUE_STRATEGY_RINGALL = 0,
94 QUEUE_STRATEGY_LEASTRECENT,
95 QUEUE_STRATEGY_FEWESTCALLS,
96 QUEUE_STRATEGY_RANDOM,
97 QUEUE_STRATEGY_RRMEMORY,
98 QUEUE_STRATEGY_LINEAR,
99 QUEUE_STRATEGY_WRANDOM
102 static struct strategy {
106 { QUEUE_STRATEGY_RINGALL, "ringall" },
107 { QUEUE_STRATEGY_LEASTRECENT, "leastrecent" },
108 { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" },
109 { QUEUE_STRATEGY_RANDOM, "random" },
110 { QUEUE_STRATEGY_RRMEMORY, "rrmemory" },
111 { QUEUE_STRATEGY_LINEAR, "linear" },
112 { QUEUE_STRATEGY_WRANDOM, "wrandom"},
115 #define DEFAULT_RETRY 5
116 #define DEFAULT_TIMEOUT 15
117 #define RECHECK 1 /* Recheck every second to see we we're at the top yet */
118 #define MAX_PERIODIC_ANNOUNCEMENTS 10 /* The maximum periodic announcements we can have */
119 #define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 /* The minimum number of seconds between position announcements
120 The default value of 15 provides backwards compatibility */
121 #define MAX_QUEUE_BUCKETS 53
123 #define RES_OKAY 0 /* Action completed */
124 #define RES_EXISTS (-1) /* Entry already exists */
125 #define RES_OUTOFMEMORY (-2) /* Out of memory */
126 #define RES_NOSUCHQUEUE (-3) /* No such queue */
127 #define RES_NOT_DYNAMIC (-4) /* Member is not dynamic */
129 static char *app = "Queue";
131 static char *synopsis = "Queue a call for a call queue";
133 static char *descrip =
134 " Queue(queuename[,options[,URL][,announceoverride][,timeout][,AGI][,macro][,gosub]):\n"
135 "Queues an incoming call in a particular call queue as defined in queues.conf.\n"
136 "This application will return to the dialplan if the queue does not exist, or\n"
137 "any of the join options cause the caller to not enter the queue.\n"
138 "The option string may contain zero or more of the following characters:\n"
139 " 'c' -- continue in the dialplan if the callee hangs up.\n"
140 " 'd' -- data-quality (modem) call (minimum delay).\n"
141 " 'h' -- allow callee to hang up by pressing *.\n"
142 " 'H' -- allow caller to hang up by pressing *.\n"
143 " 'n' -- no retries on the timeout; will exit this application and \n"
144 " go to the next step.\n"
145 " 'i' -- ignore call forward requests from queue members and do nothing\n"
146 " when they are requested.\n"
147 " 'r' -- ring instead of playing MOH. Periodic Announcements are still made, if applicable.\n"
148 " 't' -- allow the called user to transfer the calling user.\n"
149 " 'T' -- allow the calling user to transfer the call.\n"
150 " 'w' -- allow the called user to write the conversation to disk via Monitor.\n"
151 " 'W' -- allow the calling user to write the conversation to disk via Monitor.\n"
152 " 'k' -- Allow the called party to enable parking of the call by sending\n"
153 " the DTMF sequence defined for call parking in features.conf.\n"
154 " 'K' -- Allow the calling party to enable parking of the call by sending\n"
155 " the DTMF sequence defined for call parking in features.conf.\n"
156 " 'x' -- allow the called user to write the conversation to disk via MixMonitor\n"
157 " 'X' -- allow the calling user to write the conversation to disk via MixMonitor\n"
159 " In addition to transferring the call, a call may be parked and then picked\n"
160 "up by another user.\n"
161 " The optional URL will be sent to the called party if the channel supports\n"
163 " The optional AGI parameter will setup an AGI script to be executed on the \n"
164 "calling party's channel once they are connected to a queue member.\n"
165 " The optional macro parameter will run a macro on the \n"
166 "calling party's channel once they are connected to a queue member.\n"
167 " The optional gosub parameter will run a gosub on the \n"
168 "calling party's channel once they are connected to a queue member.\n"
169 " The timeout will cause the queue to fail out after a specified number of\n"
170 "seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
171 " This application sets the following channel variable upon completion:\n"
172 " QUEUESTATUS The status of the call as a text string, one of\n"
173 " TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL | CONTINUE\n";
175 static char *app_aqm = "AddQueueMember" ;
176 static char *app_aqm_synopsis = "Dynamically adds queue members" ;
177 static char *app_aqm_descrip =
178 " AddQueueMember(queuename[,interface[,penalty[,options[,membername]]]]):\n"
179 "Dynamically adds interface to an existing queue.\n"
180 "If the interface is already in the queue it will return an error.\n"
181 " This application sets the following channel variable upon completion:\n"
182 " AQMSTATUS The status of the attempt to add a queue member as a \n"
183 " text string, one of\n"
184 " ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
185 "Example: AddQueueMember(techsupport,SIP/3000)\n"
188 static char *app_rqm = "RemoveQueueMember" ;
189 static char *app_rqm_synopsis = "Dynamically removes queue members" ;
190 static char *app_rqm_descrip =
191 " RemoveQueueMember(queuename[,interface[,options]]):\n"
192 "Dynamically removes interface to an existing queue\n"
193 "If the interface is NOT in the queue it will return an error.\n"
194 " This application sets the following channel variable upon completion:\n"
195 " RQMSTATUS The status of the attempt to remove a queue member as a\n"
196 " text string, one of\n"
197 " REMOVED | NOTINQUEUE | NOSUCHQUEUE \n"
198 "Example: RemoveQueueMember(techsupport,SIP/3000)\n"
201 static char *app_pqm = "PauseQueueMember" ;
202 static char *app_pqm_synopsis = "Pauses a queue member" ;
203 static char *app_pqm_descrip =
204 " PauseQueueMember([queuename],interface[,options[,reason]]):\n"
205 "Pauses (blocks calls for) a queue member.\n"
206 "The given interface will be paused in the given queue. This prevents\n"
207 "any calls from being sent from the queue to the interface until it is\n"
208 "unpaused with UnpauseQueueMember or the manager interface. If no\n"
209 "queuename is given, the interface is paused in every queue it is a\n"
210 "member of. The application will fail if the interface is not found.\n"
211 "The reason string is entirely optional and is used to add extra information\n"
212 "to the appropriate queue_log entries and manager events.\n"
213 " This application sets the following channel variable upon completion:\n"
214 " PQMSTATUS The status of the attempt to pause a queue member as a\n"
215 " text string, one of\n"
216 " PAUSED | NOTFOUND\n"
217 "Example: PauseQueueMember(,SIP/3000)\n";
219 static char *app_upqm = "UnpauseQueueMember" ;
220 static char *app_upqm_synopsis = "Unpauses a queue member" ;
221 static char *app_upqm_descrip =
222 " UnpauseQueueMember([queuename],interface[,options[,reason]]):\n"
223 "Unpauses (resumes calls to) a queue member.\n"
224 "This is the counterpart to PauseQueueMember and operates exactly the\n"
225 "same way, except it unpauses instead of pausing the given interface.\n"
226 "The reason string is entirely optional and is used to add extra information\n"
227 "to the appropriate queue_log entries and manager events.\n"
228 " This application sets the following channel variable upon completion:\n"
229 " UPQMSTATUS The status of the attempt to unpause a queue \n"
230 " member as a text string, one of\n"
231 " UNPAUSED | NOTFOUND\n"
232 "Example: UnpauseQueueMember(,SIP/3000)\n";
234 static char *app_ql = "QueueLog" ;
235 static char *app_ql_synopsis = "Writes to the queue_log" ;
236 static char *app_ql_descrip =
237 " QueueLog(queuename,uniqueid,agent,event[,additionalinfo]):\n"
238 "Allows you to write your own events into the queue log\n"
239 "Example: QueueLog(101,${UNIQUEID},${AGENT},WENTONBREAK,600)\n";
241 /*! \brief Persistent Members astdb family */
242 static const char *pm_family = "Queue/PersistentMembers";
243 /* The maximum length of each persistent member queue database entry */
244 #define PM_MAX_LEN 8192
246 /*! \brief queues.conf [general] option */
247 static int queue_keep_stats = 0;
249 /*! \brief queues.conf [general] option */
250 static int queue_persistent_members = 0;
252 /*! \brief queues.conf per-queue weight option */
253 static int use_weight = 0;
255 /*! \brief queues.conf [general] option */
256 static int autofill_default = 0;
258 /*! \brief queues.conf [general] option */
259 static int montype_default = 0;
261 /*! \brief queues.conf [general] option */
262 static int shared_lastcall = 0;
264 /*! \brief Subscription to device state change events */
265 static struct ast_event_sub *device_state_sub;
267 /*! \brief queues.conf [general] option */
268 static int update_cdr = 0;
274 QUEUE_LEAVEEMPTY = 3,
275 QUEUE_JOINUNAVAIL = 4,
276 QUEUE_LEAVEUNAVAIL = 5,
282 enum queue_result id;
284 } queue_results[] = {
285 { QUEUE_UNKNOWN, "UNKNOWN" },
286 { QUEUE_TIMEOUT, "TIMEOUT" },
287 { QUEUE_JOINEMPTY,"JOINEMPTY" },
288 { QUEUE_LEAVEEMPTY, "LEAVEEMPTY" },
289 { QUEUE_JOINUNAVAIL, "JOINUNAVAIL" },
290 { QUEUE_LEAVEUNAVAIL, "LEAVEUNAVAIL" },
291 { QUEUE_FULL, "FULL" },
292 { QUEUE_CONTINUE, "CONTINUE" },
295 /*! \brief We define a custom "local user" structure because we
296 use it not only for keeping track of what is in use but
297 also for keeping track of who we're dialing. */
300 struct callattempt *q_next;
301 struct ast_channel *chan;
307 struct call_queue *lastqueue;
308 struct member *member;
313 struct call_queue *parent; /*!< What queue is our parent */
314 char moh[80]; /*!< Name of musiconhold to be used */
315 char announce[80]; /*!< Announcement to play for member when call is answered */
316 char context[AST_MAX_CONTEXT]; /*!< Context when user exits queue */
317 char digits[AST_MAX_EXTENSION]; /*!< Digits entered while in queue */
318 int valid_digits; /*!< Digits entered correspond to valid extension. Exited */
319 int pos; /*!< Where we are in the queue */
320 int prio; /*!< Our priority */
321 int last_pos_said; /*!< Last position we told the user */
322 time_t last_periodic_announce_time; /*!< The last time we played a periodic announcement */
323 int last_periodic_announce_sound; /*!< The last periodic announcement we made */
324 time_t last_pos; /*!< Last time we told the user their position */
325 int opos; /*!< Where we started in the queue */
326 int handled; /*!< Whether our call was handled */
327 int pending; /*!< Non-zero if we are attempting to call a member */
328 int max_penalty; /*!< Limit the members that can take this call to this penalty or lower */
329 int linpos; /*!< If using linear strategy, what position are we at? */
330 int linwrapped; /*!< Is the linpos wrapped? */
331 time_t start; /*!< When we started holding */
332 time_t expire; /*!< When this entry should expire (time out of queue) */
333 struct ast_channel *chan; /*!< Our channel */
334 struct queue_ent *next; /*!< The next queue entry */
338 char interface[80]; /*!< Technology/Location */
339 char membername[80]; /*!< Member name to use in queue logs */
340 int penalty; /*!< Are we a last resort? */
341 int calls; /*!< Number of calls serviced by this member */
342 int dynamic; /*!< Are we dynamically added? */
343 int realtime; /*!< Is this member realtime? */
344 int status; /*!< Status of queue member */
345 int paused; /*!< Are we paused (not accepting calls)? */
346 time_t lastcall; /*!< When last successful call was hungup */
347 struct call_queue *lastqueue; /*!< Last queue we received a call */
348 unsigned int dead:1; /*!< Used to detect members deleted in realtime */
349 unsigned int delme:1; /*!< Flag to delete entry on reload */
352 struct member_interface {
354 AST_LIST_ENTRY(member_interface) list; /*!< Next call queue */
357 static AST_LIST_HEAD_STATIC(interfaces, member_interface);
359 /* values used in multi-bit flags in call_queue */
360 #define QUEUE_EMPTY_NORMAL 1
361 #define QUEUE_EMPTY_STRICT 2
362 #define QUEUE_EMPTY_LOOSE 3
363 #define ANNOUNCEHOLDTIME_ALWAYS 1
364 #define ANNOUNCEHOLDTIME_ONCE 2
365 #define QUEUE_EVENT_VARIABLES 3
368 AST_DECLARE_STRING_FIELDS(
370 AST_STRING_FIELD(name);
371 /*! Music on Hold class */
372 AST_STRING_FIELD(moh);
373 /*! Announcement to play when call is answered */
374 AST_STRING_FIELD(announce);
376 AST_STRING_FIELD(context);
377 /*! Macro to run upon member connection */
378 AST_STRING_FIELD(membermacro);
379 /*! Gosub to run upon member connection */
380 AST_STRING_FIELD(membergosub);
381 /*! Sound file: "Your call is now first in line" (def. queue-youarenext) */
382 AST_STRING_FIELD(sound_next);
383 /*! Sound file: "There are currently" (def. queue-thereare) */
384 AST_STRING_FIELD(sound_thereare);
385 /*! Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting) */
386 AST_STRING_FIELD(sound_calls);
387 /*! Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
388 AST_STRING_FIELD(sound_holdtime);
389 /*! Sound file: "minutes." (def. queue-minutes) */
390 AST_STRING_FIELD(sound_minutes);
391 /*! Sound file: "less-than" (def. queue-lessthan) */
392 AST_STRING_FIELD(sound_lessthan);
393 /*! Sound file: "seconds." (def. queue-seconds) */
394 AST_STRING_FIELD(sound_seconds);
395 /*! Sound file: "Thank you for your patience." (def. queue-thankyou) */
396 AST_STRING_FIELD(sound_thanks);
397 /*! Sound file: Custom announce for caller, no default */
398 AST_STRING_FIELD(sound_callerannounce);
399 /*! Sound file: "Hold time" (def. queue-reporthold) */
400 AST_STRING_FIELD(sound_reporthold);
402 /*! Sound files: Custom announce, no default */
403 struct ast_str *sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS];
405 unsigned int joinempty:2;
406 unsigned int eventwhencalled:2;
407 unsigned int leavewhenempty:2;
408 unsigned int ringinuse:1;
409 unsigned int setinterfacevar:1;
410 unsigned int setqueuevar:1;
411 unsigned int setqueueentryvar:1;
412 unsigned int reportholdtime:1;
413 unsigned int wrapped:1;
414 unsigned int timeoutrestart:1;
415 unsigned int announceholdtime:2;
416 unsigned int announceposition:1;
418 unsigned int maskmemberstatus:1;
419 unsigned int realtime:1;
420 unsigned int found:1;
421 int announcefrequency; /*!< How often to announce their position */
422 int minannouncefrequency; /*!< The minimum number of seconds between position announcements (def. 15) */
423 int periodicannouncefrequency; /*!< How often to play periodic announcement */
424 int roundingseconds; /*!< How many seconds do we round to? */
425 int holdtime; /*!< Current avg holdtime, based on recursive boxcar filter */
426 int callscompleted; /*!< Number of queue calls completed */
427 int callsabandoned; /*!< Number of queue calls abandoned */
428 int servicelevel; /*!< seconds setting for servicelevel*/
429 int callscompletedinsl; /*!< Number of calls answered with servicelevel*/
430 char monfmt[8]; /*!< Format to use when recording calls */
431 int montype; /*!< Monitor type Monitor vs. MixMonitor */
432 int count; /*!< How many entries */
433 int maxlen; /*!< Max number of entries */
434 int wrapuptime; /*!< Wrapup Time */
436 int retry; /*!< Retry calling everyone after this amount of time */
437 int timeout; /*!< How long to wait for an answer */
438 int weight; /*!< Respective weight */
439 int autopause; /*!< Auto pause queue members if they fail to answer */
441 /* Queue strategy things */
442 int rrpos; /*!< Round Robin - position */
443 int memberdelay; /*!< Seconds to delay connecting member to caller */
444 int autofill; /*!< Ignore the head call status and ring an available agent */
446 struct ao2_container *members; /*!< Head of the list of members */
448 * \brief Number of members _logged in_
449 * \note There will be members in the members container that are not logged
450 * in, so this can not simply be replaced with ao2_container_count().
453 struct queue_ent *head; /*!< Head of the list of callers */
454 AST_LIST_ENTRY(call_queue) list; /*!< Next call queue */
457 static struct ao2_container *queues;
459 static void update_realtime_members(struct call_queue *q);
460 static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused);
462 static void set_queue_result(struct ast_channel *chan, enum queue_result res)
466 for (i = 0; i < sizeof(queue_results) / sizeof(queue_results[0]); i++) {
467 if (queue_results[i].id == res) {
468 pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
474 static char *int2strat(int strategy)
478 for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
479 if (strategy == strategies[x].strategy)
480 return strategies[x].name;
486 static int strat2int(const char *strategy)
490 for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
491 if (!strcasecmp(strategy, strategies[x].name))
492 return strategies[x].strategy;
498 static int queue_hash_cb(const void *obj, const int flags)
500 const struct call_queue *q = obj;
501 return ast_str_hash(q->name);
504 static int queue_cmp_cb(void *obj, void *arg, int flags)
506 struct call_queue *q = obj, *q2 = arg;
507 return !strcasecmp(q->name, q2->name) ? CMP_MATCH : 0;
510 static inline struct call_queue *queue_ref(struct call_queue *q)
516 static inline struct call_queue *queue_unref(struct call_queue *q)
522 static void set_queue_variables(struct queue_ent *qe)
525 char interfacevar[256]="";
528 if (qe->parent->setqueuevar) {
530 if (qe->parent->callscompleted > 0)
531 sl = 100 * ((float) qe->parent->callscompletedinsl / (float) qe->parent->callscompleted);
533 snprintf(interfacevar,sizeof(interfacevar),
534 "QUEUEMAX=%d|QUEUESTRATEGY=%s|QUEUECALLS=%d|QUEUEHOLDTIME=%d|QUEUECOMPLETED=%d|QUEUEABANDONED=%d|QUEUESRVLEVEL=%d|QUEUESRVLEVELPERF=%2.1f",
535 qe->parent->maxlen, int2strat(qe->parent->strategy), qe->parent->count, qe->parent->holdtime, qe->parent->callscompleted,
536 qe->parent->callsabandoned, qe->parent->servicelevel, sl);
538 pbx_builtin_setvar(qe->chan, interfacevar);
542 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
543 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
545 struct queue_ent *cur;
562 enum queue_member_status {
564 QUEUE_NO_REACHABLE_MEMBERS,
565 QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
569 static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty)
571 struct member *member;
572 struct ao2_iterator mem_iter;
573 enum queue_member_status result = QUEUE_NO_MEMBERS;
576 mem_iter = ao2_iterator_init(q->members, 0);
577 for (; (member = ao2_iterator_next(&mem_iter)); ao2_ref(member, -1)) {
578 if (max_penalty && (member->penalty > max_penalty))
581 switch (member->status) {
582 case AST_DEVICE_INVALID:
585 case AST_DEVICE_UNAVAILABLE:
586 if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)
587 result = QUEUE_NO_REACHABLE_MEMBERS;
590 if (member->paused) {
591 result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
606 AST_LIST_ENTRY(statechange) entry;
611 static void *handle_statechange(struct statechange *sc)
613 struct call_queue *q;
615 struct ao2_iterator mem_iter;
616 struct member_interface *curint;
617 struct ao2_iterator queue_iter;
621 technology = ast_strdupa(sc->dev);
622 loc = strchr(technology, '/');
629 AST_LIST_LOCK(&interfaces);
630 AST_LIST_TRAVERSE(&interfaces, curint, list) {
633 interface = ast_strdupa(curint->interface);
634 if ((slash_pos = strchr(interface, '/')))
635 if ((slash_pos = strchr(slash_pos + 1, '/')))
638 if (!strcasecmp(interface, sc->dev))
641 AST_LIST_UNLOCK(&interfaces);
644 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));
648 ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
649 queue_iter = ao2_iterator_init(queues, 0);
650 while ((q = ao2_iterator_next(&queue_iter))) {
652 mem_iter = ao2_iterator_init(q->members, 0);
653 while ((cur = ao2_iterator_next(&mem_iter))) {
656 interface = ast_strdupa(cur->interface);
657 if ((slash_pos = strchr(interface, '/')))
658 if ((slash_pos = strchr(slash_pos + 1, '/')))
661 if (strcasecmp(sc->dev, interface)) {
666 if (cur->status != sc->state) {
667 cur->status = sc->state;
668 if (q->maskmemberstatus) {
673 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
683 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static",
684 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
696 * \brief Data used by the device state thread
699 /*! Set to 1 to stop the thread */
701 /*! The device state monitoring thread */
703 /*! Lock for the state change queue */
705 /*! Condition for the state change queue */
707 /*! Queue of state changes */
708 AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
710 .thread = AST_PTHREADT_NULL,
713 static void *device_state_thread(void *data)
715 struct statechange *sc = NULL;
717 while (!device_state.stop) {
718 ast_mutex_lock(&device_state.lock);
719 if (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
720 ast_cond_wait(&device_state.cond, &device_state.lock);
721 sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry);
723 ast_mutex_unlock(&device_state.lock);
725 /* Check to see if we were woken up to see the request to stop */
726 if (device_state.stop)
732 handle_statechange(sc);
741 while ((sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry)))
747 static int statechange_queue(const char *dev, enum ast_device_state state)
749 struct statechange *sc;
751 if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
755 strcpy(sc->dev, dev);
757 ast_mutex_lock(&device_state.lock);
758 AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
759 ast_cond_signal(&device_state.cond);
760 ast_mutex_unlock(&device_state.lock);
765 static void device_state_cb(const struct ast_event *event, void *unused)
767 enum ast_device_state state;
770 state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
771 device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
773 if (ast_strlen_zero(device)) {
774 ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
778 statechange_queue(device, state);
781 static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused)
785 if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
786 cur->penalty = penalty;
787 cur->paused = paused;
788 ast_copy_string(cur->interface, interface, sizeof(cur->interface));
789 if(!ast_strlen_zero(membername))
790 ast_copy_string(cur->membername, membername, sizeof(cur->membername));
792 ast_copy_string(cur->membername, interface, sizeof(cur->membername));
793 if (!strchr(cur->interface, '/'))
794 ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
795 cur->status = ast_device_state(interface);
802 static int compress_char(const char c)
812 static int member_hash_fn(const void *obj, const int flags)
814 const struct member *mem = obj;
815 const char *chname = strchr(mem->interface, '/');
818 chname = mem->interface;
819 for (i = 0; i < 5 && chname[i]; i++)
820 ret += compress_char(chname[i]) << (i * 6);
824 static int member_cmp_fn(void *obj1, void *obj2, int flags)
826 struct member *mem1 = obj1, *mem2 = obj2;
827 return strcasecmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
830 static void init_queue(struct call_queue *q)
835 q->retry = DEFAULT_RETRY;
838 q->announcefrequency = 0;
839 q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
840 q->announceholdtime = 0;
841 q->announceholdtime = 1;
842 q->roundingseconds = 0; /* Default - don't announce seconds */
845 q->setinterfacevar = 0;
847 q->setqueueentryvar = 0;
848 q->autofill = autofill_default;
849 q->montype = montype_default;
851 q->periodicannouncefrequency = 0;
853 if(q->strategy == QUEUE_STRATEGY_LINEAR)
854 /* linear strategy depends on order, so we have to place all members in a single bucket */
855 q->members = ao2_container_alloc(1, member_hash_fn, member_cmp_fn);
857 q->members = ao2_container_alloc(37, member_hash_fn, member_cmp_fn);
862 ast_string_field_set(q, sound_next, "queue-youarenext");
863 ast_string_field_set(q, sound_thereare, "queue-thereare");
864 ast_string_field_set(q, sound_calls, "queue-callswaiting");
865 ast_string_field_set(q, sound_holdtime, "queue-holdtime");
866 ast_string_field_set(q, sound_minutes, "queue-minutes");
867 ast_string_field_set(q, sound_seconds, "queue-seconds");
868 ast_string_field_set(q, sound_thanks, "queue-thankyou");
869 ast_string_field_set(q, sound_lessthan, "queue-less-than");
870 ast_string_field_set(q, sound_reporthold, "queue-reporthold");
872 if ((q->sound_periodicannounce[0] = ast_str_create(32)))
873 ast_str_set(&q->sound_periodicannounce[0], 0, "queue-periodic-announce");
875 for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
876 if (q->sound_periodicannounce[i])
877 ast_str_set(&q->sound_periodicannounce[i], 0, "%s", "");
881 static void clear_queue(struct call_queue *q)
884 q->callscompleted = 0;
885 q->callsabandoned = 0;
886 q->callscompletedinsl = 0;
890 static int add_to_interfaces(const char *interface)
892 struct member_interface *curint;
894 AST_LIST_LOCK(&interfaces);
895 AST_LIST_TRAVERSE(&interfaces, curint, list) {
896 if (!strcasecmp(curint->interface, interface))
901 AST_LIST_UNLOCK(&interfaces);
905 ast_debug(1, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
907 if ((curint = ast_calloc(1, sizeof(*curint)))) {
908 ast_copy_string(curint->interface, interface, sizeof(curint->interface));
909 AST_LIST_INSERT_HEAD(&interfaces, curint, list);
911 AST_LIST_UNLOCK(&interfaces);
916 static int interface_exists_global(const char *interface)
918 struct call_queue *q;
919 struct member *mem, tmpmem;
920 struct ao2_iterator queue_iter;
923 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
924 queue_iter = ao2_iterator_init(queues, 0);
925 while ((q = ao2_iterator_next(&queue_iter))) {
928 if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
942 static int remove_from_interfaces(const char *interface)
944 struct member_interface *curint;
946 AST_LIST_LOCK(&interfaces);
947 AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
948 if (!strcasecmp(curint->interface, interface)) {
949 if (!interface_exists_global(interface)) {
950 ast_debug(1, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
951 AST_LIST_REMOVE_CURRENT(list);
957 AST_LIST_TRAVERSE_SAFE_END;
958 AST_LIST_UNLOCK(&interfaces);
963 static void clear_and_free_interfaces(void)
965 struct member_interface *curint;
967 AST_LIST_LOCK(&interfaces);
968 while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
970 AST_LIST_UNLOCK(&interfaces);
973 /*! \brief Configure a queue parameter.
975 For error reporting, line number is passed for .conf static configuration.
976 For Realtime queues, linenum is -1.
977 The failunknown flag is set for config files (and static realtime) to show
978 errors for unknown parameters. It is cleared for dynamic realtime to allow
979 extra fields in the tables. */
980 static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
982 if (!strcasecmp(param, "musicclass") ||
983 !strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
984 ast_string_field_set(q, moh, val);
985 } else if (!strcasecmp(param, "announce")) {
986 ast_string_field_set(q, announce, val);
987 } else if (!strcasecmp(param, "context")) {
988 ast_string_field_set(q, context, val);
989 } else if (!strcasecmp(param, "timeout")) {
990 q->timeout = atoi(val);
992 q->timeout = DEFAULT_TIMEOUT;
993 } else if (!strcasecmp(param, "ringinuse")) {
994 q->ringinuse = ast_true(val);
995 } else if (!strcasecmp(param, "setinterfacevar")) {
996 q->setinterfacevar = ast_true(val);
997 } else if (!strcasecmp(param, "setqueuevar")) {
998 q->setqueuevar = ast_true(val);
999 } else if (!strcasecmp(param, "setqueueentryvar")) {
1000 q->setqueueentryvar = ast_true(val);
1001 } else if (!strcasecmp(param, "monitor-format")) {
1002 ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
1003 } else if (!strcasecmp(param, "membermacro")) {
1004 ast_string_field_set(q, membermacro, val);
1005 } else if (!strcasecmp(param, "membergosub")) {
1006 ast_string_field_set(q, membergosub, val);
1007 } else if (!strcasecmp(param, "queue-youarenext")) {
1008 ast_string_field_set(q, sound_next, val);
1009 } else if (!strcasecmp(param, "queue-thereare")) {
1010 ast_string_field_set(q, sound_thereare, val);
1011 } else if (!strcasecmp(param, "queue-callswaiting")) {
1012 ast_string_field_set(q, sound_calls, val);
1013 } else if (!strcasecmp(param, "queue-holdtime")) {
1014 ast_string_field_set(q, sound_holdtime, val);
1015 } else if (!strcasecmp(param, "queue-minutes")) {
1016 ast_string_field_set(q, sound_minutes, val);
1017 } else if (!strcasecmp(param, "queue-seconds")) {
1018 ast_string_field_set(q, sound_seconds, val);
1019 } else if (!strcasecmp(param, "queue-lessthan")) {
1020 ast_string_field_set(q, sound_lessthan, val);
1021 } else if (!strcasecmp(param, "queue-thankyou")) {
1022 ast_string_field_set(q, sound_thanks, val);
1023 } else if (!strcasecmp(param, "queue-callerannounce")) {
1024 ast_string_field_set(q, sound_callerannounce, val);
1025 } else if (!strcasecmp(param, "queue-reporthold")) {
1026 ast_string_field_set(q, sound_reporthold, val);
1027 } else if (!strcasecmp(param, "announce-frequency")) {
1028 q->announcefrequency = atoi(val);
1029 } else if (!strcasecmp(param, "min-announce-frequency")) {
1030 q->minannouncefrequency = atoi(val);
1031 ast_debug(1, "%s=%s for queue '%s'\n", param, val, q->name);
1032 } else if (!strcasecmp(param, "announce-round-seconds")) {
1033 q->roundingseconds = atoi(val);
1034 /* Rounding to any other values just doesn't make sense... */
1035 if (!(q->roundingseconds == 0 || q->roundingseconds == 1 || q->roundingseconds == 5 || q->roundingseconds == 10
1036 || q->roundingseconds == 15 || q->roundingseconds == 20 || q->roundingseconds == 30)) {
1038 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1039 "using 0 instead for queue '%s' at line %d of queues.conf\n",
1040 val, param, q->name, linenum);
1042 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
1043 "using 0 instead for queue '%s'\n", val, param, q->name);
1045 q->roundingseconds=0;
1047 } else if (!strcasecmp(param, "announce-holdtime")) {
1048 if (!strcasecmp(val, "once"))
1049 q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
1050 else if (ast_true(val))
1051 q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
1053 q->announceholdtime = 0;
1054 } else if (!strcasecmp(param, "announce-position")) {
1055 q->announceposition = ast_true(val);
1056 } else if (!strcasecmp(param, "periodic-announce")) {
1057 if (strchr(val, ',')) {
1058 char *s, *buf = ast_strdupa(val);
1061 while ((s = strsep(&buf, ",|"))) {
1062 if (!q->sound_periodicannounce[i])
1063 q->sound_periodicannounce[i] = ast_str_create(16);
1064 ast_str_set(&q->sound_periodicannounce[i], 0, s);
1066 if (i == MAX_PERIODIC_ANNOUNCEMENTS)
1070 ast_str_set(&q->sound_periodicannounce[0], 0, val);
1072 } else if (!strcasecmp(param, "periodic-announce-frequency")) {
1073 q->periodicannouncefrequency = atoi(val);
1074 } else if (!strcasecmp(param, "retry")) {
1075 q->retry = atoi(val);
1077 q->retry = DEFAULT_RETRY;
1078 } else if (!strcasecmp(param, "wrapuptime")) {
1079 q->wrapuptime = atoi(val);
1080 } else if (!strcasecmp(param, "autofill")) {
1081 q->autofill = ast_true(val);
1082 } else if (!strcasecmp(param, "monitor-type")) {
1083 if (!strcasecmp(val, "mixmonitor"))
1085 } else if (!strcasecmp(param, "autopause")) {
1086 q->autopause = ast_true(val);
1087 } else if (!strcasecmp(param, "maxlen")) {
1088 q->maxlen = atoi(val);
1091 } else if (!strcasecmp(param, "servicelevel")) {
1092 q->servicelevel= atoi(val);
1093 } else if (!strcasecmp(param, "strategy")) {
1094 /* We already have set this, no need to do it again */
1096 } else if (!strcasecmp(param, "joinempty")) {
1097 if (!strcasecmp(val, "loose"))
1098 q->joinempty = QUEUE_EMPTY_LOOSE;
1099 else if (!strcasecmp(val, "strict"))
1100 q->joinempty = QUEUE_EMPTY_STRICT;
1101 else if (ast_true(val))
1102 q->joinempty = QUEUE_EMPTY_NORMAL;
1105 } else if (!strcasecmp(param, "leavewhenempty")) {
1106 if (!strcasecmp(val, "loose"))
1107 q->leavewhenempty = QUEUE_EMPTY_LOOSE;
1108 else if (!strcasecmp(val, "strict"))
1109 q->leavewhenempty = QUEUE_EMPTY_STRICT;
1110 else if (ast_true(val))
1111 q->leavewhenempty = QUEUE_EMPTY_NORMAL;
1113 q->leavewhenempty = 0;
1114 } else if (!strcasecmp(param, "eventmemberstatus")) {
1115 q->maskmemberstatus = !ast_true(val);
1116 } else if (!strcasecmp(param, "eventwhencalled")) {
1117 if (!strcasecmp(val, "vars")) {
1118 q->eventwhencalled = QUEUE_EVENT_VARIABLES;
1120 q->eventwhencalled = ast_true(val) ? 1 : 0;
1122 } else if (!strcasecmp(param, "reportholdtime")) {
1123 q->reportholdtime = ast_true(val);
1124 } else if (!strcasecmp(param, "memberdelay")) {
1125 q->memberdelay = atoi(val);
1126 } else if (!strcasecmp(param, "weight")) {
1127 q->weight = atoi(val);
1130 /* With Realtime queues, if the last queue using weights is deleted in realtime,
1131 we will not see any effect on use_weight until next reload. */
1132 } else if (!strcasecmp(param, "timeoutrestart")) {
1133 q->timeoutrestart = ast_true(val);
1134 } else if (failunknown) {
1136 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
1137 q->name, param, linenum);
1139 ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
1144 static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str)
1146 struct member *m, tmpmem;
1151 penalty = atoi(penalty_str);
1157 paused = atoi(paused_str);
1162 /* Find the member, or the place to put a new one. */
1163 ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1164 m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
1166 /* Create a new one if not found, else update penalty */
1168 if ((m = create_queue_member(interface, membername, penalty, paused))) {
1171 add_to_interfaces(interface);
1172 ao2_link(q->members, m);
1178 m->dead = 0; /* Do not delete this one. */
1181 m->penalty = penalty;
1186 static void free_members(struct call_queue *q, int all)
1188 /* Free non-dynamic members */
1190 struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
1192 while ((cur = ao2_iterator_next(&mem_iter))) {
1193 if (all || !cur->dynamic) {
1194 ao2_unlink(q->members, cur);
1195 remove_from_interfaces(cur->interface);
1202 static void destroy_queue(void *obj)
1204 struct call_queue *q = obj;
1207 ast_debug(0, "Queue destructor called for queue '%s'!\n", q->name);
1210 ast_string_field_free_memory(q);
1211 for (i = 0; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
1212 if (q->sound_periodicannounce[i])
1213 free(q->sound_periodicannounce[i]);
1215 ao2_ref(q->members, -1);
1218 static struct call_queue *alloc_queue(const char *queuename)
1220 struct call_queue *q;
1222 if ((q = ao2_alloc(sizeof(*q), destroy_queue))) {
1223 if (ast_string_field_init(q, 64)) {
1227 ast_string_field_set(q, name, queuename);
1232 /*!\brief Reload a single queue via realtime.
1233 \return Return the queue, or NULL if it doesn't exist.
1234 \note Should be called with the global qlock locked. */
1235 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
1237 struct ast_variable *v;
1238 struct call_queue *q, tmpq = {
1242 struct ao2_iterator mem_iter;
1243 char *interface = NULL;
1244 const char *tmp_name;
1246 char tmpbuf[64]; /* Must be longer than the longest queue param name. */
1248 /* Static queues override realtime. */
1249 if ((q = ao2_find(queues, &tmpq, OBJ_POINTER))) {
1257 ast_log(LOG_WARNING, "Static queue '%s' already exists. Not loading from realtime\n", q->name);
1263 } else if (!member_config)
1264 /* Not found in the list, and it's not realtime ... */
1267 /* Check if queue is defined in realtime. */
1269 /* Delete queue from in-core list if it has been deleted in realtime. */
1271 /*! \note Hmm, can't seem to distinguish a DB failure from a not
1272 found condition... So we might delete an in-core queue
1273 in case of DB failure. */
1274 ast_debug(1, "Queue %s not found in realtime.\n", queuename);
1277 /* Delete if unused (else will be deleted when last caller leaves). */
1278 ao2_unlink(queues, q);
1285 /* Create a new queue if an in-core entry does not exist yet. */
1287 if (!(q = alloc_queue(queuename)))
1292 init_queue(q); /* Ensure defaults for all parameters not set explicitly. */
1293 ao2_link(queues, q);
1296 memset(tmpbuf, 0, sizeof(tmpbuf));
1297 for (v = queue_vars; v; v = v->next) {
1298 /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
1299 if ((tmp = strchr(v->name, '_'))) {
1300 ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
1303 while ((tmp = strchr(tmp, '_')))
1307 queue_set_param(q, tmp_name, v->value, -1, 0);
1310 /* Temporarily set realtime members dead so we can detect deleted ones.
1311 * Also set the membercount correctly for realtime*/
1312 mem_iter = ao2_iterator_init(q->members, 0);
1313 while ((m = ao2_iterator_next(&mem_iter))) {
1320 while ((interface = ast_category_browse(member_config, interface))) {
1321 rt_handle_member_record(q, interface,
1322 ast_variable_retrieve(member_config, interface, "membername"),
1323 ast_variable_retrieve(member_config, interface, "penalty"),
1324 ast_variable_retrieve(member_config, interface, "paused"));
1327 /* Delete all realtime members that have been deleted in DB. */
1328 mem_iter = ao2_iterator_init(q->members, 0);
1329 while ((m = ao2_iterator_next(&mem_iter))) {
1331 ao2_unlink(q->members, m);
1333 remove_from_interfaces(m->interface);
1345 static struct call_queue *load_realtime_queue(const char *queuename)
1347 struct ast_variable *queue_vars;
1348 struct ast_config *member_config = NULL;
1349 struct call_queue *q = NULL, tmpq = {
1353 /* Find the queue in the in-core list first. */
1354 q = ao2_find(queues, &tmpq, OBJ_POINTER);
1356 if (!q || q->realtime) {
1357 /*! \note Load from realtime before taking the global qlock, to avoid blocking all
1358 queue operations while waiting for the DB.
1360 This will be two separate database transactions, so we might
1361 see queue parameters as they were before another process
1362 changed the queue and member list as it was after the change.
1363 Thus we might see an empty member list when a queue is
1364 deleted. In practise, this is unlikely to cause a problem. */
1366 queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
1368 member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
1369 if (!member_config) {
1370 ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
1371 ast_variables_destroy(queue_vars);
1377 q = find_queue_by_name_rt(queuename, queue_vars, member_config);
1379 ast_config_destroy(member_config);
1381 ast_variables_destroy(queue_vars);
1385 update_realtime_members(q);
1390 static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
1392 struct ast_variable *var;
1395 if(!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL)))
1398 if(!strcmp(var->name, "uniqueid"))
1402 if(var && !ast_strlen_zero(var->value)) {
1403 if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
1409 static void update_realtime_members(struct call_queue *q)
1411 struct ast_config *member_config = NULL;
1413 char *interface = NULL;
1414 struct ao2_iterator mem_iter;
1416 member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL);
1417 if (!member_config) {
1418 /*This queue doesn't have realtime members*/
1419 ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
1425 /* Temporarily set realtime members dead so we can detect deleted ones.*/
1426 mem_iter = ao2_iterator_init(q->members, 0);
1427 while ((m = ao2_iterator_next(&mem_iter))) {
1433 while ((interface = ast_category_browse(member_config, interface))) {
1434 rt_handle_member_record(q, interface,
1435 S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
1436 ast_variable_retrieve(member_config, interface, "penalty"),
1437 ast_variable_retrieve(member_config, interface, "paused"));
1440 /* Delete all realtime members that have been deleted in DB. */
1441 mem_iter = ao2_iterator_init(q->members, 0);
1442 while ((m = ao2_iterator_next(&mem_iter))) {
1444 ao2_unlink(q->members, m);
1446 remove_from_interfaces(m->interface);
1455 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
1457 struct call_queue *q;
1458 struct queue_ent *cur, *prev = NULL;
1462 enum queue_member_status stat;
1464 if (!(q = load_realtime_queue(queuename)))
1470 /* This is our one */
1471 stat = get_member_status(q, qe->max_penalty);
1472 if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
1473 *reason = QUEUE_JOINEMPTY;
1474 else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
1475 *reason = QUEUE_JOINUNAVAIL;
1476 else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
1477 *reason = QUEUE_JOINUNAVAIL;
1478 else if (q->maxlen && (q->count >= q->maxlen))
1479 *reason = QUEUE_FULL;
1481 /* There's space for us, put us at the right position inside
1483 * Take into account the priority of the calling user */
1488 /* We have higher priority than the current user, enter
1489 * before him, after all the other users with priority
1490 * higher or equal to our priority. */
1491 if ((!inserted) && (qe->prio > cur->prio)) {
1492 insert_entry(q, prev, qe, &pos);
1499 /* No luck, join at the end of the queue */
1501 insert_entry(q, prev, qe, &pos);
1502 ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
1503 ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
1504 ast_copy_string(qe->context, q->context, sizeof(qe->context));
1507 manager_event(EVENT_FLAG_CALL, "Join",
1508 "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
1510 S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
1511 S_OR(qe->chan->cid.cid_name, "unknown"),
1512 q->name, qe->pos, q->count, qe->chan->uniqueid );
1513 ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
1521 static int play_file(struct ast_channel *chan, const char *filename)
1525 ast_stopstream(chan);
1527 res = ast_streamfile(chan, filename, chan->language);
1529 res = ast_waitstream(chan, AST_DIGIT_ANY);
1531 ast_stopstream(chan);
1536 static int valid_exit(struct queue_ent *qe, char digit)
1538 int digitlen = strlen(qe->digits);
1540 /* Prevent possible buffer overflow */
1541 if (digitlen < sizeof(qe->digits) - 2) {
1542 qe->digits[digitlen] = digit;
1543 qe->digits[digitlen + 1] = '\0';
1545 qe->digits[0] = '\0';
1549 /* If there's no context to goto, short-circuit */
1550 if (ast_strlen_zero(qe->context))
1553 /* If the extension is bad, then reset the digits to blank */
1554 if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
1555 qe->digits[0] = '\0';
1559 /* We have an exact match */
1560 if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
1561 qe->valid_digits = 1;
1562 /* Return 1 on a successful goto */
1569 static int say_position(struct queue_ent *qe, int ringing)
1571 int res = 0, avgholdmins, avgholdsecs;
1574 /* Let minannouncefrequency seconds pass between the start of each position announcement */
1576 if ((now - qe->last_pos) < qe->parent->minannouncefrequency)
1579 /* If either our position has changed, or we are over the freq timer, say position */
1580 if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
1584 ast_indicate(qe->chan,-1);
1586 ast_moh_stop(qe->chan);
1588 if (qe->parent->announceposition) {
1589 /* Say we're next, if we are */
1591 res = play_file(qe->chan, qe->parent->sound_next);
1597 res = play_file(qe->chan, qe->parent->sound_thereare);
1600 res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */
1603 res = play_file(qe->chan, qe->parent->sound_calls);
1608 /* Round hold time to nearest minute */
1609 avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
1611 /* If they have specified a rounding then round the seconds as well */
1612 if (qe->parent->roundingseconds) {
1613 avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
1614 avgholdsecs *= qe->parent->roundingseconds;
1619 ast_verb(3, "Hold time for %s is %d minutes %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
1621 /* If the hold time is >1 min, if it's enabled, and if it's not
1622 supposed to be only once and we have already said it, say it */
1623 if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
1624 (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
1625 res = play_file(qe->chan, qe->parent->sound_holdtime);
1629 if (avgholdmins > 0) {
1630 if (avgholdmins < 2) {
1631 res = play_file(qe->chan, qe->parent->sound_lessthan);
1635 res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
1639 res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
1644 res = play_file(qe->chan, qe->parent->sound_minutes);
1648 if (avgholdsecs>0) {
1649 res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
1653 res = play_file(qe->chan, qe->parent->sound_seconds);
1661 if (qe->parent->announceposition) {
1662 ast_verb(3, "Told %s in %s their queue position (which was %d)\n",
1663 qe->chan->name, qe->parent->name, qe->pos);
1665 res = play_file(qe->chan, qe->parent->sound_thanks);
1668 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
1671 /* Set our last_pos indicators */
1673 qe->last_pos_said = qe->pos;
1675 /* Don't restart music on hold if we're about to exit the caller from the queue */
1678 ast_indicate(qe->chan, AST_CONTROL_RINGING);
1680 ast_moh_start(qe->chan, qe->moh, NULL);
1685 static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
1689 /* Calculate holdtime using a recursive boxcar filter */
1690 /* Thanks to SRT for this contribution */
1691 /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
1693 ao2_lock(qe->parent);
1694 oldvalue = qe->parent->holdtime;
1695 qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
1696 ao2_unlock(qe->parent);
1700 static void leave_queue(struct queue_ent *qe)
1702 struct call_queue *q;
1703 struct queue_ent *cur, *prev = NULL;
1706 if (!(q = qe->parent))
1712 for (cur = q->head; cur; cur = cur->next) {
1716 /* Take us out of the queue */
1717 manager_event(EVENT_FLAG_CALL, "Leave",
1718 "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
1719 qe->chan->name, q->name, q->count, qe->chan->uniqueid);
1720 ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
1721 /* Take us out of the queue */
1723 prev->next = cur->next;
1725 q->head = cur->next;
1727 /* Renumber the people after us in the queue based on a new count */
1734 /*If the queue is a realtime queue, check to see if it's still defined in real time*/
1736 if(!ast_load_realtime("queues", "name", q->name, NULL))
1741 /* It's dead and nobody is in it, so kill it */
1742 ao2_unlink(queues, q);
1748 /* Hang up a list of outgoing calls */
1749 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
1751 struct callattempt *oo;
1754 /* Hangup any existing lines we have open */
1755 if (outgoing->chan && (outgoing->chan != exception))
1756 ast_hangup(outgoing->chan);
1758 outgoing = outgoing->q_next;
1760 ao2_ref(oo->member, -1);
1765 static int update_status(struct call_queue *q, struct member *member, int status)
1768 struct ao2_iterator mem_iter;
1770 /* Since a reload could have taken place, we have to traverse the list to
1771 be sure it's still valid */
1773 mem_iter = ao2_iterator_init(q->members, 0);
1774 while ((cur = ao2_iterator_next(&mem_iter))) {
1775 if (member != cur) {
1780 cur->status = status;
1781 if (!q->maskmemberstatus) {
1782 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
1785 "MemberName: %s\r\n"
1786 "Membership: %s\r\n"
1788 "CallsTaken: %d\r\n"
1792 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime": "static",
1793 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
1801 static int update_dial_status(struct call_queue *q, struct member *member, int status)
1803 if (status == AST_CAUSE_BUSY)
1804 status = AST_DEVICE_BUSY;
1805 else if (status == AST_CAUSE_UNREGISTERED)
1806 status = AST_DEVICE_UNAVAILABLE;
1807 else if (status == AST_CAUSE_NOSUCHDRIVER)
1808 status = AST_DEVICE_INVALID;
1810 status = AST_DEVICE_UNKNOWN;
1811 return update_status(q, member, status);
1814 /* traverse all defined queues which have calls waiting and contain this member
1815 return 0 if no other queue has precedence (higher weight) or 1 if found */
1816 static int compare_weight(struct call_queue *rq, struct member *member)
1818 struct call_queue *q;
1821 struct ao2_iterator queue_iter;
1823 /* &qlock and &rq->lock already set by try_calling()
1824 * to solve deadlock */
1825 queue_iter = ao2_iterator_init(queues, 0);
1826 while ((q = ao2_iterator_next(&queue_iter))) {
1827 if (q == rq) { /* don't check myself, could deadlock */
1832 if (q->count && q->members) {
1833 if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
1834 ast_debug(1, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
1835 if (q->weight > rq->weight) {
1836 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);
1852 /*! \brief common hangup actions */
1853 static void do_hang(struct callattempt *o)
1856 ast_hangup(o->chan);
1860 static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
1862 struct ast_str *buf = ast_str_alloca(len + 1);
1865 if (pbx_builtin_serialize_variables(chan, &buf)) {
1868 /* convert "\n" to "\nVariable: " */
1869 strcpy(vars, "Variable: ");
1872 for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
1875 if (tmp[i + 1] == '\0')
1877 if (tmp[i] == '\n') {
1881 ast_copy_string(&(vars[j]), "Variable: ", len - j);
1891 /* there are no channel variables; leave it blank */
1897 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
1904 /* on entry here, we know that tmp->chan == NULL */
1905 if ((tmp->lastqueue && tmp->lastqueue->wrapuptime && (time(NULL) - tmp->lastcall < tmp->lastqueue->wrapuptime)) ||
1906 (!tmp->lastqueue && qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime))) {
1907 ast_debug(1, "Wrapuptime not yet expired on queue %s for %s\n",
1908 (tmp->lastqueue ? tmp->lastqueue->name : qe->parent->name), tmp->interface);
1910 ast_cdr_busy(qe->chan->cdr);
1911 tmp->stillgoing = 0;
1916 if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
1917 ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
1919 ast_cdr_busy(qe->chan->cdr);
1920 tmp->stillgoing = 0;
1924 if (tmp->member->paused) {
1925 ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
1927 ast_cdr_busy(qe->chan->cdr);
1928 tmp->stillgoing = 0;
1931 if (use_weight && compare_weight(qe->parent,tmp->member)) {
1932 ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
1934 ast_cdr_busy(qe->chan->cdr);
1935 tmp->stillgoing = 0;
1940 ast_copy_string(tech, tmp->interface, sizeof(tech));
1941 if ((location = strchr(tech, '/')))
1946 /* Request the peer */
1947 tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
1948 if (!tmp->chan) { /* If we can't, just go on to the next call */
1950 ast_cdr_busy(qe->chan->cdr);
1951 tmp->stillgoing = 0;
1952 update_dial_status(qe->parent, tmp->member, status);
1954 ao2_lock(qe->parent);
1955 qe->parent->rrpos++;
1957 ao2_unlock(qe->parent);
1962 } else if (status != tmp->oldstatus)
1963 update_dial_status(qe->parent, tmp->member, status);
1965 tmp->chan->appl = "AppQueue";
1966 tmp->chan->data = "(Outgoing Line)";
1967 tmp->chan->whentohangup = 0;
1968 if (tmp->chan->cid.cid_num)
1969 ast_free(tmp->chan->cid.cid_num);
1970 tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
1971 if (tmp->chan->cid.cid_name)
1972 ast_free(tmp->chan->cid.cid_name);
1973 tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
1974 if (tmp->chan->cid.cid_ani)
1975 ast_free(tmp->chan->cid.cid_ani);
1976 tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
1978 /* Inherit specially named variables from parent channel */
1979 ast_channel_inherit_variables(qe->chan, tmp->chan);
1981 /* Presense of ADSI CPE on outgoing channel follows ours */
1982 tmp->chan->adsicpe = qe->chan->adsicpe;
1984 /* Place the call, but don't wait on the answer */
1985 if ((res = ast_call(tmp->chan, location, 0))) {
1986 /* Again, keep going even if there's an error */
1987 ast_debug(1, "ast call on peer returned %d\n", res);
1988 ast_verb(3, "Couldn't call %s\n", tmp->interface);
1992 } else if (qe->parent->eventwhencalled) {
1995 manager_event(EVENT_FLAG_AGENT, "AgentCalled",
1997 "AgentCalled: %s\r\n"
1999 "ChannelCalling: %s\r\n"
2000 "DestinationChannel: %s\r\n"
2001 "CallerIDNum: %s\r\n"
2002 "CallerIDName: %s\r\n"
2007 qe->parent->name, tmp->interface, tmp->member->membername, qe->chan->name, tmp->chan->name,
2008 tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
2009 tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
2010 qe->chan->context, qe->chan->exten, qe->chan->priority,
2011 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2012 ast_verb(3, "Called %s\n", tmp->interface);
2018 /*! \brief find the entry with the best metric, or NULL */
2019 static struct callattempt *find_best(struct callattempt *outgoing)
2021 struct callattempt *best = NULL, *cur;
2023 for (cur = outgoing; cur; cur = cur->q_next) {
2024 if (cur->stillgoing && /* Not already done */
2025 !cur->chan && /* Isn't already going */
2026 (!best || cur->metric < best->metric)) { /* We haven't found one yet, or it's better */
2034 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
2039 struct callattempt *best = find_best(outgoing);
2041 ast_debug(1, "Nobody left to try ringing in queue\n");
2044 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2045 struct callattempt *cur;
2046 /* Ring everyone who shares this best metric (for ringall) */
2047 for (cur = outgoing; cur; cur = cur->q_next) {
2048 if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
2049 ast_debug(1, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
2050 ring_entry(qe, cur, busies);
2054 /* Ring just the best channel */
2055 ast_debug(1, "Trying '%s' with metric %d\n", best->interface, best->metric);
2056 ring_entry(qe, best, busies);
2058 if (best->chan) /* break out with result = 1 */
2065 static int store_next_rr(struct queue_ent *qe, struct callattempt *outgoing)
2067 struct callattempt *best = find_best(outgoing);
2070 /* Ring just the best channel */
2071 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2072 qe->parent->rrpos = best->metric % 1000;
2074 /* Just increment rrpos */
2075 if (qe->parent->wrapped) {
2076 /* No more channels, start over */
2077 qe->parent->rrpos = 0;
2079 /* Prioritize next entry */
2080 qe->parent->rrpos++;
2083 qe->parent->wrapped = 0;
2088 static int store_next_lin(struct queue_ent *qe, struct callattempt *outgoing)
2090 struct callattempt *best = find_best(outgoing);
2093 /* Ring just the best channel */
2094 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
2095 qe->linpos = best->metric % 1000;
2097 /* Just increment rrpos */
2098 if (qe->linwrapped) {
2099 /* No more channels, start over */
2102 /* Prioritize next entry */
2111 static int say_periodic_announcement(struct queue_ent *qe, int ringing)
2116 /* Get the current time */
2119 /* Check to see if it is time to announce */
2120 if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
2123 /* Stop the music on hold so we can play our own file */
2125 ast_indicate(qe->chan,-1);
2127 ast_moh_stop(qe->chan);
2129 ast_verb(3, "Playing periodic announcement\n");
2131 /* Check to make sure we have a sound file. If not, reset to the first sound file */
2132 if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS ||
2133 !qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound] ||
2134 ast_strlen_zero(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str)) {
2135 qe->last_periodic_announce_sound = 0;
2138 /* play the announcement */
2139 res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]->str);
2141 if ((res > 0 && !valid_exit(qe, res)) || res < 0)
2144 /* Resume Music on Hold if the caller is going to stay in the queue */
2147 ast_indicate(qe->chan, AST_CONTROL_RINGING);
2149 ast_moh_start(qe->chan, qe->moh, NULL);
2152 /* update last_periodic_announce_time */
2153 qe->last_periodic_announce_time = now;
2155 /* Update the current periodic announcement to the next announcement */
2156 qe->last_periodic_announce_sound++;
2161 static void record_abandoned(struct queue_ent *qe)
2163 ao2_lock(qe->parent);
2164 set_queue_variables(qe);
2165 manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
2169 "OriginalPosition: %d\r\n"
2171 qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
2173 qe->parent->callsabandoned++;
2174 ao2_unlock(qe->parent);
2177 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
2178 static void rna(int rnatime, struct queue_ent *qe, char *interface, char *membername)
2180 ast_verb(3, "Nobody picked up in %d ms\n", rnatime);
2181 ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
2182 if (qe->parent->autopause) {
2183 if (!set_member_paused(qe->parent->name, interface, "Auto-Pause", 1)) {
2184 ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
2186 ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
2192 #define AST_MAX_WATCHERS 256
2194 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
2196 const char *queue = qe->parent->name;
2197 struct callattempt *o;
2199 int numbusies = prebusies;
2203 struct ast_frame *f;
2204 struct callattempt *peer = NULL;
2205 struct ast_channel *winner;
2206 struct ast_channel *in = qe->chan;
2208 char membername[80] = "";
2212 struct callattempt *epollo;
2215 starttime = (long) time(NULL);
2217 for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2219 ast_poll_channel_add(in, epollo->chan);
2223 while (*to && !peer) {
2224 int numlines, retry, pos = 1;
2225 struct ast_channel *watchers[AST_MAX_WATCHERS];
2228 for (retry = 0; retry < 2; retry++) {
2230 for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
2231 if (o->stillgoing) { /* Keep track of important channels */
2234 watchers[pos++] = o->chan;
2238 if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
2239 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
2241 /* On "ringall" strategy we only move to the next penalty level
2242 when *all* ringing phones are done in the current penalty level */
2243 ring_one(qe, outgoing, &numbusies);
2246 if (pos == 1 /* not found */) {
2247 if (numlines == (numbusies + numnochan)) {
2248 ast_debug(1, "Everyone is busy at this time\n");
2250 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
2255 winner = ast_waitfor_n(watchers, pos, to);
2256 for (o = outgoing; o; o = o->q_next) {
2257 if (o->stillgoing && (o->chan) && (o->chan->_state == AST_STATE_UP)) {
2259 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2262 } else if (o->chan && (o->chan == winner)) {
2264 ast_copy_string(on, o->member->interface, sizeof(on));
2265 ast_copy_string(membername, o->member->membername, sizeof(membername));
2267 if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
2268 ast_verb(3, "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
2273 } else if (!ast_strlen_zero(o->chan->call_forward)) {
2278 ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
2279 if ((stuff = strchr(tmpchan, '/'))) {
2283 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
2287 /* Before processing channel, go ahead and check for forwarding */
2288 ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
2289 /* Setup parameters */
2290 o->chan = ast_request(tech, in->nativeformats, stuff, &status);
2291 if (status != o->oldstatus)
2292 update_dial_status(qe->parent, o->member, status);
2294 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
2298 ast_channel_inherit_variables(in, o->chan);
2299 ast_channel_datastore_inherit(in, o->chan);
2300 if (o->chan->cid.cid_num)
2301 ast_free(o->chan->cid.cid_num);
2302 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
2304 if (o->chan->cid.cid_name)
2305 ast_free(o->chan->cid.cid_name);
2306 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
2308 ast_string_field_set(o->chan, accountcode, in->accountcode);
2309 o->chan->cdrflags = in->cdrflags;
2311 if (in->cid.cid_ani) {
2312 if (o->chan->cid.cid_ani)
2313 ast_free(o->chan->cid.cid_ani);
2314 o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
2316 if (o->chan->cid.cid_rdnis)
2317 ast_free(o->chan->cid.cid_rdnis);
2318 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
2319 if (ast_call(o->chan, tmpchan, 0)) {
2320 ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
2325 /* Hangup the original channel now, in case we needed it */
2329 f = ast_read(winner);
2331 if (f->frametype == AST_FRAME_CONTROL) {
2332 switch (f->subclass) {
2333 case AST_CONTROL_ANSWER:
2334 /* This is our guy if someone answered. */
2336 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2340 case AST_CONTROL_BUSY:
2341 ast_verb(3, "%s is busy\n", o->chan->name);
2343 ast_cdr_busy(in->cdr);
2345 endtime = (long) time(NULL);
2346 endtime -= starttime;
2347 rna(endtime*1000, qe, on, membername);
2348 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2349 if (qe->parent->timeoutrestart)
2351 ring_one(qe, outgoing, &numbusies);
2355 case AST_CONTROL_CONGESTION:
2356 ast_verb(3, "%s is circuit-busy\n", o->chan->name);
2358 ast_cdr_busy(in->cdr);
2359 endtime = (long) time(NULL);
2360 endtime -= starttime;
2361 rna(endtime*1000, qe, on, membername);
2363 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2364 if (qe->parent->timeoutrestart)
2366 ring_one(qe, outgoing, &numbusies);
2370 case AST_CONTROL_RINGING:
2371 ast_verb(3, "%s is ringing\n", o->chan->name);
2373 case AST_CONTROL_OFFHOOK:
2374 /* Ignore going off hook */
2377 ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
2382 endtime = (long) time(NULL) - starttime;
2383 rna(endtime * 1000, qe, on, membername);
2385 if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2386 if (qe->parent->timeoutrestart)
2388 ring_one(qe, outgoing, &numbusies);
2395 if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2403 if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2404 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
2409 if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
2410 ast_verb(3, "User pressed digit: %c\n", f->subclass);
2412 *digit = f->subclass;
2419 rna(orig, qe, on, membername);
2423 for(epollo = outgoing; epollo; epollo = epollo->q_next) {
2425 ast_poll_channel_del(in, epollo->chan);
2432 static int is_our_turn(struct queue_ent *qe)
2434 struct queue_ent *ch;
2440 if (!qe->parent->autofill) {
2441 /* Atomically read the parent head -- does not need a lock */
2442 ch = qe->parent->head;
2443 /* If we are now at the top of the head, break out */
2445 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2448 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2453 /* This needs a lock. How many members are available to be served? */
2454 ao2_lock(qe->parent);
2456 ch = qe->parent->head;
2458 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2459 ast_debug(1, "Even though there may be multiple members available, the strategy is ringall so only the head call is allowed in\n");
2462 struct ao2_iterator mem_iter = ao2_iterator_init(qe->parent->members, 0);
2463 while ((cur = ao2_iterator_next(&mem_iter))) {
2464 switch (cur->status) {
2465 case AST_DEVICE_NOT_INUSE:
2466 case AST_DEVICE_UNKNOWN:
2475 ast_debug(1, "There are %d available members.\n", avl);
2477 while ((idx < avl) && (ch) && !ch->pending && (ch != qe)) {
2482 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2483 if (ch && idx < avl) {
2484 ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2487 ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2491 ao2_unlock(qe->parent);
2497 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2501 /* This is the holding pen for callers 2 through maxlen */
2503 enum queue_member_status stat;
2505 if (is_our_turn(qe))
2508 /* If we have timed out, break out */
2509 if (qe->expire && (time(NULL) > qe->expire)) {
2510 *reason = QUEUE_TIMEOUT;
2514 stat = get_member_status(qe->parent, qe->max_penalty);
2516 /* leave the queue if no agents, if enabled */
2517 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2518 *reason = QUEUE_LEAVEEMPTY;
2519 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2524 /* leave the queue if no reachable agents, if enabled */
2525 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
2526 *reason = QUEUE_LEAVEUNAVAIL;
2527 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2531 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2532 *reason = QUEUE_LEAVEUNAVAIL;
2533 ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2538 /* Make a position announcement, if enabled */
2539 if (qe->parent->announcefrequency &&
2540 (res = say_position(qe,ringing)))
2543 /* Make a periodic announcement, if enabled */
2544 if (qe->parent->periodicannouncefrequency &&
2545 (res = say_periodic_announcement(qe,ringing)))
2548 /* Wait a second before checking again */
2549 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
2550 if (res > 0 && !valid_exit(qe, res))
2560 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
2563 struct call_queue *qtmp;
2564 struct ao2_iterator queue_iter;
2566 if (shared_lastcall) {
2567 queue_iter = ao2_iterator_init(queues, 0);
2568 while ((qtmp = ao2_iterator_next(&queue_iter))) {
2570 if ((mem = ao2_find(qtmp->members, member, OBJ_POINTER))) {
2571 time(&mem->lastcall);
2581 time(&member->lastcall);
2583 member->lastqueue = q;
2587 q->callscompleted++;
2588 if (callcompletedinsl)
2589 q->callscompletedinsl++;
2594 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2596 if (qe->max_penalty && (mem->penalty > qe->max_penalty))
2599 switch (q->strategy) {
2600 case QUEUE_STRATEGY_RINGALL:
2601 /* Everyone equal, except for penalty */
2602 tmp->metric = mem->penalty * 1000000;
2604 case QUEUE_STRATEGY_LINEAR:
2605 if (pos < qe->linpos) {
2606 tmp->metric = 1000 + pos;
2608 if (pos > qe->linpos)
2609 /* Indicate there is another priority */
2613 tmp->metric += mem->penalty * 1000000;
2615 case QUEUE_STRATEGY_RRMEMORY:
2616 if (pos < q->rrpos) {
2617 tmp->metric = 1000 + pos;
2620 /* Indicate there is another priority */
2624 tmp->metric += mem->penalty * 1000000;
2626 case QUEUE_STRATEGY_RANDOM:
2627 tmp->metric = ast_random() % 1000;
2628 tmp->metric += mem->penalty * 1000000;
2630 case QUEUE_STRATEGY_WRANDOM:
2631 tmp->metric = ast_random() % ((1 + mem->penalty) * 1000);
2633 case QUEUE_STRATEGY_FEWESTCALLS:
2634 tmp->metric = mem->calls;
2635 tmp->metric += mem->penalty * 1000000;
2637 case QUEUE_STRATEGY_LEASTRECENT:
2641 tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2642 tmp->metric += mem->penalty * 1000000;
2645 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2651 enum agent_complete_reason {
2657 static void send_agent_complete(const struct queue_ent *qe, const char *queuename,
2658 const struct ast_channel *peer, const struct member *member, time_t callstart,
2659 char *vars, size_t vars_len, enum agent_complete_reason rsn)
2661 const char *reason = NULL; /* silence dumb compilers */
2663 if (!qe->parent->eventwhencalled)
2674 reason = "transfer";
2678 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2683 "MemberName: %s\r\n"
2688 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2689 (long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
2690 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
2693 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)
2696 struct callattempt *outgoing = NULL; /* the list of calls we are building */
2698 char oldexten[AST_MAX_EXTENSION]="";
2699 char oldcontext[AST_MAX_CONTEXT]="";
2700 char queuename[256]="";
2701 char interfacevar[256]="";
2702 struct ast_channel *peer;
2703 struct ast_channel *which;
2704 struct callattempt *lpeer;
2705 struct member *member;
2706 struct ast_app *app;
2707 int res = 0, bridge = 0;
2710 char *announce = NULL;
2713 time_t now = time(NULL);
2714 struct ast_bridge_config bridge_config;
2715 char nondataquality = 1;
2716 char *agiexec = NULL;
2717 char *macroexec = NULL;
2718 char *gosubexec = NULL;
2720 const char *monitorfilename;
2721 const char *monitor_exec;
2722 const char *monitor_options;
2723 char tmpid[256], tmpid2[256];
2724 char meid[1024], meid2[1024];
2725 char mixmonargs[1512];
2726 struct ast_app *mixmonapp = NULL;
2729 int forwardsallowed = 1;
2730 int callcompletedinsl;
2731 struct ao2_iterator memi;
2732 struct ast_datastore *datastore;
2734 ast_channel_lock(qe->chan);
2735 datastore = ast_channel_datastore_find(qe->chan, &dialed_interface_info, NULL);
2736 ast_channel_unlock(qe->chan);
2738 memset(&bridge_config, 0, sizeof(bridge_config));
2743 for (; options && *options; options++)
2746 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
2749 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
2752 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
2755 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
2761 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
2764 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
2767 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_PARKCALL);
2770 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_PARKCALL);
2773 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY || qe->parent->strategy == QUEUE_STRATEGY_LINEAR)
2776 *tries = qe->parent->membercount;
2780 forwardsallowed = 0;
2783 ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMIXMON);
2786 ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMIXMON);
2791 /* Hold the lock while we setup the outgoing calls */
2794 ao2_lock(qe->parent);
2795 ast_debug(1, "%s is trying to call a queue member.\n",
2797 ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
2798 if (!ast_strlen_zero(qe->announce))
2799 announce = qe->announce;
2800 if (!ast_strlen_zero(announceoverride))
2801 announce = announceoverride;
2803 memi = ao2_iterator_init(qe->parent->members, 0);
2804 while ((cur = ao2_iterator_next(&memi))) {
2805 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
2806 struct ast_dialed_interface *di;
2807 AST_LIST_HEAD(, ast_dialed_interface) *dialed_interfaces;
2810 ao2_unlock(qe->parent);
2816 if (!(datastore = ast_channel_datastore_alloc(&dialed_interface_info, NULL))) {
2818 ao2_unlock(qe->parent);
2824 datastore->inheritance = DATASTORE_INHERIT_FOREVER;
2825 if (!(dialed_interfaces = ast_calloc(1, sizeof(*dialed_interfaces)))) {
2827 ao2_unlock(&qe->parent);
2833 datastore->data = dialed_interfaces;
2834 AST_LIST_HEAD_INIT(dialed_interfaces);
2836 ast_channel_lock(qe->chan);
2837 ast_channel_datastore_add(qe->chan, datastore);
2838 ast_channel_unlock(qe->chan);
2840 dialed_interfaces = datastore->data;
2842 AST_LIST_LOCK(dialed_interfaces);
2843 AST_LIST_TRAVERSE(dialed_interfaces, di, list) {
2844 if (!strcasecmp(cur->interface, di->interface)) {
2845 ast_log(LOG_DEBUG, "Skipping dialing interface '%s' since it has already been dialed\n",
2850 AST_LIST_UNLOCK(dialed_interfaces);
2857 /* It is always ok to dial a Local interface. We only keep track of
2858 * which "real" interfaces have been dialed. The Local channel will
2859 * inherit this list so that if it ends up dialing a real interface,
2860 * it won't call one that has already been called. */
2861 if (strncasecmp(cur->interface, "Local/", 6)) {
2862 if (!(di = ast_calloc(1, sizeof(*di) + strlen(cur->interface)))) {
2864 ao2_unlock(qe->parent);
2870 strcpy(di->interface, cur->interface);
2872 AST_LIST_LOCK(dialed_interfaces);
2873 AST_LIST_INSERT_TAIL(dialed_interfaces, di, list);
2874 AST_LIST_UNLOCK(dialed_interfaces);
2877 tmp->stillgoing = -1;
2879 tmp->oldstatus = cur->status;
2880 tmp->lastcall = cur->lastcall;
2881 tmp->lastqueue = cur->lastqueue;
2882 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
2883 /* Special case: If we ring everyone, go ahead and ring them, otherwise
2884 just calculate their metric for the appropriate strategy */
2885 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
2886 /* Put them in the list of outgoing thingies... We're ready now.
2887 XXX If we're forcibly removed, these outgoing calls won't get
2889 tmp->q_next = outgoing;
2891 /* If this line is up, don't try anybody else */
2892 if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
2899 if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
2900 to = (qe->expire - now) * 1000;
2902 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
2905 ring_one(qe, outgoing, &numbusies);
2906 ao2_unlock(qe->parent);
2909 lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
2911 ast_channel_datastore_remove(qe->chan, datastore);
2912 ast_channel_datastore_free(datastore);
2914 ao2_lock(qe->parent);
2915 if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
2916 store_next_rr(qe, outgoing);
2918 if (qe->parent->strategy == QUEUE_STRATEGY_LINEAR) {
2919 store_next_lin(qe, outgoing);
2921 ao2_unlock(qe->parent);
2922 peer = lpeer ? lpeer->chan : NULL;
2926 /* Must gotten hung up */
2929 /* User exited by pressing a digit */
2933 ast_debug(1, "%s: Nobody answered.\n", qe->chan->name);
2934 } else { /* peer is valid */
2935 /* Ah ha! Someone answered within the desired timeframe. Of course after this
2936 we will always return with -1 so that it is hung up properly after the
2939 if (!strcmp(qe->chan->tech->type, "Zap"))
2940 ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2941 if (!strcmp(peer->tech->type, "Zap"))
2942 ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2943 /* Update parameters for the queue */
2945 recalc_holdtime(qe, (now - qe->start));
2946 ao2_lock(qe->parent);
2947 callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
2948 ao2_unlock(qe->parent);
2949 member = lpeer->member;
2950 /* Increment the refcount for this member, since we're going to be using it for awhile in here. */
2952 hangupcalls(outgoing, peer);
2954 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
2957 res2 = ast_autoservice_start(qe->chan);
2959 if (qe->parent->memberdelay) {
2960 ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
2961 res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
2963 if (!res2 && announce) {
2964 play_file(peer, announce);
2966 if (!res2 && qe->parent->reportholdtime) {
2967 if (!play_file(peer, qe->parent->sound_reporthold)) {
2971 holdtime = abs((now - qe->start) / 60);
2973 play_file(peer, qe->parent->sound_lessthan);
2974 ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
2976 ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
2977 play_file(peer, qe->parent->sound_minutes);
2981 res2 |= ast_autoservice_stop(qe->chan);
2982 if (ast_check_hangup(peer)) {
2983 /* Agent must have hung up */
2984 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
2985 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
2986 record_abandoned(qe);
2987 if (qe->parent->eventwhencalled)
2988 manager_event(EVENT_FLAG_AGENT, "AgentDump",
2993 "MemberName: %s\r\n"
2995 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2996 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2998 ao2_ref(member, -1);
3001 /* Caller must have hung up just before being connected*/
3002 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
3003 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
3004 record_abandoned(qe);
3006 ao2_ref(member, -1);
3010 /* Stop music on hold */
3012 ast_indicate(qe->chan,-1);
3014 ast_moh_stop(qe->chan);
3015 /* If appropriate, log that we have a destination channel */
3017 ast_cdr_setdestchan(qe->chan->cdr, peer->name);
3018 /* Make sure channels are compatible */
3019 res = ast_channel_make_compatible(qe->chan, peer);
3021 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
3022 ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
3023 record_abandoned(qe);
3025 ao2_ref(member, -1);
3029 /* Play announcement to the caller telling it's his turn if defined */
3030 if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
3031 if (play_file(qe->chan, qe->parent->sound_callerannounce))
3032 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
3035 ao2_lock(qe->parent);
3036 /* if setinterfacevar is defined, make member variables available to the channel */
3037 /* use pbx_builtin_setvar to set a load of variables with one call */
3038 if (qe->parent->setinterfacevar) {
3039 snprintf(interfacevar,sizeof(interfacevar), "MEMBERINTERFACE=%s|MEMBERNAME=%s|MEMBERCALLS=%d|MEMBERLASTCALL=%ld|MEMBERPENALTY=%d|MEMBERDYNAMIC=%d|MEMBERREALTIME=%d",
3040 member->interface, member->membername, member->calls, (long)member->lastcall, member->penalty, member->dynamic, member->realtime);
3041 pbx_builtin_setvar(qe->chan, interfacevar);
3044 /* if setqueueentryvar is defined, make queue entry (i.e. the caller) variables available to the channel */
3045 /* use pbx_builtin_setvar to set a load of variables with one call */
3046 if (qe->parent->setqueueentryvar) {
3047 snprintf(interfacevar,sizeof(interfacevar), "QEHOLDTIME=%ld|QEORIGINALPOS=%d",
3048 (long) time(NULL) - qe->start, qe->opos);
3049 pbx_builtin_setvar(qe->chan, interfacevar);
3052 /* try to set queue variables if configured to do so*/
3053 set_queue_variables(qe);
3054 ao2_unlock(qe->parent);
3056 /* Begin Monitoring */
3057 if (qe->parent->monfmt && *qe->parent->monfmt) {
3058 if (!qe->parent->montype) {
3059 ast_debug(1, "Starting Monitor as requested.\n");
3060 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
3061 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
3065 if (monitorfilename)
3066 ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT);
3067 else if (qe->chan->cdr)
3068 ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1, X_REC_IN | X_REC_OUT);
3070 /* Last ditch effort -- no CDR, make up something */
3071 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
3072 ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT);
3075 ast_debug(1, "Starting MixMonitor as requested.\n");
3076 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
3077 if (!monitorfilename) {
3079 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid));
3081 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
3083 const char *m = monitorfilename;
3084 for (p = tmpid2; p < tmpid2 + sizeof(tmpid2) - 1; p++, m++) {
3087 if (*(m + 1) == '{')
3099 if (p == tmpid2 + sizeof(tmpid2))
3100 tmpid2[sizeof(tmpid2) - 1] = '\0';
3102 pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
3105 monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
3106 monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
3109 const char *m = monitor_exec;
3110 for (p = meid2; p < meid2 + sizeof(meid2) - 1; p++, m++) {
3113 if (*(m + 1) == '{')
3125 if (p == meid2 + sizeof(meid2))
3126 meid2[sizeof(meid2) - 1] = '\0';
3128 pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
3131 snprintf(tmpid2, sizeof(tmpid2), "%s.%s", tmpid, qe->parent->monfmt);
3133 mixmonapp = pbx_findapp("MixMonitor");
3135 if (!monitor_options)
3136 monitor_options = "";
3139 if (!ast_strlen_zero(monitor_exec))
3140 snprintf(mixmonargs, sizeof(mixmonargs), "%s,b%s,%s", tmpid2, monitor_options, monitor_exec);
3142 snprintf(mixmonargs, sizeof(mixmonargs), "%s,b%s", tmpid2, monitor_options);
3144 ast_debug(1, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
3145 /* We purposely lock the CDR so that pbx_exec does not update the application data */
3147 ast_set_flag(qe->chan->cdr, AST_CDR_FLAG_LOCKED);
3148 ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
3150 ast_clear_flag(qe->chan->cdr, AST_CDR_FLAG_LOCKED);
3153 ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
3157 /* Drop out of the queue at this point, to prepare for next caller */
3159 if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
3160 ast_debug(1, "app_queue: sendurl=%s.\n", url);
3161 ast_channel_sendurl(peer, url);
3164 /* run a macro for this connection if defined. The macro simply returns, no action is taken on the result */
3165 /* use macro from dialplan if passed as a option, otherwise use the default queue macro */
3166 if (!ast_strlen_zero(macro)) {
3167 macroexec = ast_strdupa(macro);
3169 if (qe->parent->membermacro)
3170 macroexec = ast_strdupa(qe->parent->membermacro);
3173 if (!ast_strlen_zero(macroexec)) {
3174 ast_debug(1, "app_queue: macro=%s.\n", macroexec);
3176 res = ast_autoservice_start(qe->chan);
3178 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
3182 app = pbx_findapp("Macro");
3185 res = pbx_exec(qe->chan, app, macroexec);
3186 ast_debug(1, "Macro exited with status %d\n", res);
3189 ast_log(LOG_ERROR, "Could not find application Macro\n");
3193 if (ast_autoservice_stop(qe->chan) < 0) {
3194 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
3199 /* run a gosub for this connection if defined. The gosub simply returns, no action is taken on the result */
3200 /* use gosub from dialplan if passed as a option, otherwise use the default queue gosub */
3201 if (!ast_strlen_zero(gosub)) {
3202 gosubexec = ast_strdupa(gosub);
3204 if (qe->parent->membergosub)
3205 gosubexec = ast_strdupa(qe->parent->membergosub);
3208 if (!ast_strlen_zero(gosubexec)) {
3210 ast_log(LOG_DEBUG, "app_queue: gosub=%s.\n", gosubexec);
3212 res = ast_autoservice_start(qe->chan);
3214 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
3218 app = pbx_findapp("Gosub");
3221 char *gosub_args, *gosub_argstart;
3223 /* Set where we came from */
3224 ast_copy_string(qe->chan->context, "app_dial_gosub_virtual_context", sizeof(qe->chan->context));
3225 ast_copy_string(qe->chan->exten, "s", sizeof(qe->chan->exten));
3226 qe->chan->priority = 0;
3228 gosub_argstart = strchr(gosubexec, ',');
3229 if (gosub_argstart) {
3230 *gosub_argstart = 0;
3231 asprintf(&gosub_args, "%s,s,1(%s)", gosubexec, gosub_argstart + 1);
3232 *gosub_argstart = '|';
3234 asprintf(&gosub_args, "%s,s,1", gosubexec);
3237 res = pbx_exec(qe->chan, app, gosub_args);
3238 ast_pbx_run(qe->chan);
3241 ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res);
3243 ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
3247 ast_log(LOG_ERROR, "Could not find application Gosub\n");
3251 if (ast_autoservice_stop(qe->chan) < 0) {
3252 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
3257 if (!ast_strlen_zero(agi)) {
3258 ast_debug(1, "app_queue: agi=%s.\n", agi);
3259 app = pbx_findapp("agi");
3261 agiexec = ast_strdupa(agi);
3262 ret = pbx_exec(qe->chan, app, agiexec);
3264 ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
3266 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s|%ld", (long) time(NULL) - qe->start, peer->uniqueid,
3267 (long)(orig - to > 0 ? (orig - to) / 1000 : 0));
3268 if (update_cdr && qe->chan->cdr)
3269 ast_copy_string(qe->chan->cdr->dstchannel, member->membername, sizeof(qe->chan->cdr->dstchannel));
3270 if (qe->parent->eventwhencalled)
3271 manager_event(EVENT_FLAG_AGENT, "AgentConnect",
3276 "MemberName: %s\r\n"
3278 "BridgedChannel: %s\r\n"
3281 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
3282 (long) time(NULL) - qe->start, peer->uniqueid, (long)(orig - to > 0 ? (orig - to) / 1000 : 0),
3283 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
3284 ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
3285 ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
3288 bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
3290 if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
3291 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "TRANSFER", "%s|%s|%ld|%ld",
3292 qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
3293 (long) (time(NULL) - callstart));
3294 send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
3295 } else if (ast_check_hangup(qe->chan)) {
3296 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETECALLER", "%ld|%ld|%d",
3297 (long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
3298 send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), CALLER);
3300 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "COMPLETEAGENT", "%ld|%ld|%d",
3301 (long) (callstart - qe->start), (long) (time(NULL) - callstart), qe->opos);
3302 send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), AGENT);
3305 if (bridge != AST_PBX_NO_HANGUP_PEER)
3307 update_queue(qe->parent, member, callcompletedinsl);
3308 res = bridge ? bridge : 1;
3309 ao2_ref(member, -1);
3312 hangupcalls(outgoing, NULL);
3317 static int wait_a_bit(struct queue_ent *qe)
3319 /* Don't need to hold the lock while we setup the outgoing calls */
3320 int retrywait = qe->parent->retry * 1000;
3322 int res = ast_waitfordigit(qe->chan, retrywait);
3323 if (res > 0 && !valid_exit(qe, res))
3329 static struct member *interface_exists(struct call_queue *q, const char *interface)