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