3e2f15340c5aa7b0dda72b399acb1b49c195bcbd
[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 8192
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                         break;
2139                 }
2140
2141                 stat = get_member_status(qe->parent, qe->max_penalty);
2142
2143                 /* leave the queue if no agents, if enabled */
2144                 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2145                         *reason = QUEUE_LEAVEEMPTY;
2146                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
2147                         leave_queue(qe);
2148                         break;
2149                 }
2150
2151                 /* leave the queue if no reachable agents, if enabled */
2152                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2153                         *reason = QUEUE_LEAVEUNAVAIL;
2154                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
2155                         leave_queue(qe);
2156                         break;
2157                 }
2158
2159                 /* Make a position announcement, if enabled */
2160                 if (qe->parent->announcefrequency && !ringing &&
2161                         (res = say_position(qe)))
2162                         break;
2163
2164                 /* Make a periodic announcement, if enabled */
2165                 if (qe->parent->periodicannouncefrequency && !ringing &&
2166                         (res = say_periodic_announcement(qe)))
2167                         break;
2168
2169                 /* Wait a second before checking again */
2170                 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000)))
2171                         break;
2172         }
2173
2174         return res;
2175 }
2176
2177 static int update_queue(struct call_queue *q, struct member *member)
2178 {
2179         struct member *cur;
2180
2181         /* Since a reload could have taken place, we have to traverse the list to
2182                 be sure it's still valid */
2183         ast_mutex_lock(&q->lock);
2184         cur = q->members;
2185         while (cur) {
2186                 if (member == cur) {
2187                         time(&cur->lastcall);
2188                         cur->calls++;
2189                         break;
2190                 }
2191                 cur = cur->next;
2192         }
2193         q->callscompleted++;
2194         ast_mutex_unlock(&q->lock);
2195         return 0;
2196 }
2197
2198 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2199 {
2200         if (qe->max_penalty && (mem->penalty > qe->max_penalty))
2201                 return -1;
2202
2203         switch (q->strategy) {
2204         case QUEUE_STRATEGY_RINGALL:
2205                 /* Everyone equal, except for penalty */
2206                 tmp->metric = mem->penalty * 1000000;
2207                 break;
2208         case QUEUE_STRATEGY_ROUNDROBIN:
2209                 if (!pos) {
2210                         if (!q->wrapped) {
2211                                 /* No more channels, start over */
2212                                 q->rrpos = 0;
2213                         } else {
2214                                 /* Prioritize next entry */
2215                                 q->rrpos++;
2216                         }
2217                         q->wrapped = 0;
2218                 }
2219                 /* Fall through */
2220         case QUEUE_STRATEGY_RRMEMORY:
2221                 if (pos < q->rrpos) {
2222                         tmp->metric = 1000 + pos;
2223                 } else {
2224                         if (pos > q->rrpos)
2225                                 /* Indicate there is another priority */
2226                                 q->wrapped = 1;
2227                         tmp->metric = pos;
2228                 }
2229                 tmp->metric += mem->penalty * 1000000;
2230                 break;
2231         case QUEUE_STRATEGY_RANDOM:
2232                 tmp->metric = ast_random() % 1000;
2233                 tmp->metric += mem->penalty * 1000000;
2234                 break;
2235         case QUEUE_STRATEGY_FEWESTCALLS:
2236                 tmp->metric = mem->calls;
2237                 tmp->metric += mem->penalty * 1000000;
2238                 break;
2239         case QUEUE_STRATEGY_LEASTRECENT:
2240                 if (!mem->lastcall)
2241                         tmp->metric = 0;
2242                 else
2243                         tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2244                 tmp->metric += mem->penalty * 1000000;
2245                 break;
2246         default:
2247                 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2248                 break;
2249         }
2250         return 0;
2251 }
2252
2253 static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on, const char *agi)
2254 {
2255         struct member *cur;
2256         struct callattempt *outgoing = NULL; /* the list of calls we are building */
2257         int to;
2258         char oldexten[AST_MAX_EXTENSION]="";
2259         char oldcontext[AST_MAX_CONTEXT]="";
2260         char queuename[256]="";
2261         struct ast_channel *peer;
2262         struct ast_channel *which;
2263         struct callattempt *lpeer;
2264         struct member *member;
2265         struct ast_app *app;
2266         int res = 0, bridge = 0;
2267         int numbusies = 0;
2268         int x=0;
2269         char *announce = NULL;
2270         char digit = 0;
2271         time_t callstart;
2272         time_t now = time(NULL);
2273         struct ast_bridge_config bridge_config;
2274         char nondataquality = 1;
2275         char *agiexec = NULL;
2276         int ret = 0;
2277         const char *monitorfilename;
2278         const char *monitor_exec;
2279         const char *monitor_options;
2280         char tmpid[256], tmpid2[256];
2281         char meid[1024], meid2[1024];
2282         char mixmonargs[1512];
2283         struct ast_app *mixmonapp = NULL;
2284         char *p;
2285         char vars[2048];
2286
2287         memset(&bridge_config, 0, sizeof(bridge_config));
2288         time(&now);
2289                 
2290         for (; options && *options; options++)
2291                 switch (*options) {
2292                 case 't':
2293                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
2294                         break;
2295                 case 'T':
2296                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
2297                         break;
2298                 case 'w':
2299                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
2300                         break;
2301                 case 'W':
2302                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
2303                         break;
2304                 case 'd':
2305                         nondataquality = 0;
2306                         break;
2307                 case 'h':
2308                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
2309                         break;
2310                 case 'H':
2311                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
2312                         break;
2313                 case 'n':
2314                         if ((now - qe->start >= qe->parent->timeout))
2315                                 *go_on = 1;
2316                         break;
2317                 }
2318
2319         /* Hold the lock while we setup the outgoing calls */
2320         if (use_weight)
2321                 AST_LIST_LOCK(&queues);
2322         ast_mutex_lock(&qe->parent->lock);
2323         if (option_debug)
2324                 ast_log(LOG_DEBUG, "%s is trying to call a queue member.\n",
2325                                                         qe->chan->name);
2326         ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
2327         cur = qe->parent->members;
2328         if (!ast_strlen_zero(qe->announce))
2329                 announce = qe->announce;
2330         if (!ast_strlen_zero(announceoverride))
2331                 announce = announceoverride;
2332
2333         for (; cur; cur = cur->next) {
2334                 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
2335
2336                 if (!tmp) {
2337                         ast_mutex_unlock(&qe->parent->lock);
2338                         if (use_weight)
2339                                 AST_LIST_UNLOCK(&queues);
2340                         goto out;
2341                 }
2342                 tmp->stillgoing = -1;
2343                 tmp->member = cur;              /* Never directly dereference!  Could change on reload */
2344                 tmp->oldstatus = cur->status;
2345                 tmp->lastcall = cur->lastcall;
2346                 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
2347                 /* Special case: If we ring everyone, go ahead and ring them, otherwise
2348                    just calculate their metric for the appropriate strategy */
2349                 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
2350                         /* Put them in the list of outgoing thingies...  We're ready now.
2351                            XXX If we're forcibly removed, these outgoing calls won't get
2352                            hung up XXX */
2353                         tmp->q_next = outgoing;
2354                         outgoing = tmp;         
2355                         /* If this line is up, don't try anybody else */
2356                         if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
2357                                 break;
2358                 } else {
2359                         free(tmp);
2360                 }
2361         }
2362         if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
2363                 to = (qe->expire - now) * 1000;
2364         else
2365                 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
2366         ring_one(qe, outgoing, &numbusies);
2367         ast_mutex_unlock(&qe->parent->lock);
2368         if (use_weight)
2369                 AST_LIST_UNLOCK(&queues);
2370         lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT));
2371         ast_mutex_lock(&qe->parent->lock);
2372         if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
2373                 store_next(qe, outgoing);
2374         }
2375         ast_mutex_unlock(&qe->parent->lock);
2376         peer = lpeer ? lpeer->chan : NULL;
2377         if (!peer) {
2378                 if (to) {
2379                         /* Must gotten hung up */
2380                         res = -1;
2381                 } else {
2382                         res = digit;
2383                 }
2384                 if (option_debug)
2385                         ast_log(LOG_DEBUG, "%s: Nobody answered.\n", qe->chan->name);
2386         } else { /* peer is valid */
2387                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
2388                    we will always return with -1 so that it is hung up properly after the
2389                    conversation.  */
2390                 qe->handled++;
2391                 if (!strcmp(qe->chan->tech->type, "Zap"))
2392                         ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2393                 if (!strcmp(peer->tech->type, "Zap"))
2394                         ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2395                 /* Update parameters for the queue */
2396                 recalc_holdtime(qe);
2397                 member = lpeer->member;
2398                 hangupcalls(outgoing, peer);
2399                 outgoing = NULL;
2400                 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
2401                         int res2;
2402
2403                         res2 = ast_autoservice_start(qe->chan);
2404                         if (!res2) {
2405                                 if (qe->parent->memberdelay) {
2406                                         ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
2407                                         res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
2408                                 }
2409                                 if (!res2 && announce) {
2410                                         if (play_file(peer, announce))
2411                                                 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", announce);
2412                                 }
2413                                 if (!res2 && qe->parent->reportholdtime) {
2414                                         if (!play_file(peer, qe->parent->sound_reporthold)) {
2415                                                 int holdtime;
2416
2417                                                 time(&now);
2418                                                 holdtime = abs((now - qe->start) / 60);
2419                                                 if (holdtime < 2) {
2420                                                         play_file(peer, qe->parent->sound_lessthan);
2421                                                         ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
2422                                                 } else
2423                                                         ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
2424                                                 play_file(peer, qe->parent->sound_minutes);
2425                                         }
2426                                 }
2427                         }
2428                         res2 |= ast_autoservice_stop(qe->chan);
2429                         if (peer->_softhangup) {
2430                                 /* Agent must have hung up */
2431                                 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.  They're going to be pissed.\n", peer->name);
2432                                 ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "AGENTDUMP", "%s", "");
2433                                 record_abandoned(qe);
2434                                 if (qe->parent->eventwhencalled)
2435                                         manager_event(EVENT_FLAG_AGENT, "AgentDump",
2436                                                         "Queue: %s\r\n"
2437                                                         "Uniqueid: %s\r\n"
2438                                                         "Channel: %s\r\n"
2439                                                         "Member: %s\r\n"
2440                                                         "%s",
2441                                                         queuename, qe->chan->uniqueid, peer->name, member->interface,
2442                                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2443                                 ast_hangup(peer);
2444                                 goto out;
2445                         } else if (res2) {
2446                                 /* Caller must have hung up just before being connected*/
2447                                 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
2448                                 ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long)time(NULL) - qe->start);
2449                                 record_abandoned(qe);
2450                                 ast_hangup(peer);
2451                                 return -1;
2452                         }
2453                 }
2454                 /* Stop music on hold */
2455                 ast_moh_stop(qe->chan);
2456                 /* If appropriate, log that we have a destination channel */
2457                 if (qe->chan->cdr)
2458                         ast_cdr_setdestchan(qe->chan->cdr, peer->name);
2459                 /* Make sure channels are compatible */
2460                 res = ast_channel_make_compatible(qe->chan, peer);
2461                 if (res < 0) {
2462                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "SYSCOMPAT", "%s", "");
2463                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
2464                         record_abandoned(qe);
2465                         ast_hangup(peer);
2466                         return -1;
2467                 }
2468                 /* Begin Monitoring */
2469                 if (qe->parent->monfmt && *qe->parent->monfmt) {
2470                         if (!qe->parent->montype) {
2471                                 if (option_debug)
2472                                         ast_log(LOG_DEBUG, "Starting Monitor as requested.\n");
2473                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2474                                 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
2475                                         which = qe->chan;
2476                                 else
2477                                         which = peer;
2478                                 if (monitorfilename)
2479                                         ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1 );
2480                                 else if (qe->chan->cdr)
2481                                         ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1 );
2482                                 else {
2483                                         /* Last ditch effort -- no CDR, make up something */
2484                                         snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2485                                         ast_monitor_start(which, qe->parent->monfmt, tmpid, 1 );
2486                                 }
2487                                 if (qe->parent->monjoin)
2488                                         ast_monitor_setjoinfiles(which, 1);
2489                         } else {
2490                                 if (option_debug)
2491                                         ast_log(LOG_DEBUG, "Starting MixMonitor as requested.\n");
2492                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2493                                 if (!monitorfilename) {
2494                                         if (qe->chan->cdr)
2495                                                 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid)-1);
2496                                         else
2497                                                 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2498                                 } else {
2499                                         ast_copy_string(tmpid2, monitorfilename, sizeof(tmpid2)-1);
2500                                         for (p = tmpid2; *p ; p++) {
2501                                                 if (*p == '^' && *(p+1) == '{') {
2502                                                         *p = '$';
2503                                                 }
2504                                         }
2505
2506                                         memset(tmpid, 0, sizeof(tmpid));
2507                                         pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
2508                                 }
2509
2510                                 monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
2511                                 monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
2512
2513                                 if (monitor_exec) {
2514                                         ast_copy_string(meid2, monitor_exec, sizeof(meid2)-1);
2515                                         for (p = meid2; *p ; p++) {
2516                                                 if (*p == '^' && *(p+1) == '{') {
2517                                                         *p = '$';
2518                                                 }
2519                                         }
2520
2521                                         memset(meid, 0, sizeof(meid));
2522                                         pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
2523                                 }
2524         
2525                                 snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
2526
2527                                 mixmonapp = pbx_findapp("MixMonitor");
2528
2529                                 if (strchr(tmpid2, '|')) {
2530                                         ast_log(LOG_WARNING, "monitor-format (in queues.conf) and MONITOR_FILENAME cannot contain a '|'! Not recording.\n");
2531                                         mixmonapp = NULL;
2532                                 }
2533
2534                                 if (!monitor_options)
2535                                         monitor_options = "";
2536                                 
2537                                 if (strchr(monitor_options, '|')) {
2538                                         ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
2539                                         mixmonapp = NULL;
2540                                 }
2541
2542                                 if (mixmonapp) {
2543                                         if (!ast_strlen_zero(monitor_exec) && !ast_strlen_zero(monitor_options))
2544                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
2545                                         else
2546                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
2547                                                 
2548                                         if (option_debug)
2549                                                 ast_log(LOG_DEBUG, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
2550
2551                                         ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
2552
2553                                 } else
2554                                         ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
2555
2556                         }
2557                 }
2558                 /* Drop out of the queue at this point, to prepare for next caller */
2559                 leave_queue(qe);                        
2560                 if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
2561                         if (option_debug)
2562                                 ast_log(LOG_DEBUG, "app_queue: sendurl=%s.\n", url);
2563                         ast_channel_sendurl(peer, url);
2564                 }
2565                 if (qe->parent->setinterfacevar)
2566                                 pbx_builtin_setvar_helper(qe->chan, "MEMBERINTERFACE", member->interface);
2567                 if (!ast_strlen_zero(agi)) {
2568                         if (option_debug)
2569                                 ast_log(LOG_DEBUG, "app_queue: agi=%s.\n", agi);
2570                         app = pbx_findapp("agi");
2571                         if (app) {
2572                                 agiexec = ast_strdupa(agi);
2573                                 ret = pbx_exec(qe->chan, app, agiexec);
2574                         } else
2575                                 ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
2576                 }
2577                 ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "CONNECT", "%ld|%s", (long)time(NULL) - qe->start, peer->uniqueid);
2578                 if (qe->parent->eventwhencalled)
2579                         manager_event(EVENT_FLAG_AGENT, "AgentConnect",
2580                                         "Queue: %s\r\n"
2581                                         "Uniqueid: %s\r\n"
2582                                         "Channel: %s\r\n"
2583                                         "Member: %s\r\n"
2584                                         "Holdtime: %ld\r\n"
2585                                         "BridgedChannel: %s\r\n"
2586                                         "%s",
2587                                         queuename, qe->chan->uniqueid, peer->name, member->interface,
2588                                         (long)time(NULL) - qe->start, peer->uniqueid,
2589                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2590                 ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
2591                 ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
2592                 time(&callstart);
2593
2594                 bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
2595
2596                 if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
2597                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "TRANSFER", "%s|%s|%ld|%ld",
2598                                 qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
2599                                 (long) (time(NULL) - callstart));
2600                 } else if (qe->chan->_softhangup) {
2601                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETECALLER", "%ld|%ld",
2602                                 (long) (callstart - qe->start), (long) (time(NULL) - callstart));
2603                         if (qe->parent->eventwhencalled)
2604                                 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2605                                                 "Queue: %s\r\n"
2606                                                 "Uniqueid: %s\r\n"
2607                                                 "Channel: %s\r\n"
2608                                                 "Member: %s\r\n"
2609                                                 "HoldTime: %ld\r\n"
2610                                                 "TalkTime: %ld\r\n"
2611                                                 "Reason: caller\r\n"
2612                                                 "%s",
2613                                                 queuename, qe->chan->uniqueid, peer->name, member->interface,
2614                                                 (long)(callstart - qe->start), (long)(time(NULL) - callstart),
2615                                                 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2616                 } else {
2617                         ast_queue_log(queuename, qe->chan->uniqueid, peer->name, "COMPLETEAGENT", "%ld|%ld",
2618                                 (long) (callstart - qe->start), (long) (time(NULL) - callstart));
2619                         if (qe->parent->eventwhencalled)
2620                                 manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2621                                                 "Queue: %s\r\n"
2622                                                 "Uniqueid: %s\r\n"
2623                                                 "Channel: %s\r\n"
2624                                                 "HoldTime: %ld\r\n"
2625                                                 "TalkTime: %ld\r\n"
2626                                                 "Reason: agent\r\n"
2627                                                 "%s",
2628                                                 queuename, qe->chan->uniqueid, peer->name, (long)(callstart - qe->start),
2629                                                 (long)(time(NULL) - callstart),
2630                                                 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2631                 }
2632
2633                 if (bridge != AST_PBX_NO_HANGUP_PEER)
2634                         ast_hangup(peer);
2635                 update_queue(qe->parent, member);
2636                 res = bridge ? bridge : 1;
2637         }
2638 out:
2639         hangupcalls(outgoing, NULL);
2640
2641         return res;
2642 }
2643
2644 static int wait_a_bit(struct queue_ent *qe)
2645 {
2646         /* Don't need to hold the lock while we setup the outgoing calls */
2647         int retrywait = qe->parent->retry * 1000;
2648
2649         return ast_waitfordigit(qe->chan, retrywait);
2650 }
2651
2652 static struct member *interface_exists(struct call_queue *q, char *interface)
2653 {
2654         struct member *mem;
2655
2656         if (!q)
2657                 return NULL;
2658
2659         for (mem = q->members; mem; mem = mem->next) {
2660                 if (!strcasecmp(interface, mem->interface))
2661                         return mem;
2662         }
2663
2664         return NULL;
2665 }
2666
2667
2668 /* Dump all members in a specific queue to the database
2669  *
2670  * <pm_family>/<queuename> = <interface>;<penalty>;<paused>[|...]
2671  *
2672  */
2673 static void dump_queue_members(struct call_queue *pm_queue)
2674 {
2675         struct member *cur_member;
2676         char value[PM_MAX_LEN];
2677         int value_len = 0;
2678         int res;
2679
2680         memset(value, 0, sizeof(value));
2681
2682         if (!pm_queue)
2683                 return;
2684
2685         for (cur_member = pm_queue->members; cur_member; cur_member = cur_member->next) {
2686                 if (!cur_member->dynamic)
2687                         continue;
2688
2689                 res = snprintf(value + value_len, sizeof(value) - value_len, "%s;%d;%d%s",
2690                         cur_member->interface, cur_member->penalty, cur_member->paused,
2691                         cur_member->next ? "|" : "");
2692                 if (res != strlen(value + value_len)) {
2693                         ast_log(LOG_WARNING, "Could not create persistent member string, out of space\n");
2694                         break;
2695                 }
2696                 value_len += res;
2697         }
2698         
2699         if (value_len && !cur_member) {
2700                 if (ast_db_put(pm_family, pm_queue->name, value))
2701                         ast_log(LOG_WARNING, "failed to create persistent dynamic entry!\n");
2702         } else
2703                 /* Delete the entry if the queue is empty or there is an error */
2704                 ast_db_del(pm_family, pm_queue->name);
2705 }
2706
2707 static int remove_from_queue(char *queuename, char *interface)
2708 {
2709         struct call_queue *q;
2710         struct member *last_member, *look;
2711         int res = RES_NOSUCHQUEUE;
2712
2713         AST_LIST_LOCK(&queues);
2714         AST_LIST_TRAVERSE(&queues, q, list) {
2715                 ast_mutex_lock(&q->lock);
2716                 if (strcmp(q->name, queuename)) {
2717                         ast_mutex_unlock(&q->lock);
2718                         continue;
2719                 }
2720
2721                 if ((last_member = interface_exists(q, interface))) {
2722                         if ((look = q->members) == last_member) {
2723                                 q->members = last_member->next;
2724                         } else {
2725                                 while (look != NULL) {
2726                                         if (look->next == last_member) {
2727                                                 look->next = last_member->next;
2728                                                 break;
2729                                         } else {
2730                                                 look = look->next;
2731                                         }
2732                                 }
2733                         }
2734                         manager_event(EVENT_FLAG_AGENT, "QueueMemberRemoved",
2735                                 "Queue: %s\r\n"
2736                                 "Location: %s\r\n",
2737                                 q->name, last_member->interface);
2738                         free(last_member);
2739                         
2740                         if (queue_persistent_members)
2741                                 dump_queue_members(q);
2742                         
2743                         res = RES_OKAY;
2744                 } else {
2745                         res = RES_EXISTS;
2746                 }
2747                 ast_mutex_unlock(&q->lock);
2748                 break;
2749         }
2750
2751         if (res == RES_OKAY)
2752                 remove_from_interfaces(interface);
2753
2754         AST_LIST_UNLOCK(&queues);
2755
2756         return res;
2757 }
2758
2759
2760 static int add_to_queue(char *queuename, char *interface, int penalty, int paused, int dump)
2761 {
2762         struct call_queue *q;
2763         struct member *new_member;
2764         int res = RES_NOSUCHQUEUE;
2765
2766         /* \note Ensure the appropriate realtime queue is loaded.  Note that this
2767          * short-circuits if the queue is already in memory. */
2768         if (!(q = load_realtime_queue(queuename)))
2769                 return res;
2770
2771         AST_LIST_LOCK(&queues);
2772
2773         ast_mutex_lock(&q->lock);
2774         if (interface_exists(q, interface) == NULL) {
2775                 add_to_interfaces(interface);
2776                 if ((new_member = create_queue_member(interface, penalty, paused))) {
2777                         new_member->dynamic = 1;
2778                         new_member->next = q->members;
2779                         q->members = new_member;
2780                         manager_event(EVENT_FLAG_AGENT, "QueueMemberAdded",
2781                                 "Queue: %s\r\n"
2782                                 "Location: %s\r\n"
2783                                 "Membership: %s\r\n"
2784                                 "Penalty: %d\r\n"
2785                                 "CallsTaken: %d\r\n"
2786                                 "LastCall: %d\r\n"
2787                                 "Status: %d\r\n"
2788                                 "Paused: %d\r\n",
2789                                 q->name, new_member->interface, new_member->dynamic ? "dynamic" : "static",
2790                                 new_member->penalty, new_member->calls, (int) new_member->lastcall,
2791                                 new_member->status, new_member->paused);
2792                         
2793                         if (dump)
2794                                 dump_queue_members(q);
2795                         
2796                         res = RES_OKAY;
2797                 } else {
2798                         res = RES_OUTOFMEMORY;
2799                 }
2800         } else {
2801                 res = RES_EXISTS;
2802         }
2803         ast_mutex_unlock(&q->lock);
2804         AST_LIST_UNLOCK(&queues);
2805
2806         return res;
2807 }
2808
2809 static int set_member_paused(char *queuename, char *interface, int paused)
2810 {
2811         int found = 0;
2812         struct call_queue *q;
2813         struct member *mem;
2814
2815         /* Special event for when all queues are paused - individual events still generated */
2816
2817         if (ast_strlen_zero(queuename))
2818                 ast_queue_log("NONE", "NONE", interface, (paused ? "PAUSEALL" : "UNPAUSEALL"), "%s", "");
2819
2820         AST_LIST_LOCK(&queues);
2821         AST_LIST_TRAVERSE(&queues, q, list) {
2822                 ast_mutex_lock(&q->lock);
2823                 if (ast_strlen_zero(queuename) || !strcasecmp(q->name, queuename)) {
2824                         if ((mem = interface_exists(q, interface))) {
2825                                 found++;
2826                                 if (mem->paused == paused)
2827                                         ast_log(LOG_DEBUG, "%spausing already-%spaused queue member %s:%s\n", (paused ? "" : "un"), (paused ? "" : "un"), q->name, interface);
2828                                 mem->paused = paused;
2829
2830                                 if (queue_persistent_members)
2831                                         dump_queue_members(q);
2832
2833                                 ast_queue_log(q->name, "NONE", interface, (paused ? "PAUSE" : "UNPAUSE"), "%s", "");
2834
2835                                 manager_event(EVENT_FLAG_AGENT, "QueueMemberPaused",
2836                                         "Queue: %s\r\n"
2837                                         "Location: %s\r\n"
2838                                         "Paused: %d\r\n",
2839                                                 q->name, mem->interface, paused);
2840                         }
2841                 }
2842                 ast_mutex_unlock(&q->lock);
2843         }
2844         AST_LIST_UNLOCK(&queues);
2845
2846         return found ? RESULT_SUCCESS : RESULT_FAILURE;
2847 }
2848
2849 /* Reload dynamic queue members persisted into the astdb */
2850 static void reload_queue_members(void)
2851 {
2852         char *cur_ptr;  
2853         char *queue_name;
2854         char *member;
2855         char *interface;
2856         char *penalty_tok;
2857         int penalty = 0;
2858         char *paused_tok;
2859         int paused = 0;
2860         struct ast_db_entry *db_tree;
2861         struct ast_db_entry *entry;
2862         struct call_queue *cur_queue;
2863         char queue_data[PM_MAX_LEN];
2864
2865         AST_LIST_LOCK(&queues);
2866
2867         /* Each key in 'pm_family' is the name of a queue */
2868         db_tree = ast_db_gettree(pm_family, NULL);
2869         for (entry = db_tree; entry; entry = entry->next) {
2870
2871                 queue_name = entry->key + strlen(pm_family) + 2;
2872
2873                 AST_LIST_TRAVERSE(&queues, cur_queue, list) {
2874                         ast_mutex_lock(&cur_queue->lock);
2875                         if (!strcmp(queue_name, cur_queue->name))
2876                                 break;
2877                         ast_mutex_unlock(&cur_queue->lock);
2878                 }
2879
2880                 if (!cur_queue) {
2881                         /* If the queue no longer exists, remove it from the
2882                          * database */
2883                         ast_db_del(pm_family, queue_name);
2884                         continue;
2885                 } else
2886                         ast_mutex_unlock(&cur_queue->lock);
2887
2888                 if (ast_db_get(pm_family, queue_name, queue_data, PM_MAX_LEN))
2889                         continue;
2890
2891                 cur_ptr = queue_data;
2892                 while ((member = strsep(&cur_ptr, "|"))) {
2893                         if (ast_strlen_zero(member))
2894                                 continue;
2895
2896                         interface = strsep(&member, ";");
2897                         penalty_tok = strsep(&member, ";");
2898                         paused_tok = strsep(&member, ";");
2899
2900                         if (!penalty_tok) {
2901                                 ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (penalty)\n", queue_name);
2902                                 break;
2903                         }
2904                         penalty = strtol(penalty_tok, NULL, 10);
2905                         if (errno == ERANGE) {
2906                                 ast_log(LOG_WARNING, "Error converting penalty: %s: Out of range.\n", penalty_tok);
2907                                 break;
2908                         }
2909                         
2910                         if (!paused_tok) {
2911                                 ast_log(LOG_WARNING, "Error parsing persistent member string for '%s' (paused)\n", queue_name);
2912                                 break;
2913                         }
2914                         paused = strtol(paused_tok, NULL, 10);
2915                         if ((errno == ERANGE) || paused < 0 || paused > 1) {
2916                                 ast_log(LOG_WARNING, "Error converting paused: %s: Expected 0 or 1.\n", paused_tok);
2917                                 break;
2918                         }
2919
2920                         if (option_debug)
2921                                 ast_log(LOG_DEBUG, "Reload Members: Queue: %s  Member: %s  Penalty: %d  Paused: %d\n", queue_name, interface, penalty, paused);
2922                         
2923                         if (add_to_queue(queue_name, interface, penalty, paused, 0) == RES_OUTOFMEMORY) {
2924                                 ast_log(LOG_ERROR, "Out of Memory when reloading persistent queue member\n");
2925                                 break;
2926                         }
2927                 }
2928         }
2929
2930         AST_LIST_UNLOCK(&queues);
2931         if (db_tree) {
2932                 ast_log(LOG_NOTICE, "Queue members successfully reloaded from database.\n");
2933                 ast_db_freetree(db_tree);
2934         }
2935 }
2936
2937 static int pqm_exec(struct ast_channel *chan, void *data)
2938 {
2939         struct localuser *lu;
2940         char *parse;
2941         int priority_jump = 0;
2942         AST_DECLARE_APP_ARGS(args,
2943                 AST_APP_ARG(queuename);
2944                 AST_APP_ARG(interface);
2945                 AST_APP_ARG(options);
2946         );
2947
2948         if (ast_strlen_zero(data)) {
2949                 ast_log(LOG_WARNING, "PauseQueueMember requires an argument ([queuename]|interface[|options])\n");
2950                 return -1;
2951         }
2952
2953         parse = ast_strdupa(data);
2954
2955         AST_STANDARD_APP_ARGS(args, parse);
2956
2957         LOCAL_USER_ADD(lu);
2958
2959         if (args.options) {
2960                 if (strchr(args.options, 'j'))
2961                         priority_jump = 1;
2962         }
2963
2964         if (ast_strlen_zero(args.interface)) {
2965                 ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n");
2966                 LOCAL_USER_REMOVE(lu);
2967                 return -1;
2968         }
2969
2970         if (set_member_paused(args.queuename, args.interface, 1)) {
2971                 ast_log(LOG_WARNING, "Attempt to pause interface %s, not found\n", args.interface);
2972                 if (priority_jump || ast_opt_priority_jumping) {
2973                         if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
2974                                 pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND");
2975                                 LOCAL_USER_REMOVE(lu);
2976                                 return 0;
2977                         }
2978                 }
2979                 LOCAL_USER_REMOVE(lu);
2980                 pbx_builtin_setvar_helper(chan, "PQMSTATUS", "NOTFOUND");
2981                 return -1;
2982         }
2983
2984         LOCAL_USER_REMOVE(lu);
2985         pbx_builtin_setvar_helper(chan, "PQMSTATUS", "PAUSED");
2986
2987         return 0;
2988 }
2989
2990 static int upqm_exec(struct ast_channel *chan, void *data)
2991 {
2992         struct localuser *lu;
2993         char *parse;
2994         int priority_jump = 0;
2995         AST_DECLARE_APP_ARGS(args,
2996                 AST_APP_ARG(queuename);
2997                 AST_APP_ARG(interface);
2998                 AST_APP_ARG(options);
2999         );
3000
3001         if (ast_strlen_zero(data)) {
3002                 ast_log(LOG_WARNING, "UnpauseQueueMember requires an argument ([queuename]|interface[|options])\n");
3003                 return -1;
3004         }
3005
3006         parse = ast_strdupa(data);
3007
3008         AST_STANDARD_APP_ARGS(args, parse);
3009
3010         LOCAL_USER_ADD(lu);
3011
3012         if (args.options) {
3013                 if (strchr(args.options, 'j'))
3014                         priority_jump = 1;
3015         }
3016
3017         if (ast_strlen_zero(args.interface)) {
3018                 ast_log(LOG_WARNING, "Missing interface argument to PauseQueueMember ([queuename]|interface[|options])\n");
3019                 LOCAL_USER_REMOVE(lu);
3020                 return -1;
3021         }
3022
3023         if (set_member_paused(args.queuename, args.interface, 0)) {
3024                 ast_log(LOG_WARNING, "Attempt to unpause interface %s, not found\n", args.interface);
3025                 if (priority_jump || ast_opt_priority_jumping) {
3026                         if (ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101)) {
3027                                 pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND");
3028                                 LOCAL_USER_REMOVE(lu);
3029                                 return 0;
3030                         }
3031                 }
3032                 LOCAL_USER_REMOVE(lu);
3033                 pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "NOTFOUND");
3034                 return -1;
3035         }
3036
3037         LOCAL_USER_REMOVE(lu);
3038         pbx_builtin_setvar_helper(chan, "UPQMSTATUS", "UNPAUSED");
3039
3040         return 0;
3041 }
3042
3043 static int rqm_exec(struct ast_channel *chan, void *data)
3044 {
3045         int res=-1;
3046         struct localuser *lu;
3047         char *parse, *temppos = NULL;
3048         int priority_jump = 0;
3049         AST_DECLARE_APP_ARGS(args,
3050                 AST_APP_ARG(queuename);
3051                 AST_APP_ARG(interface);
3052                 AST_APP_ARG(options);
3053         );
3054
3055
3056         if (ast_strlen_zero(data)) {
3057                 ast_log(LOG_WARNING, "RemoveQueueMember requires an argument (queuename[|interface[|options]])\n");
3058                 return -1;
3059         }
3060
3061         parse = ast_strdupa(data);
3062
3063         AST_STANDARD_APP_ARGS(args, parse);
3064
3065         LOCAL_USER_ADD(lu);
3066
3067         if (ast_strlen_zero(args.interface)) {
3068                 args.interface = ast_strdupa(chan->name);
3069                 temppos = strrchr(args.interface, '-');
3070                 if (temppos)
3071                         *temppos = '\0';
3072         }
3073
3074         if (args.options) {
3075                 if (strchr(args.options, 'j'))
3076                         priority_jump = 1;
3077         }
3078
3079         switch (remove_from_queue(args.queuename, args.interface)) {
3080         case RES_OKAY:
3081                 ast_log(LOG_DEBUG, "Removed interface '%s' from queue '%s'\n", args.interface, args.queuename);
3082                 pbx_builtin_setvar_helper(chan, "RQMSTATUS", "REMOVED");
3083                 res = 0;
3084                 break;
3085         case RES_EXISTS:
3086                 ast_log(LOG_DEBUG, "Unable to remove interface '%s' from queue '%s': Not there\n", args.interface, args.queuename);
3087                 if (priority_jump || ast_opt_priority_jumping)
3088                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
3089                 pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOTINQUEUE");
3090                 res = 0;
3091                 break;
3092         case RES_NOSUCHQUEUE:
3093                 ast_log(LOG_WARNING, "Unable to remove interface from queue '%s': No such queue\n", args.queuename);
3094                 pbx_builtin_setvar_helper(chan, "RQMSTATUS", "NOSUCHQUEUE");
3095                 res = 0;
3096                 break;
3097         }
3098
3099         LOCAL_USER_REMOVE(lu);
3100
3101         return res;
3102 }
3103
3104 static int aqm_exec(struct ast_channel *chan, void *data)
3105 {
3106         int res=-1;
3107         struct localuser *lu;
3108         char *parse, *temppos = NULL;
3109         int priority_jump = 0;
3110         AST_DECLARE_APP_ARGS(args,
3111                 AST_APP_ARG(queuename);
3112                 AST_APP_ARG(interface);
3113                 AST_APP_ARG(penalty);
3114                 AST_APP_ARG(options);
3115         );
3116         int penalty = 0;
3117
3118         if (ast_strlen_zero(data)) {
3119                 ast_log(LOG_WARNING, "AddQueueMember requires an argument (queuename[|[interface]|[penalty][|options]])\n");
3120                 return -1;
3121         }
3122
3123         parse = ast_strdupa(data);
3124
3125         AST_STANDARD_APP_ARGS(args, parse);
3126
3127         LOCAL_USER_ADD(lu);
3128
3129         if (ast_strlen_zero(args.interface)) {
3130                 args.interface = ast_strdupa(chan->name);
3131                 temppos = strrchr(args.interface, '-');
3132                 if (temppos)
3133                         *temppos = '\0';
3134         }
3135
3136         if (!ast_strlen_zero(args.penalty)) {
3137                 if ((sscanf(args.penalty, "%d", &penalty) != 1) || penalty < 0) {
3138                         ast_log(LOG_WARNING, "Penalty '%s' is invalid, must be an integer >= 0\n", args.penalty);
3139                         penalty = 0;
3140                 }
3141         }
3142         
3143         if (args.options) {
3144                 if (strchr(args.options, 'j'))
3145                         priority_jump = 1;
3146         }
3147
3148
3149         switch (add_to_queue(args.queuename, args.interface, penalty, 0, queue_persistent_members)) {
3150         case RES_OKAY:
3151                 ast_log(LOG_NOTICE, "Added interface '%s' to queue '%s'\n", args.interface, args.queuename);
3152                 pbx_builtin_setvar_helper(chan, "AQMSTATUS", "ADDED");
3153                 res = 0;
3154                 break;
3155         case RES_EXISTS:
3156                 ast_log(LOG_WARNING, "Unable to add interface '%s' to queue '%s': Already there\n", args.interface, args.queuename);
3157                 if (priority_jump || ast_opt_priority_jumping)
3158                         ast_goto_if_exists(chan, chan->context, chan->exten, chan->priority + 101);
3159                 pbx_builtin_setvar_helper(chan, "AQMSTATUS", "MEMBERALREADY");
3160                 res = 0;
3161                 break;
3162         case RES_NOSUCHQUEUE:
3163                 ast_log(LOG_WARNING, "Unable to add interface to queue '%s': No such queue\n", args.queuename);
3164                 pbx_builtin_setvar_helper(chan, "AQMSTATUS", "NOSUCHQUEUE");
3165                 res = 0;
3166                 break;
3167         case RES_OUTOFMEMORY:
3168                 ast_log(LOG_ERROR, "Out of memory adding member %s to queue %s\n", args.interface, args.queuename);
3169                 break;
3170         }
3171
3172         LOCAL_USER_REMOVE(lu);
3173
3174         return res;
3175 }
3176
3177 static int ql_exec(struct ast_channel *chan, void *data)
3178 {
3179         struct localuser *u;
3180         char *parse;
3181
3182         AST_DECLARE_APP_ARGS(args,
3183                 AST_APP_ARG(queuename);
3184                 AST_APP_ARG(uniqueid);
3185                 AST_APP_ARG(peer);
3186                 AST_APP_ARG(event);
3187                 AST_APP_ARG(params);
3188         );
3189
3190         if (ast_strlen_zero(data)) {
3191                 ast_log(LOG_WARNING, "QueueLog requires arguments (queuename|uniqueid|peer|event[|additionalinfo]\n");
3192                 return -1;
3193         }
3194
3195         LOCAL_USER_ADD(u);
3196
3197         parse = ast_strdupa(data);
3198
3199         AST_STANDARD_APP_ARGS(args, parse);
3200
3201         if (ast_strlen_zero(args.queuename) || ast_strlen_zero(args.uniqueid)
3202             || ast_strlen_zero(args.peer) || ast_strlen_zero(args.event)) {
3203                 ast_log(LOG_WARNING, "QueueLog requires arguments (queuename|uniqueid|peer|event[|additionalinfo])\n");
3204                 LOCAL_USER_REMOVE(u);
3205                 return -1;
3206         }
3207
3208         ast_queue_log(args.queuename, args.uniqueid, args.peer, args.event, 
3209                 "%s", args.params ? args.params : "");
3210
3211         LOCAL_USER_REMOVE(u);
3212
3213         return 0;
3214 }
3215
3216 static int queue_exec(struct ast_channel *chan, void *data)
3217 {
3218         int res=-1;
3219         int ringing=0;
3220         struct localuser *lu;
3221         const char *user_priority;
3222         const char *max_penalty_str;
3223         int prio;
3224         int max_penalty;
3225         enum queue_result reason = QUEUE_UNKNOWN;
3226         /* whether to exit Queue application after the timeout hits */
3227         int go_on = 0;
3228         char *parse;
3229         AST_DECLARE_APP_ARGS(args,
3230                 AST_APP_ARG(queuename);
3231                 AST_APP_ARG(options);
3232                 AST_APP_ARG(url);
3233                 AST_APP_ARG(announceoverride);
3234                 AST_APP_ARG(queuetimeoutstr);
3235                 AST_APP_ARG(agi);
3236         );
3237         /* Our queue entry */
3238         struct queue_ent qe;
3239         
3240         if (ast_strlen_zero(data)) {
3241                 ast_log(LOG_WARNING, "Queue requires an argument: queuename[|options[|URL][|announceoverride][|timeout]]\n");
3242                 return -1;
3243         }
3244         
3245         parse = ast_strdupa(data);
3246         AST_STANDARD_APP_ARGS(args, parse);
3247
3248         LOCAL_USER_ADD(lu);
3249
3250         /* Setup our queue entry */
3251         memset(&qe, 0, sizeof(qe));
3252         qe.start = time(NULL);
3253
3254         /* set the expire time based on the supplied timeout; */
3255         if (args.queuetimeoutstr)
3256                 qe.expire = qe.start + atoi(args.queuetimeoutstr);
3257         else
3258                 qe.expire = 0;
3259
3260         /* Get the priority from the variable ${QUEUE_PRIO} */
3261         user_priority = pbx_builtin_getvar_helper(chan, "QUEUE_PRIO");
3262         if (user_priority) {
3263                 if (sscanf(user_priority, "%d", &prio) == 1) {
3264                         if (option_debug)
3265                                 ast_log(LOG_DEBUG, "%s: Got priority %d from ${QUEUE_PRIO}.\n",
3266                                         chan->name, prio);
3267                 } else {
3268                         ast_log(LOG_WARNING, "${QUEUE_PRIO}: Invalid value (%s), channel %s.\n",
3269                                 user_priority, chan->name);
3270                         prio = 0;
3271                 }
3272         } else {
3273                 if (option_debug > 2)
3274                         ast_log(LOG_DEBUG, "NO QUEUE_PRIO variable found. Using default.\n");
3275                 prio = 0;
3276         }
3277
3278         /* Get the maximum penalty from the variable ${QUEUE_MAX_PENALTY} */
3279         if ((max_penalty_str = pbx_builtin_getvar_helper(chan, "QUEUE_MAX_PENALTY"))) {
3280                 if (sscanf(max_penalty_str, "%d", &max_penalty) == 1) {
3281                         if (option_debug)
3282                                 ast_log(LOG_DEBUG, "%s: Got max penalty %d from ${QUEUE_MAX_PENALTY}.\n",
3283                                         chan->name, max_penalty);
3284                 } else {
3285                         ast_log(LOG_WARNING, "${QUEUE_MAX_PENALTY}: Invalid value (%s), channel %s.\n",
3286                                 max_penalty_str, chan->name);
3287                         max_penalty = 0;
3288                 }
3289         } else {
3290                 max_penalty = 0;
3291         }
3292
3293         if (args.options && (strchr(args.options, 'r')))
3294                 ringing = 1;
3295
3296         if (option_debug)
3297                 ast_log(LOG_DEBUG, "queue: %s, options: %s, url: %s, announce: %s, expires: %ld, priority: %d\n",
3298                         args.queuename, args.options, args.url, args.announceoverride, (long)qe.expire, prio);
3299
3300         qe.chan = chan;
3301         qe.prio = prio;
3302         qe.max_penalty = max_penalty;
3303         qe.last_pos_said = 0;
3304         qe.last_pos = 0;
3305         qe.last_periodic_announce_time = time(NULL);
3306         qe.last_periodic_announce_sound = 0;
3307         if (!join_queue(args.queuename, &qe, &reason)) {
3308                 ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ENTERQUEUE", "%s|%s", S_OR(args.url, ""),
3309                         S_OR(chan->cid.cid_num, ""));
3310 check_turns:
3311                 if (ringing) {
3312                         ast_indicate(chan, AST_CONTROL_RINGING);
3313                 } else {
3314                         ast_moh_start(chan, qe.moh, NULL);
3315                 }
3316                 for (;;) {
3317                         /* This is the wait loop for callers 2 through maxlen */
3318
3319                         res = wait_our_turn(&qe, ringing, &reason);
3320                         /* If they hungup, return immediately */
3321                         if (res < 0) {
3322                                 /* Record this abandoned call */
3323                                 record_abandoned(&qe);
3324                                 ast_queue_log(args.queuename, chan->uniqueid, "NONE", "ABANDON", "%d|%d|%ld",
3325                                         qe.pos, qe.opos, (long) time(NULL) - qe.start);
3326                                 if (option_verbose > 2) {
3327                                         ast_verbose(VERBOSE_PREFIX_3 "User disconnected from queue %s while waiting their turn\n", args.queuename);
3328                                 }
3329                                 res = -1;
3330                                 break;
3331                         }
3332                         if (!res)
3333                                 break;
3334                         if (valid_exit(&qe, res)) {
3335                                 ast_queue_log(args.queuename, chan->uniqueid, "NONE", "EXITWITHKEY", "%s|%d", qe.digits, qe.pos);
3336                                 break;
3337                         }
3338                 }
3339                 if (!res) {
3340                         int makeannouncement = 0;
3341
3342                         for (;;) {
3343                                 /* This is the wait loop for the head caller*/
3344                                 /* To exit, they may get their call answered; */
3345                                 /* they may dial a digit from the queue context; */
3346                                 /* or, they may timeout. */
3347
3348                                 enum queue_member_status stat;
3349
3350                                 /* Leave if we have exceeded our queuetimeout */
3351                                 if (qe.expire && (time(NULL) > qe.expire)) {
3352                                         record_abandoned(&qe);
3353                                         reason = QUEUE_TIMEOUT;
3354                                         res = 0;