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