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