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