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