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