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