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