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