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