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