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