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