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