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