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