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