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