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