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