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