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