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