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