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