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