Merge "res_musiconhold: Start playlist after initial announcement"
[asterisk/asterisk.git] / apps / app_agent_pool.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2013 Digium, Inc.
5  *
6  * Richard Mudgett <rmudgett@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 /*!
20  * \file
21  * \brief Call center agent pool.
22  *
23  * \author Richard Mudgett <rmudgett@digium.com>
24  *
25  * See Also:
26  * \arg \ref AstCREDITS
27  * \arg \ref Config_agent
28  */
29 /*** MODULEINFO
30         <support_level>core</support_level>
31  ***/
32
33
34 #include "asterisk.h"
35
36 #include "asterisk/cli.h"
37 #include "asterisk/app.h"
38 #include "asterisk/pbx.h"
39 #include "asterisk/module.h"
40 #include "asterisk/channel.h"
41 #include "asterisk/bridge.h"
42 #include "asterisk/bridge_internal.h"
43 #include "asterisk/bridge_basic.h"
44 #include "asterisk/bridge_after.h"
45 #include "asterisk/config_options.h"
46 #include "asterisk/features_config.h"
47 #include "asterisk/astobj2.h"
48 #include "asterisk/stringfields.h"
49 #include "asterisk/stasis_channels.h"
50 #include "asterisk/causes.h"
51
52 /*** DOCUMENTATION
53         <application name="AgentLogin" language="en_US">
54                 <synopsis>
55                         Login an agent.
56                 </synopsis>
57                 <syntax argsep=",">
58                         <parameter name="AgentId" required="true" />
59                         <parameter name="options">
60                                 <optionlist>
61                                         <option name="s">
62                                                 <para>silent login - do not announce the login ok segment after
63                                                 agent logged on.</para>
64                                         </option>
65                                 </optionlist>
66                         </parameter>
67                 </syntax>
68                 <description>
69                         <para>Login an agent to the system.  Any agent authentication is assumed to
70                         already be done by dialplan.  While logged in, the agent can receive calls
71                         and will hear the sound file specified by the config option custom_beep
72                         when a new call comes in for the agent.  Login failures will continue in
73                         the dialplan with <variable>AGENT_STATUS</variable> set.</para>
74                         <para>Before logging in, you can setup on the real agent channel the
75                         CHANNEL(dtmf_features) an agent will have when talking to a caller
76                         and you can setup on the channel running this application the
77                         CONNECTEDLINE() information the agent will see while waiting for a
78                         caller.</para>
79                         <para><variable>AGENT_STATUS</variable> enumeration values:</para>
80                         <enumlist>
81                                 <enum name = "INVALID"><para>The specified agent is invalid.</para></enum>
82                                 <enum name = "ALREADY_LOGGED_IN"><para>The agent is already logged in.</para></enum>
83                         </enumlist>
84                         <note><para>The Agent:<replaceable>AgentId</replaceable> device state is
85                         available to monitor the status of the agent.</para></note>
86                 </description>
87                 <see-also>
88                         <ref type="application">Authenticate</ref>
89                         <ref type="application">Queue</ref>
90                         <ref type="application">AddQueueMember</ref>
91                         <ref type="application">RemoveQueueMember</ref>
92                         <ref type="application">PauseQueueMember</ref>
93                         <ref type="application">UnpauseQueueMember</ref>
94                         <ref type="function">AGENT</ref>
95                         <ref type="function">CHANNEL(dtmf_features)</ref>
96                         <ref type="function">CONNECTEDLINE()</ref>
97                         <ref type="filename">agents.conf</ref>
98                         <ref type="filename">queues.conf</ref>
99                 </see-also>
100         </application>
101         <application name="AgentRequest" language="en_US">
102                 <synopsis>
103                         Request an agent to connect with the channel.
104                 </synopsis>
105                 <syntax argsep=",">
106                         <parameter name="AgentId" required="true" />
107                 </syntax>
108                 <description>
109                         <para>Request an agent to connect with the channel.  Failure to find,
110                         alert the agent, or acknowledge the call will continue in the dialplan
111                         with <variable>AGENT_STATUS</variable> set.</para>
112                         <para><variable>AGENT_STATUS</variable> enumeration values:</para>
113                         <enumlist>
114                                 <enum name = "INVALID"><para>The specified agent is invalid.</para></enum>
115                                 <enum name = "NOT_LOGGED_IN"><para>The agent is not available.</para></enum>
116                                 <enum name = "BUSY"><para>The agent is on another call.</para></enum>
117                                 <enum name = "NOT_CONNECTED"><para>The agent did not connect with the
118                                 call.  The agent most likely did not acknowledge the call.</para></enum>
119                                 <enum name = "ERROR"><para>Alerting the agent failed.</para></enum>
120                         </enumlist>
121                 </description>
122                 <see-also>
123                         <ref type="application">AgentLogin</ref>
124                 </see-also>
125         </application>
126         <function name="AGENT" language="en_US">
127                 <synopsis>
128                         Gets information about an Agent
129                 </synopsis>
130                 <syntax argsep=":">
131                         <parameter name="AgentId" required="true" />
132                         <parameter name="item">
133                                 <para>The valid items to retrieve are:</para>
134                                 <enumlist>
135                                         <enum name="status">
136                                                 <para>(default) The status of the agent (LOGGEDIN | LOGGEDOUT)</para>
137                                         </enum>
138                                         <enum name="password">
139                                                 <para>Deprecated.  The dialplan handles any agent authentication.</para>
140                                         </enum>
141                                         <enum name="name">
142                                                 <para>The name of the agent</para>
143                                         </enum>
144                                         <enum name="mohclass">
145                                                 <para>MusicOnHold class</para>
146                                         </enum>
147                                         <enum name="channel">
148                                                 <para>The name of the active channel for the Agent (AgentLogin)</para>
149                                         </enum>
150                                         <enum name="fullchannel">
151                                                 <para>The untruncated name of the active channel for the Agent (AgentLogin)</para>
152                                         </enum>
153                                 </enumlist>
154                         </parameter>
155                 </syntax>
156                 <description></description>
157         </function>
158         <manager name="Agents" language="en_US">
159                 <synopsis>
160                         Lists agents and their status.
161                 </synopsis>
162                 <syntax>
163                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
164                 </syntax>
165                 <description>
166                         <para>Will list info about all defined agents.</para>
167                 </description>
168                 <see-also>
169                         <ref type="managerEvent">Agents</ref>
170                         <ref type="managerEvent">AgentsComplete</ref>
171                 </see-also>
172         </manager>
173         <managerEvent language="en_US" name="Agents">
174                 <managerEventInstance class="EVENT_FLAG_AGENT">
175                         <synopsis>
176                                 Response event in a series to the Agents AMI action containing
177                                 information about a defined agent.
178                         </synopsis>
179                         <syntax>
180                                 <parameter name="Agent">
181                                         <para>Agent ID of the agent.</para>
182                                 </parameter>
183                                 <parameter name="Name">
184                                         <para>User friendly name of the agent.</para>
185                                 </parameter>
186                                 <parameter name="Status">
187                                         <para>Current status of the agent.</para>
188                                         <para>The valid values are:</para>
189                                         <enumlist>
190                                                 <enum name="AGENT_LOGGEDOFF" />
191                                                 <enum name="AGENT_IDLE" />
192                                                 <enum name="AGENT_ONCALL" />
193                                         </enumlist>
194                                 </parameter>
195                                 <parameter name="TalkingToChan">
196                                         <para><variable>BRIDGEPEER</variable> value on agent channel.</para>
197                                         <para>Present if Status value is <literal>AGENT_ONCALL</literal>.</para>
198                                 </parameter>
199                                 <parameter name="CallStarted">
200                                         <para>Epoche time when the agent started talking with the caller.</para>
201                                         <para>Present if Status value is <literal>AGENT_ONCALL</literal>.</para>
202                                 </parameter>
203                                 <parameter name="LoggedInTime">
204                                         <para>Epoche time when the agent logged in.</para>
205                                         <para>Present if Status value is <literal>AGENT_IDLE</literal> or <literal>AGENT_ONCALL</literal>.</para>
206                                 </parameter>
207                                 <channel_snapshot/>
208                                 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
209                         </syntax>
210                         <description>
211                                 <para>The channel snapshot is present if the Status value is <literal>AGENT_IDLE</literal> or <literal>AGENT_ONCALL</literal>.</para>
212                         </description>
213                         <see-also>
214                                 <ref type="manager">Agents</ref>
215                         </see-also>
216                 </managerEventInstance>
217         </managerEvent>
218         <managerEvent language="en_US" name="AgentsComplete">
219                 <managerEventInstance class="EVENT_FLAG_AGENT">
220                         <synopsis>
221                                 Final response event in a series of events to the Agents AMI action.
222                         </synopsis>
223                         <syntax>
224                                 <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
225                         </syntax>
226                         <see-also>
227                                 <ref type="manager">Agents</ref>
228                         </see-also>
229                 </managerEventInstance>
230         </managerEvent>
231         <manager name="AgentLogoff" language="en_US">
232                 <synopsis>
233                         Sets an agent as no longer logged in.
234                 </synopsis>
235                 <syntax>
236                         <xi:include xpointer="xpointer(/docs/manager[@name='Login']/syntax/parameter[@name='ActionID'])" />
237                         <parameter name="Agent" required="true">
238                                 <para>Agent ID of the agent to log off.</para>
239                         </parameter>
240                         <parameter name="Soft">
241                                 <para>Set to <literal>true</literal> to not hangup existing calls.</para>
242                         </parameter>
243                 </syntax>
244                 <description>
245                         <para>Sets an agent as no longer logged in.</para>
246                 </description>
247         </manager>
248         <configInfo name="app_agent_pool" language="en_US">
249                 <synopsis>Agent pool applications</synopsis>
250                 <description>
251                         <note><para>Option changes take effect on agent login or after an agent
252                         disconnects from a call.</para></note>
253                 </description>
254                 <configFile name="agents.conf">
255                         <configObject name="global">
256                                 <synopsis>Unused, but reserved.</synopsis>
257                         </configObject>
258                         <configObject name="agent-id">
259                                 <synopsis>Configure an agent for the pool.</synopsis>
260                                 <description>
261                                         <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
262                                 </description>
263                                 <configOption name="ackcall">
264                                         <synopsis>Enable to require the agent to acknowledge a call.</synopsis>
265                                         <description>
266                                                 <para>Enable to require the agent to give a DTMF acknowledgement
267                                                 when the agent receives a call.</para>
268                                                 <note><para>The option is overridden by <variable>AGENTACKCALL</variable> on agent login.</para></note>
269                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
270                                         </description>
271                                 </configOption>
272                                 <configOption name="acceptdtmf">
273                                         <synopsis>DTMF key sequence the agent uses to acknowledge a call.</synopsis>
274                                         <description>
275                                                 <note><para>The option is overridden by <variable>AGENTACCEPTDTMF</variable> on agent login.</para></note>
276                                                 <note><para>The option is ignored unless the ackcall option is enabled.</para></note>
277                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
278                                         </description>
279                                 </configOption>
280                                 <configOption name="autologoff">
281                                         <synopsis>Time the agent has to acknowledge a call before being logged off.</synopsis>
282                                         <description>
283                                                 <para>Set how many seconds a call for the agent has to wait for the
284                                                 agent to acknowledge the call before the agent is automatically
285                                                 logged off.  If set to zero then the call will wait forever for
286                                                 the agent to acknowledge.</para>
287                                                 <note><para>The option is overridden by <variable>AGENTAUTOLOGOFF</variable> on agent login.</para></note>
288                                                 <note><para>The option is ignored unless the ackcall option is enabled.</para></note>
289                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
290                                         </description>
291                                 </configOption>
292                                 <configOption name="wrapuptime">
293                                         <synopsis>Minimum time the agent has between calls.</synopsis>
294                                         <description>
295                                                 <para>Set the minimum amount of time in milliseconds after
296                                                 disconnecting a call before the agent can receive a new call.</para>
297                                                 <note><para>The option is overridden by <variable>AGENTWRAPUPTIME</variable> on agent login.</para></note>
298                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
299                                         </description>
300                                 </configOption>
301                                 <configOption name="musiconhold">
302                                         <synopsis>Music on hold class the agent listens to between calls.</synopsis>
303                                         <description>
304                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
305                                         </description>
306                                 </configOption>
307                                 <configOption name="recordagentcalls">
308                                         <synopsis>Enable to automatically record calls the agent takes.</synopsis>
309                                         <description>
310                                                 <para>Enable recording calls the agent takes automatically by
311                                                 invoking the automixmon DTMF feature when the agent connects
312                                                 to a caller.  See <filename>features.conf.sample</filename> for information about
313                                                 the automixmon feature.</para>
314                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
315                                         </description>
316                                 </configOption>
317                                 <configOption name="custom_beep">
318                                         <synopsis>Sound file played to alert the agent when a call is present.</synopsis>
319                                         <description>
320                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
321                                         </description>
322                                 </configOption>
323                                 <configOption name="fullname">
324                                         <synopsis>A friendly name for the agent used in log messages.</synopsis>
325                                         <description>
326                                                 <xi:include xpointer="xpointer(/docs/configInfo[@name='app_agent_pool']/description/note)" />
327                                         </description>
328                                 </configOption>
329                         </configObject>
330                 </configFile>
331         </configInfo>
332  ***/
333
334 /* ------------------------------------------------------------------- */
335
336 #define AST_MAX_BUF     256
337
338 /*! Maximum wait time (in ms) for the custom_beep file to play announcing the caller. */
339 #define CALLER_SAFETY_TIMEOUT_TIME      (2 * 60 * 1000)
340
341 /*! Number of seconds to wait for local channel optimizations to complete. */
342 #define LOGIN_WAIT_TIMEOUT_TIME         5
343
344 static const char app_agent_login[] = "AgentLogin";
345 static const char app_agent_request[] = "AgentRequest";
346
347 /*! Agent config parameters. */
348 struct agent_cfg {
349         AST_DECLARE_STRING_FIELDS(
350                 /*! Identification of the agent.  (agents config container key) */
351                 AST_STRING_FIELD(username);
352                 /*! Name of agent for logging and querying purposes */
353                 AST_STRING_FIELD(full_name);
354
355                 /*!
356                  * \brief DTMF string for an agent to accept a call.
357                  *
358                  * \note The channel variable AGENTACCEPTDTMF overrides on login.
359                  */
360                 AST_STRING_FIELD(dtmf_accept);
361                 /*! Beep sound file to use.  Alert the agent a call is waiting. */
362                 AST_STRING_FIELD(beep_sound);
363                 /*! MOH class to use while agent waiting for call. */
364                 AST_STRING_FIELD(moh);
365         );
366         /*!
367          * \brief Number of seconds for agent to ack a call before being logged off.
368          *
369          * \note The channel variable AGENTAUTOLOGOFF overrides on login.
370          * \note If zero then timer is disabled.
371          */
372         unsigned int auto_logoff;
373         /*!
374          * \brief Time after a call in ms before the agent can get a new call.
375          *
376          * \note The channel variable AGENTWRAPUPTIME overrides on login.
377          */
378         unsigned int wrapup_time;
379         /*!
380          * \brief TRUE if agent needs to ack a call to accept it.
381          *
382          * \note The channel variable AGENTACKCALL overrides on login.
383          */
384         int ack_call;
385         /*! TRUE if agent calls are automatically recorded. */
386         int record_agent_calls;
387 };
388
389 /*!
390  * \internal
391  * \brief Agent config ao2 container sort function.
392  * \since 12.0.0
393  *
394  * \param obj_left pointer to the (user-defined part) of an object.
395  * \param obj_right pointer to the (user-defined part) of an object.
396  * \param flags flags from ao2_callback()
397  *   OBJ_POINTER - if set, 'obj_right', is an object.
398  *   OBJ_KEY - if set, 'obj_right', is a search key item that is not an object.
399  *   OBJ_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
400  *
401  * \retval <0 if obj_left < obj_right
402  * \retval =0 if obj_left == obj_right
403  * \retval >0 if obj_left > obj_right
404  */
405 static int agent_cfg_sort_cmp(const void *obj_left, const void *obj_right, int flags)
406 {
407         const struct agent_cfg *cfg_left = obj_left;
408         const struct agent_cfg *cfg_right = obj_right;
409         const char *right_key = obj_right;
410         int cmp;
411
412         switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
413         default:
414         case OBJ_POINTER:
415                 right_key = cfg_right->username;
416                 /* Fall through */
417         case OBJ_KEY:
418                 cmp = strcmp(cfg_left->username, right_key);
419                 break;
420         case OBJ_PARTIAL_KEY:
421                 cmp = strncmp(cfg_left->username, right_key, strlen(right_key));
422                 break;
423         }
424         return cmp;
425 }
426
427 static void agent_cfg_destructor(void *vdoomed)
428 {
429         struct agent_cfg *doomed = vdoomed;
430
431         ast_string_field_free_memory(doomed);
432 }
433
434 static void *agent_cfg_alloc(const char *name)
435 {
436         struct agent_cfg *cfg;
437
438         cfg = ao2_alloc_options(sizeof(*cfg), agent_cfg_destructor,
439                 AO2_ALLOC_OPT_LOCK_NOLOCK);
440         if (!cfg || ast_string_field_init(cfg, 64)) {
441                 return NULL;
442         }
443         ast_string_field_set(cfg, username, name);
444         return cfg;
445 }
446
447 static void *agent_cfg_find(struct ao2_container *agents, const char *username)
448 {
449         return ao2_find(agents, username, OBJ_KEY);
450 }
451
452 /*! Agents configuration */
453 struct agents_cfg {
454         /*! Master configured agents container. */
455         struct ao2_container *agents;
456 };
457
458 static struct aco_type agent_type = {
459         .type = ACO_ITEM,
460         .name = "agent-id",
461         .category_match = ACO_BLACKLIST,
462         .category = "^(general|agents)$",
463         .item_alloc = agent_cfg_alloc,
464         .item_find = agent_cfg_find,
465         .item_offset = offsetof(struct agents_cfg, agents),
466 };
467
468 static struct aco_type *agent_types[] = ACO_TYPES(&agent_type);
469
470 /* The general category is reserved, but unused */
471 static struct aco_type general_type = {
472         .type = ACO_GLOBAL,
473         .name = "global",
474         .category_match = ACO_WHITELIST,
475         .category = "^general$",
476 };
477
478 static struct aco_file agents_conf = {
479         .filename = "agents.conf",
480         .types = ACO_TYPES(&general_type, &agent_type),
481 };
482
483 static AO2_GLOBAL_OBJ_STATIC(cfg_handle);
484
485 static void agents_cfg_destructor(void *vdoomed)
486 {
487         struct agents_cfg *doomed = vdoomed;
488
489         ao2_cleanup(doomed->agents);
490         doomed->agents = NULL;
491 }
492
493 /*!
494  * \internal
495  * \brief Create struct agents_cfg object.
496  * \since 12.0.0
497  *
498  * \note A lock is not needed for the object or any secondary
499  * created cfg objects.  These objects are immutable after the
500  * config is loaded and applied.
501  *
502  * \retval New struct agents_cfg object.
503  * \retval NULL on error.
504  */
505 static void *agents_cfg_alloc(void)
506 {
507         struct agents_cfg *cfg;
508
509         cfg = ao2_alloc_options(sizeof(*cfg), agents_cfg_destructor,
510                 AO2_ALLOC_OPT_LOCK_NOLOCK);
511         if (!cfg) {
512                 return NULL;
513         }
514         cfg->agents = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_NOLOCK,
515                 AO2_CONTAINER_ALLOC_OPT_DUPS_REJECT, agent_cfg_sort_cmp, NULL);
516         if (!cfg->agents) {
517                 ao2_ref(cfg, -1);
518                 cfg = NULL;
519         }
520         return cfg;
521 }
522
523 static void agents_post_apply_config(void);
524
525 CONFIG_INFO_STANDARD(cfg_info, cfg_handle, agents_cfg_alloc,
526         .files = ACO_FILES(&agents_conf),
527         .post_apply_config = agents_post_apply_config,
528 );
529
530 static void destroy_config(void)
531 {
532         ao2_global_obj_release(cfg_handle);
533         aco_info_destroy(&cfg_info);
534 }
535
536 static int load_config(void)
537 {
538         if (aco_info_init(&cfg_info)) {
539                 return -1;
540         }
541
542         /* Agent options */
543         aco_option_register(&cfg_info, "ackcall", ACO_EXACT, agent_types, "no", OPT_BOOL_T, 1, FLDSET(struct agent_cfg, ack_call));
544         aco_option_register(&cfg_info, "acceptdtmf", ACO_EXACT, agent_types, "#", OPT_STRINGFIELD_T, 1, STRFLDSET(struct agent_cfg, dtmf_accept));
545         aco_option_register(&cfg_info, "autologoff", ACO_EXACT, agent_types, "0", OPT_UINT_T, 0, FLDSET(struct agent_cfg, auto_logoff));
546         aco_option_register(&cfg_info, "wrapuptime", ACO_EXACT, agent_types, "0", OPT_UINT_T, 0, FLDSET(struct agent_cfg, wrapup_time));
547         aco_option_register(&cfg_info, "musiconhold", ACO_EXACT, agent_types, "default", OPT_STRINGFIELD_T, 0, STRFLDSET(struct agent_cfg, moh));
548         aco_option_register(&cfg_info, "recordagentcalls", ACO_EXACT, agent_types, "no", OPT_BOOL_T, 1, FLDSET(struct agent_cfg, record_agent_calls));
549         aco_option_register(&cfg_info, "custom_beep", ACO_EXACT, agent_types, "beep", OPT_STRINGFIELD_T, 0, STRFLDSET(struct agent_cfg, beep_sound));
550         aco_option_register(&cfg_info, "fullname", ACO_EXACT, agent_types, NULL, OPT_STRINGFIELD_T, 0, STRFLDSET(struct agent_cfg, full_name));
551
552         if (aco_process_config(&cfg_info, 0) == ACO_PROCESS_ERROR) {
553                 return -1;
554         }
555
556         return 0;
557 }
558
559 enum agent_state {
560         /*! The agent is defined but an agent is not present. */
561         AGENT_STATE_LOGGED_OUT,
562         /*! Forced initial login wait to allow any local channel optimizations to happen. */
563         AGENT_STATE_PROBATION_WAIT,
564         /*! The agent is ready for a call. */
565         AGENT_STATE_READY_FOR_CALL,
566         /*! The agent has a call waiting to connect. */
567         AGENT_STATE_CALL_PRESENT,
568         /*! The agent needs to ack the call. */
569         AGENT_STATE_CALL_WAIT_ACK,
570         /*! The agent is connected with a call. */
571         AGENT_STATE_ON_CALL,
572         /*! The agent is resting between calls. */
573         AGENT_STATE_CALL_WRAPUP,
574         /*! The agent is being kicked out. */
575         AGENT_STATE_LOGGING_OUT,
576 };
577
578 /*! Agent config option override flags. */
579 enum agent_override_flags {
580         AGENT_FLAG_ACK_CALL = (1 << 0),
581         AGENT_FLAG_DTMF_ACCEPT = (1 << 1),
582         AGENT_FLAG_AUTO_LOGOFF = (1 << 2),
583         AGENT_FLAG_WRAPUP_TIME = (1 << 3),
584 };
585
586 /*! \brief Structure representing an agent. */
587 struct agent_pvt {
588         AST_DECLARE_STRING_FIELDS(
589                 /*! Identification of the agent.  (agents container key) */
590                 AST_STRING_FIELD(username);
591                 /*! Login override DTMF string for an agent to accept a call. */
592                 AST_STRING_FIELD(override_dtmf_accept);
593         );
594         /*! Connected line information to send when reentering the holding bridge. */
595         struct ast_party_connected_line waiting_colp;
596         /*! Flags show if settings were overridden by channel vars. */
597         unsigned int flags;
598         /*! Login override number of seconds for agent to ack a call before being logged off. */
599         unsigned int override_auto_logoff;
600         /*! Login override time after a call in ms before the agent can get a new call. */
601         unsigned int override_wrapup_time;
602         /*! Login override if agent needs to ack a call to accept it. */
603         unsigned int override_ack_call:1;
604
605         /*! TRUE if the agent is requested to logoff when the current call ends. */
606         unsigned int deferred_logoff:1;
607
608         /*! Mark and sweep config update to determine if an agent is dead. */
609         unsigned int the_mark:1;
610         /*!
611          * \brief TRUE if the agent is no longer configured and is being destroyed.
612          *
613          * \note Agents cannot log in if they are dead.
614          */
615         unsigned int dead:1;
616
617         /*! Agent control state variable. */
618         enum agent_state state;
619         /*! Custom device state of agent. */
620         enum ast_device_state devstate;
621
622         /*! When agent first logged in */
623         time_t login_start;
624         /*! When agent login probation started. */
625         time_t probation_start;
626         /*! When call started */
627         time_t call_start;
628         /*! When ack timer started */
629         struct timeval ack_time;
630         /*! When last disconnected */
631         struct timeval last_disconnect;
632
633         /*! Caller is waiting in this bridge for agent to join. (Holds ref) */
634         struct ast_bridge *caller_bridge;
635         /*! Agent is logged in with this channel. (Holds ref) (NULL if not logged in.) */
636         struct ast_channel *logged;
637         /*! Active config values from config file. (Holds ref) */
638         struct agent_cfg *cfg;
639 };
640
641 /*! Container of defined agents. */
642 static struct ao2_container *agents;
643
644 /*!
645  * \brief Lock the agent.
646  *
647  * \param agent Agent to lock
648  *
649  * \return Nothing
650  */
651 #define agent_lock(agent)       _agent_lock(agent, __FILE__, __PRETTY_FUNCTION__, __LINE__, #agent)
652 static inline void _agent_lock(struct agent_pvt *agent, const char *file, const char *function, int line, const char *var)
653 {
654         __ao2_lock(agent, AO2_LOCK_REQ_MUTEX, file, function, line, var);
655 }
656
657 /*!
658  * \brief Unlock the agent.
659  *
660  * \param agent Agent to unlock
661  *
662  * \return Nothing
663  */
664 #define agent_unlock(agent)     _agent_unlock(agent, __FILE__, __PRETTY_FUNCTION__, __LINE__, #agent)
665 static inline void _agent_unlock(struct agent_pvt *agent, const char *file, const char *function, int line, const char *var)
666 {
667         __ao2_unlock(agent, file, function, line, var);
668 }
669
670 /*!
671  * \internal
672  * \brief Obtain the agent logged in channel lock if it exists.
673  * \since 12.0.0
674  *
675  * \param agent Pointer to the LOCKED agent_pvt.
676  *
677  * \note Assumes the agent lock is already obtained.
678  *
679  * \note Defined locking order is channel lock then agent lock.
680  *
681  * \return Nothing
682  */
683 static struct ast_channel *agent_lock_logged(struct agent_pvt *agent)
684 {
685         struct ast_channel *logged;
686
687         for (;;) {
688                 if (!agent->logged) { /* No owner. Nothing to do. */
689                         return NULL;
690                 }
691
692                 /* If we don't ref the logged, it could be killed when we unlock the agent. */
693                 logged = ast_channel_ref(agent->logged);
694
695                 /* Locking logged requires us to lock channel, then agent. */
696                 agent_unlock(agent);
697                 ast_channel_lock(logged);
698                 agent_lock(agent);
699
700                 /* Check if logged changed during agent unlock period */
701                 if (logged != agent->logged) {
702                         /* Channel changed. Unref and do another pass. */
703                         ast_channel_unlock(logged);
704                         ast_channel_unref(logged);
705                 } else {
706                         /* Channel stayed the same. Return it. */
707                         return logged;
708                 }
709         }
710 }
711
712 /*!
713  * \internal
714  * \brief Get the Agent:agent_id device state.
715  * \since 12.0.0
716  *
717  * \param agent_id Username of the agent.
718  *
719  * \details
720  * Search the agents container for the agent and return the
721  * current state.
722  *
723  * \return Device state of the agent.
724  */
725 static enum ast_device_state agent_pvt_devstate_get(const char *agent_id)
726 {
727         enum ast_device_state dev_state = AST_DEVICE_INVALID;
728         struct agent_pvt *agent;
729
730         agent = ao2_find(agents, agent_id, OBJ_KEY);
731         if (agent) {
732                 agent_lock(agent);
733                 dev_state = agent->devstate;
734                 agent_unlock(agent);
735                 ao2_ref(agent, -1);
736         }
737         return dev_state;
738 }
739
740 /*!
741  * \internal
742  * \brief Request an agent device state be updated.
743  * \since 12.0.0
744  *
745  * \param agent_id Which agent needs the device state updated.
746  *
747  * \return Nothing
748  */
749 static void agent_devstate_changed(const char *agent_id)
750 {
751         ast_devstate_changed(AST_DEVICE_UNKNOWN, AST_DEVSTATE_CACHABLE, "Agent:%s", agent_id);
752 }
753
754 static void agent_pvt_destructor(void *vdoomed)
755 {
756         struct agent_pvt *doomed = vdoomed;
757
758         /* Make sure device state reflects agent destruction. */
759         if (!ast_strlen_zero(doomed->username)) {
760                 ast_debug(1, "Agent %s: Destroyed.\n", doomed->username);
761                 agent_devstate_changed(doomed->username);
762         }
763
764         ast_party_connected_line_free(&doomed->waiting_colp);
765         if (doomed->caller_bridge) {
766                 ast_bridge_destroy(doomed->caller_bridge, 0);
767                 doomed->caller_bridge = NULL;
768         }
769         if (doomed->logged) {
770                 doomed->logged = ast_channel_unref(doomed->logged);
771         }
772         ao2_cleanup(doomed->cfg);
773         doomed->cfg = NULL;
774         ast_string_field_free_memory(doomed);
775 }
776
777 static struct agent_pvt *agent_pvt_new(struct agent_cfg *cfg)
778 {
779         struct agent_pvt *agent;
780
781         agent = ao2_alloc(sizeof(*agent), agent_pvt_destructor);
782         if (!agent) {
783                 return NULL;
784         }
785         if (ast_string_field_init(agent, 32)) {
786                 ao2_ref(agent, -1);
787                 return NULL;
788         }
789         ast_string_field_set(agent, username, cfg->username);
790         ast_party_connected_line_init(&agent->waiting_colp);
791         ao2_ref(cfg, +1);
792         agent->cfg = cfg;
793         agent->devstate = AST_DEVICE_UNAVAILABLE;
794         return agent;
795 }
796
797 /*!
798  * \internal
799  * \brief Agents ao2 container sort function.
800  * \since 12.0.0
801  *
802  * \param obj_left pointer to the (user-defined part) of an object.
803  * \param obj_right pointer to the (user-defined part) of an object.
804  * \param flags flags from ao2_callback()
805  *   OBJ_POINTER - if set, 'obj_right', is an object.
806  *   OBJ_KEY - if set, 'obj_right', is a search key item that is not an object.
807  *   OBJ_PARTIAL_KEY - if set, 'obj_right', is a partial search key item that is not an object.
808  *
809  * \retval <0 if obj_left < obj_right
810  * \retval =0 if obj_left == obj_right
811  * \retval >0 if obj_left > obj_right
812  */
813 static int agent_pvt_sort_cmp(const void *obj_left, const void *obj_right, int flags)
814 {
815         const struct agent_pvt *agent_left = obj_left;
816         const struct agent_pvt *agent_right = obj_right;
817         const char *right_key = obj_right;
818         int cmp;
819
820         switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
821         default:
822         case OBJ_POINTER:
823                 right_key = agent_right->username;
824                 /* Fall through */
825         case OBJ_KEY:
826                 cmp = strcmp(agent_left->username, right_key);
827                 break;
828         case OBJ_PARTIAL_KEY:
829                 cmp = strncmp(agent_left->username, right_key, strlen(right_key));
830                 break;
831         }
832         return cmp;
833 }
834
835 /*!
836  * \internal
837  * \brief ao2_find() callback function.
838  * \since 12.0.0
839  *
840  * Usage:
841  * found = ao2_find(agents, agent, OBJ_POINTER);
842  * found = ao2_find(agents, "agent-id", OBJ_KEY);
843  * found = ao2_find(agents, agent->logged, 0);
844  */
845 static int agent_pvt_cmp(void *obj, void *arg, int flags)
846 {
847         const struct agent_pvt *agent = obj;
848         int cmp;
849
850         switch (flags & (OBJ_POINTER | OBJ_KEY | OBJ_PARTIAL_KEY)) {
851         case OBJ_POINTER:
852         case OBJ_KEY:
853         case OBJ_PARTIAL_KEY:
854                 cmp = CMP_MATCH;
855                 break;
856         default:
857                 if (agent->logged == arg) {
858                         cmp = CMP_MATCH;
859                 } else {
860                         cmp = 0;
861                 }
862                 break;
863         }
864         return cmp;
865 }
866
867 static int agent_mark(void *obj, void *arg, int flags)
868 {
869         struct agent_pvt *agent = obj;
870
871         agent_lock(agent);
872         agent->the_mark = 1;
873         agent_unlock(agent);
874         return 0;
875 }
876
877 static void agents_mark(void)
878 {
879         ao2_callback(agents, 0, agent_mark, NULL);
880 }
881
882 static int agent_sweep(void *obj, void *arg, int flags)
883 {
884         struct agent_pvt *agent = obj;
885         int cmp = 0;
886
887         agent_lock(agent);
888         if (agent->the_mark) {
889                 agent->the_mark = 0;
890                 agent->dead = 1;
891                 /* Unlink dead agents immediately. */
892                 cmp = CMP_MATCH;
893         }
894         agent_unlock(agent);
895         return cmp;
896 }
897
898 static void agents_sweep(void)
899 {
900         struct ao2_iterator *iter;
901         struct agent_pvt *agent;
902         struct ast_channel *logged;
903
904         iter = ao2_callback(agents, OBJ_MULTIPLE | OBJ_UNLINK, agent_sweep, NULL);
905         if (!iter) {
906                 return;
907         }
908         for (; (agent = ao2_iterator_next(iter)); ao2_ref(agent, -1)) {
909                 agent_lock(agent);
910                 if (agent->logged) {
911                         logged = ast_channel_ref(agent->logged);
912                 } else {
913                         logged = NULL;
914                 }
915                 agent_unlock(agent);
916                 if (!logged) {
917                         continue;
918                 }
919                 ast_log(LOG_NOTICE,
920                         "Forced logoff of agent %s(%s).  Agent no longer configured.\n",
921                         agent->username, ast_channel_name(logged));
922                 ast_softhangup(logged, AST_SOFTHANGUP_EXPLICIT);
923                 ast_channel_unref(logged);
924         }
925         ao2_iterator_destroy(iter);
926 }
927
928 static void agents_post_apply_config(void)
929 {
930         struct ao2_iterator iter;
931         struct agent_cfg *cfg;
932         RAII_VAR(struct agents_cfg *, cfgs, ao2_global_obj_ref(cfg_handle), ao2_cleanup);
933
934         ast_assert(cfgs != NULL);
935
936         agents_mark();
937         iter = ao2_iterator_init(cfgs->agents, 0);
938         for (; (cfg = ao2_iterator_next(&iter)); ao2_ref(cfg, -1)) {
939                 RAII_VAR(struct agent_pvt *, agent, ao2_find(agents, cfg->username, OBJ_KEY), ao2_cleanup);
940
941                 if (agent) {
942                         agent_lock(agent);
943                         agent->the_mark = 0;
944                         if (!agent->logged) {
945                                 struct agent_cfg *cfg_old;
946
947                                 /* Replace the config of agents not logged in. */
948                                 cfg_old = agent->cfg;
949                                 ao2_ref(cfg, +1);
950                                 agent->cfg = cfg;
951                                 ao2_cleanup(cfg_old);
952                         }
953                         agent_unlock(agent);
954                         continue;
955                 }
956                 agent = agent_pvt_new(cfg);
957                 if (!agent) {
958                         continue;
959                 }
960                 ao2_link(agents, agent);
961                 ast_debug(1, "Agent %s: Created.\n", agent->username);
962                 agent_devstate_changed(agent->username);
963         }
964         ao2_iterator_destroy(&iter);
965         agents_sweep();
966 }
967
968 static int agent_logoff_request(const char *agent_id, int soft)
969 {
970         struct ast_channel *logged;
971         RAII_VAR(struct agent_pvt *, agent, ao2_find(agents, agent_id, OBJ_KEY), ao2_cleanup);
972
973         if (!agent) {
974                 return -1;
975         }
976
977         agent_lock(agent);
978         logged = agent_lock_logged(agent);
979         if (logged) {
980                 if (soft) {
981                         agent->deferred_logoff = 1;
982                 } else {
983                         ast_softhangup(logged, AST_SOFTHANGUP_EXPLICIT);
984                 }
985                 ast_channel_unlock(logged);
986                 ast_channel_unref(logged);
987         }
988         agent_unlock(agent);
989         return 0;
990 }
991
992 /*! Agent holding bridge instance holder. */
993 static AO2_GLOBAL_OBJ_STATIC(agent_holding);
994
995 /*! Agent holding bridge deferred creation lock. */
996 AST_MUTEX_DEFINE_STATIC(agent_holding_lock);
997
998 /*!
999  * \internal
1000  * \brief Callback to clear AGENT_STATUS on the caller channel.
1001  *
1002  * \param bridge_channel Which channel to operate on.
1003  * \param payload Data to pass to the callback. (NULL if none).
1004  * \param payload_size Size of the payload if payload is non-NULL.  A number otherwise.
1005  *
1006  * \note The payload MUST NOT have any resources that need to be freed.
1007  *
1008  * \return Nothing
1009  */
1010 static void clear_agent_status(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
1011 {
1012         pbx_builtin_setvar_helper(bridge_channel->chan, "AGENT_STATUS", NULL);
1013 }
1014
1015 /*!
1016  * \internal
1017  * \brief Connect the agent with the waiting caller.
1018  * \since 12.0.0
1019  *
1020  * \param bridge_channel Agent channel connecting to the caller.
1021  * \param agent Which agent is connecting to the caller.
1022  *
1023  * \note The agent is locked on entry and not locked on exit.
1024  *
1025  * \return Nothing
1026  */
1027 static void agent_connect_caller(struct ast_bridge_channel *bridge_channel, struct agent_pvt *agent)
1028 {
1029         struct ast_bridge *caller_bridge;
1030         int record_agent_calls;
1031         int res;
1032
1033         record_agent_calls = agent->cfg->record_agent_calls;
1034         caller_bridge = agent->caller_bridge;
1035         agent->caller_bridge = NULL;
1036         agent->state = AGENT_STATE_ON_CALL;
1037         time(&agent->call_start);
1038         agent_unlock(agent);
1039
1040         if (!caller_bridge) {
1041                 /* Reset agent. */
1042                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
1043                         AST_CAUSE_NORMAL_CLEARING);
1044                 return;
1045         }
1046         res = ast_bridge_move(caller_bridge, bridge_channel->bridge, bridge_channel->chan,
1047                 NULL, 0);
1048         if (res) {
1049                 /* Reset agent. */
1050                 ast_bridge_destroy(caller_bridge, 0);
1051                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
1052                         AST_CAUSE_NORMAL_CLEARING);
1053                 return;
1054         }
1055         res = ast_bridge_channel_write_control_data(bridge_channel, AST_CONTROL_ANSWER, NULL, 0)
1056                 || ast_bridge_channel_write_callback(bridge_channel, 0, clear_agent_status, NULL, 0);
1057         if (res) {
1058                 /* Reset agent. */
1059                 ast_bridge_destroy(caller_bridge, 0);
1060                 return;
1061         }
1062
1063         if (record_agent_calls) {
1064                 struct ast_bridge_features_automixmonitor options = {
1065                         .start_stop = AUTO_MONITOR_START,
1066                         };
1067
1068                 /*
1069                  * The agent is in the new bridge so we can invoke the
1070                  * mixmonitor hook to only start recording.
1071                  */
1072                 ast_bridge_features_do(AST_BRIDGE_BUILTIN_AUTOMIXMON, bridge_channel, &options);
1073         }
1074
1075         ao2_t_ref(caller_bridge, -1, "Agent successfully in caller_bridge");
1076 }
1077
1078 static int bridge_agent_hold_ack(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
1079 {
1080         struct agent_pvt *agent = hook_pvt;
1081
1082         agent_lock(agent);
1083         switch (agent->state) {
1084         case AGENT_STATE_CALL_WAIT_ACK:
1085                 /* Connect to caller now. */
1086                 ast_debug(1, "Agent %s: Acked call.\n", agent->username);
1087                 agent_connect_caller(bridge_channel, agent);/* Will unlock agent. */
1088                 return 0;
1089         default:
1090                 break;
1091         }
1092         agent_unlock(agent);
1093         return 0;
1094 }
1095
1096 static int bridge_agent_hold_heartbeat(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
1097 {
1098         struct agent_pvt *agent = hook_pvt;
1099         int probation_timedout = 0;
1100         int ack_timedout = 0;
1101         int wrapup_timedout = 0;
1102         int deferred_logoff;
1103         unsigned int wrapup_time;
1104         unsigned int auto_logoff;
1105
1106         agent_lock(agent);
1107         deferred_logoff = agent->deferred_logoff;
1108         if (deferred_logoff) {
1109                 agent->state = AGENT_STATE_LOGGING_OUT;
1110         }
1111
1112         switch (agent->state) {
1113         case AGENT_STATE_PROBATION_WAIT:
1114                 probation_timedout =
1115                         LOGIN_WAIT_TIMEOUT_TIME <= (time(NULL) - agent->probation_start);
1116                 if (probation_timedout) {
1117                         /* Now ready for a caller. */
1118                         agent->state = AGENT_STATE_READY_FOR_CALL;
1119                         agent->devstate = AST_DEVICE_NOT_INUSE;
1120                 }
1121                 break;
1122         case AGENT_STATE_CALL_WAIT_ACK:
1123                 /* Check ack call time. */
1124                 auto_logoff = agent->cfg->auto_logoff;
1125                 if (ast_test_flag(agent, AGENT_FLAG_AUTO_LOGOFF)) {
1126                         auto_logoff = agent->override_auto_logoff;
1127                 }
1128                 if (auto_logoff) {
1129                         auto_logoff *= 1000;
1130                         ack_timedout = ast_tvdiff_ms(ast_tvnow(), agent->ack_time) > auto_logoff;
1131                         if (ack_timedout) {
1132                                 agent->state = AGENT_STATE_LOGGING_OUT;
1133                         }
1134                 }
1135                 break;
1136         case AGENT_STATE_CALL_WRAPUP:
1137                 /* Check wrapup time. */
1138                 wrapup_time = agent->cfg->wrapup_time;
1139                 if (ast_test_flag(agent, AGENT_FLAG_WRAPUP_TIME)) {
1140                         wrapup_time = agent->override_wrapup_time;
1141                 }
1142                 wrapup_timedout = ast_tvdiff_ms(ast_tvnow(), agent->last_disconnect) > wrapup_time;
1143                 if (wrapup_timedout) {
1144                         agent->state = AGENT_STATE_READY_FOR_CALL;
1145                         agent->devstate = AST_DEVICE_NOT_INUSE;
1146                 }
1147                 break;
1148         default:
1149                 break;
1150         }
1151         agent_unlock(agent);
1152
1153         if (deferred_logoff) {
1154                 ast_debug(1, "Agent %s: Deferred logoff.\n", agent->username);
1155                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
1156                         AST_CAUSE_NORMAL_CLEARING);
1157         } else if (probation_timedout) {
1158                 ast_debug(1, "Agent %s: Login complete.\n", agent->username);
1159                 agent_devstate_changed(agent->username);
1160         } else if (ack_timedout) {
1161                 ast_debug(1, "Agent %s: Ack call timeout.\n", agent->username);
1162                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
1163                         AST_CAUSE_NORMAL_CLEARING);
1164         } else if (wrapup_timedout) {
1165                 ast_debug(1, "Agent %s: Wrapup timeout. Ready for new call.\n", agent->username);
1166                 agent_devstate_changed(agent->username);
1167         }
1168
1169         return 0;
1170 }
1171
1172 static void agent_after_bridge_cb(struct ast_channel *chan, void *data);
1173 static void agent_after_bridge_cb_failed(enum ast_bridge_after_cb_reason reason, void *data);
1174
1175 /*!
1176  * \internal
1177  * \brief ast_bridge agent_hold push method.
1178  * \since 12.0.0
1179  *
1180  * \param self Bridge to operate upon.
1181  * \param bridge_channel Bridge channel to push.
1182  * \param swap Bridge channel to swap places with if not NULL.
1183  *
1184  * \note On entry, self is already locked.
1185  *
1186  * \retval 0 on success
1187  * \retval -1 on failure
1188  */
1189 static int bridge_agent_hold_push(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel, struct ast_bridge_channel *swap)
1190 {
1191         int res = 0;
1192         unsigned int wrapup_time;
1193         char dtmf[AST_FEATURE_MAX_LEN];
1194         struct ast_channel *chan;
1195         const char *moh_class;
1196         RAII_VAR(struct agent_pvt *, agent, NULL, ao2_cleanup);
1197
1198         chan = bridge_channel->chan;
1199
1200         agent = ao2_find(agents, swap ? swap->chan : chan, 0);
1201         if (!agent) {
1202                 /* Could not find the agent. */
1203                 return -1;
1204         }
1205
1206         /* Setup agent entertainment */
1207         agent_lock(agent);
1208         moh_class = ast_strdupa(agent->cfg->moh);
1209         agent_unlock(agent);
1210         res |= ast_channel_add_bridge_role(chan, "holding_participant");
1211         res |= ast_channel_set_bridge_role_option(chan, "holding_participant", "idle_mode", "musiconhold");
1212         res |= ast_channel_set_bridge_role_option(chan, "holding_participant", "moh_class", moh_class);
1213
1214         /* Add DTMF acknowledge hook. */
1215         dtmf[0] = '\0';
1216         agent_lock(agent);
1217         if (ast_test_flag(agent, AGENT_FLAG_ACK_CALL)
1218                 ? agent->override_ack_call : agent->cfg->ack_call) {
1219                 const char *dtmf_accept;
1220
1221                 dtmf_accept = ast_test_flag(agent, AGENT_FLAG_DTMF_ACCEPT)
1222                         ? agent->override_dtmf_accept : agent->cfg->dtmf_accept;
1223                 ast_copy_string(dtmf, dtmf_accept, sizeof(dtmf));
1224         }
1225         agent_unlock(agent);
1226         if (!ast_strlen_zero(dtmf)) {
1227                 ao2_ref(agent, +1);
1228                 if (ast_bridge_dtmf_hook(bridge_channel->features, dtmf, bridge_agent_hold_ack,
1229                         agent, __ao2_cleanup, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
1230                         ao2_ref(agent, -1);
1231                         res = -1;
1232                 }
1233         }
1234
1235         /* Add heartbeat interval hook. */
1236         ao2_ref(agent, +1);
1237         if (ast_bridge_interval_hook(bridge_channel->features, 0, 1000,
1238                 bridge_agent_hold_heartbeat, agent, __ao2_cleanup, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
1239                 ao2_ref(agent, -1);
1240                 res = -1;
1241         }
1242
1243         res |= ast_bridge_base_v_table.push(self, bridge_channel, swap);
1244         if (res) {
1245                 ast_channel_remove_bridge_role(chan, "holding_participant");
1246                 return -1;
1247         }
1248
1249         if (swap) {
1250                 res = ast_bridge_set_after_callback(chan, agent_after_bridge_cb,
1251                         agent_after_bridge_cb_failed, chan);
1252                 if (res) {
1253                         ast_channel_remove_bridge_role(chan, "holding_participant");
1254                         return -1;
1255                 }
1256
1257                 agent_lock(agent);
1258                 ast_channel_unref(agent->logged);
1259                 agent->logged = ast_channel_ref(chan);
1260                 agent_unlock(agent);
1261
1262                 /*
1263                  * Kick the channel out so it can come back in fully controlled.
1264                  * Otherwise, the after bridge callback will linger and the
1265                  * agent will have some slightly different behavior in corner
1266                  * cases.
1267                  */
1268                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END,
1269                         AST_CAUSE_NORMAL_CLEARING);
1270                 return 0;
1271         }
1272
1273         agent_lock(agent);
1274         switch (agent->state) {
1275         case AGENT_STATE_LOGGED_OUT:
1276                 /*!
1277                  * \todo XXX the login probation time should be only if it is needed.
1278                  *
1279                  * Need to determine if there are any local channels that can
1280                  * optimize and wait until they actually do before leaving the
1281                  * AGENT_STATE_PROBATION_WAIT state.  For now, the blind
1282                  * timer of LOGIN_WAIT_TIMEOUT_TIME will do.
1283                  */
1284                 /*
1285                  * Start the login probation timer.
1286                  *
1287                  * We cannot handle an agent local channel optimization when the
1288                  * agent is on a call.  The optimization may kick the agent
1289                  * channel we know about out of the call without our being able
1290                  * to switch to the replacement channel.  Get any agent local
1291                  * channel optimization out of the way while the agent is in the
1292                  * holding bridge.
1293                  */
1294                 time(&agent->probation_start);
1295                 agent->state = AGENT_STATE_PROBATION_WAIT;
1296                 agent_unlock(agent);
1297                 break;
1298         case AGENT_STATE_PROBATION_WAIT:
1299                 /* Restart the probation timer. */
1300                 time(&agent->probation_start);
1301                 agent_unlock(agent);
1302                 break;
1303         case AGENT_STATE_READY_FOR_CALL:
1304                 /*
1305                  * Likely someone manually kicked us out of the holding bridge
1306                  * and we came right back in.
1307                  */
1308                 agent_unlock(agent);
1309                 break;
1310         default:
1311                 /* Unexpected agent state. */
1312                 ast_assert(0);
1313                 /* Fall through */
1314         case AGENT_STATE_CALL_PRESENT:
1315         case AGENT_STATE_CALL_WAIT_ACK:
1316                 agent->state = AGENT_STATE_READY_FOR_CALL;
1317                 agent->devstate = AST_DEVICE_NOT_INUSE;
1318                 agent_unlock(agent);
1319                 ast_debug(1, "Agent %s: Call abort recovery complete.\n", agent->username);
1320                 agent_devstate_changed(agent->username);
1321                 break;
1322         case AGENT_STATE_ON_CALL:
1323         case AGENT_STATE_CALL_WRAPUP:
1324                 wrapup_time = agent->cfg->wrapup_time;
1325                 if (ast_test_flag(agent, AGENT_FLAG_WRAPUP_TIME)) {
1326                         wrapup_time = agent->override_wrapup_time;
1327                 }
1328                 if (wrapup_time) {
1329                         agent->state = AGENT_STATE_CALL_WRAPUP;
1330                 } else {
1331                         agent->state = AGENT_STATE_READY_FOR_CALL;
1332                         agent->devstate = AST_DEVICE_NOT_INUSE;
1333                 }
1334                 agent_unlock(agent);
1335                 if (!wrapup_time) {
1336                         /* No wrapup time. */
1337                         ast_debug(1, "Agent %s: Ready for new call.\n", agent->username);
1338                         agent_devstate_changed(agent->username);
1339                 }
1340                 break;
1341         }
1342
1343         return 0;
1344 }
1345
1346 /*!
1347  * \internal
1348  * \brief ast_bridge agent_hold pull method.
1349  *
1350  * \param self Bridge to operate upon.
1351  * \param bridge_channel Bridge channel to pull.
1352  *
1353  * \details
1354  * Remove any channel hooks controlled by the bridge.  Release
1355  * any resources held by bridge_channel->bridge_pvt and release
1356  * bridge_channel->bridge_pvt.
1357  *
1358  * \note On entry, self is already locked.
1359  *
1360  * \return Nothing
1361  */
1362 static void bridge_agent_hold_pull(struct ast_bridge *self, struct ast_bridge_channel *bridge_channel)
1363 {
1364         ast_channel_remove_bridge_role(bridge_channel->chan, "holding_participant");
1365         ast_bridge_base_v_table.pull(self, bridge_channel);
1366 }
1367
1368 /*!
1369  * \brief The bridge is being dissolved.
1370  *
1371  * \param self Bridge to operate upon.
1372  *
1373  * \details
1374  * The bridge is being dissolved.  Remove any external
1375  * references to the bridge so it can be destroyed.
1376  *
1377  * \note On entry, self must NOT be locked.
1378  *
1379  * \return Nothing
1380  */
1381 static void bridge_agent_hold_dissolving(struct ast_bridge *self)
1382 {
1383         ao2_global_obj_release(agent_holding);
1384         ast_bridge_base_v_table.dissolving(self);
1385 }
1386
1387 static struct ast_bridge_methods bridge_agent_hold_v_table;
1388
1389 static struct ast_bridge *bridge_agent_hold_new(void)
1390 {
1391         struct ast_bridge *bridge;
1392
1393         bridge = bridge_alloc(sizeof(struct ast_bridge), &bridge_agent_hold_v_table);
1394         bridge = bridge_base_init(bridge, AST_BRIDGE_CAPABILITY_HOLDING,
1395                 AST_BRIDGE_FLAG_MERGE_INHIBIT_TO | AST_BRIDGE_FLAG_MERGE_INHIBIT_FROM
1396                         | AST_BRIDGE_FLAG_SWAP_INHIBIT_FROM | AST_BRIDGE_FLAG_TRANSFER_PROHIBITED,
1397                 "AgentPool", NULL, NULL);
1398         bridge = bridge_register(bridge);
1399         return bridge;
1400 }
1401
1402 static void bridge_init_agent_hold(void)
1403 {
1404         /* Setup bridge agent_hold subclass v_table. */
1405         bridge_agent_hold_v_table = ast_bridge_base_v_table;
1406         bridge_agent_hold_v_table.name = "agent_hold";
1407         bridge_agent_hold_v_table.dissolving = bridge_agent_hold_dissolving;
1408         bridge_agent_hold_v_table.push = bridge_agent_hold_push;
1409         bridge_agent_hold_v_table.pull = bridge_agent_hold_pull;
1410 }
1411
1412 static int bridge_agent_hold_deferred_create(void)
1413 {
1414         RAII_VAR(struct ast_bridge *, holding, ao2_global_obj_ref(agent_holding), ao2_cleanup);
1415
1416         if (!holding) {
1417                 ast_mutex_lock(&agent_holding_lock);
1418                 holding = ao2_global_obj_ref(agent_holding);
1419                 if (!holding) {
1420                         holding = bridge_agent_hold_new();
1421                         ao2_global_obj_replace_unref(agent_holding, holding);
1422                 }
1423                 ast_mutex_unlock(&agent_holding_lock);
1424                 if (!holding) {
1425                         ast_log(LOG_ERROR, "Could not create agent holding bridge.\n");
1426                         return -1;
1427                 }
1428         }
1429         return 0;
1430 }
1431
1432 static void send_agent_login(struct ast_channel *chan, const char *agent)
1433 {
1434         RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1435
1436         ast_assert(agent != NULL);
1437
1438         blob = ast_json_pack("{s: s}",
1439                 "agent", agent);
1440         if (!blob) {
1441                 return;
1442         }
1443
1444         ast_channel_publish_cached_blob(chan, ast_channel_agent_login_type(), blob);
1445 }
1446
1447 static void send_agent_logoff(struct ast_channel *chan, const char *agent, long logintime)
1448 {
1449         RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
1450
1451         ast_assert(agent != NULL);
1452
1453         blob = ast_json_pack("{s: s, s: i}",
1454                 "agent", agent,
1455                 "logintime", logintime);
1456         if (!blob) {
1457                 return;
1458         }
1459
1460         ast_channel_publish_cached_blob(chan, ast_channel_agent_logoff_type(), blob);
1461 }
1462
1463 /*!
1464  * \internal
1465  * \brief Logout the agent.
1466  * \since 12.0.0
1467  *
1468  * \param agent Which agent logging out.
1469  *
1470  * \note On entry agent is already locked.  On exit it is no longer locked.
1471  *
1472  * \return Nothing
1473  */
1474 static void agent_logout(struct agent_pvt *agent)
1475 {
1476         struct ast_channel *logged;
1477         struct ast_bridge *caller_bridge;
1478         long time_logged_in;
1479
1480         time_logged_in = time(NULL) - agent->login_start;
1481         logged = agent->logged;
1482         agent->logged = NULL;
1483         caller_bridge = agent->caller_bridge;
1484         agent->caller_bridge = NULL;
1485         agent->state = AGENT_STATE_LOGGED_OUT;
1486         agent->devstate = AST_DEVICE_UNAVAILABLE;
1487         ast_clear_flag(agent, AST_FLAGS_ALL);
1488         agent_unlock(agent);
1489         agent_devstate_changed(agent->username);
1490
1491         if (caller_bridge) {
1492                 ast_bridge_destroy(caller_bridge, 0);
1493         }
1494
1495         ast_channel_lock(logged);
1496         send_agent_logoff(logged, agent->username, time_logged_in);
1497         ast_channel_unlock(logged);
1498         ast_verb(2, "Agent '%s' logged out.  Logged in for %ld seconds.\n",
1499                 agent->username, time_logged_in);
1500         ast_channel_unref(logged);
1501 }
1502
1503 /*!
1504  * \internal
1505  * \brief Agent driver loop.
1506  * \since 12.0.0
1507  *
1508  * \param agent Which agent.
1509  * \param logged The logged in channel.
1510  *
1511  * \return Nothing
1512  */
1513 static void agent_run(struct agent_pvt *agent, struct ast_channel *logged)
1514 {
1515         struct ast_bridge_features features;
1516
1517         if (ast_bridge_features_init(&features)) {
1518                 ast_channel_hangupcause_set(logged, AST_CAUSE_NORMAL_CLEARING);
1519                 goto agent_run_cleanup;
1520         }
1521         for (;;) {
1522                 struct agents_cfg *cfgs;
1523                 struct agent_cfg *cfg_new;
1524                 struct agent_cfg *cfg_old;
1525                 struct ast_bridge *holding;
1526                 struct ast_bridge *caller_bridge;
1527
1528                 ast_channel_hangupcause_set(logged, AST_CAUSE_NORMAL_CLEARING);
1529
1530                 holding = ao2_global_obj_ref(agent_holding);
1531                 if (!holding) {
1532                         ast_debug(1, "Agent %s: Someone destroyed the agent holding bridge.\n",
1533                                 agent->username);
1534                         break;
1535                 }
1536
1537                 /*
1538                  * When the agent channel leaves the bridging system we usually
1539                  * want to put the agent back into the holding bridge for the
1540                  * next caller.
1541                  */
1542                 ast_bridge_join(holding, logged, NULL, &features, NULL,
1543                         AST_BRIDGE_JOIN_PASS_REFERENCE);
1544                 if (logged != agent->logged) {
1545                         /* This channel is no longer the logged in agent. */
1546                         break;
1547                 }
1548
1549                 if (agent->dead) {
1550                         /* The agent is no longer configured. */
1551                         break;
1552                 }
1553
1554                 /* Update the agent's config before rejoining the holding bridge. */
1555                 cfgs = ao2_global_obj_ref(cfg_handle);
1556                 if (!cfgs) {
1557                         /* There is no agent configuration.  All agents were destroyed. */
1558                         break;
1559                 }
1560                 cfg_new = ao2_find(cfgs->agents, agent->username, OBJ_KEY);
1561                 ao2_ref(cfgs, -1);
1562                 if (!cfg_new) {
1563                         /* The agent is no longer configured. */
1564                         break;
1565                 }
1566                 agent_lock(agent);
1567                 cfg_old = agent->cfg;
1568                 agent->cfg = cfg_new;
1569
1570                 agent->last_disconnect = ast_tvnow();
1571
1572                 /* Clear out any caller bridge before rejoining the holding bridge. */
1573                 caller_bridge = agent->caller_bridge;
1574                 agent->caller_bridge = NULL;
1575                 agent_unlock(agent);
1576                 ao2_ref(cfg_old, -1);
1577                 if (caller_bridge) {
1578                         ast_bridge_destroy(caller_bridge, 0);
1579                 }
1580
1581                 if (agent->state == AGENT_STATE_LOGGING_OUT
1582                         || agent->deferred_logoff
1583                         || ast_check_hangup_locked(logged)) {
1584                         /* The agent was requested to logout or hungup. */
1585                         break;
1586                 }
1587
1588                 /*
1589                  * It is safe to access agent->waiting_colp without a lock.  It
1590                  * is only setup on agent login and not changed.
1591                  */
1592                 ast_channel_update_connected_line(logged, &agent->waiting_colp, NULL);
1593         }
1594         ast_bridge_features_cleanup(&features);
1595
1596 agent_run_cleanup:
1597         agent_lock(agent);
1598         if (logged != agent->logged) {
1599                 /*
1600                  * We are no longer the agent channel because of local channel
1601                  * optimization.
1602                  */
1603                 agent_unlock(agent);
1604                 ast_debug(1, "Agent %s: Channel %s is no longer the agent.\n",
1605                         agent->username, ast_channel_name(logged));
1606                 return;
1607         }
1608         agent_logout(agent);
1609 }
1610
1611 static void agent_after_bridge_cb(struct ast_channel *chan, void *data)
1612 {
1613         struct agent_pvt *agent;
1614
1615         agent = ao2_find(agents, chan, 0);
1616         if (!agent) {
1617                 return;
1618         }
1619
1620         ast_debug(1, "Agent %s: New agent channel %s.\n",
1621                 agent->username, ast_channel_name(chan));
1622         agent_run(agent, chan);
1623         ao2_ref(agent, -1);
1624 }
1625
1626 static void agent_after_bridge_cb_failed(enum ast_bridge_after_cb_reason reason, void *data)
1627 {
1628         struct ast_channel *chan = data;
1629         struct agent_pvt *agent;
1630
1631         agent = ao2_find(agents, chan, 0);
1632         if (!agent) {
1633                 return;
1634         }
1635         ast_log(LOG_WARNING, "Agent %s: Forced logout.  Lost control of %s because: %s\n",
1636                 agent->username, ast_channel_name(chan),
1637                 ast_bridge_after_cb_reason_string(reason));
1638         agent_lock(agent);
1639         agent_logout(agent);
1640         ao2_ref(agent, -1);
1641 }
1642
1643 /*!
1644  * \internal
1645  * \brief Get the lock on the agent bridge_channel and return it.
1646  * \since 12.0.0
1647  *
1648  * \param agent Whose bridge_channel to get.
1649  *
1650  * \retval bridge_channel on success (Reffed and locked).
1651  * \retval NULL on error.
1652  */
1653 static struct ast_bridge_channel *agent_bridge_channel_get_lock(struct agent_pvt *agent)
1654 {
1655         struct ast_channel *logged;
1656         struct ast_bridge_channel *bc;
1657
1658         for (;;) {
1659                 agent_lock(agent);
1660                 logged = agent->logged;
1661                 if (!logged) {
1662                         agent_unlock(agent);
1663                         return NULL;
1664                 }
1665                 ast_channel_ref(logged);
1666                 agent_unlock(agent);
1667
1668                 ast_channel_lock(logged);
1669                 bc = ast_channel_get_bridge_channel(logged);
1670                 ast_channel_unlock(logged);
1671                 ast_channel_unref(logged);
1672                 if (!bc) {
1673                         if (agent->logged != logged) {
1674                                 continue;
1675                         }
1676                         return NULL;
1677                 }
1678
1679                 ast_bridge_channel_lock(bc);
1680                 if (bc->chan != logged || agent->logged != logged) {
1681                         ast_bridge_channel_unlock(bc);
1682                         ao2_ref(bc, -1);
1683                         continue;
1684                 }
1685                 return bc;
1686         }
1687 }
1688
1689 static void caller_abort_agent(struct agent_pvt *agent)
1690 {
1691         struct ast_bridge_channel *logged;
1692
1693         logged = agent_bridge_channel_get_lock(agent);
1694         if (!logged) {
1695                 struct ast_bridge *caller_bridge;
1696
1697                 ast_debug(1, "Agent '%s' no longer logged in.\n", agent->username);
1698
1699                 agent_lock(agent);
1700                 caller_bridge = agent->caller_bridge;
1701                 agent->caller_bridge = NULL;
1702                 agent_unlock(agent);
1703                 if (caller_bridge) {
1704                         ast_bridge_destroy(caller_bridge, 0);
1705                 }
1706                 return;
1707         }
1708
1709         /* Kick the agent out of the holding bridge to reset it. */
1710         ast_bridge_channel_leave_bridge_nolock(logged, BRIDGE_CHANNEL_STATE_END,
1711                 AST_CAUSE_NORMAL_CLEARING);
1712         ast_bridge_channel_unlock(logged);
1713 }
1714
1715 static int caller_safety_timeout(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
1716 {
1717         struct agent_pvt *agent = hook_pvt;
1718
1719         if (agent->state == AGENT_STATE_CALL_PRESENT) {
1720                 ast_log(LOG_WARNING, "Agent '%s' process did not respond.  Safety timeout.\n",
1721                         agent->username);
1722                 pbx_builtin_setvar_helper(bridge_channel->chan, "AGENT_STATUS", "ERROR");
1723
1724                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END, 0);
1725                 caller_abort_agent(agent);
1726         }
1727
1728         return -1;
1729 }
1730
1731 static void agent_alert(struct ast_bridge_channel *bridge_channel, const void *payload, size_t payload_size)
1732 {
1733         const char *agent_id = payload;
1734         const char *playfile;
1735         const char *dtmf_accept;
1736         struct agent_pvt *agent;
1737         int digit;
1738         char dtmf[2];
1739
1740         agent = ao2_find(agents, agent_id, OBJ_KEY);
1741         if (!agent) {
1742                 ast_debug(1, "Agent '%s' does not exist.  Where did it go?\n", agent_id);
1743                 return;
1744         }
1745
1746         /* Change holding bridge participant role's idle mode to silence */
1747         ast_bridge_channel_lock_bridge(bridge_channel);
1748         ast_bridge_channel_clear_roles(bridge_channel);
1749         ast_channel_set_bridge_role_option(bridge_channel->chan, "holding_participant", "idle_mode", "silence");
1750         ast_bridge_channel_establish_roles(bridge_channel);
1751         ast_bridge_unlock(bridge_channel->bridge);
1752
1753         agent_lock(agent);
1754         playfile = ast_strdupa(agent->cfg->beep_sound);
1755
1756         /* Determine which DTMF digits interrupt the alerting signal. */
1757         if (ast_test_flag(agent, AGENT_FLAG_ACK_CALL)
1758                 ? agent->override_ack_call : agent->cfg->ack_call) {
1759                 dtmf_accept = ast_test_flag(agent, AGENT_FLAG_DTMF_ACCEPT)
1760                         ? agent->override_dtmf_accept : agent->cfg->dtmf_accept;
1761
1762                 /* Only the first digit of the ack will stop playback. */
1763                 dtmf[0] = *dtmf_accept;
1764                 dtmf[1] = '\0';
1765                 dtmf_accept = dtmf;
1766         } else {
1767                 dtmf_accept = NULL;
1768         }
1769         agent_unlock(agent);
1770
1771         /* Alert the agent. */
1772         digit = ast_stream_and_wait(bridge_channel->chan, playfile,
1773                 ast_strlen_zero(dtmf_accept) ? AST_DIGIT_ANY : dtmf_accept);
1774         ast_stopstream(bridge_channel->chan);
1775
1776         agent_lock(agent);
1777         switch (agent->state) {
1778         case AGENT_STATE_CALL_PRESENT:
1779                 if (!ast_strlen_zero(dtmf_accept)) {
1780                         agent->state = AGENT_STATE_CALL_WAIT_ACK;
1781                         agent->ack_time = ast_tvnow();
1782
1783                         if (0 < digit) {
1784                                 /* Playback was interrupted by a digit. */
1785                                 agent_unlock(agent);
1786                                 ao2_ref(agent, -1);
1787                                 ast_bridge_channel_feature_digit(bridge_channel, digit);
1788                                 return;
1789                         }
1790                         break;
1791                 }
1792
1793                 /* Connect to caller now. */
1794                 ast_debug(1, "Agent %s: Immediately connecting to call.\n", agent->username);
1795                 agent_connect_caller(bridge_channel, agent);/* Will unlock agent. */
1796                 ao2_ref(agent, -1);
1797                 return;
1798         default:
1799                 break;
1800         }
1801         agent_unlock(agent);
1802         ao2_ref(agent, -1);
1803 }
1804
1805 static int send_alert_to_agent(struct ast_bridge_channel *bridge_channel, const char *agent_id)
1806 {
1807         return ast_bridge_channel_queue_callback(bridge_channel,
1808                 AST_BRIDGE_CHANNEL_CB_OPTION_MEDIA, agent_alert, agent_id, strlen(agent_id) + 1);
1809 }
1810
1811 static int send_colp_to_agent(struct ast_bridge_channel *bridge_channel, struct ast_party_connected_line *connected)
1812 {
1813         struct ast_set_party_connected_line update = {
1814                 .id.name = 1,
1815                 .id.number = 1,
1816                 .id.subaddress = 1,
1817         };
1818         unsigned char data[1024];       /* This should be large enough */
1819         size_t datalen;
1820
1821         datalen = ast_connected_line_build_data(data, sizeof(data), connected, &update);
1822         if (datalen == (size_t) -1) {
1823                 return 0;
1824         }
1825
1826         return ast_bridge_channel_queue_control_data(bridge_channel,
1827                 AST_CONTROL_CONNECTED_LINE, data, datalen);
1828 }
1829
1830 /*!
1831  * \internal
1832  * \brief Caller joined the bridge event callback.
1833  *
1834  * \param bridge_channel Channel executing the feature
1835  * \param hook_pvt Private data passed in when the hook was created
1836  *
1837  * \retval 0 Keep the callback hook.
1838  * \retval -1 Remove the callback hook.
1839  */
1840 static int caller_joined_bridge(struct ast_bridge_channel *bridge_channel, void *hook_pvt)
1841 {
1842         struct agent_pvt *agent = hook_pvt;
1843         struct ast_bridge_channel *logged;
1844         int res;
1845
1846         logged = agent_bridge_channel_get_lock(agent);
1847         if (!logged) {
1848                 ast_verb(3, "Agent '%s' not logged in.\n", agent->username);
1849                 pbx_builtin_setvar_helper(bridge_channel->chan, "AGENT_STATUS", "NOT_LOGGED_IN");
1850
1851                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END, 0);
1852                 caller_abort_agent(agent);
1853                 return -1;
1854         }
1855
1856         res = send_alert_to_agent(logged, agent->username);
1857         ast_bridge_channel_unlock(logged);
1858         ao2_ref(logged, -1);
1859         if (res) {
1860                 ast_verb(3, "Agent '%s': Failed to alert the agent.\n", agent->username);
1861                 pbx_builtin_setvar_helper(bridge_channel->chan, "AGENT_STATUS", "ERROR");
1862
1863                 ast_bridge_channel_leave_bridge(bridge_channel, BRIDGE_CHANNEL_STATE_END, 0);
1864                 caller_abort_agent(agent);
1865                 return -1;
1866         }
1867
1868         pbx_builtin_setvar_helper(bridge_channel->chan, "AGENT_STATUS", "NOT_CONNECTED");
1869         ast_indicate(bridge_channel->chan, AST_CONTROL_RINGING);
1870         return -1;
1871 }
1872
1873 /*!
1874  * \brief Dialplan AgentRequest application to locate an agent to talk with.
1875  *
1876  * \param chan Channel wanting to talk with an agent.
1877  * \param data Application parameters
1878  *
1879  * \retval 0 To continue in dialplan.
1880  * \retval -1 To hangup.
1881  */
1882 static int agent_request_exec(struct ast_channel *chan, const char *data)
1883 {
1884         struct ast_bridge *caller_bridge;
1885         struct ast_bridge_channel *logged;
1886         char *parse;
1887         int res;
1888         struct ast_bridge_features caller_features;
1889         struct ast_party_connected_line connected;
1890         AST_DECLARE_APP_ARGS(args,
1891                 AST_APP_ARG(agent_id);
1892                 AST_APP_ARG(other);             /* Any remaining unused arguments */
1893         );
1894
1895         RAII_VAR(struct agent_pvt *, agent, NULL, ao2_cleanup);
1896
1897         if (bridge_agent_hold_deferred_create()) {
1898                 return -1;
1899         }
1900
1901         parse = ast_strdupa(data);
1902         AST_STANDARD_APP_ARGS(args, parse);
1903
1904         if (ast_strlen_zero(args.agent_id)) {
1905                 ast_log(LOG_WARNING, "AgentRequest requires an AgentId\n");
1906                 return -1;
1907         }
1908
1909         /* Find the agent. */
1910         agent = ao2_find(agents, args.agent_id, OBJ_KEY);
1911         if (!agent) {
1912                 ast_verb(3, "Agent '%s' does not exist.\n", args.agent_id);
1913                 pbx_builtin_setvar_helper(chan, "AGENT_STATUS", "INVALID");
1914                 return 0;
1915         }
1916
1917         if (ast_bridge_features_init(&caller_features)) {
1918                 return -1;
1919         }
1920
1921         /* Add safety timeout hook. */
1922         ao2_ref(agent, +1);
1923         if (ast_bridge_interval_hook(&caller_features, 0, CALLER_SAFETY_TIMEOUT_TIME,
1924                 caller_safety_timeout, agent, __ao2_cleanup, AST_BRIDGE_HOOK_REMOVE_ON_PULL)) {
1925                 ao2_ref(agent, -1);
1926                 ast_bridge_features_cleanup(&caller_features);
1927                 return -1;
1928         }
1929
1930         /* Setup the alert agent on caller joining the bridge hook. */
1931         ao2_ref(agent, +1);
1932         if (ast_bridge_join_hook(&caller_features, caller_joined_bridge, agent,
1933                 __ao2_cleanup, 0)) {
1934                 ao2_ref(agent, -1);
1935                 ast_bridge_features_cleanup(&caller_features);
1936                 return -1;
1937         }
1938
1939         caller_bridge = ast_bridge_basic_new();
1940         if (!caller_bridge) {
1941                 ast_bridge_features_cleanup(&caller_features);
1942                 return -1;
1943         }
1944
1945         agent_lock(agent);
1946         switch (agent->state) {
1947         case AGENT_STATE_LOGGED_OUT:
1948         case AGENT_STATE_LOGGING_OUT:
1949                 agent_unlock(agent);
1950                 ast_bridge_destroy(caller_bridge, 0);
1951                 ast_bridge_features_cleanup(&caller_features);
1952                 ast_verb(3, "Agent '%s' not logged in.\n", agent->username);
1953                 pbx_builtin_setvar_helper(chan, "AGENT_STATUS", "NOT_LOGGED_IN");
1954                 return 0;
1955         case AGENT_STATE_READY_FOR_CALL:
1956                 ao2_ref(caller_bridge, +1);
1957                 agent->caller_bridge = caller_bridge;
1958                 agent->state = AGENT_STATE_CALL_PRESENT;
1959                 agent->devstate = AST_DEVICE_INUSE;
1960                 break;
1961         default:
1962                 agent_unlock(agent);
1963                 ast_bridge_destroy(caller_bridge, 0);
1964                 ast_bridge_features_cleanup(&caller_features);
1965                 ast_verb(3, "Agent '%s' is busy.\n", agent->username);
1966                 pbx_builtin_setvar_helper(chan, "AGENT_STATUS", "BUSY");
1967                 return 0;
1968         }
1969         agent_unlock(agent);
1970         agent_devstate_changed(agent->username);
1971
1972         /* Get COLP for agent. */
1973         ast_party_connected_line_init(&connected);
1974         ast_channel_lock(chan);
1975         ast_connected_line_copy_from_caller(&connected, ast_channel_caller(chan));
1976         ast_channel_unlock(chan);
1977
1978         logged = agent_bridge_channel_get_lock(agent);
1979         if (!logged) {
1980                 ast_party_connected_line_free(&connected);
1981                 caller_abort_agent(agent);
1982                 ast_bridge_destroy(caller_bridge, 0);
1983                 ast_bridge_features_cleanup(&caller_features);
1984                 ast_verb(3, "Agent '%s' not logged in.\n", agent->username);
1985                 pbx_builtin_setvar_helper(chan, "AGENT_STATUS", "NOT_LOGGED_IN");
1986                 return 0;
1987         }
1988
1989         send_colp_to_agent(logged, &connected);
1990         ast_bridge_channel_unlock(logged);
1991         ao2_ref(logged, -1);
1992         ast_party_connected_line_free(&connected);
1993
1994         if (ast_bridge_join(caller_bridge, chan, NULL, &caller_features, NULL,
1995                 AST_BRIDGE_JOIN_PASS_REFERENCE)) {
1996                 caller_abort_agent(agent);
1997                 ast_verb(3, "Agent '%s': Caller %s failed to join the bridge.\n",
1998                         agent->username, ast_channel_name(chan));
1999                 pbx_builtin_setvar_helper(chan, "AGENT_STATUS", "ERROR");
2000         }
2001         ast_bridge_features_cleanup(&caller_features);
2002
2003         /* Determine if we need to continue in the dialplan after the bridge. */
2004         ast_channel_lock(chan);
2005         if (ast_channel_softhangup_internal_flag(chan) & AST_SOFTHANGUP_ASYNCGOTO) {
2006                 /*
2007                  * The bridge was broken for a hangup that isn't real.
2008                  * Don't run the h extension, because the channel isn't
2009                  * really hung up.  This should really only happen with
2010                  * AST_SOFTHANGUP_ASYNCGOTO.
2011                  */
2012                 res = 0;
2013         } else {
2014                 res = ast_check_hangup(chan)
2015                         || ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)
2016                         || ast_strlen_zero(pbx_builtin_getvar_helper(chan, "AGENT_STATUS"));
2017         }
2018         ast_channel_unlock(chan);
2019
2020         return res ? -1 : 0;
2021 }
2022
2023 /*!
2024  * \internal
2025  * \brief Get agent config values from the login channel.
2026  * \since 12.0.0
2027  *
2028  * \param agent What to setup channel config values on.
2029  * \param chan Channel logging in as an agent.
2030  *
2031  * \return Nothing
2032  */
2033 static void agent_login_channel_config(struct agent_pvt *agent, struct ast_channel *chan)
2034 {
2035         struct ast_flags opts = { 0 };
2036         struct ast_party_connected_line connected;
2037         unsigned int override_ack_call = 0;
2038         unsigned int override_auto_logoff = 0;
2039         unsigned int override_wrapup_time = 0;
2040         const char *override_dtmf_accept = NULL;
2041         const char *var;
2042
2043         ast_party_connected_line_init(&connected);
2044
2045         /* Get config values from channel. */
2046         ast_channel_lock(chan);
2047         ast_party_connected_line_copy(&connected, ast_channel_connected(chan));
2048
2049         var = pbx_builtin_getvar_helper(chan, "AGENTACKCALL");
2050         if (!ast_strlen_zero(var)) {
2051                 override_ack_call = ast_true(var) ? 1 : 0;
2052                 ast_set_flag(&opts, AGENT_FLAG_ACK_CALL);
2053         }
2054
2055         var = pbx_builtin_getvar_helper(chan, "AGENTACCEPTDTMF");
2056         if (!ast_strlen_zero(var)) {
2057                 override_dtmf_accept = ast_strdupa(var);
2058                 ast_set_flag(&opts, AGENT_FLAG_DTMF_ACCEPT);
2059         }
2060
2061         var = pbx_builtin_getvar_helper(chan, "AGENTAUTOLOGOFF");
2062         if (!ast_strlen_zero(var)) {
2063                 if (sscanf(var, "%u", &override_auto_logoff) == 1) {
2064                         ast_set_flag(&opts, AGENT_FLAG_AUTO_LOGOFF);
2065                 }
2066         }
2067
2068         var = pbx_builtin_getvar_helper(chan, "AGENTWRAPUPTIME");
2069         if (!ast_strlen_zero(var)) {
2070                 if (sscanf(var, "%u", &override_wrapup_time) == 1) {
2071                         ast_set_flag(&opts, AGENT_FLAG_WRAPUP_TIME);
2072                 }
2073         }
2074         ast_channel_unlock(chan);
2075
2076         /* Set config values on agent. */
2077         agent_lock(agent);
2078         ast_party_connected_line_free(&agent->waiting_colp);
2079         agent->waiting_colp = connected;
2080
2081         ast_string_field_set(agent, override_dtmf_accept, override_dtmf_accept);
2082         ast_copy_flags(agent, &opts, AST_FLAGS_ALL);
2083         agent->override_auto_logoff = override_auto_logoff;
2084         agent->override_wrapup_time = override_wrapup_time;
2085         agent->override_ack_call = override_ack_call;
2086         agent_unlock(agent);
2087 }
2088
2089 enum AGENT_LOGIN_OPT_FLAGS {
2090         OPT_SILENT = (1 << 0),
2091 };
2092 AST_APP_OPTIONS(agent_login_opts, BEGIN_OPTIONS
2093         AST_APP_OPTION('s', OPT_SILENT),
2094 END_OPTIONS);
2095
2096 /*!
2097  * \brief Dialplan AgentLogin application to log in an agent.
2098  *
2099  * \param chan Channel attempting to login as an agent.
2100  * \param data Application parameters
2101  *
2102  * \retval 0 To continue in dialplan.
2103  * \retval -1 To hangup.
2104  */
2105 static int agent_login_exec(struct ast_channel *chan, const char *data)
2106 {
2107         char *parse;
2108         struct ast_flags opts;
2109         AST_DECLARE_APP_ARGS(args,
2110                 AST_APP_ARG(agent_id);
2111                 AST_APP_ARG(options);
2112                 AST_APP_ARG(other);             /* Any remaining unused arguments */
2113         );
2114
2115         RAII_VAR(struct agent_pvt *, agent, NULL, ao2_cleanup);
2116
2117         if (bridge_agent_hold_deferred_create()) {
2118                 return -1;
2119         }
2120
2121         if (ast_channel_state(chan) != AST_STATE_UP && ast_answer(chan)) {
2122                 return -1;
2123         }
2124
2125         parse = ast_strdupa(data);
2126         AST_STANDARD_APP_ARGS(args, parse);
2127
2128         if (ast_strlen_zero(args.agent_id)) {
2129                 ast_log(LOG_WARNING, "AgentLogin requires an AgentId\n");
2130                 return -1;
2131         }
2132
2133         if (ast_app_parse_options(agent_login_opts, &opts, NULL, args.options)) {
2134                 /* General invalid option syntax. */
2135                 return -1;
2136         }
2137
2138         /* Find the agent. */
2139         agent = ao2_find(agents, args.agent_id, OBJ_KEY);
2140         if (!agent) {
2141                 ast_verb(3, "Agent '%s' does not exist.\n", args.agent_id);
2142                 pbx_builtin_setvar_helper(chan, "AGENT_STATUS", "INVALID");
2143                 return 0;
2144         }
2145
2146         /* Has someone already logged in as this agent already? */
2147         agent_lock(agent);
2148         if (agent->logged) {
2149                 agent_unlock(agent);
2150                 ast_verb(3, "Agent '%s' already logged in.\n", agent->username);
2151                 pbx_builtin_setvar_helper(chan, "AGENT_STATUS", "ALREADY_LOGGED_IN");
2152                 return 0;
2153         }
2154         agent->logged = ast_channel_ref(chan);
2155         agent->last_disconnect = ast_tvnow();
2156         time(&agent->login_start);
2157         agent->deferred_logoff = 0;
2158         agent_unlock(agent);
2159
2160         agent_login_channel_config(agent, chan);
2161
2162         if (!ast_test_flag(&opts, OPT_SILENT)) {
2163                 ast_stream_and_wait(chan, "agent-loginok", AST_DIGIT_NONE);
2164         }
2165
2166         ast_verb(2, "Agent '%s' logged in (format %s/%s)\n", agent->username,
2167                 ast_format_get_name(ast_channel_readformat(chan)),
2168                 ast_format_get_name(ast_channel_writeformat(chan)));
2169         ast_channel_lock(chan);
2170         send_agent_login(chan, agent->username);
2171         ast_channel_unlock(chan);
2172
2173         agent_run(agent, chan);
2174         return -1;
2175 }
2176
2177 static int agent_function_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
2178 {
2179         char *parse;
2180         struct agent_pvt *agent;
2181         struct ast_channel *logged;
2182         AST_DECLARE_APP_ARGS(args,
2183                 AST_APP_ARG(agentid);
2184                 AST_APP_ARG(item);
2185         );
2186
2187         buf[0] = '\0';
2188
2189         parse = ast_strdupa(data ?: "");
2190         AST_NONSTANDARD_APP_ARGS(args, parse, ':');
2191
2192         if (ast_strlen_zero(args.agentid)) {
2193                 ast_log(LOG_WARNING, "The AGENT function requires an argument - agentid!\n");
2194                 return -1;
2195         }
2196         if (!args.item) {
2197                 args.item = "status";
2198         }
2199
2200         agent = ao2_find(agents, args.agentid, OBJ_KEY);
2201         if (!agent) {
2202                 ast_log(LOG_WARNING, "Agent '%s' not found!\n", args.agentid);
2203                 return -1;
2204         }
2205
2206         agent_lock(agent);
2207         if (!strcasecmp(args.item, "status")) {
2208                 const char *status;
2209
2210                 if (agent->logged) {
2211                         status = "LOGGEDIN";
2212                 } else {
2213                         status = "LOGGEDOUT";
2214                 }
2215                 ast_copy_string(buf, status, len);
2216         } else if (!strcasecmp(args.item, "name")) {
2217                 ast_copy_string(buf, agent->cfg->full_name, len);
2218         } else if (!strcasecmp(args.item, "mohclass")) {
2219                 ast_copy_string(buf, agent->cfg->moh, len);
2220         } else if (!strcasecmp(args.item, "channel")) {
2221                 logged = agent_lock_logged(agent);
2222                 if (logged) {
2223                         char *pos;
2224
2225                         ast_copy_string(buf, ast_channel_name(logged), len);
2226                         ast_channel_unlock(logged);
2227                         ast_channel_unref(logged);
2228
2229                         pos = strrchr(buf, '-');
2230                         if (pos) {
2231                                 *pos = '\0';
2232                         }
2233                 }
2234         } else if (!strcasecmp(args.item, "fullchannel")) {
2235                 logged = agent_lock_logged(agent);
2236                 if (logged) {
2237                         ast_copy_string(buf, ast_channel_name(logged), len);
2238                         ast_channel_unlock(logged);
2239                         ast_channel_unref(logged);
2240                 }
2241         }
2242         agent_unlock(agent);
2243         ao2_ref(agent, -1);
2244
2245         return 0;
2246 }
2247
2248 static struct ast_custom_function agent_function = {
2249         .name = "AGENT",
2250         .read = agent_function_read,
2251 };
2252
2253 struct agent_complete {
2254         /*! Nth match to return. */
2255         int state;
2256         /*! Which match currently on. */
2257         int which;
2258 };
2259
2260 static int complete_agent_search(void *obj, void *arg, void *data, int flags)
2261 {
2262         struct agent_complete *search = data;
2263
2264         if (++search->which > search->state) {
2265                 return CMP_MATCH;
2266         }
2267         return 0;
2268 }
2269
2270 static char *complete_agent(const char *word, int state)
2271 {
2272         char *ret;
2273         struct agent_pvt *agent;
2274         struct agent_complete search = {
2275                 .state = state,
2276         };
2277
2278         agent = ao2_callback_data(agents, ast_strlen_zero(word) ? 0 : OBJ_PARTIAL_KEY,
2279                 complete_agent_search, (char *) word, &search);
2280         if (!agent) {
2281                 return NULL;
2282         }
2283         ret = ast_strdup(agent->username);
2284         ao2_ref(agent, -1);
2285         return ret;
2286 }
2287
2288 static int complete_agent_logoff_search(void *obj, void *arg, void *data, int flags)
2289 {
2290         struct agent_pvt *agent = obj;
2291         struct agent_complete *search = data;
2292
2293         if (!agent->logged) {
2294                 return 0;
2295         }
2296         if (++search->which > search->state) {
2297                 return CMP_MATCH;
2298         }
2299         return 0;
2300 }
2301
2302 static char *complete_agent_logoff(const char *word, int state)
2303 {
2304         char *ret;
2305         struct agent_pvt *agent;
2306         struct agent_complete search = {
2307                 .state = state,
2308         };
2309
2310         agent = ao2_callback_data(agents, ast_strlen_zero(word) ? 0 : OBJ_PARTIAL_KEY,
2311                 complete_agent_logoff_search, (char *) word, &search);
2312         if (!agent) {
2313                 return NULL;
2314         }
2315         ret = ast_strdup(agent->username);
2316         ao2_ref(agent, -1);
2317         return ret;
2318 }
2319
2320 static void agent_show_requested(struct ast_cli_args *a, int online_only)
2321 {
2322 #define FORMAT_HDR "%-8s %-20s %-11s %-30s %s\n"
2323 #define FORMAT_ROW "%-8s %-20s %-11s %-30s %s\n"
2324
2325         struct ao2_iterator iter;
2326         struct agent_pvt *agent;
2327         struct ast_str *out = ast_str_alloca(512);
2328         unsigned int agents_total = 0;
2329         unsigned int agents_logged_in = 0;
2330         unsigned int agents_talking = 0;
2331
2332         ast_cli(a->fd, FORMAT_HDR, "Agent-ID", "Name", "State", "Channel", "Talking with");
2333         iter = ao2_iterator_init(agents, 0);
2334         for (; (agent = ao2_iterator_next(&iter)); ao2_ref(agent, -1)) {
2335                 struct ast_channel *logged;
2336
2337                 ++agents_total;
2338
2339                 agent_lock(agent);
2340                 logged = agent_lock_logged(agent);
2341                 if (logged) {
2342                         const char *talking_with;
2343
2344                         ++agents_logged_in;
2345
2346                         talking_with = pbx_builtin_getvar_helper(logged, "BRIDGEPEER");
2347                         if (!ast_strlen_zero(talking_with)) {
2348                                 ++agents_talking;
2349                         } else {
2350                                 talking_with = "";
2351                         }
2352                         ast_str_set(&out, 0, FORMAT_ROW, agent->username, agent->cfg->full_name,
2353                                 ast_devstate_str(agent->devstate), ast_channel_name(logged), talking_with);
2354                         ast_channel_unlock(logged);
2355                         ast_channel_unref(logged);
2356                 } else {
2357                         ast_str_set(&out, 0, FORMAT_ROW, agent->username, agent->cfg->full_name,
2358                                 ast_devstate_str(agent->devstate), "", "");
2359                 }
2360                 agent_unlock(agent);
2361
2362                 if (!online_only || logged) {
2363                         ast_cli(a->fd, "%s", ast_str_buffer(out));
2364                 }
2365         }
2366         ao2_iterator_destroy(&iter);
2367
2368         ast_cli(a->fd, "\nDefined agents: %u, Logged in: %u, Talking: %u\n",
2369                 agents_total, agents_logged_in, agents_talking);
2370
2371 #undef FORMAT_HDR
2372 #undef FORMAT_ROW
2373 }
2374
2375 static char *agent_handle_show_online(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2376 {
2377         switch (cmd) {
2378         case CLI_INIT:
2379                 e->command = "agent show online";
2380                 e->usage =
2381                         "Usage: agent show online\n"
2382                         "       Provides summary information for logged in agents.\n";
2383                 return NULL;
2384         case CLI_GENERATE:
2385                 return NULL;
2386         }
2387
2388         if (a->argc != 3) {
2389                 return CLI_SHOWUSAGE;
2390         }
2391
2392         agent_show_requested(a, 1);
2393
2394         return CLI_SUCCESS;
2395 }
2396
2397 static char *agent_handle_show_all(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2398 {
2399         switch (cmd) {
2400         case CLI_INIT:
2401                 e->command = "agent show all";
2402                 e->usage =
2403                         "Usage: agent show all\n"
2404                         "       Provides summary information for all agents.\n";
2405                 return NULL;
2406         case CLI_GENERATE:
2407                 return NULL;
2408         }
2409
2410         if (a->argc != 3) {
2411                 return CLI_SHOWUSAGE;
2412         }
2413
2414         agent_show_requested(a, 0);
2415
2416         return CLI_SUCCESS;
2417 }
2418
2419 static char *agent_handle_show_specific(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2420 {
2421         struct agent_pvt *agent;
2422         struct ast_channel *logged;
2423         struct ast_str *out = ast_str_alloca(4096);
2424
2425         switch (cmd) {
2426         case CLI_INIT:
2427                 e->command = "agent show";
2428                 e->usage =
2429                         "Usage: agent show <agent-id>\n"
2430                         "       Show information about the <agent-id> agent\n";
2431                 return NULL;
2432         case CLI_GENERATE:
2433                 if (a->pos == 2) {
2434                         return complete_agent(a->word, a->n);
2435                 }
2436                 return NULL;
2437         }
2438
2439         if (a->argc != 3) {
2440                 return CLI_SHOWUSAGE;
2441         }
2442
2443         agent = ao2_find(agents, a->argv[2], OBJ_KEY);
2444         if (!agent) {
2445                 ast_cli(a->fd, "Agent '%s' not found\n", a->argv[2]);
2446                 return CLI_SUCCESS;
2447         }
2448
2449         agent_lock(agent);
2450         logged = agent_lock_logged(agent);
2451         ast_str_set(&out, 0, "Id: %s\n", agent->username);
2452         ast_str_append(&out, 0, "Name: %s\n", agent->cfg->full_name);
2453         ast_str_append(&out, 0, "Beep: %s\n", agent->cfg->beep_sound);
2454         ast_str_append(&out, 0, "MOH: %s\n", agent->cfg->moh);
2455         ast_str_append(&out, 0, "RecordCalls: %s\n", AST_CLI_YESNO(agent->cfg->record_agent_calls));
2456         ast_str_append(&out, 0, "State: %s\n", ast_devstate_str(agent->devstate));
2457         if (logged) {
2458                 const char *talking_with;
2459
2460                 ast_str_append(&out, 0, "LoggedInChannel: %s\n", ast_channel_name(logged));
2461                 ast_str_append(&out, 0, "LoggedInTime: %ld\n", (long) agent->login_start);
2462                 talking_with = pbx_builtin_getvar_helper(logged, "BRIDGEPEER");
2463                 if (!ast_strlen_zero(talking_with)) {
2464                         ast_str_append(&out, 0, "TalkingWith: %s\n", talking_with);
2465                         ast_str_append(&out, 0, "CallStarted: %ld\n", (long) agent->call_start);
2466                 }
2467                 ast_channel_unlock(logged);
2468                 ast_channel_unref(logged);
2469         }
2470         agent_unlock(agent);
2471         ao2_ref(agent, -1);
2472
2473         ast_cli(a->fd, "%s", ast_str_buffer(out));
2474
2475         return CLI_SUCCESS;
2476 }
2477
2478 static char *agent_handle_logoff_cmd(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
2479 {
2480         switch (cmd) {
2481         case CLI_INIT:
2482                 e->command = "agent logoff";
2483                 e->usage =
2484                         "Usage: agent logoff <agent-id> [soft]\n"
2485                         "       Sets an agent as no longer logged in.\n"
2486                         "       If 'soft' is specified, do not hangup existing calls.\n";
2487                 return NULL;
2488         case CLI_GENERATE:
2489                 if (a->pos == 2) {
2490                         return complete_agent_logoff(a->word, a->n);
2491                 } else if (a->pos == 3 && a->n == 0
2492                         && (ast_strlen_zero(a->word)
2493                                 || !strncasecmp("soft", a->word, strlen(a->word)))) {
2494                         return ast_strdup("soft");
2495                 }
2496                 return NULL;
2497         }
2498
2499         if (a->argc < 3 || 4 < a->argc) {
2500                 return CLI_SHOWUSAGE;
2501         }
2502         if (a->argc == 4 && strcasecmp(a->argv[3], "soft")) {
2503                 return CLI_SHOWUSAGE;
2504         }
2505
2506         if (!agent_logoff_request(a->argv[2], a->argc == 4)) {
2507                 ast_cli(a->fd, "Logging out %s\n", a->argv[2]);
2508         }
2509
2510         return CLI_SUCCESS;
2511 }
2512
2513 static struct ast_cli_entry cli_agents[] = {
2514         AST_CLI_DEFINE(agent_handle_show_online, "Show status of online agents"),
2515         AST_CLI_DEFINE(agent_handle_show_all, "Show status of all agents"),
2516         AST_CLI_DEFINE(agent_handle_show_specific, "Show information about an agent"),
2517         AST_CLI_DEFINE(agent_handle_logoff_cmd, "Sets an agent offline"),
2518 };
2519
2520 static int action_agents(struct mansession *s, const struct message *m)
2521 {
2522         const char *id = astman_get_header(m, "ActionID");
2523         char id_text[AST_MAX_BUF];
2524         struct ao2_iterator iter;
2525         struct agent_pvt *agent;
2526         struct ast_str *out = ast_str_alloca(4096);
2527         int num_agents = 0;
2528
2529         if (!ast_strlen_zero(id)) {
2530                 snprintf(id_text, sizeof(id_text), "ActionID: %s\r\n", id);
2531         } else {
2532                 id_text[0] = '\0';
2533         }
2534         astman_send_listack(s, m, "Agents will follow", "start");
2535
2536         iter = ao2_iterator_init(agents, 0);
2537         for (; (agent = ao2_iterator_next(&iter)); ao2_ref(agent, -1)) {
2538                 struct ast_channel *logged;
2539
2540                 agent_lock(agent);
2541                 logged = agent_lock_logged(agent);
2542
2543                 /*
2544                  * Status Values:
2545                  * AGENT_LOGGEDOFF - Agent isn't logged in
2546                  * AGENT_IDLE      - Agent is logged in, and waiting for call
2547                  * AGENT_ONCALL    - Agent is logged in, and on a call
2548                  * AGENT_UNKNOWN   - Don't know anything about agent. Shouldn't ever get this.
2549                  */
2550                 ast_str_set(&out, 0, "Agent: %s\r\n", agent->username);
2551                 ast_str_append(&out, 0, "Name: %s\r\n", agent->cfg->full_name);
2552
2553                 if (logged) {
2554                         const char *talking_to_chan;
2555                         struct ast_str *logged_headers;
2556                         RAII_VAR(struct ast_channel_snapshot *, logged_snapshot, ast_channel_snapshot_create(logged), ao2_cleanup);
2557
2558                         if (!logged_snapshot
2559                                 || !(logged_headers =
2560                                          ast_manager_build_channel_state_string(logged_snapshot))) {
2561                                 ast_channel_unlock(logged);
2562                                 ast_channel_unref(logged);
2563                                 agent_unlock(agent);
2564                                 continue;
2565                         }
2566
2567                         talking_to_chan = pbx_builtin_getvar_helper(logged, "BRIDGEPEER");
2568                         if (!ast_strlen_zero(talking_to_chan)) {
2569                                 ast_str_append(&out, 0, "Status: %s\r\n", "AGENT_ONCALL");
2570                                 ast_str_append(&out, 0, "TalkingToChan: %s\r\n", talking_to_chan);
2571                                 ast_str_append(&out, 0, "CallStarted: %ld\n", (long) agent->call_start);
2572                         } else {
2573                                 ast_str_append(&out, 0, "Status: %s\r\n", "AGENT_IDLE");
2574                         }
2575                         ast_str_append(&out, 0, "LoggedInTime: %ld\r\n", (long) agent->login_start);
2576                         ast_str_append(&out, 0, "%s", ast_str_buffer(logged_headers));
2577                         ast_channel_unlock(logged);
2578                         ast_channel_unref(logged);
2579                         ast_free(logged_headers);
2580                 } else {
2581                         ast_str_append(&out, 0, "Status: %s\r\n", "AGENT_LOGGEDOFF");
2582                 }
2583
2584                 agent_unlock(agent);
2585
2586                 astman_append(s, "Event: Agents\r\n"
2587                         "%s%s\r\n",
2588                         ast_str_buffer(out), id_text);
2589                 ++num_agents;
2590         }
2591         ao2_iterator_destroy(&iter);
2592
2593         astman_send_list_complete_start(s, m, "AgentsComplete", num_agents);
2594         astman_send_list_complete_end(s);
2595         return 0;
2596 }
2597
2598 static int action_agent_logoff(struct mansession *s, const struct message *m)
2599 {
2600         const char *agent = astman_get_header(m, "Agent");
2601         const char *soft_s = astman_get_header(m, "Soft"); /* "true" is don't hangup */
2602
2603         if (ast_strlen_zero(agent)) {
2604                 astman_send_error(s, m, "No agent specified");
2605                 return 0;
2606         }
2607
2608         if (!agent_logoff_request(agent, ast_true(soft_s))) {
2609                 astman_send_ack(s, m, "Agent logged out");
2610         } else {
2611                 astman_send_error(s, m, "No such agent");
2612         }
2613
2614         return 0;
2615 }
2616
2617 static int unload_module(void)
2618 {
2619         struct ast_bridge *holding;
2620
2621         /* Unregister dialplan applications */
2622         ast_unregister_application(app_agent_login);
2623         ast_unregister_application(app_agent_request);
2624
2625         /* Unregister dialplan functions */
2626         ast_custom_function_unregister(&agent_function);
2627
2628         /* Unregister manager command */
2629         ast_manager_unregister("Agents");
2630         ast_manager_unregister("AgentLogoff");
2631
2632         /* Unregister CLI commands */
2633         ast_cli_unregister_multiple(cli_agents, ARRAY_LEN(cli_agents));
2634
2635         ast_devstate_prov_del("Agent");
2636
2637         /* Destroy agent holding bridge. */
2638         holding = ao2_global_obj_replace(agent_holding, NULL);
2639         if (holding) {
2640                 ast_bridge_destroy(holding, 0);
2641         }
2642
2643         destroy_config();
2644         ao2_cleanup(agents);
2645         agents = NULL;
2646         return 0;
2647 }
2648
2649 static int load_module(void)
2650 {
2651         int res = 0;
2652
2653         agents = ao2_container_alloc_rbtree(AO2_ALLOC_OPT_LOCK_MUTEX,
2654                 AO2_CONTAINER_ALLOC_OPT_DUPS_REPLACE, agent_pvt_sort_cmp, agent_pvt_cmp);
2655         if (!agents) {
2656                 return AST_MODULE_LOAD_DECLINE;
2657         }
2658
2659         /* Init agent holding bridge v_table. */
2660         bridge_init_agent_hold();
2661
2662         /* Setup to provide Agent:agent-id device state. */
2663         res |= ast_devstate_prov_add("Agent", agent_pvt_devstate_get);
2664
2665         /* CLI Commands */
2666         res |= ast_cli_register_multiple(cli_agents, ARRAY_LEN(cli_agents));
2667
2668         /* Manager commands */
2669         res |= ast_manager_register_xml("Agents", EVENT_FLAG_AGENT, action_agents);
2670         res |= ast_manager_register_xml("AgentLogoff", EVENT_FLAG_AGENT, action_agent_logoff);
2671
2672         /* Dialplan Functions */
2673         res |= ast_custom_function_register(&agent_function);
2674
2675         /* Dialplan applications */
2676         res |= ast_register_application_xml(app_agent_login, agent_login_exec);
2677         res |= ast_register_application_xml(app_agent_request, agent_request_exec);
2678
2679         if (res) {
2680                 ast_log(LOG_ERROR, "Unable to register application. Not loading module.\n");
2681                 unload_module();
2682                 return AST_MODULE_LOAD_DECLINE;
2683         }
2684
2685         if (load_config()) {
2686                 ast_log(LOG_ERROR, "Unable to load config. Not loading module.\n");
2687                 unload_module();
2688                 return AST_MODULE_LOAD_DECLINE;
2689         }
2690
2691         return AST_MODULE_LOAD_SUCCESS;
2692 }
2693
2694 static int reload(void)
2695 {
2696         if (aco_process_config(&cfg_info, 1) == ACO_PROCESS_ERROR) {
2697                 /* Just keep the config we already have in place. */
2698                 return -1;
2699         }
2700         return 0;
2701 }
2702
2703 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "Call center agent pool applications",
2704         .support_level = AST_MODULE_SUPPORT_CORE,
2705         .load = load_module,
2706         .unload = unload_module,
2707         .reload = reload,
2708         .load_pri = AST_MODPRI_DEVSTATE_PROVIDER,
2709 );