Not having this epoll specific code in wait_for_answer was causing app_queue to infin...
[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 #ifdef HAVE_EPOLL
2046         struct callattempt *epollo;
2047 #endif
2048
2049         starttime = (long) time(NULL);
2050 #ifdef HAVE_EPOLL
2051         for (epollo = outgoing; epollo; epollo = epollo->q_next)
2052                 ast_poll_channel_add(in, epollo->chan);
2053 #endif
2054         
2055         while (*to && !peer) {
2056                 int numlines, retry, pos = 1;
2057                 struct ast_channel *watchers[AST_MAX_WATCHERS];
2058                 watchers[0] = in;
2059
2060                 for (retry = 0; retry < 2; retry++) {
2061                         numlines = 0;
2062                         for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
2063                                 if (o->stillgoing) {    /* Keep track of important channels */
2064                                         stillgoing = 1;
2065                                         if (o->chan)
2066                                                 watchers[pos++] = o->chan;
2067                                 }
2068                                 numlines++;
2069                         }
2070                         if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
2071                                 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
2072                                 break;
2073                         /* On "ringall" strategy we only move to the next penalty level
2074                            when *all* ringing phones are done in the current penalty level */
2075                         ring_one(qe, outgoing, &numbusies);
2076                         /* and retry... */
2077                 }
2078                 if (pos == 1 /* not found */) {
2079                         if (numlines == (numbusies + numnochan)) {
2080                                 ast_debug(1, "Everyone is busy at this time\n");
2081                         } else {
2082                                 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
2083                         }
2084                         *to = 0;
2085                         return NULL;
2086                 }
2087                 winner = ast_waitfor_n(watchers, pos, to);
2088                 for (o = outgoing; o; o = o->q_next) {
2089                         if (o->stillgoing && (o->chan) &&  (o->chan->_state == AST_STATE_UP)) {
2090                                 if (!peer) {
2091                                         ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2092                                         peer = o;
2093                                 }
2094                         } else if (o->chan && (o->chan == winner)) {
2095
2096                                 ast_copy_string(on, o->member->interface, sizeof(on));
2097                                 ast_copy_string(membername, o->member->membername, sizeof(membername));
2098
2099                                 if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
2100                                         ast_verb(3, "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
2101                                         numnochan++;
2102                                         do_hang(o);
2103                                         winner = NULL;
2104                                         continue;
2105                                 } else if (!ast_strlen_zero(o->chan->call_forward)) {
2106                                         char tmpchan[256];
2107                                         char *stuff;
2108                                         char *tech;
2109
2110                                         ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
2111                                         if ((stuff = strchr(tmpchan, '/'))) {
2112                                                 *stuff++ = '\0';
2113                                                 tech = tmpchan;
2114                                         } else {
2115                                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
2116                                                 stuff = tmpchan;
2117                                                 tech = "Local";
2118                                         }
2119                                         /* Before processing channel, go ahead and check for forwarding */
2120                                         ast_verb(3, "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
2121                                         /* Setup parameters */
2122                                         o->chan = ast_request(tech, in->nativeformats, stuff, &status);
2123                                         if (status != o->oldstatus)
2124                                                 update_dial_status(qe->parent, o->member, status);                                              
2125                                         if (!o->chan) {
2126                                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
2127                                                 o->stillgoing = 0;
2128                                                 numnochan++;
2129                                         } else {
2130                                                 ast_channel_inherit_variables(in, o->chan);
2131                                                 if (o->chan->cid.cid_num)
2132                                                         ast_free(o->chan->cid.cid_num);
2133                                                 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
2134
2135                                                 if (o->chan->cid.cid_name)
2136                                                         ast_free(o->chan->cid.cid_name);
2137                                                 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
2138
2139                                                 ast_string_field_set(o->chan, accountcode, in->accountcode);
2140                                                 o->chan->cdrflags = in->cdrflags;
2141
2142                                                 if (in->cid.cid_ani) {
2143                                                         if (o->chan->cid.cid_ani)
2144                                                                 ast_free(o->chan->cid.cid_ani);
2145                                                         o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
2146                                                 }
2147                                                 if (o->chan->cid.cid_rdnis)
2148                                                         ast_free(o->chan->cid.cid_rdnis);
2149                                                 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
2150                                                 if (ast_call(o->chan, tmpchan, 0)) {
2151                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
2152                                                         do_hang(o);
2153                                                         numnochan++;
2154                                                 }
2155                                         }
2156                                         /* Hangup the original channel now, in case we needed it */
2157                                         ast_hangup(winner);
2158                                         continue;
2159                                 }
2160                                 f = ast_read(winner);
2161                                 if (f) {
2162                                         if (f->frametype == AST_FRAME_CONTROL) {
2163                                                 switch (f->subclass) {
2164                                                 case AST_CONTROL_ANSWER:
2165                                                         /* This is our guy if someone answered. */
2166                                                         if (!peer) {
2167                                                                 ast_verb(3, "%s answered %s\n", o->chan->name, in->name);
2168                                                                 peer = o;
2169                                                         }
2170                                                         break;
2171                                                 case AST_CONTROL_BUSY:
2172                                                         ast_verb(3, "%s is busy\n", o->chan->name);
2173                                                         if (in->cdr)
2174                                                                 ast_cdr_busy(in->cdr);
2175                                                         do_hang(o);
2176                                                         endtime = (long) time(NULL);
2177                                                         endtime -= starttime;
2178                                                         rna(endtime*1000, qe, on, membername);
2179                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2180                                                                 if (qe->parent->timeoutrestart)
2181                                                                         *to = orig;
2182                                                                 ring_one(qe, outgoing, &numbusies);
2183                                                         }
2184                                                         numbusies++;
2185                                                         break;
2186                                                 case AST_CONTROL_CONGESTION:
2187                                                         ast_verb(3, "%s is circuit-busy\n", o->chan->name);
2188                                                         if (in->cdr)
2189                                                                 ast_cdr_busy(in->cdr);
2190                                                         endtime = (long) time(NULL);
2191                                                         endtime -= starttime;
2192                                                         rna(endtime*1000, qe, on, membername);
2193                                                         do_hang(o);
2194                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2195                                                                 if (qe->parent->timeoutrestart)
2196                                                                         *to = orig;
2197                                                                 ring_one(qe, outgoing, &numbusies);
2198                                                         }
2199                                                         numbusies++;
2200                                                         break;
2201                                                 case AST_CONTROL_RINGING:
2202                                                         ast_verb(3, "%s is ringing\n", o->chan->name);
2203                                                         if (!sentringing) {
2204 #if 0
2205                                                                 ast_indicate(in, AST_CONTROL_RINGING);
2206 #endif                                                          
2207                                                                 sentringing++;
2208                                                         }
2209                                                         break;
2210                                                 case AST_CONTROL_OFFHOOK:
2211                                                         /* Ignore going off hook */
2212                                                         break;
2213                                                 default:
2214                                                         ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
2215                                                 }
2216                                         }
2217                                         ast_frfree(f);
2218                                 } else {
2219                                         endtime = (long) time(NULL) - starttime;
2220                                         rna(endtime * 1000, qe, on, membername);
2221                                         do_hang(o);
2222                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2223                                                 if (qe->parent->timeoutrestart)
2224                                                         *to = orig;
2225                                                 ring_one(qe, outgoing, &numbusies);
2226                                         }
2227                                 }
2228                         }
2229                 }
2230                 if (winner == in) {
2231                         f = ast_read(in);
2232                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2233                                 /* Got hung up */
2234                                 *to = -1;
2235                                 if (f)
2236                                         ast_frfree(f);
2237                                 return NULL;
2238                         }
2239                         if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2240                                 ast_verb(3, "User hit %c to disconnect call.\n", f->subclass);
2241                                 *to = 0;
2242                                 ast_frfree(f);
2243                                 return NULL;
2244                         }
2245                         if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
2246                                 ast_verb(3, "User pressed digit: %c\n", f->subclass);
2247                                 *to = 0;
2248                                 *digit = f->subclass;
2249                                 ast_frfree(f);
2250                                 return NULL;
2251                         }
2252                         ast_frfree(f);
2253                 }
2254                 if (!*to)
2255                         rna(orig, qe, on, membername);
2256         }
2257
2258 #ifdef HAVE_EPOLL
2259         for(epollo = outgoing; epollo; epollo = epollo->q_next)
2260                 ast_poll_channel_del(in, epollo->chan);
2261 #endif
2262
2263         return peer;
2264 }
2265
2266 static int is_our_turn(struct queue_ent *qe)
2267 {
2268         struct queue_ent *ch;
2269         struct member *cur;
2270         int avl = 0;
2271         int idx = 0;
2272         int res;
2273
2274         if (!qe->parent->autofill) {
2275                 /* Atomically read the parent head -- does not need a lock */
2276                 ch = qe->parent->head;
2277                 /* If we are now at the top of the head, break out */
2278                 if (ch == qe) {
2279                         ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2280                         res = 1;
2281                 } else {
2282                         ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2283                         res = 0;
2284                 }       
2285
2286         } else {
2287                 /* This needs a lock. How many members are available to be served? */
2288                 ast_mutex_lock(&qe->parent->lock);
2289                         
2290                 ch = qe->parent->head;
2291         
2292                 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2293                         ast_debug(1, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in\n", avl);
2294                         avl = 1;
2295                 } else {
2296                         for (cur = qe->parent->members; cur; cur = cur->next) {
2297                                 switch (cur->status) {
2298                                 case AST_DEVICE_NOT_INUSE:
2299                                 case AST_DEVICE_UNKNOWN:
2300                                         if (!cur->paused)
2301                                                 avl++;
2302                                         break;
2303                                 }
2304                         }
2305                 }
2306
2307                 ast_debug(1, "There are %d available members.\n", avl);
2308         
2309                 while ((idx < avl) && (ch) && (ch != qe)) {
2310                         idx++;
2311                         ch = ch->next;                  
2312                 }
2313         
2314                 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2315                 if (ch && idx < avl) {
2316                         ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2317                         res = 1;
2318                 } else {
2319                         ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2320                         res = 0;
2321                 }
2322                 
2323                 ast_mutex_unlock(&qe->parent->lock);
2324         }
2325
2326         return res;
2327 }
2328
2329 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2330 {
2331         int res = 0;
2332
2333         /* This is the holding pen for callers 2 through maxlen */
2334         for (;;) {
2335                 enum queue_member_status stat;
2336
2337                 if (is_our_turn(qe))
2338                         break;
2339
2340                 /* If we have timed out, break out */
2341                 if (qe->expire && (time(NULL) > qe->expire)) {
2342                         *reason = QUEUE_TIMEOUT;
2343                         break;
2344                 }
2345
2346                 stat = get_member_status(qe->parent, qe->max_penalty);
2347
2348                 /* leave the queue if no agents, if enabled */
2349                 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2350                         *reason = QUEUE_LEAVEEMPTY;
2351                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2352                         leave_queue(qe);
2353                         break;
2354                 }
2355
2356                 /* leave the queue if no reachable agents, if enabled */
2357                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
2358                         *reason = QUEUE_LEAVEUNAVAIL;
2359                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2360                         leave_queue(qe);
2361                         break;
2362                 }
2363                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2364                         *reason = QUEUE_LEAVEUNAVAIL;
2365                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2366                         leave_queue(qe);
2367                         break;
2368                 }
2369
2370                 /* Make a position announcement, if enabled */
2371                 if (qe->parent->announcefrequency &&
2372                         (res = say_position(qe,ringing)))
2373                         break;
2374
2375                 /* Make a periodic announcement, if enabled */
2376                 if (qe->parent->periodicannouncefrequency &&
2377                         (res = say_periodic_announcement(qe,ringing)))
2378                         break;
2379
2380                 /* Wait a second before checking again */
2381                 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
2382                         if (res > 0 && !valid_exit(qe, res))
2383                                 res = 0;
2384                         else
2385                                 break;
2386                 }
2387         }
2388
2389         return res;
2390 }
2391
2392 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
2393 {
2394         struct member *cur;
2395
2396         /* Since a reload could have taken place, we have to traverse the list to
2397                 be sure it's still valid */
2398         ast_mutex_lock(&q->lock);
2399         cur = q->members;
2400         while (cur) {
2401                 if (member == cur) {
2402                         time(&cur->lastcall);
2403                         cur->calls++;
2404                         break;
2405                 }
2406                 cur = cur->next;
2407         }
2408         q->callscompleted++;
2409         if (callcompletedinsl)
2410                 q->callscompletedinsl++;
2411         ast_mutex_unlock(&q->lock);
2412         return 0;
2413 }
2414
2415 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2416 {
2417         if (qe->max_penalty && (mem->penalty > qe->max_penalty))
2418                 return -1;
2419
2420         switch (q->strategy) {
2421         case QUEUE_STRATEGY_RINGALL:
2422                 /* Everyone equal, except for penalty */
2423                 tmp->metric = mem->penalty * 1000000;
2424                 break;
2425         case QUEUE_STRATEGY_RRMEMORY:
2426                 if (pos < q->rrpos) {
2427                         tmp->metric = 1000 + pos;
2428                 } else {
2429                         if (pos > q->rrpos)
2430                                 /* Indicate there is another priority */
2431                                 q->wrapped = 1;
2432                         tmp->metric = pos;
2433                 }
2434                 tmp->metric += mem->penalty * 1000000;
2435                 break;
2436         case QUEUE_STRATEGY_RANDOM:
2437                 tmp->metric = ast_random() % 1000;
2438                 tmp->metric += mem->penalty * 1000000;
2439                 break;
2440         case QUEUE_STRATEGY_FEWESTCALLS:
2441                 tmp->metric = mem->calls;
2442                 tmp->metric += mem->penalty * 1000000;
2443                 break;
2444         case QUEUE_STRATEGY_LEASTRECENT:
2445                 if (!mem->lastcall)
2446                         tmp->metric = 0;
2447                 else
2448                         tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2449                 tmp->metric += mem->penalty * 1000000;
2450                 break;
2451         default:
2452                 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2453                 break;
2454         }
2455         return 0;
2456 }
2457
2458 enum agent_complete_reason {
2459         CALLER,
2460         AGENT,
2461         TRANSFER
2462 };
2463
2464 static void send_agent_complete(const struct queue_ent *qe, const char *queuename,
2465         const struct ast_channel *peer, const struct member *member, time_t callstart,
2466         char *vars, size_t vars_len, enum agent_complete_reason rsn)
2467 {
2468         const char *reason;
2469
2470         if (!qe->parent->eventwhencalled)
2471                 return;
2472
2473         switch (rsn) {
2474         case CALLER:
2475                 reason = "caller";
2476                 break;
2477         case AGENT:
2478                 reason = "agent";
2479                 break;
2480         case TRANSFER:
2481                 reason = "transfer";
2482                 break;
2483         }
2484
2485         manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2486                 "Queue: %s\r\n"
2487                 "Uniqueid: %s\r\n"
2488                 "Channel: %s\r\n"
2489                 "Member: %s\r\n"
2490                 "MemberName: %s\r\n"
2491                 "HoldTime: %ld\r\n"
2492                 "TalkTime: %ld\r\n"
2493                 "Reason: %s\r\n"
2494                 "%s",
2495                 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2496                 (long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
2497                 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
2498 }
2499
2500 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)
2501 {
2502         struct member *cur;
2503         struct callattempt *outgoing = NULL; /* the list of calls we are building */
2504         int to, orig;
2505         char oldexten[AST_MAX_EXTENSION]="";
2506         char oldcontext[AST_MAX_CONTEXT]="";
2507         char queuename[256]="";
2508         char interfacevar[256]="";
2509         struct ast_channel *peer;
2510         struct ast_channel *which;
2511         struct callattempt *lpeer;
2512         struct member *member;
2513         struct ast_app *app;
2514         int res = 0, bridge = 0;
2515         int numbusies = 0;
2516         int x=0;
2517         char *announce = NULL;
2518         char digit = 0;
2519         time_t callstart;
2520         time_t now = time(NULL);
2521         struct ast_bridge_config bridge_config;
2522         char nondataquality = 1;
2523         char *agiexec = NULL;
2524         char *macroexec = NULL;
2525         char *gosubexec = NULL;
2526         int ret = 0;
2527         const char *monitorfilename;
2528         const char *monitor_exec;
2529         const char *monitor_options;
2530         char tmpid[256], tmpid2[256];
2531         char meid[1024], meid2[1024];
2532         char mixmonargs[1512];
2533         struct ast_app *mixmonapp = NULL;
2534         char *p;
2535         char vars[2048];
2536         int forwardsallowed = 1;
2537         int callcompletedinsl;
2538
2539         memset(&bridge_config, 0, sizeof(bridge_config));
2540         time(&now);
2541                 
2542         for (; options && *options; options++)
2543                 switch (*options) {
2544                 case 't':
2545                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
2546                         break;
2547                 case 'T':
2548                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
2549                         break;
2550                 case 'w':
2551                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
2552                         break;
2553                 case 'W':
2554                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
2555                         break;
2556                 case 'd':
2557                         nondataquality = 0;
2558                         break;
2559                 case 'h':
2560                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
2561                         break;
2562                 case 'H':
2563                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
2564                         break;
2565                 case 'n':
2566                         if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY)
2567                                 (*tries)++;
2568                         else
2569                                 *tries = qe->parent->membercount;
2570                         *noption = 1;
2571                         break;
2572                 case 'i':
2573                         forwardsallowed = 0;
2574                         break;
2575                 }
2576
2577         /* Hold the lock while we setup the outgoing calls */
2578         if (use_weight)
2579                 AST_LIST_LOCK(&queues);
2580         ast_mutex_lock(&qe->parent->lock);
2581         ast_debug(1, "%s is trying to call a queue member.\n",
2582                                                         qe->chan->name);
2583         ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
2584         cur = qe->parent->members;
2585         if (!ast_strlen_zero(qe->announce))
2586                 announce = qe->announce;
2587         if (!ast_strlen_zero(announceoverride))
2588                 announce = announceoverride;
2589
2590         for (; cur; cur = cur->next) {
2591                 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
2592
2593                 if (!tmp) {
2594                         ast_mutex_unlock(&qe->parent->lock);
2595                         if (use_weight)
2596                                 AST_LIST_UNLOCK(&queues);
2597                         goto out;
2598                 }
2599                 tmp->stillgoing = -1;
2600                 tmp->member = cur;              /* Never directly dereference!  Could change on reload */
2601                 tmp->oldstatus = cur->status;
2602                 tmp->lastcall = cur->lastcall;
2603                 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
2604                 /* Special case: If we ring everyone, go ahead and ring them, otherwise
2605                    just calculate their metric for the appropriate strategy */
2606                 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
2607                         /* Put them in the list of outgoing thingies...  We're ready now.
2608                            XXX If we're forcibly removed, these outgoing calls won't get
2609                            hung up XXX */
2610                         tmp->q_next = outgoing;
2611                         outgoing = tmp;         
2612                         /* If this line is up, don't try anybody else */
2613                         if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
2614                                 break;
2615                 } else {
2616                         ast_free(tmp);
2617                 }
2618         }
2619         if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
2620                 to = (qe->expire - now) * 1000;
2621         else
2622                 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
2623         orig = to;
2624         ring_one(qe, outgoing, &numbusies);
2625         ast_mutex_unlock(&qe->parent->lock);
2626         if (use_weight)
2627                 AST_LIST_UNLOCK(&queues);
2628         lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
2629         ast_mutex_lock(&qe->parent->lock);
2630         if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
2631                 store_next(qe, outgoing);
2632         }
2633         ast_mutex_unlock(&qe->parent->lock);
2634         peer = lpeer ? lpeer->chan : NULL;
2635         if (!peer) {
2636                 if (to) {
2637                         /* Must gotten hung up */
2638                         res = -1;
2639                 } else {
2640                         res = digit;
2641                         if (res > 0 && !valid_exit(qe, res))
2642                                 res = 0;
2643                 }
2644                 ast_debug(1, "%s: Nobody answered.\n", qe->chan->name);
2645         } else { /* peer is valid */
2646                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
2647                    we will always return with -1 so that it is hung up properly after the
2648                    conversation.  */
2649                 qe->handled++;
2650                 if (!strcmp(qe->chan->tech->type, "Zap"))
2651                         ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2652                 if (!strcmp(peer->tech->type, "Zap"))
2653                         ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2654                 /* Update parameters for the queue */
2655                 time(&now);
2656                 recalc_holdtime(qe, (now - qe->start));
2657                 ast_mutex_lock(&qe->parent->lock);
2658                 callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
2659                 ast_mutex_unlock(&qe->parent->lock);
2660                 member = lpeer->member;
2661                 hangupcalls(outgoing, peer);
2662                 outgoing = NULL;
2663                 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
2664                         int res2;
2665
2666                         res2 = ast_autoservice_start(qe->chan);
2667                         if (!res2) {
2668                                 if (qe->parent->memberdelay) {
2669                                         ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
2670                                         res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
2671                                 }
2672                                 if (!res2 && announce) {
2673                                         play_file(peer, announce);
2674                                 }
2675                                 if (!res2 && qe->parent->reportholdtime) {
2676                                         if (!play_file(peer, qe->parent->sound_reporthold)) {
2677                                                 int holdtime;
2678
2679                                                 time(&now);
2680                                                 holdtime = abs((now - qe->start) / 60);
2681                                                 if (holdtime < 2) {
2682                                                         play_file(peer, qe->parent->sound_lessthan);
2683                                                         ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
2684                                                 } else
2685                                                         ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
2686                                                 play_file(peer, qe->parent->sound_minutes);
2687                                         }
2688                                 }
2689                         }
2690                         res2 |= ast_autoservice_stop(qe->chan);
2691                         if (ast_check_hangup(peer)) {
2692                                 /* Agent must have hung up */
2693                                 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
2694                                 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
2695                                 record_abandoned(qe);
2696                                 if (qe->parent->eventwhencalled)
2697                                         manager_event(EVENT_FLAG_AGENT, "AgentDump",
2698                                                         "Queue: %s\r\n"
2699                                                         "Uniqueid: %s\r\n"
2700                                                         "Channel: %s\r\n"
2701                                                         "Member: %s\r\n"
2702                                                         "MemberName: %s\r\n"
2703                                                         "%s",
2704                                                         queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2705                                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2706                                 ast_hangup(peer);
2707                                 goto out;
2708                         } else if (res2) {
2709                                 /* Caller must have hung up just before being connected*/
2710                                 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
2711                                 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2712                                 record_abandoned(qe);
2713                                 ast_hangup(peer);
2714                                 return -1;
2715                         }
2716                 }
2717                 /* Stop music on hold */
2718                 if (ringing)
2719                         ast_indicate(qe->chan,-1);
2720                 else
2721                         ast_moh_stop(qe->chan);
2722                 /* If appropriate, log that we have a destination channel */
2723                 if (qe->chan->cdr)
2724                         ast_cdr_setdestchan(qe->chan->cdr, peer->name);
2725                 /* Make sure channels are compatible */
2726                 res = ast_channel_make_compatible(qe->chan, peer);
2727                 if (res < 0) {
2728                         ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
2729                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
2730                         record_abandoned(qe);
2731                         ast_hangup(peer);
2732                         return -1;
2733                 }
2734
2735                 /* Play announcement to the caller telling it's his turn if defined */
2736                 if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
2737                         if (play_file(qe->chan, qe->parent->sound_callerannounce))
2738                                 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
2739                 }
2740
2741                 /* Begin Monitoring */
2742                 if (qe->parent->monfmt && *qe->parent->monfmt) {
2743                         if (!qe->parent->montype) {
2744                                 ast_debug(1, "Starting Monitor as requested.\n");
2745                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2746                                 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
2747                                         which = qe->chan;
2748                                 else
2749                                         which = peer;
2750                                 if (monitorfilename)
2751                                         ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT);
2752                                 else if (qe->chan->cdr)
2753                                         ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1, X_REC_IN | X_REC_OUT);
2754                                 else {
2755                                         /* Last ditch effort -- no CDR, make up something */
2756                                         snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2757                                         ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT);
2758                                 }
2759                                 if (qe->parent->monjoin)
2760                                         ast_monitor_setjoinfiles(which, 1);
2761                         } else {
2762                                 ast_debug(1, "Starting MixMonitor as requested.\n");
2763                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2764                                 if (!monitorfilename) {
2765                                         if (qe->chan->cdr)
2766                                                 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid)-1);
2767                                         else
2768                                                 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2769                                 } else {
2770                                         ast_copy_string(tmpid2, monitorfilename, sizeof(tmpid2)-1);
2771                                         for (p = tmpid2; *p ; p++) {
2772                                                 if (*p == '^' && *(p+1) == '{') {
2773                                                         *p = '$';
2774                                                 }
2775                                         }
2776
2777                                         memset(tmpid, 0, sizeof(tmpid));
2778                                         pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
2779                                 }
2780
2781                                 monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
2782                                 monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
2783
2784                                 if (monitor_exec) {
2785                                         ast_copy_string(meid2, monitor_exec, sizeof(meid2)-1);
2786                                         for (p = meid2; *p ; p++) {
2787                                                 if (*p == '^' && *(p+1) == '{') {
2788                                                         *p = '$';
2789                                                 }
2790                                         }
2791
2792                                         memset(meid, 0, sizeof(meid));
2793                                         pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
2794                                 }
2795         
2796                                 snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
2797
2798                                 mixmonapp = pbx_findapp("MixMonitor");
2799
2800                                 if (strchr(tmpid2, '|')) {
2801                                         ast_log(LOG_WARNING, "monitor-format (in queues.conf) and MONITOR_FILENAME cannot contain a '|'! Not recording.\n");
2802                                         mixmonapp = NULL;
2803                                 }
2804
2805                                 if (!monitor_options)
2806                                         monitor_options = "";
2807                                 
2808                                 if (strchr(monitor_options, '|')) {
2809                                         ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
2810                                         mixmonapp = NULL;
2811                                 }
2812
2813                                 if (mixmonapp) {
2814                                         if (!ast_strlen_zero(monitor_exec))
2815                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
2816                                         else
2817                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
2818                                                 
2819                                         ast_debug(1, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
2820
2821                                         ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
2822
2823                                 } else
2824                                         ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
2825
2826                         }
2827                 }
2828                 /* Drop out of the queue at this point, to prepare for next caller */
2829                 leave_queue(qe);                        
2830                 if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
2831                         ast_debug(1, "app_queue: sendurl=%s.\n", url);
2832                         ast_channel_sendurl(peer, url);
2833                 }
2834                 
2835                 ast_mutex_lock(&qe->parent->lock);
2836                 /* if setinterfacevar is defined, make member variables available to the channel */
2837                 /* use  pbx_builtin_setvar to set a load of variables with one call */
2838                 if (qe->parent->setinterfacevar) {
2839                         snprintf(interfacevar,sizeof(interfacevar), "MEMBERINTERFACE=%s|MEMBERNAME=%s|MEMBERCALLS=%d|MEMBERLASTCALL=%ld|MEMBERPENALTY=%d|MEMBERDYNAMIC=%d|MEMBERREALTIME=%d",
2840                                 member->interface, member->membername, member->calls, (long)member->lastcall, member->penalty, member->dynamic, member->realtime);
2841                         pbx_builtin_setvar(qe->chan, interfacevar);
2842                 }
2843                 
2844                 /* if setqueueentryvar is defined, make queue entry (i.e. the caller) variables available to the channel */
2845                 /* use  pbx_builtin_setvar to set a load of variables with one call */
2846                 if (qe->parent->setqueueentryvar) {
2847                         snprintf(interfacevar,sizeof(interfacevar), "QEHOLDTIME=%ld|QEORIGINALPOS=%d",
2848                                 (long) time(NULL) - qe->start, qe->opos);
2849                         pbx_builtin_setvar(qe->chan, interfacevar);
2850                 }
2851         
2852                 /* try to set queue variables if configured to do so*/
2853                 set_queue_variables(qe);
2854                 ast_mutex_unlock(&qe->parent->lock);
2855                 
2856                 /* run a macro for this connection if defined. The macro simply returns, no action is taken on the result */
2857                 /* use macro from dialplan if passed as a option, otherwise use the default queue macro */
2858                 if (!ast_strlen_zero(macro)) {
2859                                 macroexec = ast_strdupa(macro);
2860                 } else {
2861                         if (qe->parent->membermacro)
2862                                 macroexec = ast_strdupa(qe->parent->membermacro);
2863                 }
2864
2865                 if (!ast_strlen_zero(macroexec)) {
2866                         ast_debug(1, "app_queue: macro=%s.\n", macroexec);
2867                         
2868                         res = ast_autoservice_start(qe->chan);
2869                         if (res) {
2870                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2871                                 res = -1;
2872                         }
2873                         
2874                         app = pbx_findapp("Macro");
2875                         
2876                         if (app) {
2877                                 res = pbx_exec(qe->chan, app, macroexec);
2878                                 ast_debug(1, "Macro exited with status %d\n", res);
2879                                 res = 0;
2880                         } else {
2881                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
2882                                 res = -1;
2883                         }
2884                 
2885                         if (ast_autoservice_stop(qe->chan) < 0) {
2886                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
2887                                 res = -1;
2888                         }
2889                 }
2890
2891                 /* run a gosub for this connection if defined. The gosub simply returns, no action is taken on the result */
2892                 /* use gosub from dialplan if passed as a option, otherwise use the default queue gosub */
2893                 if (!ast_strlen_zero(gosub)) {
2894                                 gosubexec = ast_strdupa(gosub);
2895                 } else {
2896                         if (qe->parent->membergosub)
2897                                 gosubexec = ast_strdupa(qe->parent->membergosub);
2898                 }
2899
2900                 if (!ast_strlen_zero(gosubexec)) {
2901                         if (option_debug)
2902                                 ast_log(LOG_DEBUG, "app_queue: gosub=%s.\n", gosubexec);
2903                         
2904                         res = ast_autoservice_start(qe->chan);
2905                         if (res) {
2906                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2907                                 res = -1;
2908                         }
2909                         
2910                         app = pbx_findapp("Gosub");
2911                         
2912                         if (app) {
2913                                 char *gosub_args, *gosub_argstart;
2914
2915                                 /* Set where we came from */
2916                                 ast_copy_string(qe->chan->context, "app_dial_gosub_virtual_context", sizeof(qe->chan->context));
2917                                 ast_copy_string(qe->chan->exten, "s", sizeof(qe->chan->exten));
2918                                 qe->chan->priority = 0;
2919
2920                                 gosub_argstart = strchr(gosubexec, '|');
2921                                 if (gosub_argstart) {
2922                                         *gosub_argstart = 0;
2923                                         asprintf(&gosub_args, "%s|s|1(%s)", gosubexec, gosub_argstart + 1);
2924                                         *gosub_argstart = '|';
2925                                 } else {