Merge the dialplan_aesthetics branch. Most of this patch simply converts applications
[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 #include "asterisk.h"
60
61 ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
62
63 #include <stdlib.h>
64 #include <errno.h>
65 #include <unistd.h>
66 #include <string.h>
67 #include <stdlib.h>
68 #include <stdio.h>
69 #include <sys/time.h>
70 #include <sys/signal.h>
71 #include <netinet/in.h>
72
73 #include "asterisk/lock.h"
74 #include "asterisk/file.h"
75 #include "asterisk/logger.h"
76 #include "asterisk/channel.h"
77 #include "asterisk/pbx.h"
78 #include "asterisk/options.h"
79 #include "asterisk/app.h"
80 #include "asterisk/linkedlists.h"
81 #include "asterisk/module.h"
82 #include "asterisk/translate.h"
83 #include "asterisk/say.h"
84 #include "asterisk/features.h"
85 #include "asterisk/musiconhold.h"
86 #include "asterisk/cli.h"
87 #include "asterisk/manager.h"
88 #include "asterisk/config.h"
89 #include "asterisk/monitor.h"
90 #include "asterisk/utils.h"
91 #include "asterisk/causes.h"
92 #include "asterisk/astdb.h"
93 #include "asterisk/devicestate.h"
94 #include "asterisk/stringfields.h"
95 #include "asterisk/event.h"
96
97 enum {
98         QUEUE_STRATEGY_RINGALL = 0,
99         QUEUE_STRATEGY_LEASTRECENT,
100         QUEUE_STRATEGY_FEWESTCALLS,
101         QUEUE_STRATEGY_RANDOM,
102         QUEUE_STRATEGY_RRMEMORY
103 };
104
105 static struct strategy {
106         int strategy;
107         char *name;
108 } strategies[] = {
109         { QUEUE_STRATEGY_RINGALL, "ringall" },
110         { QUEUE_STRATEGY_LEASTRECENT, "leastrecent" },
111         { QUEUE_STRATEGY_FEWESTCALLS, "fewestcalls" },
112         { QUEUE_STRATEGY_RANDOM, "random" },
113         { QUEUE_STRATEGY_RRMEMORY, "rrmemory" },
114 };
115
116 #define DEFAULT_RETRY           5
117 #define DEFAULT_TIMEOUT         15
118 #define RECHECK                 1               /* Recheck every second to see we we're at the top yet */
119 #define MAX_PERIODIC_ANNOUNCEMENTS 10 /* The maximum periodic announcements we can have */
120 #define DEFAULT_MIN_ANNOUNCE_FREQUENCY 15 /* The minimum number of seconds between position announcements
121                                              The default value of 15 provides backwards compatibility */
122
123 #define RES_OKAY        0               /* Action completed */
124 #define RES_EXISTS      (-1)            /* Entry already exists */
125 #define RES_OUTOFMEMORY (-2)            /* Out of memory */
126 #define RES_NOSUCHQUEUE (-3)            /* No such queue */
127
128 static char *app = "Queue";
129
130 static char *synopsis = "Queue a call for a call queue";
131
132 static char *descrip =
133 "  Queue(queuename[|options[|URL][|announceoverride][|timeout][|AGI][|macro][|gosub]):\n"
134 "Queues an incoming call in a particular call queue as defined in queues.conf.\n"
135 "This application will return to the dialplan if the queue does not exist, or\n"
136 "any of the join options cause the caller to not enter the queue.\n"
137 "The option string may contain zero or more of the following characters:\n"
138 "      'c' -- continue in the dialplan if the callee hangs up.\n"
139 "      'd' -- data-quality (modem) call (minimum delay).\n"
140 "      'h' -- allow callee to hang up by pressing *.\n"
141 "      'H' -- allow caller to hang up by pressing *.\n"
142 "      'n' -- no retries on the timeout; will exit this application and \n"
143 "             go to the next step.\n"
144 "      'i' -- ignore call forward requests from queue members and do nothing\n"
145 "             when they are requested.\n"
146 "      'r' -- ring instead of playing MOH. Periodic Announcements are still made, if applicable.\n"
147 "      't' -- allow the called user to transfer the calling user.\n"
148 "      'T' -- allow the calling user to transfer the call.\n"
149 "      'w' -- allow the called user to write the conversation to disk via Monitor.\n"
150 "      'W' -- allow the calling user to write the conversation to disk via Monitor.\n"
151 "  In addition to transferring the call, a call may be parked and then picked\n"
152 "up by another user.\n"
153 "  The optional URL will be sent to the called party if the channel supports\n"
154 "it.\n"
155 "  The optional AGI parameter will setup an AGI script to be executed on the \n"
156 "calling party's channel once they are connected to a queue member.\n"
157 "  The optional macro parameter will run a macro on the \n"
158 "calling party's channel once they are connected to a queue member.\n"
159 "  The optional gosub parameter will run a gosub on the \n"
160 "calling party's channel once they are connected to a queue member.\n"
161 "  The timeout will cause the queue to fail out after a specified number of\n"
162 "seconds, checked between each queues.conf 'timeout' and 'retry' cycle.\n"
163 "  This application sets the following channel variable upon completion:\n"
164 "      QUEUESTATUS    The status of the call as a text string, one of\n"
165 "             TIMEOUT | FULL | JOINEMPTY | LEAVEEMPTY | JOINUNAVAIL | LEAVEUNAVAIL | CONTINUE\n";
166
167 static char *app_aqm = "AddQueueMember" ;
168 static char *app_aqm_synopsis = "Dynamically adds queue members" ;
169 static char *app_aqm_descrip =
170 "   AddQueueMember(queuename[|interface[|penalty[|options[|membername]]]]):\n"
171 "Dynamically adds interface to an existing queue.\n"
172 "If the interface is already in the queue it will return an error.\n"
173 "  This application sets the following channel variable upon completion:\n"
174 "     AQMSTATUS    The status of the attempt to add a queue member as a \n"
175 "                     text string, one of\n"
176 "           ADDED | MEMBERALREADY | NOSUCHQUEUE \n"
177 "Example: AddQueueMember(techsupport|SIP/3000)\n"
178 "";
179
180 static char *app_rqm = "RemoveQueueMember" ;
181 static char *app_rqm_synopsis = "Dynamically removes queue members" ;
182 static char *app_rqm_descrip =
183 "   RemoveQueueMember(queuename[|interface[|options]]):\n"
184 "Dynamically removes interface to an existing queue\n"
185 "If the interface is NOT in the queue it will return an error.\n"
186 "  This application sets the following channel variable upon completion:\n"
187 "     RQMSTATUS      The status of the attempt to remove a queue member as a\n"
188 "                     text string, one of\n"
189 "           REMOVED | NOTINQUEUE | NOSUCHQUEUE \n"
190 "Example: RemoveQueueMember(techsupport|SIP/3000)\n"
191 "";
192
193 static char *app_pqm = "PauseQueueMember" ;
194 static char *app_pqm_synopsis = "Pauses a queue member" ;
195 static char *app_pqm_descrip =
196 "   PauseQueueMember([queuename]|interface[|options]):\n"
197 "Pauses (blocks calls for) a queue member.\n"
198 "The given interface will be paused in the given queue.  This prevents\n"
199 "any calls from being sent from the queue to the interface until it is\n"
200 "unpaused with UnpauseQueueMember or the manager interface.  If no\n"
201 "queuename is given, the interface is paused in every queue it is a\n"
202 "member of. The application will fail if the interface is not found.\n"
203 "  This application sets the following channel variable upon completion:\n"
204 "     PQMSTATUS      The status of the attempt to pause a queue member as a\n"
205 "                     text string, one of\n"
206 "           PAUSED | NOTFOUND\n"
207 "Example: PauseQueueMember(|SIP/3000)\n";
208
209 static char *app_upqm = "UnpauseQueueMember" ;
210 static char *app_upqm_synopsis = "Unpauses a queue member" ;
211 static char *app_upqm_descrip =
212 "   UnpauseQueueMember([queuename]|interface[|options]):\n"
213 "Unpauses (resumes calls to) a queue member.\n"
214 "This is the counterpart to PauseQueueMember and operates exactly the\n"
215 "same way, except it unpauses instead of pausing the given interface.\n"
216 "  This application sets the following channel variable upon completion:\n"
217 "     UPQMSTATUS       The status of the attempt to unpause a queue \n"
218 "                      member as a text string, one of\n"
219 "            UNPAUSED | NOTFOUND\n"
220 "Example: UnpauseQueueMember(|SIP/3000)\n";
221
222 static char *app_ql = "QueueLog" ;
223 static char *app_ql_synopsis = "Writes to the queue_log" ;
224 static char *app_ql_descrip =
225 "   QueueLog(queuename|uniqueid|agent|event[|additionalinfo]):\n"
226 "Allows you to write your own events into the queue log\n"
227 "Example: QueueLog(101|${UNIQUEID}|${AGENT}|WENTONBREAK|600)\n";
228
229 /*! \brief Persistent Members astdb family */
230 static const char *pm_family = "Queue/PersistentMembers";
231 /* The maximum length of each persistent member queue database entry */
232 #define PM_MAX_LEN 8192
233
234 /*! \brief queues.conf [general] option */
235 static int queue_keep_stats = 0;
236
237 /*! \brief queues.conf [general] option */
238 static int queue_persistent_members = 0;
239
240 /*! \brief queues.conf per-queue weight option */
241 static int use_weight = 0;
242
243 /*! \brief queues.conf [general] option */
244 static int autofill_default = 0;
245
246 /*! \brief queues.conf [general] option */
247 static int montype_default = 0;
248
249 /*! \brief Subscription to device state change events */
250 static struct ast_event_sub *device_state_sub;
251
252 enum queue_result {
253         QUEUE_UNKNOWN = 0,
254         QUEUE_TIMEOUT = 1,
255         QUEUE_JOINEMPTY = 2,
256         QUEUE_LEAVEEMPTY = 3,
257         QUEUE_JOINUNAVAIL = 4,
258         QUEUE_LEAVEUNAVAIL = 5,
259         QUEUE_FULL = 6,
260         QUEUE_CONTINUE = 7,
261 };
262
263 const struct {
264         enum queue_result id;
265         char *text;
266 } queue_results[] = {
267         { QUEUE_UNKNOWN, "UNKNOWN" },
268         { QUEUE_TIMEOUT, "TIMEOUT" },
269         { QUEUE_JOINEMPTY,"JOINEMPTY" },
270         { QUEUE_LEAVEEMPTY, "LEAVEEMPTY" },
271         { QUEUE_JOINUNAVAIL, "JOINUNAVAIL" },
272         { QUEUE_LEAVEUNAVAIL, "LEAVEUNAVAIL" },
273         { QUEUE_FULL, "FULL" },
274         { QUEUE_CONTINUE, "CONTINUE" },
275 };
276
277 /*! \brief We define a custom "local user" structure because we
278    use it not only for keeping track of what is in use but
279    also for keeping track of who we're dialing. */
280
281 struct callattempt {
282         struct callattempt *q_next;
283         struct ast_channel *chan;
284         char interface[256];
285         int stillgoing;
286         int metric;
287         int oldstatus;
288         time_t lastcall;
289         struct member *member;
290 };
291
292
293 struct queue_ent {
294         struct call_queue *parent;          /*!< What queue is our parent */
295         char moh[80];                       /*!< Name of musiconhold to be used */
296         char announce[80];                  /*!< Announcement to play for member when call is answered */
297         char context[AST_MAX_CONTEXT];      /*!< Context when user exits queue */
298         char digits[AST_MAX_EXTENSION];     /*!< Digits entered while in queue */
299         int valid_digits;                   /*!< Digits entered correspond to valid extension. Exited */
300         int pos;                            /*!< Where we are in the queue */
301         int prio;                           /*!< Our priority */
302         int last_pos_said;                  /*!< Last position we told the user */
303         time_t last_periodic_announce_time; /*!< The last time we played a periodic announcement */
304         int last_periodic_announce_sound;   /*!< The last periodic announcement we made */
305         time_t last_pos;                    /*!< Last time we told the user their position */
306         int opos;                           /*!< Where we started in the queue */
307         int handled;                        /*!< Whether our call was handled */
308         int max_penalty;                    /*!< Limit the members that can take this call to this penalty or lower */
309         time_t start;                       /*!< When we started holding */
310         time_t expire;                      /*!< When this entry should expire (time out of queue) */
311         struct ast_channel *chan;           /*!< Our channel */
312         struct queue_ent *next;             /*!< The next queue entry */
313 };
314
315 struct member {
316         char interface[80];                 /*!< Technology/Location */
317         char membername[80];                /*!< Member name to use in queue logs */
318         int penalty;                        /*!< Are we a last resort? */
319         int calls;                          /*!< Number of calls serviced by this member */
320         int dynamic;                        /*!< Are we dynamically added? */
321         int status;                         /*!< Status of queue member */
322         int paused;                         /*!< Are we paused (not accepting calls)? */
323         time_t lastcall;                    /*!< When last successful call was hungup */
324         unsigned int dead:1;                /*!< Used to detect members deleted in realtime */
325         unsigned int delme:1;               /*!< Flag to delete entry on reload */
326         struct member *next;                /*!< Next member */
327 };
328
329 struct member_interface {
330         char interface[80];
331         AST_LIST_ENTRY(member_interface) list;    /*!< Next call queue */
332 };
333
334 static AST_LIST_HEAD_STATIC(interfaces, member_interface);
335
336 /* values used in multi-bit flags in call_queue */
337 #define QUEUE_EMPTY_NORMAL 1
338 #define QUEUE_EMPTY_STRICT 2
339 #define QUEUE_EMPTY_LOOSE 3
340 #define ANNOUNCEHOLDTIME_ALWAYS 1
341 #define ANNOUNCEHOLDTIME_ONCE 2
342 #define QUEUE_EVENT_VARIABLES 3
343
344 struct call_queue {
345         ast_mutex_t lock;       
346         char name[80];                      /*!< Name */
347         char moh[80];                       /*!< Music On Hold class to be used */
348         char announce[80];                  /*!< Announcement to play when call is answered */
349         char context[AST_MAX_CONTEXT];      /*!< Exit context */
350         unsigned int monjoin:1;
351         unsigned int dead:1;
352         unsigned int joinempty:2;
353         unsigned int eventwhencalled:2;
354         unsigned int leavewhenempty:2;
355         unsigned int ringinuse:1;
356         unsigned int setinterfacevar:1;
357         unsigned int setqueuevar:1;
358         unsigned int setqueueentryvar:1;
359         unsigned int reportholdtime:1;
360         unsigned int wrapped:1;
361         unsigned int timeoutrestart:1;
362         unsigned int announceholdtime:2;
363         unsigned int strategy:3;
364         unsigned int maskmemberstatus:1;
365         unsigned int realtime:1;
366         int announcefrequency;              /*!< How often to announce their position */
367         int minannouncefrequency;           /*!< The minimum number of seconds between position announcements (def. 15) */
368         int periodicannouncefrequency;      /*!< How often to play periodic announcement */
369         int roundingseconds;                /*!< How many seconds do we round to? */
370         int holdtime;                       /*!< Current avg holdtime, based on recursive boxcar filter */
371         int callscompleted;                 /*!< Number of queue calls completed */
372         int callsabandoned;                 /*!< Number of queue calls abandoned */
373         int servicelevel;                   /*!< seconds setting for servicelevel*/
374         int callscompletedinsl;             /*!< Number of calls answered with servicelevel*/
375         char monfmt[8];                     /*!< Format to use when recording calls */
376         int montype;                        /*!< Monitor type  Monitor vs. MixMonitor */
377         char membermacro[32];               /*!< Macro to run upon member connection */
378         char membergosub[32];               /*!< Gosub to run upon member connection */
379         char sound_next[80];                /*!< Sound file: "Your call is now first in line" (def. queue-youarenext) */
380         char sound_thereare[80];            /*!< Sound file: "There are currently" (def. queue-thereare) */
381         char sound_calls[80];               /*!< Sound file: "calls waiting to speak to a representative." (def. queue-callswaiting)*/
382         char sound_holdtime[80];            /*!< Sound file: "The current estimated total holdtime is" (def. queue-holdtime) */
383         char sound_minutes[80];             /*!< Sound file: "minutes." (def. queue-minutes) */
384         char sound_lessthan[80];            /*!< Sound file: "less-than" (def. queue-lessthan) */
385         char sound_seconds[80];             /*!< Sound file: "seconds." (def. queue-seconds) */
386         char sound_thanks[80];              /*!< Sound file: "Thank you for your patience." (def. queue-thankyou) */
387         char sound_callerannounce[80];      /*!< Sound file: Custom announce for caller, no default */
388         char sound_reporthold[80];          /*!< Sound file: "Hold time" (def. queue-reporthold) */
389         char sound_periodicannounce[MAX_PERIODIC_ANNOUNCEMENTS][80];/*!< Sound files: Custom announce, no default */
390
391         int count;                          /*!< How many entries */
392         int maxlen;                         /*!< Max number of entries */
393         int wrapuptime;                     /*!< Wrapup Time */
394
395         int retry;                          /*!< Retry calling everyone after this amount of time */
396         int timeout;                        /*!< How long to wait for an answer */
397         int weight;                         /*!< Respective weight */
398         int autopause;                      /*!< Auto pause queue members if they fail to answer */
399
400         /* Queue strategy things */
401         int rrpos;                          /*!< Round Robin - position */
402         int memberdelay;                    /*!< Seconds to delay connecting member to caller */
403         int autofill;                       /*!< Ignore the head call status and ring an available agent */
404         
405         struct member *members;             /*!< Head of the list of members */
406         struct queue_ent *head;             /*!< Head of the list of callers */
407         AST_LIST_ENTRY(call_queue) list;    /*!< Next call queue */
408 };
409
410 static AST_LIST_HEAD_STATIC(queues, call_queue);
411
412 static int set_member_paused(const char *queuename, const char *interface, int paused);
413
414 static void set_queue_result(struct ast_channel *chan, enum queue_result res)
415 {
416         int i;
417
418         for (i = 0; i < sizeof(queue_results) / sizeof(queue_results[0]); i++) {
419                 if (queue_results[i].id == res) {
420                         pbx_builtin_setvar_helper(chan, "QUEUESTATUS", queue_results[i].text);
421                         return;
422                 }
423         }
424 }
425
426 static char *int2strat(int strategy)
427 {
428         int x;
429
430         for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
431                 if (strategy == strategies[x].strategy)
432                         return strategies[x].name;
433         }
434
435         return "<unknown>";
436 }
437
438 static int strat2int(const char *strategy)
439 {
440         int x;
441
442         for (x = 0; x < sizeof(strategies) / sizeof(strategies[0]); x++) {
443                 if (!strcasecmp(strategy, strategies[x].name))
444                         return strategies[x].strategy;
445         }
446
447         return -1;
448 }
449
450 static void set_queue_variables(struct queue_ent *qe)
451 {
452
453         char interfacevar[256]="";
454         float sl = 0;
455         
456         if (qe->parent->setqueuevar) {
457         sl = 0;
458         if (qe->parent->callscompleted > 0) 
459                 sl = 100 * ((float) qe->parent->callscompletedinsl / (float) qe->parent->callscompleted);
460
461         snprintf(interfacevar,sizeof(interfacevar),
462                 "QUEUEMAX=%d|QUEUESTRATEGY=%s|QUEUECALLS=%d|QUEUEHOLDTIME=%d|QUEUECOMPLETED=%d|QUEUEABANDONED=%d|QUEUESRVLEVEL=%d|QUEUESRVLEVELPERF=%2.1f",
463                 qe->parent->maxlen, int2strat(qe->parent->strategy), qe->parent->count, qe->parent->holdtime, qe->parent->callscompleted,
464                 qe->parent->callsabandoned,  qe->parent->servicelevel, sl);
465         
466         pbx_builtin_setvar(qe->chan, interfacevar); 
467         }
468 }
469
470 /*! \brief Insert the 'new' entry after the 'prev' entry of queue 'q' */
471 static inline void insert_entry(struct call_queue *q, struct queue_ent *prev, struct queue_ent *new, int *pos)
472 {
473         struct queue_ent *cur;
474
475         if (!q || !new)
476                 return;
477         if (prev) {
478                 cur = prev->next;
479                 prev->next = new;
480         } else {
481                 cur = q->head;
482                 q->head = new;
483         }
484         new->next = cur;
485         new->parent = q;
486         new->pos = ++(*pos);
487         new->opos = *pos;
488 }
489
490 enum queue_member_status {
491         QUEUE_NO_MEMBERS,
492         QUEUE_NO_REACHABLE_MEMBERS,
493         QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS,
494         QUEUE_NORMAL
495 };
496
497 static enum queue_member_status get_member_status(struct call_queue *q, int max_penalty)
498 {
499         struct member *member;
500         enum queue_member_status result = QUEUE_NO_MEMBERS;
501
502         ast_mutex_lock(&q->lock);
503         for (member = q->members; member; member = member->next) {
504                 if (max_penalty && (member->penalty > max_penalty))
505                         continue;
506
507                 switch (member->status) {
508                 case AST_DEVICE_INVALID:
509                         /* nothing to do */
510                         break;
511                 case AST_DEVICE_UNAVAILABLE:
512                         if (result != QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS) 
513                                 result = QUEUE_NO_REACHABLE_MEMBERS;
514                         break;
515                 default:
516                         if (member->paused) {
517                                 result = QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS;
518                         } else {
519                                 ast_mutex_unlock(&q->lock);
520                                 return QUEUE_NORMAL;
521                         }
522                         break;
523                 }
524         }
525         
526         ast_mutex_unlock(&q->lock);
527         return result;
528 }
529
530 struct statechange {
531         AST_LIST_ENTRY(statechange) entry;
532         int state;
533         char dev[0];
534 };
535
536 static void *handle_statechange(struct statechange *sc)
537 {
538         struct call_queue *q;
539         struct member *cur;
540         struct member_interface *curint;
541         char *loc;
542         char *technology;
543
544         technology = ast_strdupa(sc->dev);
545         loc = strchr(technology, '/');
546         if (loc) {
547                 *loc++ = '\0';
548         } else {
549                 return NULL;
550         }
551
552         AST_LIST_LOCK(&interfaces);
553         AST_LIST_TRAVERSE(&interfaces, curint, list) {
554                 char *interface;
555                 char *slash_pos;
556                 interface = ast_strdupa(curint->interface);
557                 if ((slash_pos = strchr(interface, '/')))
558                         if ((slash_pos = strchr(slash_pos + 1, '/')))
559                                 *slash_pos = '\0';
560
561                 if (!strcasecmp(interface, sc->dev))
562                         break;
563         }
564         AST_LIST_UNLOCK(&interfaces);
565
566         if (!curint) {
567                 ast_debug(3, "Device '%s/%s' changed to state '%d' (%s) but we don't care because they're not a member of any queue.\n", technology, loc, sc->state, devstate2str(sc->state));
568                 return NULL;
569         }
570
571         ast_debug(1, "Device '%s/%s' changed to state '%d' (%s)\n", technology, loc, sc->state, devstate2str(sc->state));
572         AST_LIST_LOCK(&queues);
573         AST_LIST_TRAVERSE(&queues, q, list) {
574                 ast_mutex_lock(&q->lock);
575                 for (cur = q->members; cur; cur = cur->next) {
576                         char *interface;
577                         char *slash_pos;
578                         interface = ast_strdupa(cur->interface);
579                         if ((slash_pos = strchr(interface, '/')))
580                                 if ((slash_pos = strchr(slash_pos + 1, '/')))
581                                         *slash_pos = '\0';
582
583                         if (strcasecmp(sc->dev, interface))
584                                 continue;
585
586                         if (cur->status != sc->state) {
587                                 cur->status = sc->state;
588                                 if (q->maskmemberstatus)
589                                         continue;
590
591                                 manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
592                                         "Queue: %s\r\n"
593                                         "Location: %s\r\n"
594                                         "MemberName: %s\r\n"
595                                         "Membership: %s\r\n"
596                                         "Penalty: %d\r\n"
597                                         "CallsTaken: %d\r\n"
598                                         "LastCall: %d\r\n"
599                                         "Status: %d\r\n"
600                                         "Paused: %d\r\n",
601                                         q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : "static",
602                                         cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
603                         }
604                 }
605                 ast_mutex_unlock(&q->lock);
606         }
607         AST_LIST_UNLOCK(&queues);
608
609         return NULL;
610 }
611
612 /*!
613  * \brief Data used by the device state thread
614  */
615 static struct {
616         /*! Set to 1 to stop the thread */
617         unsigned int stop:1;
618         /*! The device state monitoring thread */
619         pthread_t thread;
620         /*! Lock for the state change queue */
621         ast_mutex_t lock;
622         /*! Condition for the state change queue */
623         ast_cond_t cond;
624         /*! Queue of state changes */
625         AST_LIST_HEAD_NOLOCK(, statechange) state_change_q;
626 } device_state = {
627         .thread = AST_PTHREADT_NULL,
628 };
629
630 static void *device_state_thread(void *data)
631 {
632         struct statechange *sc;
633
634         while (!device_state.stop) {
635                 ast_mutex_lock(&device_state.lock);
636                 if (!(sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry))) {
637                         ast_cond_wait(&device_state.cond, &device_state.lock);
638                         sc = AST_LIST_REMOVE_HEAD(&device_state.state_change_q, entry);
639                 }
640                 ast_mutex_unlock(&device_state.lock);
641
642                 /* Check to see if we were woken up to see the request to stop */
643                 if (device_state.stop)
644                         return NULL;
645
646                 if (!sc)
647                         continue;
648
649                 handle_statechange(sc);
650
651                 free(sc);
652         }
653
654         return NULL;
655 }
656
657 static int statechange_queue(const char *dev, enum ast_device_state state)
658 {
659         struct statechange *sc;
660
661         if (!(sc = ast_calloc(1, sizeof(*sc) + strlen(dev) + 1)))
662                 return 0;
663
664         sc->state = state;
665         strcpy(sc->dev, dev);
666
667         ast_mutex_lock(&device_state.lock);
668         AST_LIST_INSERT_TAIL(&device_state.state_change_q, sc, entry);
669         ast_cond_signal(&device_state.cond);
670         ast_mutex_unlock(&device_state.lock);
671
672         return 0;
673 }
674
675 static void device_state_cb(const struct ast_event *event, void *unused)
676 {
677         enum ast_device_state state;
678         const char *device;
679
680         state = ast_event_get_ie_uint(event, AST_EVENT_IE_STATE);
681         device = ast_event_get_ie_str(event, AST_EVENT_IE_DEVICE);
682
683         if (ast_strlen_zero(device)) {
684                 ast_log(LOG_ERROR, "Received invalid event that had no device IE\n");
685                 return;
686         }
687
688         statechange_queue(device, state);
689 }
690
691 static struct member *create_queue_member(const char *interface, const char *membername, int penalty, int paused)
692 {
693         struct member *cur;
694         
695         if ((cur = ast_calloc(1, sizeof(*cur)))) {
696                 cur->penalty = penalty;
697                 cur->paused = paused;
698                 ast_copy_string(cur->interface, interface, sizeof(cur->interface));
699                 ast_copy_string(cur->membername, membername, sizeof(cur->membername));
700                 if (!strchr(cur->interface, '/'))
701                         ast_log(LOG_WARNING, "No location at interface '%s'\n", interface);
702                 cur->status = ast_device_state(interface);
703         }
704
705         return cur;
706 }
707
708 static struct call_queue *alloc_queue(const char *queuename)
709 {
710         struct call_queue *q;
711
712         if ((q = ast_calloc(1, sizeof(*q)))) {
713                 ast_mutex_init(&q->lock);
714                 ast_copy_string(q->name, queuename, sizeof(q->name));
715         }
716         return q;
717 }
718
719 static void init_queue(struct call_queue *q)
720 {
721         int i;
722
723         q->dead = 0;
724         q->retry = DEFAULT_RETRY;
725         q->timeout = -1;
726         q->maxlen = 0;
727         q->announcefrequency = 0;
728         q->minannouncefrequency = DEFAULT_MIN_ANNOUNCE_FREQUENCY;
729         q->announceholdtime = 0;
730         q->roundingseconds = 0; /* Default - don't announce seconds */
731         q->servicelevel = 0;
732         q->ringinuse = 1;
733         q->setinterfacevar = 0;
734         q->setqueuevar = 0;
735         q->setqueueentryvar = 0;
736         q->autofill = autofill_default;
737         q->montype = montype_default;
738         q->membermacro[0] = '\0';
739         q->membergosub[0] = '\0';
740         q->moh[0] = '\0';
741         q->announce[0] = '\0';
742         q->context[0] = '\0';
743         q->monfmt[0] = '\0';
744         q->periodicannouncefrequency = 0;
745         q->sound_callerannounce[0] = '\0';      /* Default, don't announce the caller that he has been answered */
746         ast_copy_string(q->sound_next, "queue-youarenext", sizeof(q->sound_next));
747         ast_copy_string(q->sound_thereare, "queue-thereare", sizeof(q->sound_thereare));
748         ast_copy_string(q->sound_calls, "queue-callswaiting", sizeof(q->sound_calls));
749         ast_copy_string(q->sound_holdtime, "queue-holdtime", sizeof(q->sound_holdtime));
750         ast_copy_string(q->sound_minutes, "queue-minutes", sizeof(q->sound_minutes));
751         ast_copy_string(q->sound_seconds, "queue-seconds", sizeof(q->sound_seconds));
752         ast_copy_string(q->sound_thanks, "queue-thankyou", sizeof(q->sound_thanks));
753         ast_copy_string(q->sound_lessthan, "queue-less-than", sizeof(q->sound_lessthan));
754         ast_copy_string(q->sound_reporthold, "queue-reporthold", sizeof(q->sound_reporthold));
755         ast_copy_string(q->sound_periodicannounce[0], "queue-periodic-announce", sizeof(q->sound_periodicannounce[0]));
756         for (i = 1; i < MAX_PERIODIC_ANNOUNCEMENTS; i++) {
757                 q->sound_periodicannounce[i][0]='\0';
758         }
759 }
760
761 static void clear_queue(struct call_queue *q)
762 {
763         q->holdtime = 0;
764         q->callscompleted = 0;
765         q->callsabandoned = 0;
766         q->callscompletedinsl = 0;
767         q->wrapuptime = 0;
768 }
769
770 static int add_to_interfaces(const char *interface)
771 {
772         struct member_interface *curint;
773
774         AST_LIST_LOCK(&interfaces);
775         AST_LIST_TRAVERSE(&interfaces, curint, list) {
776                 if (!strcasecmp(curint->interface, interface))
777                         break;
778         }
779
780         if (curint) {
781                 AST_LIST_UNLOCK(&interfaces);
782                 return 0;
783         }
784
785         ast_debug(1, "Adding %s to the list of interfaces that make up all of our queue members.\n", interface);
786         
787         if ((curint = ast_calloc(1, sizeof(*curint)))) {
788                 ast_copy_string(curint->interface, interface, sizeof(curint->interface));
789                 AST_LIST_INSERT_HEAD(&interfaces, curint, list);
790         }
791         AST_LIST_UNLOCK(&interfaces);
792
793         return 0;
794 }
795
796 static int interface_exists_global(const char *interface)
797 {
798         struct call_queue *q;
799         struct member *mem;
800         int ret = 0;
801
802         AST_LIST_LOCK(&queues);
803         AST_LIST_TRAVERSE(&queues, q, list) {
804                 ast_mutex_lock(&q->lock);
805                 for (mem = q->members; mem && !ret; mem = mem->next) {
806                         if (!strcasecmp(interface, mem->interface))
807                                 ret = 1;
808                 }
809                 ast_mutex_unlock(&q->lock);
810                 if (ret)
811                         break;
812         }
813         AST_LIST_UNLOCK(&queues);
814
815         return ret;
816 }
817
818 static int remove_from_interfaces(const char *interface)
819 {
820         struct member_interface *curint;
821
822         AST_LIST_LOCK(&interfaces);
823         AST_LIST_TRAVERSE_SAFE_BEGIN(&interfaces, curint, list) {
824                 if (!strcasecmp(curint->interface, interface)) {
825                         if (!interface_exists_global(interface)) {
826                                 ast_debug(1, "Removing %s from the list of interfaces that make up all of our queue members.\n", interface);
827                                 AST_LIST_REMOVE_CURRENT(&interfaces, list);
828                                 ast_free(curint);
829                         }
830                         break;
831                 }
832         }
833         AST_LIST_TRAVERSE_SAFE_END;
834         AST_LIST_UNLOCK(&interfaces);
835
836         return 0;
837 }
838
839 static void clear_and_free_interfaces(void)
840 {
841         struct member_interface *curint;
842
843         AST_LIST_LOCK(&interfaces);
844         while ((curint = AST_LIST_REMOVE_HEAD(&interfaces, list)))
845                 ast_free(curint);
846         AST_LIST_UNLOCK(&interfaces);
847 }
848
849 /*! \brief Configure a queue parameter.
850 \par
851    For error reporting, line number is passed for .conf static configuration.
852    For Realtime queues, linenum is -1.
853    The failunknown flag is set for config files (and static realtime) to show
854    errors for unknown parameters. It is cleared for dynamic realtime to allow
855    extra fields in the tables. */
856 static void queue_set_param(struct call_queue *q, const char *param, const char *val, int linenum, int failunknown)
857 {
858         if (!strcasecmp(param, "musicclass") || 
859                 !strcasecmp(param, "music") || !strcasecmp(param, "musiconhold")) {
860                 ast_copy_string(q->moh, val, sizeof(q->moh));
861         } else if (!strcasecmp(param, "announce")) {
862                 ast_copy_string(q->announce, val, sizeof(q->announce));
863         } else if (!strcasecmp(param, "context")) {
864                 ast_copy_string(q->context, val, sizeof(q->context));
865         } else if (!strcasecmp(param, "timeout")) {
866                 q->timeout = atoi(val);
867                 if (q->timeout < 0)
868                         q->timeout = DEFAULT_TIMEOUT;
869         } else if (!strcasecmp(param, "ringinuse")) {
870                 q->ringinuse = ast_true(val);
871         } else if (!strcasecmp(param, "setinterfacevar")) {
872                 q->setinterfacevar = ast_true(val);
873         } else if (!strcasecmp(param, "setqueuevar")) {
874                 q->setqueuevar = ast_true(val);
875         } else if (!strcasecmp(param, "setqueueentryvar")) {
876                 q->setqueueentryvar = ast_true(val);
877         } else if (!strcasecmp(param, "monitor-join")) {
878                 q->monjoin = ast_true(val);
879         } else if (!strcasecmp(param, "monitor-format")) {
880                 ast_copy_string(q->monfmt, val, sizeof(q->monfmt));
881         } else if (!strcasecmp(param, "membermacro")) {
882                 ast_copy_string(q->membermacro, val, sizeof(q->membermacro));
883         } else if (!strcasecmp(param, "membergosub")) {
884                 ast_copy_string(q->membergosub, val, sizeof(q->membergosub));
885         } else if (!strcasecmp(param, "queue-youarenext")) {
886                 ast_copy_string(q->sound_next, val, sizeof(q->sound_next));
887         } else if (!strcasecmp(param, "queue-thereare")) {
888                 ast_copy_string(q->sound_thereare, val, sizeof(q->sound_thereare));
889         } else if (!strcasecmp(param, "queue-callswaiting")) {
890                 ast_copy_string(q->sound_calls, val, sizeof(q->sound_calls));
891         } else if (!strcasecmp(param, "queue-holdtime")) {
892                 ast_copy_string(q->sound_holdtime, val, sizeof(q->sound_holdtime));
893         } else if (!strcasecmp(param, "queue-minutes")) {
894                 ast_copy_string(q->sound_minutes, val, sizeof(q->sound_minutes));
895         } else if (!strcasecmp(param, "queue-seconds")) {
896                 ast_copy_string(q->sound_seconds, val, sizeof(q->sound_seconds));
897         } else if (!strcasecmp(param, "queue-lessthan")) {
898                 ast_copy_string(q->sound_lessthan, val, sizeof(q->sound_lessthan));
899         } else if (!strcasecmp(param, "queue-thankyou")) {
900                 ast_copy_string(q->sound_thanks, val, sizeof(q->sound_thanks));
901         } else if (!strcasecmp(param, "queue-callerannounce")) {
902                 ast_copy_string(q->sound_callerannounce, val, sizeof(q->sound_callerannounce));
903         } else if (!strcasecmp(param, "queue-reporthold")) {
904                 ast_copy_string(q->sound_reporthold, val, sizeof(q->sound_reporthold));
905         } else if (!strcasecmp(param, "announce-frequency")) {
906                 q->announcefrequency = atoi(val);
907         } else if (!strcasecmp(param, "min-announce-frequency")) {
908                 q->minannouncefrequency = atoi(val);
909                 ast_debug(1, "%s=%s for queue '%s'\n", param, val, q->name);
910         } else if (!strcasecmp(param, "announce-round-seconds")) {
911                 q->roundingseconds = atoi(val);
912                 /* Rounding to any other values just doesn't make sense... */
913                 if (!(q->roundingseconds == 0 || q->roundingseconds == 1 || q->roundingseconds == 5 || q->roundingseconds == 10
914                         || q->roundingseconds == 15 || q->roundingseconds == 20 || q->roundingseconds == 30)) {
915                         if (linenum >= 0) {
916                                 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
917                                         "using 0 instead for queue '%s' at line %d of queues.conf\n",
918                                         val, param, q->name, linenum);
919                         } else {
920                                 ast_log(LOG_WARNING, "'%s' isn't a valid value for %s "
921                                         "using 0 instead for queue '%s'\n", val, param, q->name);
922                         }
923                         q->roundingseconds=0;
924                 }
925         } else if (!strcasecmp(param, "announce-holdtime")) {
926                 if (!strcasecmp(val, "once"))
927                         q->announceholdtime = ANNOUNCEHOLDTIME_ONCE;
928                 else if (ast_true(val))
929                         q->announceholdtime = ANNOUNCEHOLDTIME_ALWAYS;
930                 else
931                         q->announceholdtime = 0;
932         } else if (!strcasecmp(param, "periodic-announce")) {
933                 if (strchr(val, ',')) {
934                         char *s, *buf = ast_strdupa(val);
935                         unsigned int i = 0;
936
937                         while ((s = strsep(&buf, ",|"))) {
938                                 ast_copy_string(q->sound_periodicannounce[i], s, sizeof(q->sound_periodicannounce[i]));
939                                 i++;
940                                 if (i == MAX_PERIODIC_ANNOUNCEMENTS)
941                                         break;
942                         }
943                 } else {
944                         ast_copy_string(q->sound_periodicannounce[0], val, sizeof(q->sound_periodicannounce[0]));
945                 }
946         } else if (!strcasecmp(param, "periodic-announce-frequency")) {
947                 q->periodicannouncefrequency = atoi(val);
948         } else if (!strcasecmp(param, "retry")) {
949                 q->retry = atoi(val);
950                 if (q->retry <= 0)
951                         q->retry = DEFAULT_RETRY;
952         } else if (!strcasecmp(param, "wrapuptime")) {
953                 q->wrapuptime = atoi(val);
954         } else if (!strcasecmp(param, "autofill")) {
955                 q->autofill = ast_true(val);
956         } else if (!strcasecmp(param, "monitor-type")) {
957                 if (!strcasecmp(val, "mixmonitor"))
958                         q->montype = 1;
959         } else if (!strcasecmp(param, "autopause")) {
960                 q->autopause = ast_true(val);
961         } else if (!strcasecmp(param, "maxlen")) {
962                 q->maxlen = atoi(val);
963                 if (q->maxlen < 0)
964                         q->maxlen = 0;
965         } else if (!strcasecmp(param, "servicelevel")) {
966                 q->servicelevel= atoi(val);
967         } else if (!strcasecmp(param, "strategy")) {
968                 q->strategy = strat2int(val);
969                 if (q->strategy < 0) {
970                         ast_log(LOG_WARNING, "'%s' isn't a valid strategy for queue '%s', using ringall instead\n",
971                                 val, q->name);
972                         q->strategy = QUEUE_STRATEGY_RINGALL;
973                 }
974         } else if (!strcasecmp(param, "joinempty")) {
975                 if (!strcasecmp(val, "loose"))
976                         q->joinempty = QUEUE_EMPTY_LOOSE;
977                 else if (!strcasecmp(val, "strict"))
978                         q->joinempty = QUEUE_EMPTY_STRICT;
979                 else if (ast_true(val))
980                         q->joinempty = QUEUE_EMPTY_NORMAL;
981                 else
982                         q->joinempty = 0;
983         } else if (!strcasecmp(param, "leavewhenempty")) {
984                 if (!strcasecmp(val, "loose"))
985                         q->leavewhenempty = QUEUE_EMPTY_LOOSE;
986                 else if (!strcasecmp(val, "strict"))
987                         q->leavewhenempty = QUEUE_EMPTY_STRICT;
988                 else if (ast_true(val))
989                         q->leavewhenempty = QUEUE_EMPTY_NORMAL;
990                 else
991                         q->leavewhenempty = 0;
992         } else if (!strcasecmp(param, "eventmemberstatus")) {
993                 q->maskmemberstatus = !ast_true(val);
994         } else if (!strcasecmp(param, "eventwhencalled")) {
995                 if (!strcasecmp(val, "vars")) {
996                         q->eventwhencalled = QUEUE_EVENT_VARIABLES;
997                 } else {
998                         q->eventwhencalled = ast_true(val);
999                 }
1000         } else if (!strcasecmp(param, "reportholdtime")) {
1001                 q->reportholdtime = ast_true(val);
1002         } else if (!strcasecmp(param, "memberdelay")) {
1003                 q->memberdelay = atoi(val);
1004         } else if (!strcasecmp(param, "weight")) {
1005                 q->weight = atoi(val);
1006                 if (q->weight)
1007                         use_weight++;
1008                 /* With Realtime queues, if the last queue using weights is deleted in realtime,
1009                    we will not see any effect on use_weight until next reload. */
1010         } else if (!strcasecmp(param, "timeoutrestart")) {
1011                 q->timeoutrestart = ast_true(val);
1012         } else if (failunknown) {
1013                 if (linenum >= 0) {
1014                         ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s at line %d of queues.conf\n",
1015                                 q->name, param, linenum);
1016                 } else {
1017                         ast_log(LOG_WARNING, "Unknown keyword in queue '%s': %s\n", q->name, param);
1018                 }
1019         }
1020 }
1021
1022 static void rt_handle_member_record(struct call_queue *q, char *interface, const char *membername, const char *penalty_str, const char *paused_str)
1023 {
1024         struct member *m, *prev_m;
1025         int penalty = 0;
1026         int paused  = 0;
1027
1028         if (penalty_str) {
1029                 penalty = atoi(penalty_str);
1030                 if (penalty < 0)
1031                         penalty = 0;
1032         }
1033
1034         if (paused_str) {
1035                 paused = atoi(paused_str);
1036                 if (paused < 0)
1037                         paused = 0;
1038         }
1039
1040         /* Find the member, or the place to put a new one. */
1041         for (m = q->members, prev_m = NULL;
1042                 m && strcmp(m->interface, interface);
1043                 prev_m = m, m = m->next);
1044
1045         /* Create a new one if not found, else update penalty */
1046         if (!m) {
1047                 if ((m = create_queue_member(interface, membername, penalty, paused))) {
1048                         m->dead = 0;
1049                         add_to_interfaces(interface);
1050                         if (prev_m) {
1051                                 prev_m->next = m;
1052                         } else {
1053                                 q->members = m;
1054                         }
1055                 }
1056         } else {
1057                 m->dead = 0;    /* Do not delete this one. */
1058                 if (paused_str)
1059                         m->paused = paused;
1060                 m->penalty = penalty;
1061         }
1062 }
1063
1064 static void free_members(struct call_queue *q, int all)
1065 {
1066         /* Free non-dynamic members */
1067         struct member *curm, *next, *prev = NULL;
1068
1069         for (curm = q->members; curm; curm = next) {
1070                 next = curm->next;
1071                 if (all || !curm->dynamic) {
1072                         if (prev)
1073                                 prev->next = next;
1074                         else
1075                                 q->members = next;
1076                         remove_from_interfaces(curm->interface);
1077                         ast_free(curm);
1078                 } else
1079                         prev = curm;
1080         }
1081 }
1082
1083 static void destroy_queue(struct call_queue *q)
1084 {
1085         free_members(q, 1);
1086         ast_mutex_destroy(&q->lock);
1087         ast_free(q);
1088 }
1089
1090 /*!\brief Reload a single queue via realtime.
1091    \return Return the queue, or NULL if it doesn't exist.
1092    \note Should be called with the global qlock locked. */
1093 static struct call_queue *find_queue_by_name_rt(const char *queuename, struct ast_variable *queue_vars, struct ast_config *member_config)
1094 {
1095         struct ast_variable *v;
1096         struct call_queue *q;
1097         struct member *m, *prev_m, *next_m;
1098         char *interface = NULL;
1099         char *tmp, *tmp_name;
1100         char tmpbuf[64];        /* Must be longer than the longest queue param name. */
1101
1102         /* Find the queue in the in-core list (we will create a new one if not found). */
1103         AST_LIST_TRAVERSE(&queues, q, list) {
1104                 if (!strcasecmp(q->name, queuename))
1105                         break;
1106         }
1107
1108         /* Static queues override realtime. */
1109         if (q) {
1110                 ast_mutex_lock(&q->lock);
1111                 if (!q->realtime) {
1112                         if (q->dead) {
1113                                 ast_mutex_unlock(&q->lock);
1114                                 return NULL;
1115                         } else {
1116                                 ast_mutex_unlock(&q->lock);
1117                                 return q;
1118                         }
1119                 }
1120         } else if (!member_config)
1121                 /* Not found in the list, and it's not realtime ... */
1122                 return NULL;
1123
1124         /* Check if queue is defined in realtime. */
1125         if (!queue_vars) {
1126                 /* Delete queue from in-core list if it has been deleted in realtime. */
1127                 if (q) {
1128                         /*! \note Hmm, can't seem to distinguish a DB failure from a not
1129                            found condition... So we might delete an in-core queue
1130                            in case of DB failure. */
1131                         ast_debug(1, "Queue %s not found in realtime.\n", queuename);
1132
1133                         q->dead = 1;
1134                         /* Delete if unused (else will be deleted when last caller leaves). */
1135                         if (!q->count) {
1136                                 /* Delete. */
1137                                 AST_LIST_REMOVE(&queues, q, list);
1138                                 ast_mutex_unlock(&q->lock);
1139                                 destroy_queue(q);
1140                         } else
1141                                 ast_mutex_unlock(&q->lock);
1142                 }
1143                 return NULL;
1144         }
1145
1146         /* Create a new queue if an in-core entry does not exist yet. */
1147         if (!q) {
1148                 if (!(q = alloc_queue(queuename)))
1149                         return NULL;
1150                 ast_mutex_lock(&q->lock);
1151                 clear_queue(q);
1152                 q->realtime = 1;
1153                 AST_LIST_INSERT_HEAD(&queues, q, list);
1154         }
1155         init_queue(q);          /* Ensure defaults for all parameters not set explicitly. */
1156
1157         memset(tmpbuf, 0, sizeof(tmpbuf));
1158         for (v = queue_vars; v; v = v->next) {
1159                 /* Convert to dashes `-' from underscores `_' as the latter are more SQL friendly. */
1160                 if ((tmp = strchr(v->name, '_'))) {
1161                         ast_copy_string(tmpbuf, v->name, sizeof(tmpbuf));
1162                         tmp_name = tmpbuf;
1163                         tmp = tmp_name;
1164                         while ((tmp = strchr(tmp, '_')))
1165                                 *tmp++ = '-';
1166                 } else
1167                         tmp_name = v->name;
1168                 queue_set_param(q, tmp_name, v->value, -1, 0);
1169         }
1170
1171         /* Temporarily set non-dynamic members dead so we can detect deleted ones. */
1172         for (m = q->members; m; m = m->next) {
1173                 if (!m->dynamic)
1174                         m->dead = 1;
1175         }
1176
1177         while ((interface = ast_category_browse(member_config, interface))) {
1178                 rt_handle_member_record(q, interface,
1179                         S_OR(ast_variable_retrieve(member_config, interface, "membername"), interface),
1180                         ast_variable_retrieve(member_config, interface, "penalty"),
1181                         ast_variable_retrieve(member_config, interface, "paused"));
1182         }
1183
1184         /* Delete all realtime members that have been deleted in DB. */
1185         m = q->members;
1186         prev_m = NULL;
1187         while (m) {
1188                 next_m = m->next;
1189                 if (m->dead) {
1190                         if (prev_m) {
1191                                 prev_m->next = next_m;
1192                         } else {
1193                                 q->members = next_m;
1194                         }
1195                         remove_from_interfaces(m->interface);
1196                         ast_free(m);
1197                 } else {
1198                         prev_m = m;
1199                 }
1200                 m = next_m;
1201         }
1202
1203         ast_mutex_unlock(&q->lock);
1204
1205         return q;
1206 }
1207
1208 static struct call_queue *load_realtime_queue(const char *queuename)
1209 {
1210         struct ast_variable *queue_vars;
1211         struct ast_config *member_config = NULL;
1212         struct call_queue *q;
1213
1214         /* Find the queue in the in-core list first. */
1215         AST_LIST_LOCK(&queues);
1216         AST_LIST_TRAVERSE(&queues, q, list) {
1217                 if (!strcasecmp(q->name, queuename)) {
1218                         break;
1219                 }
1220         }
1221         AST_LIST_UNLOCK(&queues);
1222
1223         if (!q || q->realtime) {
1224                 /*! \note Load from realtime before taking the global qlock, to avoid blocking all
1225                    queue operations while waiting for the DB.
1226
1227                    This will be two separate database transactions, so we might
1228                    see queue parameters as they were before another process
1229                    changed the queue and member list as it was after the change.
1230                    Thus we might see an empty member list when a queue is
1231                    deleted. In practise, this is unlikely to cause a problem. */
1232
1233                 queue_vars = ast_load_realtime("queues", "name", queuename, NULL);
1234                 if (queue_vars) {
1235                         member_config = ast_load_realtime_multientry("queue_members", "interface LIKE", "%", "queue_name", queuename, NULL);
1236                         if (!member_config) {
1237                                 ast_log(LOG_ERROR, "no queue_members defined in your config (extconfig.conf).\n");
1238                                 return NULL;
1239                         }
1240                 }
1241
1242                 AST_LIST_LOCK(&queues);
1243
1244                 q = find_queue_by_name_rt(queuename, queue_vars, member_config);
1245                 if (member_config)
1246                         ast_config_destroy(member_config);
1247                 if (queue_vars)
1248                         ast_variables_destroy(queue_vars);
1249
1250                 AST_LIST_UNLOCK(&queues);
1251         }
1252         return q;
1253 }
1254
1255 static int join_queue(char *queuename, struct queue_ent *qe, enum queue_result *reason)
1256 {
1257         struct call_queue *q;
1258         struct queue_ent *cur, *prev = NULL;
1259         int res = -1;
1260         int pos = 0;
1261         int inserted = 0;
1262         enum queue_member_status stat;
1263
1264         if (!(q = load_realtime_queue(queuename)))
1265                 return res;
1266
1267         AST_LIST_LOCK(&queues);
1268         ast_mutex_lock(&q->lock);
1269
1270         /* This is our one */
1271         stat = get_member_status(q, qe->max_penalty);
1272         if (!q->joinempty && (stat == QUEUE_NO_MEMBERS))
1273                 *reason = QUEUE_JOINEMPTY;
1274         else if ((q->joinempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS))
1275                 *reason = QUEUE_JOINUNAVAIL;
1276         else if ((q->joinempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS))
1277                 *reason = QUEUE_JOINUNAVAIL;
1278         else if (q->maxlen && (q->count >= q->maxlen))
1279                 *reason = QUEUE_FULL;
1280         else {
1281                 /* There's space for us, put us at the right position inside
1282                  * the queue.
1283                  * Take into account the priority of the calling user */
1284                 inserted = 0;
1285                 prev = NULL;
1286                 cur = q->head;
1287                 while (cur) {
1288                         /* We have higher priority than the current user, enter
1289                          * before him, after all the other users with priority
1290                          * higher or equal to our priority. */
1291                         if ((!inserted) && (qe->prio > cur->prio)) {
1292                                 insert_entry(q, prev, qe, &pos);
1293                                 inserted = 1;
1294                         }
1295                         cur->pos = ++pos;
1296                         prev = cur;
1297                         cur = cur->next;
1298                 }
1299                 /* No luck, join at the end of the queue */
1300                 if (!inserted)
1301                         insert_entry(q, prev, qe, &pos);
1302                 ast_copy_string(qe->moh, q->moh, sizeof(qe->moh));
1303                 ast_copy_string(qe->announce, q->announce, sizeof(qe->announce));
1304                 ast_copy_string(qe->context, q->context, sizeof(qe->context));
1305                 q->count++;
1306                 res = 0;
1307                 manager_event(EVENT_FLAG_CALL, "Join",
1308                         "Channel: %s\r\nCallerID: %s\r\nCallerIDName: %s\r\nQueue: %s\r\nPosition: %d\r\nCount: %d\r\nUniqueid: %s\r\n",
1309                         qe->chan->name,
1310                         S_OR(qe->chan->cid.cid_num, "unknown"), /* XXX somewhere else it is <unknown> */
1311                         S_OR(qe->chan->cid.cid_name, "unknown"),
1312                         q->name, qe->pos, q->count, qe->chan->uniqueid );
1313                 ast_debug(1, "Queue '%s' Join, Channel '%s', Position '%d'\n", q->name, qe->chan->name, qe->pos );
1314         }
1315         ast_mutex_unlock(&q->lock);
1316         AST_LIST_UNLOCK(&queues);
1317
1318         return res;
1319 }
1320
1321 static int play_file(struct ast_channel *chan, char *filename)
1322 {
1323         int res;
1324
1325         ast_stopstream(chan);
1326
1327         res = ast_streamfile(chan, filename, chan->language);
1328         if (!res)
1329                 res = ast_waitstream(chan, AST_DIGIT_ANY);
1330
1331         ast_stopstream(chan);
1332
1333         return res;
1334 }
1335
1336 static int valid_exit(struct queue_ent *qe, char digit)
1337 {
1338         int digitlen = strlen(qe->digits);
1339
1340         /* Prevent possible buffer overflow */
1341         if (digitlen < sizeof(qe->digits) - 2) {
1342                 qe->digits[digitlen] = digit;
1343                 qe->digits[digitlen + 1] = '\0';
1344         } else {
1345                 qe->digits[0] = '\0';
1346                 return 0;
1347         }
1348
1349         /* If there's no context to goto, short-circuit */
1350         if (ast_strlen_zero(qe->context))
1351                 return 0;
1352
1353         /* If the extension is bad, then reset the digits to blank */
1354         if (!ast_canmatch_extension(qe->chan, qe->context, qe->digits, 1, qe->chan->cid.cid_num)) {
1355                 qe->digits[0] = '\0';
1356                 return 0;
1357         }
1358
1359         /* We have an exact match */
1360         if (!ast_goto_if_exists(qe->chan, qe->context, qe->digits, 1)) {
1361                 qe->valid_digits = 1;
1362                 /* Return 1 on a successful goto */
1363                 return 1;
1364         }
1365
1366         return 0;
1367 }
1368
1369 static int say_position(struct queue_ent *qe, int ringing)
1370 {
1371         int res = 0, avgholdmins, avgholdsecs;
1372         time_t now;
1373
1374         /* Let minannouncefrequency seconds pass between the start of each position announcement */
1375         time(&now);
1376         if ((now - qe->last_pos) < qe->parent->minannouncefrequency)
1377                 return 0;
1378
1379         /* If either our position has changed, or we are over the freq timer, say position */
1380         if ((qe->last_pos_said == qe->pos) && ((now - qe->last_pos) < qe->parent->announcefrequency))
1381                 return 0;
1382
1383         if (ringing) {
1384                 ast_indicate(qe->chan,-1);
1385         } else {
1386                 ast_moh_stop(qe->chan);
1387         }
1388         /* Say we're next, if we are */
1389         if (qe->pos == 1) {
1390                 res = play_file(qe->chan, qe->parent->sound_next);
1391                 if (res)
1392                         goto playout;
1393                 else
1394                         goto posout;
1395         } else {
1396                 res = play_file(qe->chan, qe->parent->sound_thereare);
1397                 if (res)
1398                         goto playout;
1399                 res = ast_say_number(qe->chan, qe->pos, AST_DIGIT_ANY, qe->chan->language, (char *) NULL); /* Needs gender */
1400                 if (res)
1401                         goto playout;
1402                 res = play_file(qe->chan, qe->parent->sound_calls);
1403                 if (res)
1404                         goto playout;
1405         }
1406         /* Round hold time to nearest minute */
1407         avgholdmins = abs(((qe->parent->holdtime + 30) - (now - qe->start)) / 60);
1408
1409         /* If they have specified a rounding then round the seconds as well */
1410         if (qe->parent->roundingseconds) {
1411                 avgholdsecs = (abs(((qe->parent->holdtime + 30) - (now - qe->start))) - 60 * avgholdmins) / qe->parent->roundingseconds;
1412                 avgholdsecs *= qe->parent->roundingseconds;
1413         } else {
1414                 avgholdsecs = 0;
1415         }
1416
1417         if (option_verbose > 2)
1418                 ast_verbose(VERBOSE_PREFIX_3 "Hold time for %s is %d minutes %d seconds\n", qe->parent->name, avgholdmins, avgholdsecs);
1419
1420         /* If the hold time is >1 min, if it's enabled, and if it's not
1421            supposed to be only once and we have already said it, say it */
1422         if ((avgholdmins+avgholdsecs) > 0 && (qe->parent->announceholdtime) &&
1423                 (!(qe->parent->announceholdtime == ANNOUNCEHOLDTIME_ONCE) && qe->last_pos)) {
1424                 res = play_file(qe->chan, qe->parent->sound_holdtime);
1425                 if (res)
1426                         goto playout;
1427
1428                 if (avgholdmins > 0) {
1429                         if (avgholdmins < 2) {
1430                                 res = play_file(qe->chan, qe->parent->sound_lessthan);
1431                                 if (res)
1432                                         goto playout;
1433
1434                                 res = ast_say_number(qe->chan, 2, AST_DIGIT_ANY, qe->chan->language, NULL);
1435                                 if (res)
1436                                         goto playout;
1437                         } else {
1438                                 res = ast_say_number(qe->chan, avgholdmins, AST_DIGIT_ANY, qe->chan->language, NULL);
1439                                 if (res)
1440                                         goto playout;
1441                         }
1442                         
1443                         res = play_file(qe->chan, qe->parent->sound_minutes);
1444                         if (res)
1445                                 goto playout;
1446                 }
1447                 if (avgholdsecs>0) {
1448                         res = ast_say_number(qe->chan, avgholdsecs, AST_DIGIT_ANY, qe->chan->language, NULL);
1449                         if (res)
1450                                 goto playout;
1451
1452                         res = play_file(qe->chan, qe->parent->sound_seconds);
1453                         if (res)
1454                                 goto playout;
1455                 }
1456
1457         }
1458
1459 posout:
1460         if (option_verbose > 2)
1461                 ast_verbose(VERBOSE_PREFIX_3 "Told %s in %s their queue position (which was %d)\n",
1462                         qe->chan->name, qe->parent->name, qe->pos);
1463         res = play_file(qe->chan, qe->parent->sound_thanks);
1464
1465 playout:
1466         if (res > 0 && !valid_exit(qe, res))
1467                 res = 0;
1468
1469         /* Set our last_pos indicators */
1470         qe->last_pos = now;
1471         qe->last_pos_said = qe->pos;
1472
1473         /* Don't restart music on hold if we're about to exit the caller from the queue */
1474         if (!res) {
1475                 if (ringing)
1476                         ast_indicate(qe->chan, AST_CONTROL_RINGING);
1477                 else
1478                         ast_moh_start(qe->chan, qe->moh, NULL);
1479         }
1480         return res;
1481 }
1482
1483 static void recalc_holdtime(struct queue_ent *qe, int newholdtime)
1484 {
1485         int oldvalue;
1486
1487         /* Calculate holdtime using a recursive boxcar filter */
1488         /* Thanks to SRT for this contribution */
1489         /* 2^2 (4) is the filter coefficient; a higher exponent would give old entries more weight */
1490
1491         ast_mutex_lock(&qe->parent->lock);
1492         oldvalue = qe->parent->holdtime;
1493         qe->parent->holdtime = (((oldvalue << 2) - oldvalue) + newholdtime) >> 2;
1494         ast_mutex_unlock(&qe->parent->lock);
1495 }
1496
1497
1498 static void leave_queue(struct queue_ent *qe)
1499 {
1500         struct call_queue *q;
1501         struct queue_ent *cur, *prev = NULL;
1502         int pos = 0;
1503
1504         if (!(q = qe->parent))
1505                 return;
1506         ast_mutex_lock(&q->lock);
1507
1508         prev = NULL;
1509         for (cur = q->head; cur; cur = cur->next) {
1510                 if (cur == qe) {
1511                         q->count--;
1512
1513                         /* Take us out of the queue */
1514                         manager_event(EVENT_FLAG_CALL, "Leave",
1515                                 "Channel: %s\r\nQueue: %s\r\nCount: %d\r\nUniqueid: %s\r\n",
1516                                 qe->chan->name, q->name,  q->count, qe->chan->uniqueid);
1517                         ast_debug(1, "Queue '%s' Leave, Channel '%s'\n", q->name, qe->chan->name );
1518                         /* Take us out of the queue */
1519                         if (prev)
1520                                 prev->next = cur->next;
1521                         else
1522                                 q->head = cur->next;
1523                 } else {
1524                         /* Renumber the people after us in the queue based on a new count */
1525                         cur->pos = ++pos;
1526                         prev = cur;
1527                 }
1528         }
1529         ast_mutex_unlock(&q->lock);
1530
1531         if (q->dead && !q->count) {     
1532                 /* It's dead and nobody is in it, so kill it */
1533                 AST_LIST_LOCK(&queues);
1534                 AST_LIST_REMOVE(&queues, q, list);
1535                 AST_LIST_UNLOCK(&queues);
1536                 destroy_queue(q);
1537         }
1538 }
1539
1540 /* Hang up a list of outgoing calls */
1541 static void hangupcalls(struct callattempt *outgoing, struct ast_channel *exception)
1542 {
1543         struct callattempt *oo;
1544
1545         while (outgoing) {
1546                 /* Hangup any existing lines we have open */
1547                 if (outgoing->chan && (outgoing->chan != exception))
1548                         ast_hangup(outgoing->chan);
1549                 oo = outgoing;
1550                 outgoing = outgoing->q_next;
1551                 ast_free(oo);
1552         }
1553 }
1554
1555 static int update_status(struct call_queue *q, struct member *member, int status)
1556 {
1557         struct member *cur;
1558
1559         /* Since a reload could have taken place, we have to traverse the list to
1560                 be sure it's still valid */
1561         ast_mutex_lock(&q->lock);
1562         for (cur = q->members; cur; cur = cur->next) {
1563                 if (member != cur)
1564                         continue;
1565
1566                 cur->status = status;
1567                 if (!q->maskmemberstatus) {
1568                         manager_event(EVENT_FLAG_AGENT, "QueueMemberStatus",
1569                                 "Queue: %s\r\n"
1570                                 "Location: %s\r\n"
1571                                 "MemberName: %s\r\n"
1572                                 "Membership: %s\r\n"
1573                                 "Penalty: %d\r\n"
1574                                 "CallsTaken: %d\r\n"
1575                                 "LastCall: %d\r\n"
1576                                 "Status: %d\r\n"
1577                                 "Paused: %d\r\n",
1578                                 q->name, cur->interface, cur->membername, cur->dynamic ? "dynamic" : "static",
1579                                 cur->penalty, cur->calls, (int)cur->lastcall, cur->status, cur->paused);
1580                 }
1581         }
1582         ast_mutex_unlock(&q->lock);
1583         return 0;
1584 }
1585
1586 static int update_dial_status(struct call_queue *q, struct member *member, int status)
1587 {
1588         if (status == AST_CAUSE_BUSY)
1589                 status = AST_DEVICE_BUSY;
1590         else if (status == AST_CAUSE_UNREGISTERED)
1591                 status = AST_DEVICE_UNAVAILABLE;
1592         else if (status == AST_CAUSE_NOSUCHDRIVER)
1593                 status = AST_DEVICE_INVALID;
1594         else
1595                 status = AST_DEVICE_UNKNOWN;
1596         return update_status(q, member, status);
1597 }
1598
1599 /* traverse all defined queues which have calls waiting and contain this member
1600    return 0 if no other queue has precedence (higher weight) or 1 if found  */
1601 static int compare_weight(struct call_queue *rq, struct member *member)
1602 {
1603         struct call_queue *q;
1604         struct member *mem;
1605         int found = 0;
1606         
1607         /* &qlock and &rq->lock already set by try_calling()
1608          * to solve deadlock */
1609         AST_LIST_TRAVERSE(&queues, q, list) {
1610                 if (q == rq) /* don't check myself, could deadlock */
1611                         continue;
1612                 ast_mutex_lock(&q->lock);
1613                 if (q->count && q->members) {
1614                         for (mem = q->members; mem; mem = mem->next) {
1615                                 if (strcmp(mem->interface, member->interface))
1616                                         continue;
1617
1618                                 ast_debug(1, "Found matching member %s in queue '%s'\n", mem->interface, q->name);
1619                                 if (q->weight > rq->weight) {
1620                                         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);
1621                                         found = 1;
1622                                         break;
1623                                 }
1624                         }
1625                 }
1626                 ast_mutex_unlock(&q->lock);
1627                 if (found)
1628                         break;
1629         }
1630         return found;
1631 }
1632
1633 /*! \brief common hangup actions */
1634 static void do_hang(struct callattempt *o)
1635 {
1636         o->stillgoing = 0;
1637         ast_hangup(o->chan);
1638         o->chan = NULL;
1639 }
1640
1641 static char *vars2manager(struct ast_channel *chan, char *vars, size_t len)
1642 {
1643         struct ast_str *buf = ast_str_alloca(len + 1);
1644         char *tmp;
1645
1646         if (pbx_builtin_serialize_variables(chan, &buf)) {
1647                 int i, j;
1648
1649                 /* convert "\n" to "\nVariable: " */
1650                 strcpy(vars, "Variable: ");
1651                 tmp = buf->str;
1652
1653                 for (i = 0, j = 10; (i < len - 1) && (j < len - 1); i++, j++) {
1654                         vars[j] = tmp[i];
1655
1656                         if (tmp[i + 1] == '\0')
1657                                 break;
1658                         if (tmp[i] == '\n') {
1659                                 vars[j] = '\r';
1660                                 vars[++j] = '\n';
1661
1662                                 ast_copy_string(&(vars[j]), "Variable: ", len - j);
1663                                 j += 9;
1664                         }
1665                 }
1666                 if (j > len - 1)
1667                         j = len - 1;
1668                 vars[j - 2] = '\r';
1669                 vars[j - 1] = '\n';
1670                 vars[j] = '\0';
1671         } else {
1672                 /* there are no channel variables; leave it blank */
1673                 *vars = '\0';
1674         }
1675         return vars;
1676 }
1677
1678 static int ring_entry(struct queue_ent *qe, struct callattempt *tmp, int *busies)
1679 {
1680         int res;
1681         int status;
1682         char tech[256];
1683         char *location;
1684
1685         /* on entry here, we know that tmp->chan == NULL */
1686         if (qe->parent->wrapuptime && (time(NULL) - tmp->lastcall < qe->parent->wrapuptime)) {
1687                 ast_debug(1, "Wrapuptime not yet expired for %s\n", tmp->interface);
1688                 if (qe->chan->cdr)
1689                         ast_cdr_busy(qe->chan->cdr);
1690                 tmp->stillgoing = 0;
1691                 (*busies)++;
1692                 return 0;
1693         }
1694
1695         if (!qe->parent->ringinuse && (tmp->member->status != AST_DEVICE_NOT_INUSE) && (tmp->member->status != AST_DEVICE_UNKNOWN)) {
1696                 ast_debug(1, "%s in use, can't receive call\n", tmp->interface);
1697                 if (qe->chan->cdr)
1698                         ast_cdr_busy(qe->chan->cdr);
1699                 tmp->stillgoing = 0;
1700                 return 0;
1701         }
1702
1703         if (tmp->member->paused) {
1704                 ast_debug(1, "%s paused, can't receive call\n", tmp->interface);
1705                 if (qe->chan->cdr)
1706                         ast_cdr_busy(qe->chan->cdr);
1707                 tmp->stillgoing = 0;
1708                 return 0;
1709         }
1710         if (use_weight && compare_weight(qe->parent,tmp->member)) {
1711                 ast_debug(1, "Priority queue delaying call to %s:%s\n", qe->parent->name, tmp->interface);
1712                 if (qe->chan->cdr)
1713                         ast_cdr_busy(qe->chan->cdr);
1714                 tmp->stillgoing = 0;
1715                 (*busies)++;
1716                 return 0;
1717         }
1718
1719         ast_copy_string(tech, tmp->interface, sizeof(tech));
1720         if ((location = strchr(tech, '/')))
1721                 *location++ = '\0';
1722         else
1723                 location = "";
1724
1725         /* Request the peer */
1726         tmp->chan = ast_request(tech, qe->chan->nativeformats, location, &status);
1727         if (!tmp->chan) {                       /* If we can't, just go on to the next call */
1728                 if (qe->chan->cdr)
1729                         ast_cdr_busy(qe->chan->cdr);
1730                 tmp->stillgoing = 0;
1731                 update_dial_status(qe->parent, tmp->member, status);
1732
1733                 ast_mutex_lock(&qe->parent->lock);
1734                 qe->parent->rrpos++;
1735                 ast_mutex_unlock(&qe->parent->lock);
1736
1737                 (*busies)++;
1738                 return 0;
1739         } else if (status != tmp->oldstatus)
1740                 update_dial_status(qe->parent, tmp->member, status);
1741         
1742         tmp->chan->appl = "AppQueue";
1743         tmp->chan->data = "(Outgoing Line)";
1744         tmp->chan->whentohangup = 0;
1745         if (tmp->chan->cid.cid_num)
1746                 ast_free(tmp->chan->cid.cid_num);
1747         tmp->chan->cid.cid_num = ast_strdup(qe->chan->cid.cid_num);
1748         if (tmp->chan->cid.cid_name)
1749                 ast_free(tmp->chan->cid.cid_name);
1750         tmp->chan->cid.cid_name = ast_strdup(qe->chan->cid.cid_name);
1751         if (tmp->chan->cid.cid_ani)
1752                 ast_free(tmp->chan->cid.cid_ani);
1753         tmp->chan->cid.cid_ani = ast_strdup(qe->chan->cid.cid_ani);
1754
1755         /* Inherit specially named variables from parent channel */
1756         ast_channel_inherit_variables(qe->chan, tmp->chan);
1757
1758         /* Presense of ADSI CPE on outgoing channel follows ours */
1759         tmp->chan->adsicpe = qe->chan->adsicpe;
1760
1761         /* Place the call, but don't wait on the answer */
1762         if ((res = ast_call(tmp->chan, location, 0))) {
1763                 /* Again, keep going even if there's an error */
1764                 ast_debug(1, "ast call on peer returned %d\n", res);
1765                 if (option_verbose > 2)
1766                         ast_verbose(VERBOSE_PREFIX_3 "Couldn't call %s\n", tmp->interface);
1767                 do_hang(tmp);
1768                 (*busies)++;
1769                 return 0;
1770         } else if (qe->parent->eventwhencalled) {
1771                 char vars[2048];
1772
1773                 manager_event(EVENT_FLAG_AGENT, "AgentCalled",
1774                                         "Queue: %s\r\n"
1775                                         "AgentCalled: %s\r\n"
1776                                         "ChannelCalling: %s\r\n"
1777                                         "DestinationChannel: %s\r\n"
1778                                         "CallerIDNum: %s\r\n"
1779                                         "CallerIDName: %s\r\n"
1780                                         "Context: %s\r\n"
1781                                         "Extension: %s\r\n"
1782                                         "Priority: %d\r\n"
1783                                         "%s",
1784                                         qe->parent->name, tmp->interface, qe->chan->name, tmp->chan->name,
1785                                         tmp->chan->cid.cid_num ? tmp->chan->cid.cid_num : "unknown",
1786                                         tmp->chan->cid.cid_name ? tmp->chan->cid.cid_name : "unknown",
1787                                         qe->chan->context, qe->chan->exten, qe->chan->priority,
1788                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
1789                 if (option_verbose > 2)
1790                         ast_verbose(VERBOSE_PREFIX_3 "Called %s\n", tmp->interface);
1791         }
1792
1793         return 1;
1794 }
1795
1796 /*! \brief find the entry with the best metric, or NULL */
1797 static struct callattempt *find_best(struct callattempt *outgoing)
1798 {
1799         struct callattempt *best = NULL, *cur;
1800
1801         for (cur = outgoing; cur; cur = cur->q_next) {
1802                 if (cur->stillgoing &&                                  /* Not already done */
1803                         !cur->chan &&                                   /* Isn't already going */
1804                         (!best || cur->metric < best->metric)) {                /* We haven't found one yet, or it's better */
1805                         best = cur;
1806                 }
1807         }
1808
1809         return best;
1810 }
1811
1812 static int ring_one(struct queue_ent *qe, struct callattempt *outgoing, int *busies)
1813 {
1814         int ret = 0;
1815
1816         while (ret == 0) {
1817                 struct callattempt *best = find_best(outgoing);
1818                 if (!best) {
1819                         ast_debug(1, "Nobody left to try ringing in queue\n");
1820                         break;
1821                 }
1822                 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
1823                         struct callattempt *cur;
1824                         /* Ring everyone who shares this best metric (for ringall) */
1825                         for (cur = outgoing; cur; cur = cur->q_next) {
1826                                 if (cur->stillgoing && !cur->chan && cur->metric <= best->metric) {
1827                                         ast_debug(1, "(Parallel) Trying '%s' with metric %d\n", cur->interface, cur->metric);
1828                                         ring_entry(qe, cur, busies);
1829                                 }
1830                         }
1831                 } else {
1832                         /* Ring just the best channel */
1833                         ast_debug(1, "Trying '%s' with metric %d\n", best->interface, best->metric);
1834                         ring_entry(qe, best, busies);
1835                 }
1836                 if (best->chan) /* break out with result = 1 */
1837                         ret = 1;
1838         }
1839
1840         return ret;
1841 }
1842
1843 static int store_next(struct queue_ent *qe, struct callattempt *outgoing)
1844 {
1845         struct callattempt *best = find_best(outgoing);
1846
1847         if (best) {
1848                 /* Ring just the best channel */
1849                 ast_debug(1, "Next is '%s' with metric %d\n", best->interface, best->metric);
1850                 qe->parent->rrpos = best->metric % 1000;
1851         } else {
1852                 /* Just increment rrpos */
1853                 if (qe->parent->wrapped) {
1854                         /* No more channels, start over */
1855                         qe->parent->rrpos = 0;
1856                 } else {
1857                         /* Prioritize next entry */
1858                         qe->parent->rrpos++;
1859                 }
1860         }
1861         qe->parent->wrapped = 0;
1862
1863         return 0;
1864 }
1865
1866 static int say_periodic_announcement(struct queue_ent *qe, int ringing)
1867 {
1868         int res = 0;
1869         time_t now;
1870
1871         /* Get the current time */
1872         time(&now);
1873
1874         /* Check to see if it is time to announce */
1875         if ((now - qe->last_periodic_announce_time) < qe->parent->periodicannouncefrequency)
1876                 return 0;
1877
1878         /* Stop the music on hold so we can play our own file */
1879         if (ringing)
1880                 ast_indicate(qe->chan,-1);
1881         else
1882                 ast_moh_stop(qe->chan);
1883
1884         if (option_verbose > 2)
1885                 ast_verbose(VERBOSE_PREFIX_3 "Playing periodic announcement\n");
1886
1887         /* Check to make sure we have a sound file. If not, reset to the first sound file */
1888         if (qe->last_periodic_announce_sound >= MAX_PERIODIC_ANNOUNCEMENTS || !strlen(qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound])) {
1889                 qe->last_periodic_announce_sound = 0;
1890         }
1891         
1892         /* play the announcement */
1893         res = play_file(qe->chan, qe->parent->sound_periodicannounce[qe->last_periodic_announce_sound]);
1894
1895         if (res > 0 && !valid_exit(qe, res))
1896                 res = 0;
1897
1898         /* Resume Music on Hold if the caller is going to stay in the queue */
1899         if (!res) {
1900                 if (ringing)
1901                         ast_indicate(qe->chan, AST_CONTROL_RINGING);
1902                 else
1903                         ast_moh_start(qe->chan, qe->moh, NULL);
1904         }
1905
1906         /* update last_periodic_announce_time */
1907         qe->last_periodic_announce_time = now;
1908
1909         /* Update the current periodic announcement to the next announcement */
1910         qe->last_periodic_announce_sound++;
1911         
1912         return res;
1913 }
1914
1915 static void record_abandoned(struct queue_ent *qe)
1916 {
1917         ast_mutex_lock(&qe->parent->lock);
1918         set_queue_variables(qe);
1919         manager_event(EVENT_FLAG_AGENT, "QueueCallerAbandon",
1920                 "Queue: %s\r\n"
1921                 "Uniqueid: %s\r\n"
1922                 "Position: %d\r\n"
1923                 "OriginalPosition: %d\r\n"
1924                 "HoldTime: %d\r\n",
1925                 qe->parent->name, qe->chan->uniqueid, qe->pos, qe->opos, (int)(time(NULL) - qe->start));
1926
1927         qe->parent->callsabandoned++;
1928         ast_mutex_unlock(&qe->parent->lock);
1929 }
1930
1931 /*! \brief RNA == Ring No Answer. Common code that is executed when we try a queue member and they don't answer. */
1932 static void rna(int rnatime, struct queue_ent *qe, char *interface, char *membername)
1933 {
1934         if (option_verbose > 2)
1935                 ast_verbose( VERBOSE_PREFIX_3 "Nobody picked up in %d ms\n", rnatime);
1936         ast_queue_log(qe->parent->name, qe->chan->uniqueid, membername, "RINGNOANSWER", "%d", rnatime);
1937         if (qe->parent->autopause) {
1938                 if (!set_member_paused(qe->parent->name, interface, 1)) {
1939                         if (option_verbose > 2)
1940                                 ast_verbose( VERBOSE_PREFIX_3 "Auto-Pausing Queue Member %s in queue %s since they failed to answer.\n", interface, qe->parent->name);
1941                 } else {
1942                         if (option_verbose > 2)
1943                                 ast_verbose( VERBOSE_PREFIX_3 "Failed to pause Queue Member %s in queue %s!\n", interface, qe->parent->name);
1944                 }
1945         }
1946         return;
1947 }
1948
1949 #define AST_MAX_WATCHERS 256
1950
1951 static struct callattempt *wait_for_answer(struct queue_ent *qe, struct callattempt *outgoing, int *to, char *digit, int prebusies, int caller_disconnect, int forwardsallowed)
1952 {
1953         char *queue = qe->parent->name;
1954         struct callattempt *o;
1955         int status;
1956         int sentringing = 0;
1957         int numbusies = prebusies;
1958         int numnochan = 0;
1959         int stillgoing = 0;
1960         int orig = *to;
1961         struct ast_frame *f;
1962         struct callattempt *peer = NULL;
1963         struct ast_channel *winner;
1964         struct ast_channel *in = qe->chan;
1965         char on[80] = "";
1966         char membername[80] = "";
1967         long starttime = 0;
1968         long endtime = 0;       
1969
1970         starttime = (long) time(NULL);
1971         
1972         while (*to && !peer) {
1973                 int numlines, retry, pos = 1;
1974                 struct ast_channel *watchers[AST_MAX_WATCHERS];
1975                 watchers[0] = in;
1976
1977                 for (retry = 0; retry < 2; retry++) {
1978                         numlines = 0;
1979                         for (o = outgoing; o; o = o->q_next) { /* Keep track of important channels */
1980                                 if (o->stillgoing) {    /* Keep track of important channels */
1981                                         stillgoing = 1;
1982                                         if (o->chan)
1983                                                 watchers[pos++] = o->chan;
1984                                 }
1985                                 numlines++;
1986                         }
1987                         if (pos > 1 /* found */ || !stillgoing /* nobody listening */ ||
1988                                 (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) /* ring would not be delivered */)
1989                                 break;
1990                         /* On "ringall" strategy we only move to the next penalty level
1991                            when *all* ringing phones are done in the current penalty level */
1992                         ring_one(qe, outgoing, &numbusies);
1993                         /* and retry... */
1994                 }
1995                 if (pos == 1 /* not found */) {
1996                         if (numlines == (numbusies + numnochan)) {
1997                                 ast_debug(1, "Everyone is busy at this time\n");
1998                         } else {
1999                                 ast_log(LOG_NOTICE, "No one is answering queue '%s' (%d/%d/%d)\n", queue, numlines, numbusies, numnochan);
2000                         }
2001                         *to = 0;
2002                         return NULL;
2003                 }
2004                 winner = ast_waitfor_n(watchers, pos, to);
2005                 for (o = outgoing; o; o = o->q_next) {
2006                         if (o->stillgoing && (o->chan) &&  (o->chan->_state == AST_STATE_UP)) {
2007                                 if (!peer) {
2008                                         if (option_verbose > 2)
2009                                                 ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
2010                                         peer = o;
2011                                 }
2012                         } else if (o->chan && (o->chan == winner)) {
2013
2014                                 ast_copy_string(on, o->member->interface, sizeof(on));
2015                                 ast_copy_string(membername, o->member->membername, sizeof(membername));
2016
2017                                 if (!ast_strlen_zero(o->chan->call_forward) && !forwardsallowed) {
2018                                         if (option_verbose > 2)
2019                                                 ast_verbose(VERBOSE_PREFIX_3 "Forwarding %s to '%s' prevented.\n", in->name, o->chan->call_forward);
2020                                         numnochan++;
2021                                         do_hang(o);
2022                                         winner = NULL;
2023                                         continue;
2024                                 } else if (!ast_strlen_zero(o->chan->call_forward)) {
2025                                         char tmpchan[256];
2026                                         char *stuff;
2027                                         char *tech;
2028
2029                                         ast_copy_string(tmpchan, o->chan->call_forward, sizeof(tmpchan));
2030                                         if ((stuff = strchr(tmpchan, '/'))) {
2031                                                 *stuff++ = '\0';
2032                                                 tech = tmpchan;
2033                                         } else {
2034                                                 snprintf(tmpchan, sizeof(tmpchan), "%s@%s", o->chan->call_forward, o->chan->context);
2035                                                 stuff = tmpchan;
2036                                                 tech = "Local";
2037                                         }
2038                                         /* Before processing channel, go ahead and check for forwarding */
2039                                         if (option_verbose > 2)
2040                                                 ast_verbose(VERBOSE_PREFIX_3 "Now forwarding %s to '%s/%s' (thanks to %s)\n", in->name, tech, stuff, o->chan->name);
2041                                         /* Setup parameters */
2042                                         o->chan = ast_request(tech, in->nativeformats, stuff, &status);
2043                                         if (status != o->oldstatus)
2044                                                 update_dial_status(qe->parent, o->member, status);                                              
2045                                         if (!o->chan) {
2046                                                 ast_log(LOG_NOTICE, "Unable to create local channel for call forward to '%s/%s'\n", tech, stuff);
2047                                                 o->stillgoing = 0;
2048                                                 numnochan++;
2049                                         } else {
2050                                                 ast_channel_inherit_variables(in, o->chan);
2051                                                 if (o->chan->cid.cid_num)
2052                                                         ast_free(o->chan->cid.cid_num);
2053                                                 o->chan->cid.cid_num = ast_strdup(in->cid.cid_num);
2054
2055                                                 if (o->chan->cid.cid_name)
2056                                                         ast_free(o->chan->cid.cid_name);
2057                                                 o->chan->cid.cid_name = ast_strdup(in->cid.cid_name);
2058
2059                                                 ast_string_field_set(o->chan, accountcode, in->accountcode);
2060                                                 o->chan->cdrflags = in->cdrflags;
2061
2062                                                 if (in->cid.cid_ani) {
2063                                                         if (o->chan->cid.cid_ani)
2064                                                                 ast_free(o->chan->cid.cid_ani);
2065                                                         o->chan->cid.cid_ani = ast_strdup(in->cid.cid_ani);
2066                                                 }
2067                                                 if (o->chan->cid.cid_rdnis)
2068                                                         ast_free(o->chan->cid.cid_rdnis);
2069                                                 o->chan->cid.cid_rdnis = ast_strdup(S_OR(in->macroexten, in->exten));
2070                                                 if (ast_call(o->chan, tmpchan, 0)) {
2071                                                         ast_log(LOG_NOTICE, "Failed to dial on local channel for call forward to '%s'\n", tmpchan);
2072                                                         do_hang(o);
2073                                                         numnochan++;
2074                                                 }
2075                                         }
2076                                         /* Hangup the original channel now, in case we needed it */
2077                                         ast_hangup(winner);
2078                                         continue;
2079                                 }
2080                                 f = ast_read(winner);
2081                                 if (f) {
2082                                         if (f->frametype == AST_FRAME_CONTROL) {
2083                                                 switch (f->subclass) {
2084                                                 case AST_CONTROL_ANSWER:
2085                                                         /* This is our guy if someone answered. */
2086                                                         if (!peer) {
2087                                                                 if (option_verbose > 2)
2088                                                                         ast_verbose( VERBOSE_PREFIX_3 "%s answered %s\n", o->chan->name, in->name);
2089                                                                 peer = o;
2090                                                         }
2091                                                         break;
2092                                                 case AST_CONTROL_BUSY:
2093                                                         if (option_verbose > 2)
2094                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is busy\n", o->chan->name);
2095                                                         if (in->cdr)
2096                                                                 ast_cdr_busy(in->cdr);
2097                                                         do_hang(o);
2098                                                         endtime = (long) time(NULL);
2099                                                         endtime -= starttime;
2100                                                         rna(endtime*1000, qe, on, membername);
2101                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2102                                                                 if (qe->parent->timeoutrestart)
2103                                                                         *to = orig;
2104                                                                 ring_one(qe, outgoing, &numbusies);
2105                                                         }
2106                                                         numbusies++;
2107                                                         break;
2108                                                 case AST_CONTROL_CONGESTION:
2109                                                         if (option_verbose > 2)
2110                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is circuit-busy\n", o->chan->name);
2111                                                         if (in->cdr)
2112                                                                 ast_cdr_busy(in->cdr);
2113                                                         endtime = (long) time(NULL);
2114                                                         endtime -= starttime;
2115                                                         rna(endtime*1000, qe, on, membername);
2116                                                         do_hang(o);
2117                                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2118                                                                 if (qe->parent->timeoutrestart)
2119                                                                         *to = orig;
2120                                                                 ring_one(qe, outgoing, &numbusies);
2121                                                         }
2122                                                         numbusies++;
2123                                                         break;
2124                                                 case AST_CONTROL_RINGING:
2125                                                         if (option_verbose > 2)
2126                                                                 ast_verbose( VERBOSE_PREFIX_3 "%s is ringing\n", o->chan->name);
2127                                                         if (!sentringing) {
2128 #if 0
2129                                                                 ast_indicate(in, AST_CONTROL_RINGING);
2130 #endif                                                          
2131                                                                 sentringing++;
2132                                                         }
2133                                                         break;
2134                                                 case AST_CONTROL_OFFHOOK:
2135                                                         /* Ignore going off hook */
2136                                                         break;
2137                                                 default:
2138                                                         ast_debug(1, "Dunno what to do with control type %d\n", f->subclass);
2139                                                 }
2140                                         }
2141                                         ast_frfree(f);
2142                                 } else {
2143                                         endtime = (long) time(NULL) - starttime;
2144                                         rna(endtime * 1000, qe, on, membername);
2145                                         do_hang(o);
2146                                         if (qe->parent->strategy != QUEUE_STRATEGY_RINGALL) {
2147                                                 if (qe->parent->timeoutrestart)
2148                                                         *to = orig;
2149                                                 ring_one(qe, outgoing, &numbusies);
2150                                         }
2151                                 }
2152                         }
2153                 }
2154                 if (winner == in) {
2155                         f = ast_read(in);
2156                         if (!f || ((f->frametype == AST_FRAME_CONTROL) && (f->subclass == AST_CONTROL_HANGUP))) {
2157                                 /* Got hung up */
2158                                 *to = -1;
2159                                 if (f)
2160                                         ast_frfree(f);
2161                                 return NULL;
2162                         }
2163                         if ((f->frametype == AST_FRAME_DTMF) && caller_disconnect && (f->subclass == '*')) {
2164                                 if (option_verbose > 3)
2165                                         ast_verbose(VERBOSE_PREFIX_3 "User hit %c to disconnect call.\n", f->subclass);
2166                                 *to = 0;
2167                                 ast_frfree(f);
2168                                 return NULL;
2169                         }
2170                         if ((f->frametype == AST_FRAME_DTMF) && valid_exit(qe, f->subclass)) {
2171                                 if (option_verbose > 3)
2172                                         ast_verbose(VERBOSE_PREFIX_3 "User pressed digit: %c\n", f->subclass);
2173                                 *to = 0;
2174                                 *digit = f->subclass;
2175                                 ast_frfree(f);
2176                                 return NULL;
2177                         }
2178                         ast_frfree(f);
2179                 }
2180                 if (!*to)
2181                         rna(orig, qe, on, membername);
2182         }
2183
2184         return peer;
2185 }
2186
2187 static int is_our_turn(struct queue_ent *qe)
2188 {
2189         struct queue_ent *ch;
2190         struct member *cur;
2191         int avl = 0;
2192         int idx = 0;
2193         int res;
2194
2195         if (!qe->parent->autofill) {
2196                 /* Atomically read the parent head -- does not need a lock */
2197                 ch = qe->parent->head;
2198                 /* If we are now at the top of the head, break out */
2199                 if (ch == qe) {
2200                         ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2201                         res = 1;
2202                 } else {
2203                         ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2204                         res = 0;
2205                 }       
2206
2207         } else {
2208                 /* This needs a lock. How many members are available to be served? */
2209                 ast_mutex_lock(&qe->parent->lock);
2210                         
2211                 ch = qe->parent->head;
2212         
2213                 if (qe->parent->strategy == QUEUE_STRATEGY_RINGALL) {
2214                         ast_debug(1, "Even though there are %d available members, the strategy is ringall so only the head call is allowed in\n", avl);
2215                         avl = 1;
2216                 } else {
2217                         for (cur = qe->parent->members; cur; cur = cur->next) {
2218                                 switch (cur->status) {
2219                                 case AST_DEVICE_NOT_INUSE:
2220                                 case AST_DEVICE_UNKNOWN:
2221                                         avl++;
2222                                         break;
2223                                 }
2224                         }
2225                 }
2226
2227                 ast_debug(1, "There are %d available members.\n", avl);
2228         
2229                 while ((idx < avl) && (ch) && (ch != qe)) {
2230                         idx++;
2231                         ch = ch->next;                  
2232                 }
2233         
2234                 /* If the queue entry is within avl [the number of available members] calls from the top ... */
2235                 if (ch && idx < avl) {
2236                         ast_debug(1, "It's our turn (%s).\n", qe->chan->name);
2237                         res = 1;
2238                 } else {
2239                         ast_debug(1, "It's not our turn (%s).\n", qe->chan->name);
2240                         res = 0;
2241                 }
2242                 
2243                 ast_mutex_unlock(&qe->parent->lock);
2244         }
2245
2246         return res;
2247 }
2248
2249 static int wait_our_turn(struct queue_ent *qe, int ringing, enum queue_result *reason)
2250 {
2251         int res = 0;
2252
2253         /* This is the holding pen for callers 2 through maxlen */
2254         for (;;) {
2255                 enum queue_member_status stat;
2256
2257                 if (is_our_turn(qe))
2258                         break;
2259
2260                 /* If we have timed out, break out */
2261                 if (qe->expire && (time(NULL) > qe->expire)) {
2262                         *reason = QUEUE_TIMEOUT;
2263                         break;
2264                 }
2265
2266                 stat = get_member_status(qe->parent, qe->max_penalty);
2267
2268                 /* leave the queue if no agents, if enabled */
2269                 if (qe->parent->leavewhenempty && (stat == QUEUE_NO_MEMBERS)) {
2270                         *reason = QUEUE_LEAVEEMPTY;
2271                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2272                         leave_queue(qe);
2273                         break;
2274                 }
2275
2276                 /* leave the queue if no reachable agents, if enabled */
2277                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_STRICT) && (stat == QUEUE_NO_REACHABLE_MEMBERS || stat == QUEUE_NO_UNPAUSED_REACHABLE_MEMBERS)) {
2278                         *reason = QUEUE_LEAVEUNAVAIL;
2279                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2280                         leave_queue(qe);
2281                         break;
2282                 }
2283                 if ((qe->parent->leavewhenempty == QUEUE_EMPTY_LOOSE) && (stat == QUEUE_NO_REACHABLE_MEMBERS)) {
2284                         *reason = QUEUE_LEAVEUNAVAIL;
2285                         ast_queue_log(qe->parent->name, qe->chan->uniqueid, "NONE", "EXITEMPTY", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2286                         leave_queue(qe);
2287                         break;
2288                 }
2289
2290                 /* Make a position announcement, if enabled */
2291                 if (qe->parent->announcefrequency &&
2292                         (res = say_position(qe,ringing)))
2293                         break;
2294
2295                 /* Make a periodic announcement, if enabled */
2296                 if (qe->parent->periodicannouncefrequency &&
2297                         (res = say_periodic_announcement(qe,ringing)))
2298                         break;
2299
2300                 /* Wait a second before checking again */
2301                 if ((res = ast_waitfordigit(qe->chan, RECHECK * 1000))) {
2302                         if (res > 0 && !valid_exit(qe, res))
2303                                 res = 0;
2304                         else
2305                                 break;
2306                 }
2307         }
2308
2309         return res;
2310 }
2311
2312 static int update_queue(struct call_queue *q, struct member *member, int callcompletedinsl)
2313 {
2314         struct member *cur;
2315
2316         /* Since a reload could have taken place, we have to traverse the list to
2317                 be sure it's still valid */
2318         ast_mutex_lock(&q->lock);
2319         cur = q->members;
2320         while (cur) {
2321                 if (member == cur) {
2322                         time(&cur->lastcall);
2323                         cur->calls++;
2324                         break;
2325                 }
2326                 cur = cur->next;
2327         }
2328         q->callscompleted++;
2329         if (callcompletedinsl)
2330                 q->callscompletedinsl++;
2331         ast_mutex_unlock(&q->lock);
2332         return 0;
2333 }
2334
2335 static int calc_metric(struct call_queue *q, struct member *mem, int pos, struct queue_ent *qe, struct callattempt *tmp)
2336 {
2337         if (qe->max_penalty && (mem->penalty > qe->max_penalty))
2338                 return -1;
2339
2340         switch (q->strategy) {
2341         case QUEUE_STRATEGY_RINGALL:
2342                 /* Everyone equal, except for penalty */
2343                 tmp->metric = mem->penalty * 1000000;
2344                 break;
2345         case QUEUE_STRATEGY_RRMEMORY:
2346                 if (pos < q->rrpos) {
2347                         tmp->metric = 1000 + pos;
2348                 } else {
2349                         if (pos > q->rrpos)
2350                                 /* Indicate there is another priority */
2351                                 q->wrapped = 1;
2352                         tmp->metric = pos;
2353                 }
2354                 tmp->metric += mem->penalty * 1000000;
2355                 break;
2356         case QUEUE_STRATEGY_RANDOM:
2357                 tmp->metric = ast_random() % 1000;
2358                 tmp->metric += mem->penalty * 1000000;
2359                 break;
2360         case QUEUE_STRATEGY_FEWESTCALLS:
2361                 tmp->metric = mem->calls;
2362                 tmp->metric += mem->penalty * 1000000;
2363                 break;
2364         case QUEUE_STRATEGY_LEASTRECENT:
2365                 if (!mem->lastcall)
2366                         tmp->metric = 0;
2367                 else
2368                         tmp->metric = 1000000 - (time(NULL) - mem->lastcall);
2369                 tmp->metric += mem->penalty * 1000000;
2370                 break;
2371         default:
2372                 ast_log(LOG_WARNING, "Can't calculate metric for unknown strategy %d\n", q->strategy);
2373                 break;
2374         }
2375         return 0;
2376 }
2377
2378 enum agent_complete_reason {
2379         CALLER,
2380         AGENT,
2381         TRANSFER
2382 };
2383
2384 static void send_agent_complete(const struct queue_ent *qe, const char *queuename,
2385         const struct ast_channel *peer, const struct member *member, time_t callstart,
2386         char *vars, size_t vars_len, enum agent_complete_reason rsn)
2387 {
2388         const char *reason;
2389
2390         if (!qe->parent->eventwhencalled)
2391                 return;
2392
2393         switch (rsn) {
2394         case CALLER:
2395                 reason = "caller";
2396                 break;
2397         case AGENT:
2398                 reason = "agent";
2399                 break;
2400         case TRANSFER:
2401                 reason = "transfer";
2402                 break;
2403         }
2404
2405         manager_event(EVENT_FLAG_AGENT, "AgentComplete",
2406                 "Queue: %s\r\n"
2407                 "Uniqueid: %s\r\n"
2408                 "Channel: %s\r\n"
2409                 "Member: %s\r\n"
2410                 "MemberName: %s\r\n"
2411                 "HoldTime: %ld\r\n"
2412                 "TalkTime: %ld\r\n"
2413                 "Reason: %s\r\n"
2414                 "%s",
2415                 queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2416                 (long)(callstart - qe->start), (long)(time(NULL) - callstart), reason,
2417                 qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, vars_len) : "");
2418 }
2419
2420 static int try_calling(struct queue_ent *qe, const char *options, char *announceoverride, const char *url, int *go_on, const char *agi, const char *macro, const char *gosub, int ringing)
2421 {
2422         struct member *cur;
2423         struct callattempt *outgoing = NULL; /* the list of calls we are building */
2424         int to;
2425         char oldexten[AST_MAX_EXTENSION]="";
2426         char oldcontext[AST_MAX_CONTEXT]="";
2427         char queuename[256]="";
2428         char interfacevar[256]="";
2429         struct ast_channel *peer;
2430         struct ast_channel *which;
2431         struct callattempt *lpeer;
2432         struct member *member;
2433         struct ast_app *app;
2434         int res = 0, bridge = 0;
2435         int numbusies = 0;
2436         int x=0;
2437         char *announce = NULL;
2438         char digit = 0;
2439         time_t callstart;
2440         time_t now = time(NULL);
2441         struct ast_bridge_config bridge_config;
2442         char nondataquality = 1;
2443         char *agiexec = NULL;
2444         char *macroexec = NULL;
2445         char *gosubexec = NULL;
2446         int ret = 0;
2447         const char *monitorfilename;
2448         const char *monitor_exec;
2449         const char *monitor_options;
2450         char tmpid[256], tmpid2[256];
2451         char meid[1024], meid2[1024];
2452         char mixmonargs[1512];
2453         struct ast_app *mixmonapp = NULL;
2454         char *p;
2455         char vars[2048];
2456         int forwardsallowed = 1;
2457         int callcompletedinsl;
2458
2459         memset(&bridge_config, 0, sizeof(bridge_config));
2460         time(&now);
2461                 
2462         for (; options && *options; options++)
2463                 switch (*options) {
2464                 case 't':
2465                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_REDIRECT);
2466                         break;
2467                 case 'T':
2468                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_REDIRECT);
2469                         break;
2470                 case 'w':
2471                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_AUTOMON);
2472                         break;
2473                 case 'W':
2474                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_AUTOMON);
2475                         break;
2476                 case 'd':
2477                         nondataquality = 0;
2478                         break;
2479                 case 'h':
2480                         ast_set_flag(&(bridge_config.features_callee), AST_FEATURE_DISCONNECT);
2481                         break;
2482                 case 'H':
2483                         ast_set_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT);
2484                         break;
2485                 case 'n':
2486                         *go_on = 1;
2487                         break;
2488                 case 'i':
2489                         forwardsallowed = 0;
2490                         break;
2491                 }
2492
2493         /* Hold the lock while we setup the outgoing calls */
2494         if (use_weight)
2495                 AST_LIST_LOCK(&queues);
2496         ast_mutex_lock(&qe->parent->lock);
2497         ast_debug(1, "%s is trying to call a queue member.\n",
2498                                                         qe->chan->name);
2499         ast_copy_string(queuename, qe->parent->name, sizeof(queuename));
2500         cur = qe->parent->members;
2501         if (!ast_strlen_zero(qe->announce))
2502                 announce = qe->announce;
2503         if (!ast_strlen_zero(announceoverride))
2504                 announce = announceoverride;
2505
2506         for (; cur; cur = cur->next) {
2507                 struct callattempt *tmp = ast_calloc(1, sizeof(*tmp));
2508
2509                 if (!tmp) {
2510                         ast_mutex_unlock(&qe->parent->lock);
2511                         if (use_weight)
2512                                 AST_LIST_UNLOCK(&queues);
2513                         goto out;
2514                 }
2515                 tmp->stillgoing = -1;
2516                 tmp->member = cur;              /* Never directly dereference!  Could change on reload */
2517                 tmp->oldstatus = cur->status;
2518                 tmp->lastcall = cur->lastcall;
2519                 ast_copy_string(tmp->interface, cur->interface, sizeof(tmp->interface));
2520                 /* Special case: If we ring everyone, go ahead and ring them, otherwise
2521                    just calculate their metric for the appropriate strategy */
2522                 if (!calc_metric(qe->parent, cur, x++, qe, tmp)) {
2523                         /* Put them in the list of outgoing thingies...  We're ready now.
2524                            XXX If we're forcibly removed, these outgoing calls won't get
2525                            hung up XXX */
2526                         tmp->q_next = outgoing;
2527                         outgoing = tmp;         
2528                         /* If this line is up, don't try anybody else */
2529                         if (outgoing->chan && (outgoing->chan->_state == AST_STATE_UP))
2530                                 break;
2531                 } else {
2532                         ast_free(tmp);
2533                 }
2534         }
2535         if (qe->expire && (!qe->parent->timeout || (qe->expire - now) <= qe->parent->timeout))
2536                 to = (qe->expire - now) * 1000;
2537         else
2538                 to = (qe->parent->timeout) ? qe->parent->timeout * 1000 : -1;
2539         ring_one(qe, outgoing, &numbusies);
2540         ast_mutex_unlock(&qe->parent->lock);
2541         if (use_weight)
2542                 AST_LIST_UNLOCK(&queues);
2543         lpeer = wait_for_answer(qe, outgoing, &to, &digit, numbusies, ast_test_flag(&(bridge_config.features_caller), AST_FEATURE_DISCONNECT), forwardsallowed);
2544         ast_mutex_lock(&qe->parent->lock);
2545         if (qe->parent->strategy == QUEUE_STRATEGY_RRMEMORY) {
2546                 store_next(qe, outgoing);
2547         }
2548         ast_mutex_unlock(&qe->parent->lock);
2549         peer = lpeer ? lpeer->chan : NULL;
2550         if (!peer) {
2551                 if (to) {
2552                         /* Must gotten hung up */
2553                         res = -1;
2554                 } else {
2555                         res = digit;
2556                         if (res > 0 && !valid_exit(qe, res))
2557                                 res = 0;
2558                 }
2559                 ast_debug(1, "%s: Nobody answered.\n", qe->chan->name);
2560         } else { /* peer is valid */
2561                 /* Ah ha!  Someone answered within the desired timeframe.  Of course after this
2562                    we will always return with -1 so that it is hung up properly after the
2563                    conversation.  */
2564                 qe->handled++;
2565                 if (!strcmp(qe->chan->tech->type, "Zap"))
2566                         ast_channel_setoption(qe->chan, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2567                 if (!strcmp(peer->tech->type, "Zap"))
2568                         ast_channel_setoption(peer, AST_OPTION_TONE_VERIFY, &nondataquality, sizeof(nondataquality), 0);
2569                 /* Update parameters for the queue */
2570                 time(&now);
2571                 recalc_holdtime(qe, (now - qe->start));
2572                 ast_mutex_lock(&qe->parent->lock);
2573                 callcompletedinsl = ((now - qe->start) <= qe->parent->servicelevel);
2574                 ast_mutex_unlock(&qe->parent->lock);
2575                 member = lpeer->member;
2576                 hangupcalls(outgoing, peer);
2577                 outgoing = NULL;
2578                 if (announce || qe->parent->reportholdtime || qe->parent->memberdelay) {
2579                         int res2;
2580
2581                         res2 = ast_autoservice_start(qe->chan);
2582                         if (!res2) {
2583                                 if (qe->parent->memberdelay) {
2584                                         ast_log(LOG_NOTICE, "Delaying member connect for %d seconds\n", qe->parent->memberdelay);
2585                                         res2 |= ast_safe_sleep(peer, qe->parent->memberdelay * 1000);
2586                                 }
2587                                 if (!res2 && announce) {
2588                                         if (play_file(peer, announce))
2589                                                 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", announce);
2590                                 }
2591                                 if (!res2 && qe->parent->reportholdtime) {
2592                                         if (!play_file(peer, qe->parent->sound_reporthold)) {
2593                                                 int holdtime;
2594
2595                                                 time(&now);
2596                                                 holdtime = abs((now - qe->start) / 60);
2597                                                 if (holdtime < 2) {
2598                                                         play_file(peer, qe->parent->sound_lessthan);
2599                                                         ast_say_number(peer, 2, AST_DIGIT_ANY, peer->language, NULL);
2600                                                 } else
2601                                                         ast_say_number(peer, holdtime, AST_DIGIT_ANY, peer->language, NULL);
2602                                                 play_file(peer, qe->parent->sound_minutes);
2603                                         }
2604                                 }
2605                         }
2606                         res2 |= ast_autoservice_stop(qe->chan);
2607                         if (peer->_softhangup) {
2608                                 /* Agent must have hung up */
2609                                 ast_log(LOG_WARNING, "Agent on %s hungup on the customer.\n", peer->name);
2610                                 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "AGENTDUMP", "%s", "");
2611                                 record_abandoned(qe);
2612                                 if (qe->parent->eventwhencalled)
2613                                         manager_event(EVENT_FLAG_AGENT, "AgentDump",
2614                                                         "Queue: %s\r\n"
2615                                                         "Uniqueid: %s\r\n"
2616                                                         "Channel: %s\r\n"
2617                                                         "Member: %s\r\n"
2618                                                         "MemberName: %s\r\n"
2619                                                         "%s",
2620                                                         queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2621                                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2622                                 ast_hangup(peer);
2623                                 goto out;
2624                         } else if (res2) {
2625                                 /* Caller must have hung up just before being connected*/
2626                                 ast_log(LOG_NOTICE, "Caller was about to talk to agent on %s but the caller hungup.\n", peer->name);
2627                                 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "ABANDON", "%d|%d|%ld", qe->pos, qe->opos, (long) time(NULL) - qe->start);
2628                                 record_abandoned(qe);
2629                                 ast_hangup(peer);
2630                                 return -1;
2631                         }
2632                 }
2633                 /* Stop music on hold */
2634                 if (ringing)
2635                         ast_indicate(qe->chan,-1);
2636                 else
2637                         ast_moh_stop(qe->chan);
2638                 /* If appropriate, log that we have a destination channel */
2639                 if (qe->chan->cdr)
2640                         ast_cdr_setdestchan(qe->chan->cdr, peer->name);
2641                 /* Make sure channels are compatible */
2642                 res = ast_channel_make_compatible(qe->chan, peer);
2643                 if (res < 0) {
2644                         ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "SYSCOMPAT", "%s", "");
2645                         ast_log(LOG_WARNING, "Had to drop call because I couldn't make %s compatible with %s\n", qe->chan->name, peer->name);
2646                         record_abandoned(qe);
2647                         ast_hangup(peer);
2648                         return -1;
2649                 }
2650
2651                 /* Play announcement to the caller telling it's his turn if defined */
2652                 if (!ast_strlen_zero(qe->parent->sound_callerannounce)) {
2653                         if (play_file(qe->chan, qe->parent->sound_callerannounce))
2654                                 ast_log(LOG_WARNING, "Announcement file '%s' is unavailable, continuing anyway...\n", qe->parent->sound_callerannounce);
2655                 }
2656
2657                 /* Begin Monitoring */
2658                 if (qe->parent->monfmt && *qe->parent->monfmt) {
2659                         if (!qe->parent->montype) {
2660                                 ast_debug(1, "Starting Monitor as requested.\n");
2661                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2662                                 if (pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC") || pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC_ARGS"))
2663                                         which = qe->chan;
2664                                 else
2665                                         which = peer;
2666                                 if (monitorfilename)
2667                                         ast_monitor_start(which, qe->parent->monfmt, monitorfilename, 1, X_REC_IN | X_REC_OUT);
2668                                 else if (qe->chan->cdr)
2669                                         ast_monitor_start(which, qe->parent->monfmt, qe->chan->cdr->uniqueid, 1, X_REC_IN | X_REC_OUT);
2670                                 else {
2671                                         /* Last ditch effort -- no CDR, make up something */
2672                                         snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2673                                         ast_monitor_start(which, qe->parent->monfmt, tmpid, 1, X_REC_IN | X_REC_OUT);
2674                                 }
2675                                 if (qe->parent->monjoin)
2676                                         ast_monitor_setjoinfiles(which, 1);
2677                         } else {
2678                                 ast_debug(1, "Starting MixMonitor as requested.\n");
2679                                 monitorfilename = pbx_builtin_getvar_helper(qe->chan, "MONITOR_FILENAME");
2680                                 if (!monitorfilename) {
2681                                         if (qe->chan->cdr)
2682                                                 ast_copy_string(tmpid, qe->chan->cdr->uniqueid, sizeof(tmpid)-1);
2683                                         else
2684                                                 snprintf(tmpid, sizeof(tmpid), "chan-%lx", ast_random());
2685                                 } else {
2686                                         ast_copy_string(tmpid2, monitorfilename, sizeof(tmpid2)-1);
2687                                         for (p = tmpid2; *p ; p++) {
2688                                                 if (*p == '^' && *(p+1) == '{') {
2689                                                         *p = '$';
2690                                                 }
2691                                         }
2692
2693                                         memset(tmpid, 0, sizeof(tmpid));
2694                                         pbx_substitute_variables_helper(qe->chan, tmpid2, tmpid, sizeof(tmpid) - 1);
2695                                 }
2696
2697                                 monitor_exec = pbx_builtin_getvar_helper(qe->chan, "MONITOR_EXEC");
2698                                 monitor_options = pbx_builtin_getvar_helper(qe->chan, "MONITOR_OPTIONS");
2699
2700                                 if (monitor_exec) {
2701                                         ast_copy_string(meid2, monitor_exec, sizeof(meid2)-1);
2702                                         for (p = meid2; *p ; p++) {
2703                                                 if (*p == '^' && *(p+1) == '{') {
2704                                                         *p = '$';
2705                                                 }
2706                                         }
2707
2708                                         memset(meid, 0, sizeof(meid));
2709                                         pbx_substitute_variables_helper(qe->chan, meid2, meid, sizeof(meid) - 1);
2710                                 }
2711         
2712                                 snprintf(tmpid2, sizeof(tmpid2)-1, "%s.%s", tmpid, qe->parent->monfmt);
2713
2714                                 mixmonapp = pbx_findapp("MixMonitor");
2715
2716                                 if (strchr(tmpid2, '|')) {
2717                                         ast_log(LOG_WARNING, "monitor-format (in queues.conf) and MONITOR_FILENAME cannot contain a '|'! Not recording.\n");
2718                                         mixmonapp = NULL;
2719                                 }
2720
2721                                 if (!monitor_options)
2722                                         monitor_options = "";
2723                                 
2724                                 if (strchr(monitor_options, '|')) {
2725                                         ast_log(LOG_WARNING, "MONITOR_OPTIONS cannot contain a '|'! Not recording.\n");
2726                                         mixmonapp = NULL;
2727                                 }
2728
2729                                 if (mixmonapp) {
2730                                         if (!ast_strlen_zero(monitor_exec))
2731                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s|%s", tmpid2, monitor_options, monitor_exec);
2732                                         else
2733                                                 snprintf(mixmonargs, sizeof(mixmonargs)-1, "%s|b%s", tmpid2, monitor_options);
2734                                                 
2735                                         ast_debug(1, "Arguments being passed to MixMonitor: %s\n", mixmonargs);
2736
2737                                         ret = pbx_exec(qe->chan, mixmonapp, mixmonargs);
2738
2739                                 } else
2740                                         ast_log(LOG_WARNING, "Asked to run MixMonitor on this call, but cannot find the MixMonitor app!\n");
2741
2742                         }
2743                 }
2744                 /* Drop out of the queue at this point, to prepare for next caller */
2745                 leave_queue(qe);                        
2746                 if (!ast_strlen_zero(url) && ast_channel_supports_html(peer)) {
2747                         ast_debug(1, "app_queue: sendurl=%s.\n", url);
2748                         ast_channel_sendurl(peer, url);
2749                 }
2750                 
2751                 ast_mutex_lock(&qe->parent->lock);
2752                 /* if setinterfacevar is defined, make member variables available to the channel */
2753                 /* use  pbx_builtin_setvar to set a load of variables with one call */
2754                 if (qe->parent->setinterfacevar) {
2755                         snprintf(interfacevar,sizeof(interfacevar), "MEMBERINTERFACE=%s|MEMBERNAME=%s|MEMBERCALLS=%d|MEMBERLASTCALL=%ld|MEMBERPENALTY=%d|MEMBERDYNAMIC=%d",
2756                                 member->interface, member->membername, member->calls, (long)member->lastcall, member->penalty, member->dynamic);
2757                         pbx_builtin_setvar(qe->chan, interfacevar);
2758                 }
2759                 
2760                 /* if setqueueentryvar is defined, make queue entry (i.e. the caller) variables available to the channel */
2761                 /* use  pbx_builtin_setvar to set a load of variables with one call */
2762                 if (qe->parent->setqueueentryvar) {
2763                         snprintf(interfacevar,sizeof(interfacevar), "QEHOLDTIME=%ld|QEORIGINALPOS=%d",
2764                                 (long) time(NULL) - qe->start, qe->opos);
2765                         pbx_builtin_setvar(qe->chan, interfacevar);
2766                 }
2767         
2768                 /* try to set queue variables if configured to do so*/
2769                 set_queue_variables(qe);
2770                 ast_mutex_unlock(&qe->parent->lock);
2771                 
2772                 /* run a macro for this connection if defined. The macro simply returns, no action is taken on the result */
2773                 /* use macro from dialplan if passed as a option, otherwise use the default queue macro */
2774                 if (!ast_strlen_zero(macro)) {
2775                                 macroexec = ast_strdupa(macro);
2776                 } else {
2777                         if (qe->parent->membermacro)
2778                                 macroexec = ast_strdupa(qe->parent->membermacro);
2779                 }
2780
2781                 if (!ast_strlen_zero(macroexec)) {
2782                         ast_debug(1, "app_queue: macro=%s.\n", macroexec);
2783                         
2784                         res = ast_autoservice_start(qe->chan);
2785                         if (res) {
2786                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2787                                 res = -1;
2788                         }
2789                         
2790                         app = pbx_findapp("Macro");
2791                         
2792                         if (app) {
2793                                 res = pbx_exec(qe->chan, app, macroexec);
2794                                 ast_debug(1, "Macro exited with status %d\n", res);
2795                                 res = 0;
2796                         } else {
2797                                 ast_log(LOG_ERROR, "Could not find application Macro\n");
2798                                 res = -1;
2799                         }
2800                 
2801                         if (ast_autoservice_stop(qe->chan) < 0) {
2802                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
2803                                 res = -1;
2804                         }
2805                 }
2806
2807                 /* run a gosub for this connection if defined. The gosub simply returns, no action is taken on the result */
2808                 /* use gosub from dialplan if passed as a option, otherwise use the default queue gosub */
2809                 if (!ast_strlen_zero(gosub)) {
2810                                 gosubexec = ast_strdupa(gosub);
2811                 } else {
2812                         if (qe->parent->membergosub)
2813                                 gosubexec = ast_strdupa(qe->parent->membergosub);
2814                 }
2815
2816                 if (!ast_strlen_zero(gosubexec)) {
2817                         if (option_debug)
2818                                 ast_log(LOG_DEBUG, "app_queue: gosub=%s.\n", gosubexec);
2819                         
2820                         res = ast_autoservice_start(qe->chan);
2821                         if (res) {
2822                                 ast_log(LOG_ERROR, "Unable to start autoservice on calling channel\n");
2823                                 res = -1;
2824                         }
2825                         
2826                         app = pbx_findapp("Gosub");
2827                         
2828                         if (app) {
2829                                 char *gosub_args, *gosub_argstart;
2830
2831                                 /* Set where we came from */
2832                                 ast_copy_string(qe->chan->context, "app_dial_gosub_virtual_context", sizeof(qe->chan->context));
2833                                 ast_copy_string(qe->chan->exten, "s", sizeof(qe->chan->exten));
2834                                 qe->chan->priority = 0;
2835
2836                                 gosub_argstart = strchr(gosubexec, '|');
2837                                 if (gosub_argstart) {
2838                                         *gosub_argstart = 0;
2839                                         asprintf(&gosub_args, "%s|s|1(%s)", gosubexec, gosub_argstart + 1);
2840                                         *gosub_argstart = '|';
2841                                 } else {
2842                                         asprintf(&gosub_args, "%s|s|1", gosubexec);
2843                                 }
2844                                 if (gosub_args) {
2845                                         res = pbx_exec(qe->chan, app, gosub_args);
2846                                         ast_pbx_run(qe->chan);
2847                                         free(gosub_args);
2848                                         if (option_debug)
2849                                                 ast_log(LOG_DEBUG, "Gosub exited with status %d\n", res);
2850                                 } else
2851                                         ast_log(LOG_ERROR, "Could not Allocate string for Gosub arguments -- Gosub Call Aborted!\n");
2852                                 
2853                                 res = 0;
2854                         } else {
2855                                 ast_log(LOG_ERROR, "Could not find application Gosub\n");
2856                                 res = -1;
2857                         }
2858                 
2859                         if (ast_autoservice_stop(qe->chan) < 0) {
2860                                 ast_log(LOG_ERROR, "Could not stop autoservice on calling channel\n");
2861                                 res = -1;
2862                         }
2863                 }
2864
2865                 if (!ast_strlen_zero(agi)) {
2866                         ast_debug(1, "app_queue: agi=%s.\n", agi);
2867                         app = pbx_findapp("agi");
2868                         if (app) {
2869                                 agiexec = ast_strdupa(agi);
2870                                 ret = pbx_exec(qe->chan, app, agiexec);
2871                         } else
2872                                 ast_log(LOG_WARNING, "Asked to execute an AGI on this channel, but could not find application (agi)!\n");
2873                 }
2874                 ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "CONNECT", "%ld|%s", (long) time(NULL) - qe->start, peer->uniqueid);
2875                 if (qe->parent->eventwhencalled)
2876                         manager_event(EVENT_FLAG_AGENT, "AgentConnect",
2877                                         "Queue: %s\r\n"
2878                                         "Uniqueid: %s\r\n"
2879                                         "Channel: %s\r\n"
2880                                         "Member: %s\r\n"
2881                                         "MemberName: %s\r\n"
2882                                         "Holdtime: %ld\r\n"
2883                                         "BridgedChannel: %s\r\n"
2884                                         "%s",
2885                                         queuename, qe->chan->uniqueid, peer->name, member->interface, member->membername,
2886                                         (long) time(NULL) - qe->start, peer->uniqueid,
2887                                         qe->parent->eventwhencalled == QUEUE_EVENT_VARIABLES ? vars2manager(qe->chan, vars, sizeof(vars)) : "");
2888                 ast_copy_string(oldcontext, qe->chan->context, sizeof(oldcontext));
2889                 ast_copy_string(oldexten, qe->chan->exten, sizeof(oldexten));
2890                 time(&callstart);
2891
2892                 bridge = ast_bridge_call(qe->chan,peer, &bridge_config);
2893
2894                 if (strcasecmp(oldcontext, qe->chan->context) || strcasecmp(oldexten, qe->chan->exten)) {
2895                         ast_queue_log(queuename, qe->chan->uniqueid, member->membername, "TRANSFER", "%s|%s|%ld|%ld",
2896                                 qe->chan->exten, qe->chan->context, (long) (callstart - qe->start),
2897                                 (long) (time(NULL) - callstart));
2898                         send_agent_complete(qe, queuename, peer, member, callstart, vars, sizeof(vars), TRANSFER);
2899