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