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