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