Fix a missing unref of a member struct. This was pointed out by Marta. Thanks!
[asterisk/asterisk.git] / apps / app_queue.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 1999 - 2006, Digium, Inc.
5  *
6  * Mark Spencer <markster@digium.com>
7  *
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.
13  *
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.
17  */
18
19 /*! \file
20  *
21  * \brief True call queues with optional send URL on answer
22  *
23  * \author Mark Spencer <markster@digium.com>
24  *
25  * \arg Config in \ref Config_qu queues.conf
26  *
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>
31  *
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.
37  *
38  * \note 2004-06-04: Priorities in queues added by inAccess Networks (work funded by Hellas On Line (HOL) www.hol.gr).
39  *
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
47  *
48  * Patch Version 1.07 2003-12-24 01
49  *
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>
52  *
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>
55  *
56  * \ingroup applications
57  */
58
59 #include "asterisk.h"
60
61 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
62
63 #include <stdlib.h>
64 #include <errno.h>
65 #include <unistd.h>
66 #include <string.h>
67 #include <stdlib.h>
68 #include <stdio.h>
69 #include <sys/time.h>
70 #include <sys/signal.h>
71 #include <netinet/in.h>
72
73 #include "asterisk/lock.h"
74 #include "asterisk/file.h"
75 #include "asterisk/logger.h"
76 #include "asterisk/channel.h"
77 #include "asterisk/pbx.h"
78 #include "asterisk/options.h"
79 #include "asterisk/app.h"
80 #include "asterisk/linkedlists.h"
81 #include "asterisk/module.h"
82 #include "asterisk/translate.h"
83 #include "asterisk/say.h"
84 #include "asterisk/features.h"
85 #include "asterisk/musiconhold.h"
86 #include "asterisk/cli.h"
87 #include "asterisk/manager.h"
88 #include "asterisk/config.h"
89 #include "asterisk/monitor.h"
90 #include "asterisk/utils.h"
91 #include "asterisk/causes.h"
92 #include "asterisk/astdb.h"
93 #include "asterisk/devicestate.h"
94 #include "asterisk/stringfields.h"
95 #include "asterisk/event.h"
96 #include "asterisk/astobj2.h"
97
98 enum {
99         QUEUE_STRATEGY_RINGALL = 0,
100         QUEUE_STRATEGY_LEASTRECENT,
101         QUEUE_STRATEGY_FEWESTCALLS,
102         QUEUE_STRATEGY_RANDOM,
103         QUEUE_STRATEGY_RRMEMORY
104 };
105
106 static struct strategy {
107         int strategy;
108         char *name;
109 } strategies[] = {
110         { QUEUE_STRATEGY_RINGALL, "ringall" },
111         { QUEUE_STRATEGY_LEASTRECENT, "leastrecent" },
112         { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" },
113         { QUEUE_STRATEGY_RANDOM, "random" },
114         { QUEUE_STRATEGY_RRMEMORY, "rrmemory" },
115 };
116
117 #define DEFAULT_RETRY           5
118 #define DEFAULT_TIMEOUT         15
119 #define RECHECK                 1               /* Recheck every second to see we we're at the top yet */
120 #define MAX_PERIODIC_ANNOUNCEMENTS 10 /* The maximum periodic announcements we can have */
121 #define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 /* The minimum number of seconds between position announcements
122                                              The default value of 15 provides backwards compatibility */
123
124 #define RES_OKAY        0               /* Action completed */
125 #define RES_EXISTS      (-1)            /* Entry already exists */
126 #define RES_OUTOFMEMORY (-2)            /* Out of memory */
127 #define RES_NOSUCHQUEUE (-3)            /* No such queue */
128
129 static char *app = "Queue";
130
131 static char *synopsis = "Queue a call for a call queue";
132
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 "  In addition to transferring the call, a call may be parked and then picked\n"
153 "up by another user.\n"
154 "  The optional URL will be sent to the called party if the channel supports\n"
155 "it.\n"
156 "  The optional AGI parameter will setup an AGI script to be executed on the \n"
157 "calling party's channel once they are connected to a queue member.\n"
158 "  The optional macro parameter will run a macro on the \n"
159 "calling party's channel once they are connected to a queue member.\n"
160 "  The optional gosub parameter will run a gosub on the \n"
161 "calling party's channel once they are connected to a queue member.\n"
162 "  The timeout will cause the queue to fail out after a specified number of\n"
163 "seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
164 "  This application sets the following channel variable upon completion:\n"
165 "      QUEUESTATUS    The status of the call as a text string, one of\n"
166 "             TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL | CONTINUE\n";
167
168 static char *app_aqm = "AddQueueMember" ;
169 static char *app_aqm_synopsis = "Dynamically adds queue members" ;
170 static char *app_aqm_descrip =
171 "   AddQueueMember(queuename[,interface[,penalty[,options[,membername]]]]):\n"
172 "Dynamically adds interface to an existing queue.\n"
173 "If the interface is already in the queue it will return an error.\n"
174 "  This application sets the following channel variable upon completion:\n"
175 "     AQMSTATUS    The status of the attempt to add a queue member as a \n"
176 "                     text string, one of\n"
177 "           ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
178 "Example: AddQueueMember(techsupport,SIP/3000)\n"
179 "";
180
181 static char *app_rqm = "RemoveQueueMember" ;
182 static char *app_rqm_synopsis = "Dynamically removes queue members" ;
183 static char *app_rqm_descrip =
184 "   RemoveQueueMember(queuename[,interface[,options]]):\n"
185 "Dynamically removes interface to an existing queue\n"
186 "If the interface is NOT in the queue it will return an error.\n"
187 "  This application sets the following channel variable upon completion:\n"
188 "     RQMSTATUS      The status of the attempt to remove a queue member as a\n"
189 "                     text string, one of\n"
190 "           REMOVED | NOTINQUEUE | NOSUCHQUEUE \n"
191 "Example: RemoveQueueMember(techsupport,SIP/3000)\n"
192 "";
193
194 static char *app_pqm = "PauseQueueMember" ;
195 static char *app_pqm_synopsis = "Pauses a queue member" ;
196 static char *app_pqm_descrip =
197 "   PauseQueueMember([queuename],interface[,options[,reason]]):\n"
198 "Pauses (blocks calls for) a queue member.\n"
199 "The given interface will be paused in the given queue.  This prevents\n"
200 "any calls from being sent from the queue to the interface until it is\n"
201 "unpaused with UnpauseQueueMember or the manager interface.  If no\n"
202 "queuename is given, the interface is paused in every queue it is a\n"
203 "member of. The application will fail if the interface is not found.\n"
204 "The reason string is entirely optional and is used to add extra information\n"
205 "to the appropriate queue_log entries and manager events.\n"
206 "  This application sets the following channel variable upon completion:\n"
207 "     PQMSTATUS      The status of the attempt to pause a queue member as a\n"
208 "                     text string, one of\n"
209 "           PAUSED | NOTFOUND\n"
210 "Example: PauseQueueMember(,SIP/3000)\n";
211
212 static char *app_upqm = "UnpauseQueueMember" ;
213 static char *app_upqm_synopsis = "Unpauses a queue member" ;
214 static char *app_upqm_descrip =
215 "   UnpauseQueueMember([queuename],interface[,options[,reason]]):\n"
216 "Unpauses (resumes calls to) a queue member.\n"
217 "This is the counterpart to PauseQueueMember and operates exactly the\n"
218 "same way, except it unpauses instead of pausing the given interface.\n"
219 "The reason string is entirely optional and is used to add extra information\n"
220 "to the appropriate queue_log entries and manager events.\n"
221 "  This application sets the following channel variable upon completion:\n"
222 "     UPQMSTATUS       The status of the attempt to unpause a queue \n"
223 "                      member as a text string, one of\n"
224 "            UNPAUSED | NOTFOUND\n"
225 "Example: UnpauseQueueMember(,SIP/3000)\n";
226
227 static char *app_ql = "QueueLog" ;
228 static char *app_ql_synopsis = "Writes to the queue_log" ;
229 static char *app_ql_descrip =
230 "   QueueLog(queuename,uniqueid,agent,event[,additionalinfo]):\n"
231 "Allows you to write your own events into the queue log\n"
232 "Example: QueueLog(101,${UNIQUEID},${AGENT},WENTONBREAK,600)\n";
233
234 /*! \brief Persistent Members astdb family */
235 static const char *pm_family = "Queue/PersistentMembers";
236 /* The maximum length of each persistent member queue database entry */
237 #define PM_MAX_LEN 8192
238
239 /*! \brief queues.conf [general] option */
240 static int queue_keep_stats = 0;
241
242 /*! \brief queues.conf [general] option */
243 static int queue_persistent_members = 0;
244
245 /*! \brief queues.conf per-queue weight option */
246 static int use_weight = 0;
247
248 /*! \brief queues.conf [general] option */
249 static int autofill_default = 0;
250
251 /*! \brief queues.conf [general] option */
252 static int montype_default = 0;
253
254 /*! \brief Subscription to device state change events */
255 static struct ast_event_sub *device_state_sub;
256
257 enum queue_result {
258         QUEUE_UNKNOWN = 0,
259         QUEUE_TIMEOUT = 1,
260         QUEUE_JOINEMPTY = 2,
261         QUEUE_LEAVEEMPTY = 3,
262         QUEUE_JOINUNAVAIL = 4,
263         QUEUE_LEAVEUNAVAIL = 5,
264         QUEUE_FULL = 6,
265         QUEUE_CONTINUE = 7,
266 };
267
268 const struct {
269         enum queue_result id;
270         char *text;
271 } queue_results[] = {
272         { QUEUE_UNKNOWN, "UNKNOWN" },
273         { QUEUE_TIMEOUT, "TIMEOUT" },
274         { QUEUE_JOINEMPTY,"JOINEMPTY" },
275         { QUEUE_LEAVEEMPTY, "LEAVEEMPTY" },
276         { QUEUE_JOINUNAVAIL, "JOINUNAVAIL" },
277         { QUEUE_LEAVEUNAVAIL, "LEAVEUNAVAIL" },
278         { QUEUE_FULL, "FULL" },
279         { QUEUE_CONTINUE, "CONTINUE" },
280 };
281
282 /*! \brief We define a custom "local user" structure because we
283    use it not only for keeping track of what is in use but
284    also for keeping track of who we're dialing. */
285
286 struct callattempt {
287         struct callattempt *q_next;
288         struct ast_channel *chan;
289         char interface[256];
290         int stillgoing;
291         int metric;
292         int oldstatus;
293         time_t lastcall;
294         struct member *member;
295 };
296
297
298 struct queue_ent {
299         struct call_queue *parent;          /*!< What queue is our parent */
300         char moh[80];                       /*!< Name of musiconhold to be used */
301         char announce[80];                  /*!< Announcement to play for member when call is answered */
302         char context[AST_MAX_CONTEXT];      /*!< Context when user exits queue */
303         char digits[AST_MAX_EXTENSION];     /*!< Digits entered while in queue */
304         int valid_digits;                   /*!< Digits entered correspond to valid extension. Exited */
305         int pos;                            /*!< Where we are in the queue */
306         int prio;                           /*!< Our priority */
307         int last_pos_said;                  /*!< Last position we told the user */
308         time_t last_periodic_announce_time; /*!< The last time we played a periodic announcement */
309         int last_periodic_announce_sound;   /*!< The last periodic announcement we made */
310         time_t last_pos;                    /*!< Last time we told the user their position */
311         int opos;                           /*!< Where we started in the queue */
312         int handled;                        /*!< Whether our call was handled */
313         int max_penalty;                    /*!< Limit the members that can take this call to this penalty or lower */
314         time_t start;                       /*!< When we started holding */
315         time_t expire;                      /*!< When this entry should expire (time out of queue) */
316         struct ast_channel *chan;           /*!< Our channel */
317         struct queue_ent *next;             /*!< The next queue entry */
318 };
319
320 struct member {
321         char interface[80];                 /*!< Technology/Location */
322         char membername[80];                /*!< Member name to use in queue logs */
323         int penalty;                        /*!< Are we a last resort? */
324         int calls;                          /*!< Number of calls serviced by this member */
325         int dynamic;                        /*!< Are we dynamically added? */
326         int realtime;                       /*!< Is this member realtime? */
327         int status;                         /*!< Status of queue member */
328         int paused;                         /*!< Are we paused (not accepting calls)? */
329         time_t lastcall;                    /*!< When last successful call was hungup */
330         unsigned int dead:1;                /*!< Used to detect members deleted in realtime */
331         unsigned int delme:1;               /*!< Flag to delete entry on reload */
332 };
333
334 struct member_interface {
335         char interface[80];
336         AST_LIST_ENTRY(member_interface) list;    /*!< Next call queue */
337 };
338
339 static AST_LIST_HEAD_STATIC(interfaces, member_interface);
340
341 /* values used in multi-bit flags in call_queue */
342 #define QUEUE_EMPTY_NORMAL 1
343 #define QUEUE_EMPTY_STRICT 2
344 #define QUEUE_EMPTY_LOOSE 3
345 #define ANNOUNCEHOLDTIME_ALWAYS 1
346 #define ANNOUNCEHOLDTIME_ONCE 2
347 #define QUEUE_EVENT_VARIABLES 3
348
349 struct call_queue {
350         ast_mutex_t lock;       
351         char name[80];                      /*!< Name */
352         char moh[80];                       /*!< Music On Hold class to be used */
353         char announce[80];                  /*!< Announcement to play when call is answered */
354         char context[AST_MAX_CONTEXT];      /*!< Exit context */
355         unsigned int monjoin:1;
356         unsigned int dead:1;
357         unsigned int joinempty:2;
358         unsigned int eventwhencalled:2;
359         unsigned int leavewhenempty:2;
360         unsigned int ringinuse:1;
361         unsigned int setinterfacevar:1;
362         unsigned int setqueuevar:1;
363         unsigned int setqueueentryvar:1;
364         unsigned int reportholdtime:1;
365         unsigned int wrapped:1;
366         unsigned int timeoutrestart:1;
367         unsigned int announceholdtime:2;
368         unsigned int strategy:3;
369         unsigned int maskmemberstatus:1;
370         unsigned int realtime:1;
371         int announcefrequency;              /*!< How often to announce their position */
372         int minannouncefrequency;           /*!< The minimum number of seconds between position announcements (def. 15) */
373         int periodicannouncefrequency;      /*!< How often to play periodic announcement */
374         int roundingseconds;                /*!< How many seconds do we round to? */
375         int holdtime;                       /*!< Current avg holdtime, based on recursive boxcar filter */
376         int callscompleted;                 /*!< Number of queue calls completed */
377         int callsabandoned;                 /*!< Number of queue calls abandoned */
378         int servicelevel;                   /*!< seconds setting for servicelevel*/
379         int callscompletedinsl;             /*!< Number of calls answered with servicelevel*/
380         char monfmt[8];                     /*!< Format to use when recording calls */
381         int montype;                        /*!< Monitor type  Monitor vs. MixMonitor */
382         char membermacro[32];               /*!< Macro to run upon member connection */
383         char membergosub[32];               /*!< Gosub to run upon member connection */
384         char sound_next[80];                /*!< Sound file: "Your call is now first in line" (def. queue-youarenext) */
385         char sound_thereare[80];            /*!< Sound file: "There are currently" (def. queue-thereare) */
386         char sound_calls[80];               /*!< Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
387         char sound_holdtime[80];            /*!< Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
388         char sound_minutes[80];             /*!< Sound file: "minutes." (def. queue-minutes) */
389         char sound_lessthan[80];            /*!< Sound file: "less-than" (def. queue-lessthan) */
390         char sound_seconds[80];             /*!< Sound file: "seconds." (def. queue-seconds) */
391         char sound_thanks[80];              /*!< Sound file: "Thank you for your patience." (def. queue-thankyou) */
392         char sound_callerannounce[80];      /*!< Sound file: Custom announce for caller, no default */
393         char sound_reporthold[80];          /*!< Sound file: "Hold time" (def. queue-reporthold) */
394         char sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS][80];/*!< Sound files: Custom announce, no default */
395
396         int count;                          /*!< How many entries */
397         int maxlen;                         /*!< Max number of entries */
398         int wrapuptime;                     /*!< Wrapup Time */
399
400         int retry;                          /*!< Retry calling everyone after this amount of time */
401         int timeout;                        /*!< How long to wait for an answer */
402         int weight;                         /*!< Respective weight */
403         int autopause;                      /*!< Auto pause queue members if they fail to answer */
404
405         /* Queue strategy things */
406         int rrpos;                          /*!< Round Robin - position */
407         int memberdelay;                    /*!< Seconds to delay connecting member to caller */
408         int autofill;                       /*!< Ignore the head call status and ring an available agent */
409         
410         struct ao2_container *members;             /*!< Head of the list of members */
411         /*! 
412          * \brief Number of members _logged in_
413          * \note There will be members in the members container that are not logged
414          *       in, so this can not simply be replaced with ao2_container_count(). 
415          */
416         int membercount;
417         struct queue_ent *head;             /*!< Head of the list of callers */
418         AST_LIST_ENTRY(call_queue) list;    /*!< Next call queue */
419 };
420
421 static AST_LIST_HEAD_STATIC(queues, call_queue);
422
423 static void update_realtime_members(struct call_queue *q);
424 static int set_member_paused(const char *queuename, const char *interface, const char *reason, int paused);
425
426 static void set_queue_result(struct ast_channel *chan, enum queue_result res)
427 {
428         int i;
429
430         for (i = 0; i < sizeof(queue_results) / sizeof(queue_results[0]); i++) {
431                 if (queue_results[i].id == res) {
432                         pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
433                         return;
434                 }
435         }
436 }
437
438 static char *int2strat(int strategy)
439 {
440         int x;
441
442         for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
443                 if (strategy == strategies[x].strategy)
444                         return strategies[x].name;
445         }
446
447         return "<unknown>";
448 }
449
450 static int strat2int(const char *strategy)
451 {
452         int x;
453
454         for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
455                 if (!strcasecmp(strategy, strategies[x].name))
456                         return strategies[x].strategy;
457         }
458
459         return -1;
460 }
461
462 static void set_queue_variables(struct queue_ent *qe)
463 {
464
465         char interfacevar[256]="";
466         float sl = 0;
467         
468         if (qe->parent->setqueuevar) {
469         sl = 0;
470         if (qe->parent->callscompleted > 0) 
471                 sl = 100 * ((float) qe->parent->callscompletedinsl / (float) qe->parent->callscompleted);
472
473         snprintf(interfacevar,sizeof(interfacevar),
474                 "QUEUEMAX=%d|QUEUESTRATEGY=%s|QUEUECALLS=%d|QUEUEHOLDTIME=%d|QUEUECOMPLETED=%d|QUEUEABANDONED=%d|QUEUESRVLEVEL=%d|QUEUESRVLEVELPERF=%2.1f",
475                 qe->parent->maxlen, int2strat(qe->parent->strategy), qe->parent->count, qe->parent->holdtime, qe->parent->callscompleted,
476                 qe->parent->callsabandoned,  qe->parent->servicelevel, sl);
477         
478         pbx_builtin_setvar(qe->chan, interfacevar); 
479         }
480 }
481
482 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
483 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
484 {
485         struct queue_ent *cur;
486
487         if (!q || !new)
488                 return;
489         if (prev) {
490                 cur = prev->next;
491                 prev->next = new;
492         } else {
493                 cur = q->head;
494                 q->head = new;
495         }
496         new->next = cur;
497         new->parent = q;
498         new->pos = ++(*pos);
499         new->opos = *pos;
500 }
501
502 enum queue_member_status {
503         QUEUE_NO_MEMBERS,
504         QUEUE_NO_REACHABLE_MEMBERS,
505         QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
506         QUEUE_NORMAL
507 };
508
509 static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty)
510 {
511         struct member *member;
512         struct ao2_iterator mem_iter;
513         enum queue_member_status result = QUEUE_NO_MEMBERS;
514
515         ast_mutex_lock(&q->lock);
516         mem_iter = ao2_iterator_init(q->members, 0);
517         for (; (member = ao2_iterator_next(&mem_iter)); ao2_ref(member, -1)) {
518                 if (max_penalty && (member->penalty > max_penalty))
519                         continue;
520
521                 switch (member->status) {
522                 case AST_DEVICE_INVALID:
523                         /* nothing to do */
524                         break;
525                 case AST_DEVICE_UNAVAILABLE:
526                         if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS) 
527                                 result = QUEUE_NO_REACHABLE_MEMBERS;
528                         break;
529                 default:
530                         if (member->paused) {
531                                 result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
532                         } else {
533                                 ast_mutex_unlock(&q->lock);
534                                 ao2_ref(member, -1);
535                                 return QUEUE_NORMAL;
536                         }
537                         break;
538                 }
539         }
540
541         ast_mutex_unlock(&q->lock);
542         return result;
543 }
544
545 struct statechange {
546         AST_LIST_ENTRY(statechange) entry;
547         int state;
548         char dev[0];
549 };
550
551 static void *handle_statechange(struct statechange *sc)
552 {
553         struct call_queue *q;
554         struct member *cur;
555         struct ao2_iterator mem_iter;
556         struct member_interface *curint;
557         char *loc;
558         char *technology;
559
560         technology = ast_strdupa(sc->dev);
561         loc = strchr(technology, '/');
562         if (loc) {
563                 *loc++ = '\0';
564         } else {
565                 return NULL;
566         }
567
568         AST_LIST_LOCK(&interfaces);
569         AST_LIST_TRAVERSE(&interfaces, curint, list) {
570                 char *interface;
571                 char *slash_pos;
572                 interface = ast_strdupa(curint->interface);
573                 if ((slash_pos = strchr(interface, '/')))
574                         if ((slash_pos = strchr(slash_pos + 1, '/')))
575                                 *slash_pos = '\0';
576
577                 if (!strcasecmp(interface, sc->dev))
578                         break;
579         }
580         AST_LIST_UNLOCK(&interfaces);
581
582         if (!curint) {
583                 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));
584                 return NULL;
585         }
586
587         ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
588         AST_LIST_LOCK(&queues);
589         AST_LIST_TRAVERSE(&queues, q, list) {
590                 ast_mutex_lock(&q->lock);
591                 mem_iter = ao2_iterator_init(q->members, 0);
592                 while ((cur = ao2_iterator_next(&mem_iter))) {
593                         char *interface;
594                         char *slash_pos;
595                         interface = ast_strdupa(cur->interface);
596                         if ((slash_pos = strchr(interface, '/')))
597                                 if ((slash_pos = strchr(slash_pos + 1, '/')))
598                                         *slash_pos = '\0';
599
600                         if (strcasecmp(sc->dev, interface)) {
601                                 ao2_ref(cur, -1);
602                                 continue;
603                         }
604
605                         if (cur->status != sc->state) {
606                                 cur->status = sc->state;
607                                 if (q->maskmemberstatus) {
608                                         ao2_ref(cur, -1);
609                                         continue;
610                                 }
611
612                                 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
613                                         "Queue: %s\r\n"
614                                         "Location: %s\r\n"
615                                         "MemberName: %s\r\n"
616                                         "Membership: %s\r\n"
617                                         "Penalty: %d\r\n"
618                                         "CallsTaken: %d\r\n"
619                                         "LastCall: %d\r\n"
620                                         "Status: %d\r\n"
621                                         "Paused: %d\r\n",
622                                         q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime" : "static",
623                                         cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
624                         }
625                         ao2_ref(cur, -1);
626                 }
627                 ast_mutex_unlock(&q->lock);
628         }
629         AST_LIST_UNLOCK(&queues);
630
631         return NULL;
632 }
633
634 /*!
635  * \brief Data used by the device state thread
636  */
637 static struct {
638         /*! Set to 1 to stop the thread */
639         unsigned int stop:1;
640         /*! The device state monitoring thread */
641         pthread_t thread;
642         /*! Lock for the state change queue */
643         ast_mutex_t lock;
644         /*! Condition for the state change queue */
645         ast_cond_t cond;
646         /*! Queue of state changes */
647         AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
648 } device_state = {
649         .thread = AST_PTHREADT_NULL,
650 };
651
652 static void *device_state_thread(void *data)
653 {
654         struct statechange *sc;
655
656         while (!device_state.stop) {
657                 ast_mutex_lock(&device_state.lock);
658                 if (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
659                         ast_cond_wait(&device_state.cond, &device_state.lock);
660                         sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry);
661                 }
662                 ast_mutex_unlock(&device_state.lock);
663
664                 /* Check to see if we were woken up to see the request to stop */
665                 if (device_state.stop)
666                         return NULL;
667
668                 if (!sc)
669                         continue;
670
671                 handle_statechange(sc);
672
673                 free(sc);
674         }
675
676         return NULL;
677 }
678
679 static int statechange_queue(const char *dev, enum ast_device_state state)
680 {
681         struct statechange *sc;
682
683         if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
684                 return 0;
685
686         sc->state = state;
687         strcpy(sc->dev, dev);
688
689         ast_mutex_lock(&device_state.lock);
690         AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
691         ast_cond_signal(&device_state.cond);
692         ast_mutex_unlock(&device_state.lock);
693
694         return 0;
695 }
696
697 static void device_state_cb(const struct ast_event *event, void *unused)
698 {
699         enum ast_device_state state;
700         const char *device;
701
702         state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
703         device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
704
705         if (ast_strlen_zero(device)) {
706                 ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
707                 return;
708         }
709
710         statechange_queue(device, state);
711 }
712
713 static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused)
714 {
715         struct member *cur;
716         
717         if ((cur = ao2_alloc(sizeof(*cur), NULL))) {
718                 cur->penalty = penalty;
719                 cur->paused = paused;
720                 ast_copy_string(cur->interface, interface, sizeof(cur->interface));
721                 ast_copy_string(cur->membername, membername, sizeof(cur->membername));
722                 if (!strchr(cur->interface, '/'))
723                         ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
724                 cur->status = ast_device_state(interface);
725         }
726
727         return cur;
728 }
729
730 static struct call_queue *alloc_queue(const char *queuename)
731 {
732         struct call_queue *q;
733
734         if ((q = ast_calloc(1, sizeof(*q)))) {
735                 ast_mutex_init(&q->lock);
736                 ast_copy_string(q->name, queuename, sizeof(q->name));
737         }
738         return q;
739 }
740
741 static int compress_char(const char c)
742 {
743         if (c < 32)
744                 return 0;
745         else if (c > 96)
746                 return c - 64;
747         else
748                 return c - 32;
749 }
750
751 static int member_hash_fn(const void *obj, const int flags)
752 {
753         const struct member *mem = obj;
754         const char *chname = strchr(mem->interface, '/');
755         int ret = 0, i;
756         if (!chname)
757                 chname = mem->interface;
758         for (i = 0; i < 5 && chname[i]; i++)
759                 ret += compress_char(chname[i]) << (i * 6);
760         return ret;
761 }
762
763 static int member_cmp_fn(void *obj1, void *obj2, int flags)
764 {
765         struct member *mem1 = obj1, *mem2 = obj2;
766         return strcmp(mem1->interface, mem2->interface) ? 0 : CMP_MATCH;
767 }
768
769 static void init_queue(struct call_queue *q)
770 {
771         int i;
772
773         q->dead = 0;
774         q->retry = DEFAULT_RETRY;
775         q->timeout = -1;
776         q->maxlen = 0;
777         q->announcefrequency = 0;
778         q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
779         q->announceholdtime = 0;
780         q->roundingseconds = 0; /* Default - don't announce seconds */
781         q->servicelevel = 0;
782         q->ringinuse = 1;
783         q->setinterfacevar = 0;
784         q->setqueuevar = 0;
785         q->setqueueentryvar = 0;
786         q->autofill = autofill_default;
787         q->montype = montype_default;
788         q->membermacro[0] = '\0';
789         q->membergosub[0] = '\0';
790         q->moh[0] = '\0';
791         q->announce[0] = '\0';
792         q->context[0] = '\0';
793         q->monfmt[0] = '\0';
794         q->periodicannouncefrequency = 0;
795         q->sound_callerannounce[0] = '\0';      /* Default, don't announce the caller that he has been answered */
796         q->members = ao2_container_alloc(37, member_hash_fn, member_cmp_fn);
797         q->membercount = 0;
798         ast_copy_string(q->sound_next, "queue-youarenext", sizeof(q->sound_next));
799         ast_copy_string(q->sound_thereare, "queue-thereare", sizeof(q->sound_thereare));
800         ast_copy_string(q->sound_calls, "queue-callswaiting", sizeof(q->sound_calls));
801         ast_copy_string(q->sound_holdtime, "queue-holdtime", sizeof(q->sound_holdtime));
802         ast_copy_string(q->sound_minutes, "queue-minutes", sizeof(q->sound_minutes));
803         ast_copy_string(q->sound_seconds, "queue-seconds", sizeof(q->sound_seconds));
804         ast_copy_string(q->sound_thanks, "queue-thankyou", sizeof(q->sound_thanks));
805         ast_copy_string(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan));
806         ast_copy_string(q->sound_reporthold, "queue-reporthold", sizeof(q->sound_reporthold));
807         ast_copy_string(q->sound_periodicannounce[0], "queue-periodic-announce", sizeof(q->sound_periodicannounce[0]));
808         for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
809                 q->sound_periodicannounce[i][0]='\0';
810         }
811 }
812
813 static void clear_queue(struct call_queue *q)
814 {
815         q->holdtime = 0;
816         q->callscompleted = 0;
817         q->callsabandoned = 0;
818         q->callscompletedinsl = 0;
819         q->wrapuptime = 0;
820 }
821
822 static int add_to_interfaces(const char *interface)
823 {
824         struct member_interface *curint;
825
826         AST_LIST_LOCK(&interfaces);
827         AST_LIST_TRAVERSE(&interfaces, curint, list) {
828                 if (!strcasecmp(curint->interface, interface))
829                         break;
830         }
831
832         if (curint) {
833                 AST_LIST_UNLOCK(&interfaces);
834                 return 0;
835         }
836
837         ast_debug(1, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
838         
839         if ((curint = ast_calloc(1, sizeof(*curint)))) {
840                 ast_copy_string(curint->interface, interface, sizeof(curint->interface));
841                 AST_LIST_INSERT_HEAD(&interfaces, curint, list);
842         }
843         AST_LIST_UNLOCK(&interfaces);
844
845         return 0;
846 }
847
848 static int interface_exists_global(const char *interface)
849 {
850         struct call_queue *q;
851         struct member *mem, tmpmem;
852         int ret = 0;
853
854         ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
855
856         AST_LIST_LOCK(&queues);
857         AST_LIST_TRAVERSE(&queues, q, list) {
858                 ast_mutex_lock(&q->lock);
859                 if ((mem = ao2_find(q->members, &tmpmem, OBJ_POINTER))) {
860                         ao2_ref(mem, -1);
861                         ret = 1;
862                 }
863                 ast_mutex_unlock(&q->lock);
864                 if (ret)
865                         break;
866         }
867         AST_LIST_UNLOCK(&queues);
868
869         return ret;
870 }
871
872 static int remove_from_interfaces(const char *interface)
873 {
874         struct member_interface *curint;
875
876         AST_LIST_LOCK(&interfaces);
877         AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
878                 if (!strcasecmp(curint->interface, interface)) {
879                         if (!interface_exists_global(interface)) {
880                                 ast_debug(1, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
881                                 AST_LIST_REMOVE_CURRENT(&interfaces, list);
882                                 ast_free(curint);
883                         }
884                         break;
885                 }
886         }
887         AST_LIST_TRAVERSE_SAFE_END;
888         AST_LIST_UNLOCK(&interfaces);
889
890         return 0;
891 }
892
893 static void clear_and_free_interfaces(void)
894 {
895         struct member_interface *curint;
896
897         AST_LIST_LOCK(&interfaces);
898         while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
899                 ast_free(curint);
900         AST_LIST_UNLOCK(&interfaces);
901 }
902
903 /*! \brief Configure a queue parameter.
904 \par
905    For error reporting, line number is passed for .conf static configuration.
906    For Realtime queues, linenum is -1.
907    The failunknown flag is set for config files (and static realtime) to show
908    errors for unknown parameters. It is cleared for dynamic realtime to allow
909    extra fields in the tables. */
910 static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
911 {
912         if (!strcasecmp(param, "musicclass") || 
913                 !strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
914                 ast_copy_string(q->moh, val, sizeof(q->moh));
915         } else if (!strcasecmp(param, "announce")) {
916                 ast_copy_string(q->announce, val, sizeof(q->announce));
917         } else if (!strcasecmp(param, "context")) {
918                 ast_copy_string(q->context, val, sizeof(q->context));
919         } else if (!strcasecmp(param, "timeout")) {
920                 q->timeout = atoi(val);
921                 if (q->timeout < 0)
922                         q->timeout = DEFAULT_TIMEOUT;
923         } else if (!strcasecmp(param, "ringinuse")) {
924                 q->ringinuse = ast_true(val);
925         } else if (!strcasecmp(param, "setinterfacevar")) {
926                 q->setinterfacevar = ast_true(val);
927         } else if (!strcasecmp(param, "setqueuevar")) {
928                 q->setqueuevar = ast_true(val);
929         } else if (!strcasecmp(param, "setqueueentryvar")) {
930                 q->setqueueentryvar = ast_true(val);
931         } else if (!strcasecmp(param, "monitor-join")) {
932                 q->monjoin = ast_true(val);
933         } else if (!strcasecmp(param, "monitor-format")) {
934                 ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
935         } else if (!strcasecmp(param, "membermacro")) {
936                 ast_copy_string(q->membermacro, val, sizeof(q->membermacro));
937         } else if (!strcasecmp(param, "membergosub")) {
938                 ast_copy_string(q->membergosub, val, sizeof(q->membergosub));
939         } else if (!strcasecmp(param, "queue-youarenext")) {
940                 ast_copy_string(q->sound_next, val, sizeof(q->sound_next));
941         } else if (!strcasecmp(param, "queue-thereare")) {
942                 ast_copy_string(q->sound_thereare, val, sizeof(q->sound_thereare));
943         } else if (!strcasecmp(param, "queue-callswaiting")) {
944                 ast_copy_string(q->sound_calls, val, sizeof(q->sound_calls));
945         } else if (!strcasecmp(param, "queue-holdtime")) {
946                 ast_copy_string(q->sound_holdtime, val, sizeof(q->sound_holdtime));
947         } else if (!strcasecmp(param, "queue-minutes")) {
948                 ast_copy_string(q->sound_minutes, val, sizeof(q->sound_minutes));
949         } else if (!strcasecmp(param, "queue-seconds")) {
950                 ast_copy_string(q->sound_seconds, val, sizeof(q->sound_seconds));
951         } else if (!strcasecmp(param, "queue-lessthan")) {
952                 ast_copy_string(q->sound_lessthan, val, sizeof(q->sound_lessthan));
953         } else if (!strcasecmp(param, "queue-thankyou")) {
954                 ast_copy_string(q->sound_thanks, val, sizeof(q->sound_thanks));
955         } else if (!strcasecmp(param, "queue-callerannounce")) {
956                 ast_copy_string(q->sound_callerannounce, val, sizeof(q->sound_callerannounce));
957         } else if (!strcasecmp(param, "queue-reporthold")) {
958                 ast_copy_string(q->sound_reporthold, val, sizeof(q->sound_reporthold));
959         } else if (!strcasecmp(param, "announce-frequency")) {
960                 q->announcefrequency = atoi(val);
961         } else if (!strcasecmp(param, "min-announce-frequency")) {
962                 q->minannouncefrequency = atoi(val);
963                 ast_debug(1, "%s=%s for queue '%s'\n", param, val, q->name);
964         } else if (!strcasecmp(param, "announce-round-seconds")) {
965                 q->roundingseconds = atoi(val);
966                 /* Rounding to any other values just doesn't make sense... */
967                 if (!(q->roundingseconds == 0 || q->roundingseconds == 1 || q->roundingseconds == 5 || q->roundingseconds == 10
968                         || q->roundingseconds == 15 || q->roundingseconds == 20 || q->roundingseconds == 30)) {
969                         if (linenum >= 0) {
970                                 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
971                                         "using 0 instead for queue '%s' at line %d of queues.conf\n",
972                                         val, param, q->name, linenum);
973                         } else {
974                                 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
975                                         "using 0 instead for queue '%s'\n", val, param, q->name);
976                         }
977                         q->roundingseconds=0;
978                 }
979         } else if (!strcasecmp(param, "announce-holdtime")) {
980                 if (!strcasecmp(val, "once"))
981                         q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
982                 else if (ast_true(val))
983                         q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
984                 else
985                         q->announceholdtime = 0;
986         } else if (!strcasecmp(param, "periodic-announce")) {
987                 if (strchr(val, ',')) {
988                         char *s, *buf = ast_strdupa(val);
989                         unsigned int i = 0;
990
991                         while ((s = strsep(&buf, ",|"))) {
992                                 ast_copy_string(q->sound_periodicannounce[i], s, sizeof(q->sound_periodicannounce[i]));
993                                 i++;
994                                 if (i == MAX_PERIODIC_ANNOUNCEMENTS)
995                                         break;
996                         }
997                 } else {
998                         ast_copy_string(q->sound_periodicannounce[0], val, sizeof(q->sound_periodicannounce[0]));
999                 }
1000         } else if (!strcasecmp(param, "periodic-announce-frequency")) {
1001                 q->periodicannouncefrequency = atoi(val);
1002         } else if (!strcasecmp(param, "retry")) {
1003                 q->retry = atoi(val);
1004                 if (q->retry <= 0)
1005                         q->retry = DEFAULT_RETRY;
1006         } else if (!strcasecmp(param, "wrapuptime")) {
1007                 q->wrapuptime = atoi(val);
1008         } else if (!strcasecmp(param, "autofill")) {
1009                 q->autofill = ast_true(val);
1010         } else if (!strcasecmp(param, "monitor-type")) {
1011                 if (!strcasecmp(val, "mixmonitor"))
1012                         q->montype = 1;
1013         } else if (!strcasecmp(param, "autopause")) {
1014                 q->autopause = ast_true(val);
1015         } else if (!strcasecmp(param, "maxlen")) {
1016                 q->maxlen = atoi(val);
1017                 if (q->maxlen < 0)
1018                         q->maxlen = 0;
1019         } else if (!strcasecmp(param, "servicelevel")) {
1020                 q->servicelevel= atoi(val);
1021         } else if (!strcasecmp(param, "strategy")) {
1022                 q->strategy = strat2int(val);
1023                 if (q->strategy < 0) {
1024                         ast_log(LOG_WARNING, "'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
1025                                 val, q->name);
1026                         q->strategy = QUEUE_STRATEGY_RINGALL;
1027                 }
1028         } else if (!strcasecmp(param, "joinempty")) {
1029                 if (!strcasecmp(val, "loose"))
1030                         q->joinempty = QUEUE_EMPTY_LOOSE;
1031                 else if (!strcasecmp(val, "strict"))
1032                         q->joinempty = QUEUE_EMPTY_STRICT;
1033                 else if (ast_true(val))
1034                         q->joinempty = QUEUE_EMPTY_NORMAL;
1035                 else
1036                         q->joinempty = 0;
1037         } else if (!strcasecmp(param, "leavewhenempty")) {
1038                 if (!strcasecmp(val, "loose"))
1039                         q->leavewhenempty = QUEUE_EMPTY_LOOSE;
1040                 else if (!strcasecmp(val, "strict"))
1041                         q->leavewhenempty = QUEUE_EMPTY_STRICT;
1042                 else if (ast_true(val))
1043                         q->leavewhenempty = QUEUE_EMPTY_NORMAL;
1044                 else
1045                         q->leavewhenempty = 0;
1046         } else if (!strcasecmp(param, "eventmemberstatus")) {
1047                 q->maskmemberstatus = !ast_true(val);
1048         } else if (!strcasecmp(param, "eventwhencalled")) {
1049                 if (!strcasecmp(val, "vars")) {
1050                         q->eventwhencalled = QUEUE_EVENT_VARIABLES;
1051                 } else {
1052                         q->eventwhencalled = ast_true(val);
1053                 }
1054         } else if (!strcasecmp(param, "reportholdtime")) {
1055                 q->reportholdtime = ast_true(val);
1056         } else if (!strcasecmp(param, "memberdelay")) {
1057                 q->memberdelay = atoi(val);
1058         } else if (!strcasecmp(param, "weight")) {
1059                 q->weight = atoi(val);
1060                 if (q->weight)
1061                         use_weight++;
1062                 /* With Realtime queues, if the last queue using weights is deleted in realtime,
1063                    we will not see any effect on use_weight until next reload. */
1064         } else if (!strcasecmp(param, "timeoutrestart")) {
1065                 q->timeoutrestart = ast_true(val);
1066         } else if (failunknown) {
1067                 if (linenum >= 0) {
1068                         ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
1069                                 q->name, param, linenum);
1070                 } else {
1071                         ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
1072                 }
1073         }
1074 }
1075
1076 static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str)
1077 {
1078         struct member *m, tmpmem;
1079         int penalty = 0;
1080         int paused  = 0;
1081
1082         if (penalty_str) {
1083                 penalty = atoi(penalty_str);
1084                 if (penalty < 0)
1085                         penalty = 0;
1086         }
1087
1088         if (paused_str) {
1089                 paused = atoi(paused_str);
1090                 if (paused < 0)
1091                         paused = 0;
1092         }
1093
1094         /* Find the member, or the place to put a new one. */
1095         ast_copy_string(tmpmem.interface, interface, sizeof(tmpmem.interface));
1096         m = ao2_find(q->members, &tmpmem, OBJ_POINTER);
1097
1098         /* Create a new one if not found, else update penalty */
1099         if (!m) {
1100                 if ((m = create_queue_member(interface, membername, penalty, paused))) {
1101                         m->dead = 0;
1102                         m->realtime = 1;
1103                         add_to_interfaces(interface);
1104                         ao2_link(q->members, m);
1105                         q->membercount++;
1106                 }
1107         } else {
1108                 m->dead = 0;    /* Do not delete this one. */
1109                 if (paused_str)
1110                         m->paused = paused;
1111                 m->penalty = penalty;
1112                 ao2_ref(m, -1);
1113         }
1114 }
1115
1116 static void free_members(struct call_queue *q, int all)
1117 {
1118         /* Free non-dynamic members */
1119         struct member *cur;
1120         struct ao2_iterator mem_iter = ao2_iterator_init(q->members, 0);
1121
1122         while ((cur = ao2_iterator_next(&mem_iter))) {
1123                 if (all || !cur->dynamic) {
1124                         ao2_unlink(q->members, cur);
1125                         remove_from_interfaces(cur->interface);
1126                         q->membercount--;
1127                 }
1128                 ao2_ref(cur, -1);
1129         }
1130 }
1131
1132 static void destroy_queue(struct call_queue *q)
1133 {
1134         free_members(q, 1);
1135         ast_mutex_destroy(&q->lock);
1136         ao2_ref(q->members, -1);
1137         free(q);
1138 }
1139
1140 /*!\brief Reload a single queue via realtime.
1141    \return Return the queue, or NULL if it doesn't exist.
1142    \note Should be called with the global qlock locked. */
1143 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
1144 {
1145         struct ast_variable *v;
1146         struct call_queue *q;
1147         struct member *m;
1148         struct ao2_iterator mem_iter;
1149         char *interface = NULL;
1150         char *tmp, *tmp_name;
1151         char tmpbuf[64];        /* Must be longer than the longest queue param name. */
1152
1153         /* Find the queue in the in-core list (we will create a new one if not found). */
1154         AST_LIST_TRAVERSE(&queues, q, list) {
1155                 if (!strcasecmp(q->name, queuename))
1156                         break;
1157         }
1158
1159         /* Static queues override realtime. */
1160         if (q) {
1161                 ast_mutex_lock(&q->lock);
1162                 if (!q->realtime) {
1163                         if (q->dead) {
1164                                 ast_mutex_unlock(&q->lock);
1165                                 return NULL;
1166                         } else {
1167                                 ast_mutex_unlock(&q->lock);
1168                                 return q;
1169                         }
1170                 }
1171         } else if (!member_config)
1172                 /* Not found in the list, and it's not realtime ... */
1173                 return NULL;
1174
1175         /* Check if queue is defined in realtime. */
1176         if (!queue_vars) {
1177                 /* Delete queue from in-core list if it has been deleted in realtime. */
1178                 if (q) {
1179                         /*! \note Hmm, can't seem to distinguish a DB failure from a not
1180                            found condition... So we might delete an in-core queue
1181                            in case of DB failure. */
1182                         ast_debug(1, "Queue %s not found in realtime.\n", queuename);
1183
1184                         q->dead = 1;
1185                         /* Delete if unused (else will be deleted when last caller leaves). */
1186                         if (!q->count) {
1187                                 /* Delete. */
1188                                 AST_LIST_REMOVE(&queues, q, list);
1189                                 ast_mutex_unlock(&q->lock);
1190                                 destroy_queue(q);
1191                         } else
1192                                 ast_mutex_unlock(&q->lock);
1193                 }
1194                 return NULL;
1195         }
1196
1197         /* Create a new queue if an in-core entry does not exist yet. */
1198         if (!q) {
1199                 if (!(q = alloc_queue(queuename)))
1200                         return NULL;
1201                 ast_mutex_lock(&q->lock);
1202                 clear_queue(q);
1203                 q->realtime = 1;
1204                 init_queue(q);          /* Ensure defaults for all parameters not set explicitly. */
1205                 AST_LIST_INSERT_HEAD(&queues, q, list);
1206         }
1207
1208         memset(tmpbuf, 0, sizeof(tmpbuf));
1209         for (v = queue_vars; v; v = v->next) {
1210                 /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
1211                 if ((tmp = strchr(v->name, '_'))) {
1212                         ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
1213                         tmp_name = tmpbuf;
1214                         tmp = tmp_name;
1215                         while ((tmp = strchr(tmp, '_')))
1216                                 *tmp++ = '-';
1217                 } else
1218                         tmp_name = v->name;
1219                 queue_set_param(q, tmp_name, v->value, -1, 0);
1220         }
1221
1222         /* Temporarily set realtime members dead so we can detect deleted ones. 
1223          * Also set the membercount correctly for realtime*/
1224         mem_iter = ao2_iterator_init(q->members, 0);
1225         while ((m = ao2_iterator_next(&mem_iter))) {
1226                 q->membercount++;
1227                 if (m->realtime)
1228                         m->dead = 1;
1229                 ao2_ref(m, -1);
1230         }
1231
1232         while ((interface = ast_category_browse(member_config, interface))) {
1233                 rt_handle_member_record(q, interface,
1234                         S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
1235                         ast_variable_retrieve(member_config, interface, "penalty"),
1236                         ast_variable_retrieve(member_config, interface, "paused"));
1237         }
1238
1239         /* Delete all realtime members that have been deleted in DB. */
1240         mem_iter = ao2_iterator_init(q->members, 0);
1241         while ((m = ao2_iterator_next(&mem_iter))) {
1242                 if (m->dead) {
1243                         ao2_unlink(q->members, m);
1244                         ast_mutex_unlock(&q->lock);
1245                         remove_from_interfaces(m->interface);
1246                         ast_mutex_lock(&q->lock);
1247                         q->membercount--;
1248                 }
1249                 ao2_ref(m, -1);
1250         }
1251
1252         ast_mutex_unlock(&q->lock);
1253
1254         return q;
1255 }
1256
1257 static struct call_queue *load_realtime_queue(const char *queuename)
1258 {
1259         struct ast_variable *queue_vars;
1260         struct ast_config *member_config = NULL;
1261         struct call_queue *q;
1262
1263         /* Find the queue in the in-core list first. */
1264         AST_LIST_LOCK(&queues);
1265         AST_LIST_TRAVERSE(&queues, q, list) {
1266                 if (!strcasecmp(q->name, queuename)) {
1267                         break;
1268                 }
1269         }
1270         AST_LIST_UNLOCK(&queues);
1271
1272         if (!q || q->realtime) {
1273                 /*! \note Load from realtime before taking the global qlock, to avoid blocking all
1274                    queue operations while waiting for the DB.
1275
1276                    This will be two separate database transactions, so we might
1277                    see queue parameters as they were before another process
1278                    changed the queue and member list as it was after the change.
1279                    Thus we might see an empty member list when a queue is
1280                    deleted. In practise, this is unlikely to cause a problem. */
1281
1282                 queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
1283                 if (queue_vars) {
1284                         member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
1285                         if (!member_config) {
1286                                 ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
1287                                 return NULL;
1288                         }
1289                 }
1290
1291                 AST_LIST_LOCK(&queues);
1292
1293                 q = find_queue_by_name_rt(queuename, queue_vars, member_config);
1294                 if (member_config)
1295                         ast_config_destroy(member_config);
1296                 if (queue_vars)
1297                         ast_variables_destroy(queue_vars);
1298
1299                 AST_LIST_UNLOCK(&queues);
1300         } else {
1301                 update_realtime_members(q);
1302         }
1303         return q;
1304 }
1305
1306 static int update_realtime_member_field(struct member *mem, const char *queue_name, const char *field, const char *value)
1307 {
1308         struct ast_variable *var;
1309         int ret = -1;
1310
1311         if(!(var = ast_load_realtime("queue_members", "interface", mem->interface, "queue_name", queue_name, NULL))) 
1312                 return ret;
1313         while (var) {
1314                 if(!strcmp(var->name, "uniqueid"))
1315                         break;
1316                 var = var->next;
1317         }
1318         if(var && !ast_strlen_zero(var->value)) {
1319                 if ((ast_update_realtime("queue_members", "uniqueid", var->value, field, value, NULL)) > -1)
1320                         ret = 0;
1321         }
1322         return ret;
1323 }
1324
1325 static void update_realtime_members(struct call_queue *q)
1326 {
1327         struct ast_config *member_config = NULL;
1328         struct member *m;
1329         char *interface = NULL;
1330         struct ao2_iterator mem_iter;
1331
1332         member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", q->name , NULL);
1333         if (!member_config) {
1334                 /*This queue doesn't have realtime members*/
1335                 ast_debug(3, "Queue %s has no realtime members defined. No need for update\n", q->name);
1336                 return;
1337         }
1338
1339         ast_mutex_lock(&q->lock);
1340         
1341         /* Temporarily set realtime  members dead so we can detect deleted ones.*/ 
1342         mem_iter = ao2_iterator_init(q->members, 0);
1343         while ((m = ao2_iterator_next(&mem_iter))) {
1344                 if (m->realtime)
1345                         m->dead = 1;
1346                 ao2_ref(m, -1);
1347         }
1348
1349         while ((interface = ast_category_browse(member_config, interface))) {
1350                 rt_handle_member_record(q, interface,
1351                         S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
1352                         ast_variable_retrieve(member_config, interface, "penalty"),
1353                         ast_variable_retrieve(member_config, interface, "paused"));
1354         }
1355
1356         /* Delete all realtime members that have been deleted in DB. */
1357         mem_iter = ao2_iterator_init(q->members, 0);
1358         while ((m = ao2_iterator_next(&mem_iter))) {
1359                 if (m->dead) {
1360                         ao2_unlink(q->members, m);
1361                         ast_mutex_unlock(&q->lock);
1362                         remove_from_interfaces(m->interface);
1363                         ast_mutex_lock(&q->lock);
1364                         q->membercount--;
1365                 }
1366                 ao2_ref(m, -1);
1367         }
1368         ast_mutex_unlock(&q->lock);
1369 }
1370
1371 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
1372 {
1373         struct call_queue *q;
1374         struct queue_ent *cur, *prev = NULL;
1375         int res = -1;
1376         int pos = 0;
1377         int inserted = 0;
1378         enum queue_member_status stat;
1379
1380         if (!(q = load_realtime_queue(queuename)))
1381                 return res;
1382
1383         AST_LIST_LOCK(&queues);
1384         ast_mutex_lock(&q->lock);
1385
1386         /* This is our one */
1387         stat = get_member_status(q, qe->max_penalty);
1388         if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
1389                 *reason = QUEUE_JOINEMPTY;
1390         else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
1391                 *reason = QUEUE_JOINUNAVAIL;
1392         else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
1393                 *reason = QUEUE_JOINUNAVAIL;
1394         else if (q->maxlen && (q->count >= q->maxlen))
1395                 *reason = QUEUE_FULL;
1396         else {
1397                 /* There's space for us, put us at the right position inside
1398                  * the queue.
1399                  * Take into account the priority of the calling user */
1400                 inserted = 0;
1401                 prev = NULL;
1402                 cur = q->head;
1403                 while (cur) {
1404                         /* We have higher priority than the current user, enter
1405                          * before him, after all the other users with priority
1406                          * higher or equal to our priority. */
1407                         if ((!inserted) && (qe->prio > cur->prio)) {
1408                                 insert_entry(q, prev, qe, &pos);
1409                                 inserted = 1;
1410                         }
1411                         cur->pos = ++pos;
1412                         prev = cur;
1413                         cur = cur->next;
1414                 }
1415                 /* No luck, join at the end of the queue */
1416                 if (!inserted)
1417                         insert_entry(q, prev, qe, &pos);
1418                 ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
1419                 ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
1420                 ast_copy_string(qe->context, q->context, sizeof(qe->context));
1421                 q->count++;
1422                 res = 0;
1423                 manager_event(EVENT_FLAG_CALL, "Join",
1424                         "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
1425                         qe->chan->name,
1426                         S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
1427                         S_OR(qe->chan->cid.cid_name, "unknown"),
1428                         q->name, qe->pos, q->count, qe->chan->uniqueid );
1429                 ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
1430         }
1431         ast_mutex_unlock(&q->lock);
1432         AST_LIST_UNLOCK(&queues);
1433
1434         return res;
1435 }
1436
1437 static int play_file(struct ast_channel *chan, char *filename)
1438 {
1439         int res;
1440
1441         ast_stopstream(chan);
1442
1443         res = ast_streamfile(chan, filename, chan->language);
1444         if (!res)
1445                 res = ast_waitstream(chan, AST_DIGIT_ANY);
1446
1447         ast_stopstream(chan);
1448
1449         return res;
1450 }
1451
1452 static int valid_exit(struct queue_ent *qe, char digit)
1453 {
1454         int digitlen = strlen(qe->digits);
1455
1456         /* Prevent possible buffer overflow */
1457         if (digitlen < sizeof(qe->digits) - 2) {
1458                 qe->digits[digitlen] = digit;
1459                 qe->digits[digitlen + 1] = '\0';
1460         } else {
1461                 qe->digits[0] = '\0';
1462                 return 0;
1463         }
1464
1465         /* If there's no context to goto, short-circuit */
1466         if (ast_strlen_zero(qe->context))
1467                 return 0;
1468
1469         /* If the extension is bad, then reset the digits to blank */
1470         if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
1471                 qe->digits[0] = '\0';
1472                 return 0;
1473         }
1474
1475         /* We have an exact match */
1476         if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
1477                 qe->valid_digits = 1;
1478                 /* Return 1 on a successful goto */
1479                 return 1;
1480         }
1481
1482         return 0;
1483 }
1484
1485 static int say_position(struct queue_ent *qe, int ringing)
1486 {
1487         int res = 0, avgholdmins, avgholdsecs;
1488         time_t now;
1489
1490         /* Let minannouncefrequency seconds pass between the start of each position announcement */
1491         time(&now);
1492         if ((now - qe->last_pos) < qe->parent->minannouncefrequency)
1493                 return 0;
1494
1495         /* If either our position has changed, or we are over the freq timer, say position */
1496         if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
1497                 return 0;
1498
1499         if (ringing) {
1500                 ast_indicate(qe->chan,-1);
1501         } else {
1502                 ast_moh_stop(qe->chan);
1503         }
1504         /* Say we're next, if we are */
1505         if (qe->pos == 1) {
1506                 res = play_file(qe->chan, qe->parent->sound_next);
1507                 if (res)
1508                         goto playout;
1509                 else
1510                         goto posout;
1511         } else {
1512                 res = play_file(qe->chan, qe->parent->sound_thereare);
1513                 if (res)
1514                         goto playout;
1515                 res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */
1516                 if (res)
1517                         goto playout;
1518                 res = play_file(qe->chan, qe->parent->sound_calls);
1519                 if (res)
1520                         goto playout;
1521         }
1522         /* Round hold time to nearest minute */
1523         avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
1524
1525         /* If they have specified a rounding then round the seconds as well */
1526         if (qe->parent->roundingseconds) {
1527                 avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
1528                 avgholdsecs *= qe->parent->roundingseconds;
1529         } else {
1530                 avgholdsecs = 0;
1531         }
1532
1533         ast_verb(3, "Hold time for %s is %d minutes %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
1534
1535         /* If the hold time is >1 min, if it's enabled, and if it's not
1536            supposed to be only once and we have already said it, say it */
1537         if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
1538                 (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
1539                 res = play_file(qe->chan, qe->parent->sound_holdtime);
1540                 if (res)
1541                         goto playout;
1542
1543                 if (avgholdmins > 0) {
1544                         if (avgholdmins < 2) {
1545                                 res = play_file(qe->chan, qe->parent->sound_lessthan);
1546                                 if (res)
1547                                         goto playout;
1548
1549                                 res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
1550                                 if (res)
1551                                         goto playout;
1552                         } else {
1553                                 res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
1554                                 if (res)
1555                                         goto playout;
1556                         }
1557                         
1558                         res = play_file(qe->chan, qe->parent->sound_minutes);
1559                         if (res)
1560                                 goto playout;
1561                 }
1562                 if (avgholdsecs>0) {
1563                         res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
1564                         if (res)
1565                                 goto playout;
1566
1567                         res = play_file(qe->chan, qe->parent->sound_seconds);
1568                         if (res)
1569                                 goto playout;
1570                 }
1571
1572         }
1573
1574 posout:
1575         ast_verb(3, "Told %s in %s their queue position (which was %d)\n",
1576                         qe->chan->name, qe->parent->name, qe->pos);
1577         res = play_file(qe->chan, qe->parent->sound_thanks);
1578
1579 playout:
1580         if (res > 0 && !valid_exit(qe, res))
1581                 res = 0;
1582
1583         /* Set our last_pos indicators */
1584         qe->last_pos = now;
1585         qe->last_pos_said = qe->pos;
1586
1587         /* Don't restart music on hold if we're about to exit the caller from the queue */
1588         if (!res) {
1589                 if (ringing)
1590                         ast_indicate(qe->chan, AST_CONTROL_RINGING);
1591                 else
1592                         ast_moh_start(qe->chan, qe->moh, NULL);
1593         }
1594         return res;
1595 }
1596
1597 static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
1598 {
1599         int oldvalue;
1600
1601         /* Calculate holdtime using a recursive boxcar filter */
1602         /* Thanks to SRT for this contribution */
1603         /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
1604
1605         ast_mutex_lock(&qe->parent->lock);
1606         oldvalue = qe->parent->holdtime;
1607         qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
1608         ast_mutex_unlock(&qe->parent->lock);
1609 }
1610
1611
1612 static void leave_queue(struct queue_ent *qe)
1613 {
1614         struct call_queue *q;
1615         struct queue_ent *cur, *prev = NULL;
1616         int pos = 0;
1617
1618         if (!(q = qe->parent))
1619                 return;
1620         ast_mutex_lock(&q->lock);
1621
1622         prev = NULL;
1623         for (cur = q->head; cur; cur = cur->next) {
1624                 if (cur == qe) {
1625                         q->count--;
1626
1627                         /* Take us out of the queue */
1628                         manager_event(EVENT_FLAG_CALL, "Leave",
1629                                 "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
1630                                 qe->chan->name, q->name,  q->count, qe->chan->uniqueid);
1631                         ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
1632                         /* Take us out of the queue */
1633                         if (prev)
1634                                 prev->next = cur->next;
1635                         else
1636                                 q->head = cur->next;
1637                 } else {
1638                         /* Renumber the people after us in the queue based on a new count */
1639                         cur->pos = ++pos;
1640                         prev = cur;
1641                 }
1642         }
1643         ast_mutex_unlock(&q->lock);
1644
1645         if (q->dead && !q->count) {     
1646                 /* It's dead and nobody is in it, so kill it */
1647                 AST_LIST_LOCK(&queues);
1648                 AST_LIST_REMOVE(&queues, q, list);
1649                 AST_LIST_UNLOCK(&queues);
1650                 destroy_queue(q);
1651         }
1652 }
1653
1654 /* Hang up a list of outgoing calls */
1655 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
1656 {
1657         struct callattempt *oo;
1658
1659         while (outgoing) {
1660                 /* Hangup any existing lines we have open */
1661                 if (outgoing->chan && (outgoing->chan != exception))
1662                         ast_hangup(outgoing->chan);
1663                 oo = outgoing;
1664                 outgoing = outgoing->q_next;
1665                 if (oo->member)
1666                         ao2_ref(oo->member, -1);
1667                 ast_free(oo);
1668         }
1669 }
1670
1671 static int update_status(struct call_queue *q, struct member *member, int status)
1672 {
1673         struct member *cur;
1674         struct ao2_iterator mem_iter;
1675
1676         /* Since a reload could have taken place, we have to traverse the list to
1677                 be sure it's still valid */
1678         ast_mutex_lock(&q->lock);
1679         mem_iter = ao2_iterator_init(q->members, 0);
1680         while ((cur = ao2_iterator_next(&mem_iter))) {
1681                 if (member != cur) {
1682                         ao2_ref(cur, -1);
1683                         continue;
1684                 }
1685
1686                 cur->status = status;
1687                 if (!q->maskmemberstatus) {
1688                         manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
1689                                 "Queue: %s\r\n"
1690                                 "Location: %s\r\n"
1691                                 "MemberName: %s\r\n"
1692                                 "Membership: %s\r\n"
1693                                 "Penalty: %d\r\n"
1694                                 "CallsTaken: %d\r\n"
1695                                 "LastCall: %d\r\n"
1696                                 "Status: %d\r\n"
1697                                 "Paused: %d\r\n",
1698                                 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : cur->realtime ? "realtime": "static",
1699                                 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
1700                 }
1701                 ao2_ref(cur, -1);
1702         }
1703         ast_mutex_unlock(&q->lock);
1704         return 0;
1705 }
1706
1707 static int update_dial_status(struct call_queue *q, struct member *member, int status)
1708 {
1709         if (status == AST_CAUSE_BUSY)
1710                 status = AST_DEVICE_BUSY;
1711         else if (status == AST_CAUSE_UNREGISTERED)
1712                 status = AST_DEVICE_UNAVAILABLE;
1713         else if (status == AST_CAUSE_NOSUCHDRIVER)
1714                 status = AST_DEVICE_INVALID;
1715         else
1716                 status = AST_DEVICE_UNKNOWN;
1717         return update_status(q, member, status);
1718 }
1719
1720 /* traverse all defined queues which have calls waiting and contain this member
1721    return 0 if no other queue has precedence (higher weight) or 1 if found  */
1722 static int compare_weight(struct call_queue *rq, struct member *member)
1723 {
1724         struct call_queue *q;
1725         struct member *mem;
1726         int found = 0;
1727         
1728         /* &qlock and &rq->lock already set by try_calling()
1729          * to solve deadlock */
1730         AST_LIST_TRAVERSE(&queues, q, list) {
1731                 if (q == rq) /* don't check myself, could deadlock */
1732                         continue;
1733                 ast_mutex_lock(&q->lock);
1734                 if (q->count && q->members) {
1735                         if ((mem = ao2_find(q->members, member, OBJ_POINTER))) {
1736                                 ast_debug(1, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
1737                                 if (q->weight > rq->weight) {
1738                                         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);
1739                                         found = 1;
1740                                 }
1741                                 ao2_ref(mem, -1);
1742                         }
1743                 }
1744                 ast_mutex_unlock(&q->lock);
1745                 if (found)
1746                         break;
1747         }
1748         return found;
1749 }
1750
1751 /*! \brief common hangup actions */
1752 static void do_hang(struct callattempt *o)
1753 {
1754         o->stillgoing = 0;
1755         ast_hangup(o->chan);
1756         o->chan = NULL;
1757 }
1758
1759 static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
1760 {
1761         struct ast_str *buf = ast_str_alloca(len + 1);
1762         char *tmp;
1763
1764         if (pbx_builtin_serialize_variables(chan, &buf)) {
1765                 int i, j;
1766
1767                 /* convert "\n" to "\nVariable: " */
1768                 strcpy(vars, "Variable: ");
1769                 tmp = buf->str;
1770
1771                 for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
1772                         vars[j] = tmp[i];
1773
1774                         if (tmp[i + 1] == '\0')
1775                                 break;
1776                         if (tmp[i] == '\n') {
1777                                 vars[j] = '\r';
1778                                 vars[++j] = '\n';
1779
1780                                 ast_copy_string(&(vars[j]), "Variable: ", len - j);
1781                                 j += 9;
1782                         }
1783                 }
1784                 if (j > len - 1)
1785                         j = len - 1;
1786                 vars[j - 2] = '\r';
1787                 vars[j - 1] = '\n';
1788                 vars[j] = '\0';
1789         } else {
1790                 /* there are no channel variables; leave it blank */
1791                 *vars = '\0';
1792         }
1793         return vars;
1794 }
1795
1796 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
1797 {
1798         int res;
1799         int status;
1800         char tech[256];
1801         char *location;
1802
1803         /* on entry here, we know that tmp->chan == NULL */
1804         if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
1805                 ast_debug(1, "Wrapuptime not yet expired for %s\n", tmp->interface);
1806                 if (qe->chan->cdr)
1807                         ast_cdr_busy(qe->chan->cdr);
1808                 tmp->stillgoing = 0;
1809                 (*busies)++;
1810                 return 0;
1811         }
1812
1813         if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
1814                 ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
1815                 if (qe->chan->cdr)
1816                         ast_cdr_busy(qe->chan->cdr);
1817                 tmp->stillgoing = 0;
1818                 return 0;
1819         }
1820
1821         if (tmp->member->paused) {
1822                 ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
1823                 if (qe->chan->cdr)
1824                         ast_cdr_busy(qe->chan->cdr);
1825                 tmp->stillgoing = 0;
1826                 return 0;
1827         }
1828         if (use_weight && compare_weight(qe->parent,tmp->member)) {
1829                 ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
1830                 if (qe->chan->cdr)
1831                         ast_cdr_busy(qe->chan->cdr);
1832                 tmp->stillgoing = 0;
1833                 (*busies)++;
1834                 return 0;
1835         }
1836
1837         ast_copy_string(tech, tmp->interface, sizeof(tech));
1838         if ((location = strchr(tech, '/')))
1839                 *location++ = '\0';
1840         else
1841                 location = "";
1842
1843         /* Request the peer */
1844         tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
1845         if (!tmp->chan) {                       /* If we can't, just go on to the next call */
1846                 if (qe->chan->cdr)
1847                         ast_cdr_busy(qe->chan->cdr);
1848                 tmp->stillgoing = 0;
1849                 update_dial_status(qe->parent, tmp->member, status);
1850
1851                 ast_mutex_lock(&qe->parent->lock);
1852                 qe->parent->rrpos++;
1853                 ast_mutex_unlock(&qe->parent->lock);
1854
1855                 (*busies)++;
1856                 return 0;
1857         } else if (status != tmp->oldstatus)
1858                 update_dial_status(qe->parent, tmp->member, status);
1859         
1860         tmp->chan->appl = "AppQueue";
1861         tmp->chan->data = "(Outgoing Line)";
1862         tmp->chan->whentohangup = 0;
1863         if (tmp->chan->cid.cid_num)
1864                 ast_free(tmp->chan->cid.cid_num);
1865         tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
1866         if (tmp->chan->cid.cid_name)
1867                 ast_free(tmp->chan->cid.cid_name);
1868         tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
1869         if (tmp->chan->cid.cid_ani)
1870                 ast_free(tmp->chan->cid.cid_ani);
1871         tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
1872
1873         /* Inherit specially named variables from parent channel */
1874         ast_channel_inherit_variables(qe->chan, tmp->chan);
1875
1876         /* Presense of ADSI CPE on outgoing channel follows ours */
1877         tmp->chan->adsicpe = qe->chan->adsicpe;
1878
1879         /* Place the call, but don't wait on the answer */
1880         if ((res = ast_call(tmp->chan, location, 0))) {
1881                 /* Again, keep going even if there's an error */
1882                 ast_debug(1, "ast call on peer returned %d\n", res);
1883                 ast_verb(3, "Couldn't call %s\n", tmp->interface);
1884                 do_hang(tmp);
1885                 (*busies)++;
1886                 return 0;
1887         } else if (qe->parent->eventwhencalled) {
1888                 char vars[2048];
1889
1890                 manager_event(EVENT_FLAG_AGENT, "AgentCalled",
1891                                         "Queue: %s\r\n"
1892                                         "AgentCalled: %s\r\n"
1893                                         "ChannelCalling: %s\r\n"
1894                                         "DestinationChannel: %s\r\n"
1895                                         "CallerIDNum: %s\r\n"
1896                                         "CallerIDName: %s\r\n"
1897                                         "Context: %s\r\n"
1898                                         "Extension: %s\r\n"
1899                                         "Priority: %d\r\n"
1900                                         "%s",
1901                                         qe->parent->name, tmp->interface, qe->chan->name, tmp->chan->name,
1902                                         tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
1903                                         tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
1904                                         qe->chan->context, qe->chan->exten, qe->chan->priority,
1905                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
1906                 ast_verb(3, "Called %s\n", tmp->interface);
1907         }
1908
1909         return 1;
1910 }
1911
1912 /*! \brief find the entry with the best metric, or NULL */
1913 static struct callattempt *find_best(struct callattempt *outgoing)
1914 {
1915         struct callattempt *best = NULL, *cur;
1916
1917         for (cur = outgoing; cur; cur = cur->q_next) {
1918                 if (cur->stillgoing &&                                  /* Not already done */
1919                         !cur->chan &&                                   /* Isn't already going */
1920                         (!best || cur->metric < best->metric)) {                /* We haven't found one yet, or it's better */
1921                         best = cur;
1922                 }
1923         }
1924
1925         return best;
1926 }
1927
1928 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
1929 {
1930         int ret = 0;
1931
1932         while (ret == 0) {
1933                 struct callattempt *best = find_best(outgoing);
1934                 if (!best) {
1935                         ast_debug(1, "Nobody left to try ringing in queue\n");
1936                         break;
1937                 }
1938                 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
1939                         struct callattempt *cur;
1940                         /* Ring everyone who shares this best metric (for ringall) */
1941                         for (cur = outgoing; cur; cur = cur->q_next) {
1942                                 if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
1943                                         ast_debug(1, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
1944                                         ring_entry(qe, cur, busies);
1945                                 }
1946                         }
1947                 } else {
1948                         /* Ring just the best channel */
1949                         ast_debug(1, "Trying '%s' with metric %d\n", best->interface, best->metric);
1950                         ring_entry(qe, best, busies);
1951                 }
1952                 if (best->chan) /* break out with result = 1 */
1953                         ret = 1;
1954         }
1955
1956         return ret;
1957 }
1958
1959 static int store_next(struct queue_ent *qe, struct callattempt *outgoing)
1960 {
1961         struct callattempt *best = find_best(outgoing);
1962
1963         if (best) {
1964                 /* Ring just the best channel */
1965                 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
1966                 qe->parent->rrpos = best->metric % 1000;
1967         } else {
1968                 /* Just increment rrpos */
1969                 if (qe->parent->wrapped) {
1970                         /* No more channels, start over */
1971                         qe->parent->rrpos = 0;
1972                 } else {
1973                         /* Prioritize next entry */
1974                         qe->parent->rrpos++;
1975                 }
1976         }
1977         qe->parent->wrapped = 0;
1978
1979         return 0;
1980 }
1981
1982 static int say_periodic_announcement(struct queue_ent *qe, int ringing)
1983 {
1984         int res = 0;
1985         time_t now;
1986
1987         /* Get the current time */
1988         time(&now);
1989
1990         /* Check to see if it is time to announce */
1991         if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
1992                 return 0;
1993
1994         /* Stop the music on hold so we can play our own file */
1995         if (ringing)
1996                 ast_indicate(qe->chan,-1);
1997         else
1998                 ast_moh_stop(qe->chan);
1999
2000         ast_verb(3, "Playing periodic announcement\n");
2001
2002         /* Check to make sure we have a sound file. If not, reset to the first sound file */
2003         if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS || ast_strlen_zero(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound])) {
2004                 qe->last_periodic_announce_sound = 0;
2005         }
2006         
2007         /* play the announcement */
2008         res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]);
2009
2010         if (res > 0 && !valid_exit(qe, res))
2011                 res = 0;
2012
2013         /* Resume Music on Hold if the caller is going to stay in the queue */
2014         if (!res) {
2015                 if (ringing)
2016                         ast_indicate(qe->chan, AST_CONTROL_RINGING);
2017                 else
2018                         ast_moh_start(qe->chan, qe->moh, NULL);
2019         }
2020
2021         /* update last_periodic_announce_time */
2022         qe->last_periodic_announce_time = now;
2023
2024         /* Update the current periodic announcement to the next announcement */
2025         qe->last_periodic_announce_sound++;
2026         
2027         return res;
2028 }
2029
2030 static void record_abandoned(struct queue_ent *qe)
2031 {
2032         ast_mutex_lock(&qe->parent->lock);
2033         set_queue_variables(qe);
2034         manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
2035                 "Queue: %s\r\n"
2036                 "Uniqueid: %s\r\n"
2037                 "Position: %d\r\n"
2038                 "OriginalPosition: %d\r\n"
2039                 "HoldTime: %d\r\n",
2040                 qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
2041
2042         qe->parent->callsabandoned++;
2043         ast_mutex_unlock(&qe->parent->lock);
2044 }
2045
2046 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
2047 static void rna(int rnatime, struct queue_ent *qe, char *interface, char *membername)
2048 {
2049         ast_verb(3, "Nobody picked up in %d ms\n", rnatime);
2050         ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
2051         if (qe->parent->autopause) {
2052                 if (!set_member_paused(qe->parent->name, interface, "Auto-Pause", 1)) {
2053                         ast_verb(3, "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
2054                 } else {
2055                         ast_verb(3, "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
2056                 }
2057         }
2058         return;
2059 }
2060
2061 #define AST_MAX_WATCHERS 256
2062
2063 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
2064 {
2065         char *queue = qe->parent->name;
2066         struct callattempt *o;
2067         int status;
2068         int sentringing = 0;
2069         int numbusies = prebusies;
2070         int numnochan = 0;
2071         int stillgoing = 0;
2072         int orig = *to;
2073         struct ast_frame *f;
2074         struct callattempt *peer = NULL;
2075         struct ast_channel *winner;
2076         struct ast_channel *in = qe->chan;
2077         char on[80] = "";
2078         char membername[80] = "";
2079         long starttime = 0;
2080         long endtime = 0;
2081 #ifdef HAVE_EPOLL
2082         struct callattempt *epollo;
2083 #endif
2084
2085         starttime = (long) time(NULL);
2086 #ifdef HAVE_EPOLL
2087         for (epollo = outgoing; epollo; epollo = epollo->q_next) {
2088                 if(epollo->chan)
2089                         ast_poll_channel_add(in, epollo->chan);
2090         }
2091 #endif
2092         
2093         while (*to && !peer) {
2094                 int numlines, retry, pos = 1;
2095                 struct ast_channel *watchers[AST_MAX_WATCHERS];
2096                 watchers[0] = in;
2097
2098                 for (retry = 0; retry < 2; retry++) {
2099                         numlines = 0;
2100                         for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
2101                                 if (o->stillgoing) {    /* Keep track of important channels */
2102                                         stillgoing = 1;
2103                                         if (o->chan)
2104                                                 watchers[pos++] = o->chan;
2105                                 }
2106                                 numlines++;
2107                         }
2108                         if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
2109                                 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
2110                                 break;
2111                         /* On "ringall" strategy we only move to the next penalty level
2112                            when *all* ringing phones are done in the current penalty level */
2113                         ring_one(qe, outgoing, &numbusies);
2114                         /* and retry... */
2115                 }
2116                 if (pos == 1 /* not found */) {
2117                         if (numlines == (numbusies + numnochan)) {
2118                                 ast_debug(1, "Everyone is busy at this time\n");
2119                         } else {
2120                                 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
2121                         }
2122                         *to = 0;
2123                         return NULL;
2124                 }
2125                 winner = ast_waitfor_n(watchers, pos, to);
2126                 for (o = outgoing; o; o = o->q_next) {
2127                         if (o->stillgoing && (o->chan) &&  (o->chan->_state == AST_STATE_UP)) {
2128                                 if (!peer) {
2129                                         ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2130                                         peer = o;
2131                                 }
2132                         } else if (o->chan && (o->chan == winner)) {
2133
2134                                 ast_copy_string(on, o->member->interface, sizeof(on));
2135                                 ast_copy_string(membername, o->member->membername, sizeof(membername));
2136
2137                                 if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
2138                                         ast_verb(3, "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
2139                                         numnochan++;
2140                                         do_hang(o);
2141                                         winner = NULL;
2142                                         continue;
2143                                 } else if (!ast_strlen_zero(o->chan->call_forward)) {
2144                                         char tmpchan[256];
2145                                         char *stuff;
2146                                         char *tech;
2147
2148                                         ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
2149                                         if ((stuff = strchr(tmpchan, '/'))) {
2150                                                 *stuff++ = '\0';
2151                                                 tech = tmpchan;
2152                                         } else {
2153                                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
2154                                                 stuff = tmpchan;
2155                                                 tech = "Local";
2156                                         }
2157                                         /* Before processing channel, go ahead and check for forwarding */
2158                                         ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
2159                                         /* Setup parameters */
2160                                         o->chan = ast_request(tech, in->nativeformats, stuff, &status);
2161                                         if (status != o->oldstatus)
2162                                                 update_dial_status(qe->parent, o->member, status);                                              
2163                                         if (!o->chan) {
2164                                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
2165                                                 o->stillgoing = 0;
2166                                                 numnochan++;
2167                                         } else {
2168                                                 ast_channel_inherit_variables(in, o->chan);
2169                                                 if (o->chan->cid.cid_num)
2170                                                         ast_free(o->chan->cid.cid_num);
2171                                                 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
2172
2173                                                 if (o->chan->cid.cid_name)
2174                                                         ast_free(o->chan->cid.cid_name);
2175                                                 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
2176
2177                                                 ast_string_field_set(o->chan, accountcode, in->accountcode);
2178                                                 o->chan->cdrflags = in->cdrflags;
2179
2180                                                 if (in->cid.cid_ani) {
2181                                                         if (o->chan->cid.cid_ani)
2182                                                                 ast_free(o->chan->cid.cid_ani);
2183                                                         o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
2184                                                 }
2185                                                 if (o->chan->cid.cid_rdnis)
2186                                                         ast_free(o->chan->cid.cid_rdnis);
2187                                                 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
2188                                                 if (ast_call(o->chan, tmpchan, 0)) {
2189                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
2190                                                         do_hang(o);
2191                                                         numnochan++;
2192                                                 }
2193                                         }
2194                                         /* Hangup the original channel now, in case we needed it */
2195                                         ast_hangup(winner);
2196                                         continue;
2197                                 }
2198                                 f = ast_read(winner);
2199                                 if (f) {
2200                                         if (f->frametype == AST_FRAME_CONTROL) {
2201                                                 switch (f->subclass) {
2202                                                 case AST_CONTROL_ANSWER:
2203                                                         /* This is our guy if someone answered. */
2204                                                         if (!peer) {
2205                                                                 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2206                                                                 peer = o;
2207                                                         }
2208                                                         break;
2209                                                 case AST_CONTROL_BUSY:
2210                                                         ast_verb(3, "%s is busy\n", o->chan->name);
2211                                                         if (in->cdr)
2212                                                                 ast_cdr_busy(in->cdr);
2213                                                         do_hang(o);
2214                                                         endtime = (long) time(NULL);
2215                                                         endtime -= starttime;
2216                                                         rna(endtime*1000, qe, on, membername);
2217                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2218                                                                 if (qe->parent->timeoutrestart)
2219                                                                         *to = orig;
2220                                                                 ring_one(qe, outgoing, &numbusies);
2221                                                         }
2222                                                         numbusies++;
2223                                                         break;
2224                                                 case AST_CONTROL_CONGESTION:
2225                                                         ast_verb(3, "%s is circuit-busy\n", o->chan->name);
2226                                                         if (in->cdr)
2227                                                                 ast_cdr_busy(in->cdr);
2228                                                         endtime = (long) time(NULL);
2229                                                         endtime -= starttime;
2230                                                         rna(endtime*1000, qe, on, membername);
2231                                                         do_hang(o);
2232                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2233                                                                 if (qe->parent->timeoutrestart)
2234                                                                         *to = orig;
2235                                                                 ring_one(qe, outgoing, &numbusies);
2236                                                         }
2237                                                         numbusies++;
2238                                                         break;
2239                                                 case AST_CONTROL_RINGING:
2240                                                         ast_verb(3, "%s is ringing\n", o->chan->name);
2241                                                         if (!sentringing) {
2242 #if 0
2243                                                                 ast_indicate(in, AST_CONTROL_RINGING);
2244 #endif                                                          
2245                                                                 sentringing++;
2246                                                         }
2247                                                         break;
2248                                                 case AST_CONTROL_OFFHOOK:
2249                                                         /* Ignore going off hook */
2250                                                         break;
2251                                                 default:
2252                                                         ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
2253                                                 }
2254                                         }
2255                                         ast_frfree(f);
2256                                 } else {
2257                                         endtime = (long) time(NULL) - starttime;
2258                                         rna(endtime * 1000, qe, on, membername);
2259                                         do_hang(o);
2260                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2261                                                 if (qe->parent->timeoutrestart)
2262                                                         *to = orig;
2263                                                 ring_one(qe, outgoing, &numbusies);
2264                                         }
2265                                 }
2266                         }
2267                 }
2268                 if (winner == in) {
2269                         f = ast_read(in);
2270                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2271                                 /* Got hung up */
2272                                 *to = -1;
2273                                 if (f)
2274                                         ast_frfree(f);
2275                                 return NULL;
2276                         }
2277                         if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2278                                 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
2279                                 *to = 0;
2280                                 ast_frfree(f);
2281                                 return NULL;
2282                         }
2283                         if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
2284                                 ast_verb(3, "User pressed digit: %c\n", f->subclass);
2285                                 *to = 0;
2286                                 *digit = f->subclass;
2287                                 ast_frfree(f);
2288                                 return NULL;
2289                         }
2290                         ast_frfree(f);
2291                 }
2292                 if (!*to)
2293                         rna(orig, qe, on, membername);
2294         }
2295
2296 #ifdef HAVE_EPOLL
2297         for(epollo = outgoing; epollo; epollo = epollo->q_next) {
2298                 if(epollo->chan)
2299                         ast_poll_channel_del(in, epollo->chan);
2300         }
2301 #endif
2302
2303         return peer;
2304 }
2305
2306 static int is_our_turn(struct queue_ent *qe)
2307 {
2308         struct queue_ent *ch;
2309         struct member *cur;
2310         int avl = 0;
2311         int idx = 0;
2312         int res;
2313
2314         if (!qe->parent->autofill) {
2315                 /* Atomically read the parent head -- does not need a lock */
2316                 ch = qe->parent->head;
2317                 /* If we are now at the top of the head, break out */
2318                 if (ch == qe) {
2319                         ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2320                         res = 1;
2321                 } else {
2322                         ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2323                         res = 0;
2324                 }       
2325
2326         } else {
2327                 /* This needs a lock. How many members are available to be served? */
2328                 ast_mutex_lock(&qe->parent->lock);
2329                         
2330                 ch = qe->parent->head;
2331         
2332                 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2333                         ast_debug(1, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in\n", avl);
2334                         avl = 1;
2335                 } else {
2336                         struct ao2_iterator mem_iter = ao2_iterator_init(qe->parent->members, 0);
2337                         while ((cur = ao2_iterator_next(&mem_iter))) {
2338                                 switch (cur->status) {
2339                                 case AST_DEVICE_NOT_INUSE:
2340                                 case AST_DEVICE_UNKNOWN:
2341                                         if (!cur->paused)
2342                                                 avl++;
2343                                         break;
2344                                 }
2345                                 ao2_ref(cur, -1);
2346                         }
2347                 }
2348
2349                 ast_debug(1, "There are %d available members.\n", avl);
2350         
2351                 while ((idx < avl) && (ch) && (ch != qe)) {
2352                         idx++;
2353                         ch = ch->next;                  
2354                 }
2355         
2356                 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2357                 if (ch && idx < avl) {
2358                         ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2359                         res = 1;
2360                 } else {
2361                         ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2362                         res = 0;
2363                 }
2364                 
2365                 ast_mutex_unlock(&qe->parent->lock);
2366         }
2367
2368         return res;
2369 }
2370
2371 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2372 {
2373         int res = 0;
2374
2375         /* This is the holding pen for callers 2 through maxlen */
2376         for (;;) {
2377                 enum queue_member_status stat;
2378
2379                 if (is_our_turn(qe))
2380                         break;
2381
2382                 /* If we have timed out, break out */
2383                 if (qe->expire && (time(NULL) > qe->expire)) {
2384                         *reason = QUEUE_TIMEOUT;
2385                         break;
2386                 }
2387
2388                 stat = get_member_status(qe->parent, qe->max_penalty);
2389
2390                 /* leave the queue if no agents, if enabled */
2391                 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2392                         *reason = QUEUE_LEAVEEMPTY;
2393                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2394                         leave_queue(qe);
2395                         break;
2396                 }
2397
2398                 /* leave the queue if no reachable agents, if enabled */
2399                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
2400                         *reason = QUEUE_LEAVEUNAVAIL;
2401                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2402                         leave_queue(qe);
2403                         break;
2404                 }
2405                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2406                         *reason = QUEUE_LEAVEUNAVAIL;
2407                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2408                         leave_queue(qe);
2409                         break;
2410                 }
2411
2412                 /* Make a position announcement, if enabled */
2413                 if (qe->parent->announcefrequency &&
2414                         (res = say_position(qe,ringing)))
2415                         break;
2416
2417                 /* Make a periodic announcement, if enabled */
2418                 if (qe->parent->periodicannouncefrequency &&
2419                         (res = say_periodic_announcement(qe,ringing)))
2420                         break;
2421
2422                 /* Wait a second before checking again */
2423                 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
2424                         if (res > 0 && !valid_exit(qe, res))
2425                                 res = 0;
2426                         else
2427                                 break;
2428                 }
2429         }
2430
2431         return res;
2432 }
2433
2434 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
2435 {
2436         ast_mutex_lock(&q->lock);
2437         time(&member->lastcall);
2438         member->calls++;
2439         q->callscompleted++;
2440         if (callcompletedinsl)
2441                 q->callscompletedinsl++;
2442         ast_mutex_unlock(&q->lock);
2443         return 0;
2444 }
2445
2446 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2447 {
2448         if (qe->max_penalty && (mem->penalty > qe->max_penalty))
2449                 return -1;
2450
2451         switch (q->strategy) {
2452         case QUEUE_STRATEGY_RINGALL:
2453                 /* Everyone equal, except for penalty */
2454                 tmp->metric = mem->penalty * 1000000;
2455                 break;
2456         case QUEUE_STRATEGY_RRMEMORY:
2457                 if (pos < q->rrpos) {
2458                         tmp->metric = 1000 + pos;
2459                 } else {
2460                         if (pos > q->rrpos)
2461                                 /* Indicate there is another priority */
2462                                 q->wrapped = 1;
2463                         tmp->metric = pos;
2464                 }
2465                 tmp->metric += mem->penalty * 1000000;
2466                 break;
2467         case QUEUE_STRATEGY_RANDOM:
2468                 tmp->metric = ast_random() % 1000;
2469                 tmp->metric += mem->penalty * 1000000;
2470                 break;
2471         case QUEUE_STRATEGY_FEWESTCALLS:
2472                 tmp->metric = mem->calls;
2473                 tmp->metric += mem->penalty * 1000000;
2474                 break;
2475         case QUEUE_STRATEGY_LEASTRECENT:
2476                 if (!mem->lastcall)
2477                         tmp->metric = 0;
2478                 else
2479                         tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2480                 tmp->metric += mem->penalty * 1000000;
2481                 break;
2482         default:
2483                 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2484                 break;
2485         }
2486         return 0;
2487 }
2488
2489 enum agent_complete_reason {
2490         CALLER,
2491         AGENT,
2492         TRANSFER
2493 };
2494
2495 static void send_agent_complete(const struct queue_ent *qe, const char *queuename,
2496         const struct ast_channel *peer, const struct member *member, time_t callstart,
2497         char *vars, size_t vars_len, enum agent_complete_reason rsn)
2498 {
2499         const char *reason;
2500
2501         if (!qe->parent->eventwhencalled)
2502                 return;
2503
2504         switch (rsn) {
2505         case CALLER:
2506                 reason = "caller";
2507                 break;
2508         case AGENT:
2509                 reason = "agent";
2510                 break;
2511         case TRANSFER:
2512                 reason = "transfer";
2513                 break;
2514         }
2515
2516         manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2517                 "Queue: %s\r\n"
2518                 "Uniqueid: %s\r\n"
2519                 "Channel: %s\r\n"
2520                 "Member: %s\r\n"
2521                 "MemberName: %s\r\n"
2522                 "HoldTime: %ld\r\n"
2523                 "TalkTime: %ld\r\n"
2524                 "Reason: %s\r\n"
2525                 "%s",
2526                 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2527                 (long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
2528                 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
2529 }
2530
2531 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)
2532 {
2533         struct member *cur;
2534         struct callattempt *outgoing = NULL; /* the list of calls we are building */
2535         int to, orig;
2536         char oldexten[AST_MAX_EXTENSION]="";
2537         char oldcontext[AST_MAX_CONTEXT]="";
2538         char queuename[256]="";
2539         char interfacevar[256]="";
2540         struct ast_channel *peer;
2541         struct ast_channel *which;
2542         struct callattempt *lpeer;
2543         struct member *member;
2544         struct ast_app *app;
2545         int res = 0, bridge = 0;
2546         int numbusies = 0;
2547         int x=0;
2548         char *announce = NULL;
2549         char digit = 0;
2550         time_t callstart;
2551         time_t now = time(NULL);
2552         struct ast_bridge_config bridge_config;
2553         char nondataquality = 1;
2554         char *agiexec = NULL;
2555         char *macroexec = NULL;
2556         char *gosubexec = NULL;
2557         int ret = 0;
2558         const char *monitorfilename;
2559         const char *monitor_exec;
2560         const char *monitor_options;
2561         char tmpid[256], tmpid2[256];
2562         char meid[1024], meid2[1024];
2563         char mixmonargs[1512];
2564         struct ast_app *mixmonapp = NULL;
2565         char *p;
2566         char vars[2048];
2567         int forwardsallowed = 1;
2568         int callcompletedinsl;
2569         struct ao2_iterator memi;
2570
2571         memset(&bridge_config, 0, sizeof(bridge_config));
2572         time(&now);
2573                 
2574         for (; options && *options; options++)
2575                 switch (*options) {
2576                 case 't':
2577                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
2578                         break;
2579                 case 'T':
2580                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
2581                         break;
2582                 case 'w':
2583                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
2584                         break;
2585                 case 'W':
2586                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
2587                         break;
2588                 case 'd':
2589                         nondataquality = 0;
2590                         break;
2591                 case 'h':
2592                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
2593                         break;
2594                 case 'H':
2595                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
2596                         break;
2597                 case 'n':
2598                         if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY)
2599                                 (*tries)++;
2600                         else
2601                                 *tries = qe->parent->membercount;
2602                         *noption = 1;
2603                         break;
2604                 case 'i':
2605                         forwardsallowed = 0;
2606                         break;
2607                 }
2608
2609         /* Hold the lock while we setup the outgoing calls */
2610         if (use_weight)
2611                 AST_LIST_LOCK(&queues);
2612         ast_mutex_lock(&qe->parent->lock);
2613         ast_debug(1, "%s is trying to call a queue member.\n",
2614                                                         qe->chan->name);
2615         ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
2616         if (!ast_strlen_zero(qe->announce))
2617                 announce = qe->announce;
2618         if (!ast_strlen_zero(announceoverride))
2619                 announce = announceoverride;
2620
2621         memi = ao2_iterator_init(qe->parent->members, 0);
2622         while ((cur = ao2_iterator_next(&memi))) {
2623                 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
2624
2625                 if (!tmp) {
2626                         ao2_ref(cur, -1);
2627                         ast_mutex_unlock(&qe->parent->lock);
2628                         if (use_weight)
2629                                 AST_LIST_UNLOCK(&queues);
2630                         goto out;
2631                 }
2632                 tmp->stillgoing = -1;
2633                 tmp->member = cur;
2634                 tmp->oldstatus = cur->status;
2635                 tmp->lastcall = cur->lastcall;
2636                 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
2637                 /* Special case: If we ring everyone, go ahead and ring them, otherwise
2638                    just calculate their metric for the appropriate strategy */
2639                 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
2640                         /* Put them in the list of outgoing thingies...  We're ready now.
2641                            XXX If we're forcibly removed, these outgoing calls won't get
2642                            hung up XXX */
2643                         tmp->q_next = outgoing;
2644                         outgoing = tmp;         
2645                         /* If this line is up, don't try anybody else */
2646                         if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
2647                                 break;
2648                 } else {
2649                         ao2_ref(cur, -1);
2650                         free(tmp);
2651                 }
2652         }
2653         if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
2654                 to = (qe->expire - now) * 1000;
2655         else
2656                 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
2657         orig = to;
2658         ring_one(qe, outgoing, &numbusies);
2659         ast_mutex_unlock(&qe->parent->lock);
2660         if (use_weight)
2661                 AST_LIST_UNLOCK(&queues);
2662         lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
2663         ast_mutex_lock(&qe->parent->lock);
2664         if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
2665                 store_next(qe, outgoing);
2666         }
2667         ast_mutex_unlock(&qe->parent->lock);
2668         peer = lpeer ? lpeer->chan : NULL;
2669         if (!peer) {
2670                 if (to) {
2671                         /* Must gotten hung up */
2672                         res = -1;
2673                 } else {
2674                         /* User exited by pressing a digit */
2675                         res = digit;
2676                 }
2677                 if (res == -1)
2678                         ast_debug(1, "%s: Nobody answered.\n", qe->chan->name);
2679         } else { /* peer is valid */
2680                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
2681                    we will always return with -1 so that it is hung up properly after the
2682                    conversation.  */
2683                 qe->handled++;
2684                 if (!strcmp(qe->chan->tech->type, "Zap"))
2685                         ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2686                 if (!strcmp(peer->tech->type, "Zap"))
2687                         ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2688                 /* Update parameters for the queue */
2689                 time(&now);
2690                 recalc_holdtime(qe, (now - qe->start));
2691                 ast_mutex_lock(&qe->parent->lock);
2692                 callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
2693                 ast_mutex_unlock(&qe->parent->lock);
2694                 member = lpeer->member;
2695                 hangupcalls(outgoing, peer);
2696                 outgoing = NULL;
2697                 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
2698                         int res2;
2699
2700                         res2 = ast_autoservice_start(qe->chan);
2701                         if (!res2) {
2702                                 if (qe->parent->memberdelay) {
2703                                         ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
2704                                         res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
2705                                 }
2706                                 if (!res2 && announce) {
2707                                         play_file(peer, announce);
2708                                 }
2709                                 if (!res2 && qe->parent->reportholdtime) {
2710                                         if (!play_file(peer, qe->parent->sound_reporthold)) {
2711                                                 int holdtime;
2712
2713                                                 time(&now);
2714                                                 holdtime = abs((now - qe->start) / 60);
2715                                                 if (holdtime < 2) {
2716                                                         play_file(peer, qe->parent->sound_lessthan);
2717                                                         ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
2718                                                 } else
2719                                                         ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
2720                                                 play_file(peer, qe->parent->sound_minutes);
2721                                         }
2722                                 }
2723                         }
2724                         res2 |= ast_autoservice_stop(qe->chan);
2725                         if (ast_check_hangup(peer)) {
2726                                 /* Agent must have hung up */
2727                                 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
2728                                 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
2729                                 record_abandoned(qe);
2730                                 if (qe->parent->eventwhencalled)
2731                                         manager_event(EVENT_FLAG_AGENT, "AgentDump",
2732                                                         "Queue: %s\r\n"
2733                                                         "Uniqueid: %s\r\n"
2734                                                         "Channel: %s\r\n"
2735                                                         "Member: %s\r\n"
2736                                                         "MemberName: %s\r\n"
2737                                                         "%s",
2738                                                         queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2739                                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2740                                 ast_hangup(peer);
2741                                 goto out;
2742                         } else if (res2) {
2743                                 /* Caller must have hung up just before being connected*/
2744                                 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
2745                                 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2746                                 record_abandoned(qe);
2747                                 ast_hangup(peer);
2748                                 return -1;
2749                         }
2750                 }
2751                 /* Stop music on hold */
2752                 if (ringing)
2753                         ast_indicate(qe->chan,-1);
2754                 else
2755                         ast_moh_stop(qe->chan);
2756                 /* If appropriate, log that we have a destination channel */
2757                 if (qe->chan->cdr)
2758                         ast_cdr_setdestchan(qe->chan->cdr, peer->name);
2759                 /* Make sure channels are compatible */
2760                 res = ast_channel_make_compatible(qe->chan, peer);
2761                 if (res < 0) {
2762                         ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
2763                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
2764                         record_abandoned(qe);
2765                         ast_hangup(peer);
2766                         return -1;
2767                 }
2768
2769                 /* Play announcement to the caller telling it's his turn if defined */
2770                 if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
2771                         if (play_file(qe->chan, qe->parent->sound_callerannounce))
2772                                 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
2773                 }
2774
2775                 ast_mutex_lock(&qe->parent->lock);
2776                 /* if setinterfacevar is defined, make member variables available to the channel */
2777                 /* use  pbx_builtin_setvar to set a load of variables with one call */
2778                 if (qe->parent->setinterfacevar) {
2779                         snprintf(interfacevar,sizeof(interfacevar), "MEMBERINTERFACE=%s|MEMBERNAME=%s|MEMBERCALLS=%d|MEMBERLASTCALL=%ld|MEMBERPENALTY=%d|MEMBERDYNAMIC=%d|MEMBERREALTIME=%d",
2780                                 member->interface, member->membername, member->calls, (long)member->lastcall, member->penalty, member->dynamic, member->realtime);
2781                         pbx_builtin_setvar(qe->chan, interfacevar);
2782                 }
2783                 
2784                 /* if setqueueentryvar is defined, make queue entry (i.e. the caller) variables available to the channel */
2785                 /* use  pbx_builtin_setvar to set a load of variables with one call */
2786                 if (qe->parent->setqueueentryvar) {
2787                         snprintf(interfacevar,sizeof(interfacevar), "QEHOLDTIME=%ld|QEORIGINALPOS=%d",
2788                                 (long) time(NULL) - qe->start, qe->opos);
2789                         pbx_builtin_setvar(qe->chan, interfacevar);
2790                 }
2791         
2792                 /* try to set queue variables if configured to do so*/
2793                 set_queue_variables(qe);
2794                 ast_mutex_unlock(&qe->parent->lock);
2795                 
2796                 /* Begin Monitoring */
2797                 if (qe->parent->monfmt && *qe->parent->monfmt) {
2798                         if (!qe->parent->montype) {
2799                                 ast_debug(1, "Starting Monitor as requested.\n");
2800                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2801                                 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
2802                                         which = qe->chan;
2803                                 else
2804                                         which = peer;
2805                                 if (monitorfilename)
2806                                         ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT);
2807                                 else if (qe->chan->cdr)
2808                                         ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1, X_REC_IN | X_REC_OUT);
2809                                 else {
2810                                         /* Last ditch effort -- no CDR, make up something */
2811                                         snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2812                                         ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT);
2813                                 }
2814                                 if (qe->parent->monjoin)
2815                                         ast_monitor_setjoinfiles(which, 1);
2816                         } else {
2817                                 ast_debug(1, "Starting MixMonitor as requested.\n");
2818                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2819                                 if (!monitorfilename) {
2820                                         if (qe->chan->cdr)
2821                                                 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid)-1);
2822                                         else
2823                                                 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2824                                 } else {
2825                                         ast_copy_string(tmpid2, monitorfilename, sizeof(tmpid2)-1);
2826                                         for (p = tmpid2; *p ; p++) {
2827                                                 if (*p == '^' && *(p+1) == '{') {
2828                                                         *p = '$';
2829                                                 }
2830                                         }
2831
2832                                         memset(tmpid, 0, sizeof(tmpid));
2833                                         pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
2834                                 }
2835
2836                                 monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
2837                                 monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
2838
2839                                 if (monitor_exec) {
2840                                         ast_copy_string(meid2, monitor_exec, sizeof(meid2)-1);
2841                                         for (p = meid2; *p ; p++) {
2842                                                 if (*p == '^' && *(p+1) == '{') {
2843                                                         *p = '$';
2844                                                 }
2845                                         }
2846
2847                                         memset(meid, 0, sizeof(meid));
2848                                         pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
2849                                 }
2850         
2851                                 snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
2852
2853                                 mixmonapp = pbx_findapp("MixMonitor");
2854
2855                                 if (strchr(tmpid2, '|')) {
2856                                         ast_log(LOG_WARNING, "monitor-format (in queues.conf) and MONITOR_FILENAME cannot contain a '|'! Not recording.\n");
2857                                         mixmonapp = NULL;
2858                                 }
2859
2860                                 if (!monitor_options)
2861                                         monitor_options = "";
2862                                 
2863                                 if (strchr(monitor_options, '|')) {
2864                                         ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
2865                                         mixmonapp = NULL;
2866                                 }
2867
2868                                 if (mixmonapp) {
2869                                         if (!ast_strlen_zero(monitor_exec))
2870                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
2871                                         else
2872                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
2873                                                 
2874                                         ast_debug(1, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
2875
2876                                         ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
2877
2878                                 } else
2879                                         ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
2880
2881                         }
2882                 }
2883                 /* Drop out of the queue at this point, to prepare for next caller */
2884                 leave_queue(qe);                        
2885                 if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
2886                         ast_debug(1, "app_queue: sendurl=%s.\n", url);
2887                         ast_channel_sendurl(peer, url);
2888                 }
2889                 
2890                 /* run a macro for this connection if defined. The macro simply returns, no action is taken on the result */
2891                 /* use macro from dialplan if passed as a option, otherwise use the default queue macro */
2892                 if (!ast_strlen_zero(macro)) {
2893                                 macroexec = ast_strdupa(macro);
2894                 } else {
2895                         if (qe->parent->membermacro)
2896                                 macroexec = ast_strdupa(qe->parent->membermacro);
2897                 }
2898
2899                 if (!ast_strlen_zero(macroexec)) {
2900                         ast_debug(1, "app_queue: macro=%s.\n", macroexec);
2901                         
2902                         res = ast_autoservice_start(qe->chan);
2903                         if (res) {
2904                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2905                                 res = -1;
2906                         }
2907                         
2908                         app = pbx_findapp("Macro");
2909                         
2910                         if (app) {
2911                                 res = pbx_exec(qe->chan, app, macroexec);
2912                                 ast_debug(1, "Macro exited with status %d\n", res);
2913                                 res = 0;
2914                         } else {
2915                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
2916                                 res = -1;
2917                         }
2918                 
2919                         if (ast_autoservice_stop(qe->chan) < 0) {
2920                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
2921                                 res = -1;
2922                         }
2923                 }
2924
2925                 /* run a gosub for this connection if defined. The gosub simply returns, no action is taken on the result */
2926                 /* use gosub from dialplan if passed as a option, otherwise use the default queue gosub */
2927                 if (!ast_strlen_zero(gosub)) {
2928                                 gosubexec = ast_strdupa(gosub);
2929                 } else {
2930                         if (qe->parent->membergosub)
2931                                 gosubexec = ast_strdupa(qe->parent->membergosub);
2932                 }
2933
2934                 if (!ast_strlen_zero(gosubexec)) {
2935                         if (option_debug)
2936                                 ast_log(LOG_DEBUG, "app_queue: gosub=%s.\n", gosubexec);
2937                         
2938                         res = ast_autoservice_start(qe->chan);
2939                         if (res) {