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