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