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