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