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