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