[asterisk-commits] mmichelson: branch mmichelson/queue_bugbug r394458 - in /team/mmichelson/queu...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Tue Jul 16 12:01:16 CDT 2013
Author: mmichelson
Date: Tue Jul 16 12:01:15 2013
New Revision: 394458
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=394458
Log:
Get up to date so I have app_agent_pool.c
Added:
team/mmichelson/queue_bugbug/apps/app_agent_pool.c
- copied unchanged from r394442, trunk/apps/app_agent_pool.c
Removed:
team/mmichelson/queue_bugbug/channels/chan_agent.c
Modified:
team/mmichelson/queue_bugbug/ (props changed)
team/mmichelson/queue_bugbug/CHANGES
team/mmichelson/queue_bugbug/UPGRADE.txt
team/mmichelson/queue_bugbug/configs/agents.conf.sample
team/mmichelson/queue_bugbug/configs/queues.conf.sample
team/mmichelson/queue_bugbug/include/asterisk/bridging.h
team/mmichelson/queue_bugbug/include/asterisk/config_options.h
team/mmichelson/queue_bugbug/include/asterisk/stasis_channels.h
team/mmichelson/queue_bugbug/main/bridging.c
team/mmichelson/queue_bugbug/main/stasis_channels.c
team/mmichelson/queue_bugbug/res/res_http_websocket.c
team/mmichelson/queue_bugbug/res/res_stasis_http.c
Propchange: team/mmichelson/queue_bugbug/
------------------------------------------------------------------------------
--- svnmerge-integrated (original)
+++ svnmerge-integrated Tue Jul 16 12:01:15 2013
@@ -1,1 +1,1 @@
-/trunk:1-394370
+/trunk:1-394457
Modified: team/mmichelson/queue_bugbug/CHANGES
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/CHANGES?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/CHANGES (original)
+++ team/mmichelson/queue_bugbug/CHANGES Tue Jul 16 12:01:15 2013
@@ -14,10 +14,17 @@
Applications
------------------
+AgentLogin
+------------------
+ * The application no longer does agent authentication. The dialplan needs to
+ perform this function before running AgentLogin. If the agent is already
+ logged in, dialplan will continue with the AGENT_STATUS channel variable
+ set to ALREADY_LOGGED_IN.
+
AgentMonitorOutgoing
------------------
- * The 'c' option has been removed. It is not possible to modify the name of a
- channel involved in a CDR.
+ * Application removed. It was a holdover from when AgentCallbackLogin was
+ removed.
ForkCDR
------------------
@@ -260,8 +267,8 @@
of "CallerID" and "ConnectedID" to avoid confusion with similarly named
parameters in the channel snapshot.
- * The "Agentlogin" and "Agentlogoff" events have been renamed "AgentLogin" and
- "AgentLogoff" respectively.
+ * The AMI events "Agentlogin" and "Agentlogoff" have been renamed
+ "AgentLogin" and "AgentLogoff" respectively.
* The "Channel" key used in the "AlarmClear", "Alarm", and "DNDState" has been
renamed "DAHDIChannel" since it does not convey an Asterisk channel name.
@@ -453,6 +460,21 @@
and pretending otherwise helps no one.
* The AGENTUPDATECDR channel variable has also been removed, for the same
reason as the updatecdr option.
+ * The driver is no longer a Data retrieval API data provider for the
+ AMI DataGet action.
+ * The endcall and enddtmf configuration options are removed. Use the
+ dialplan function CHANNEL(dtmf-features) to set DTMF features on the agent
+ channel before calling AgentLogin.
+ * chan_agent is removed and replaced with AgentLogin and AgentRequest dialplan
+ applications. Agents are connected with callers using the new AgentRequest
+ dialplan application. The Agents:<agent-id> device state is available to
+ monitor the status of an agent. See agents.conf.sample for valid
+ configuration options.
+
+chan_bridge
+------------------
+ * chan_bridge is removed and its functionality is incorporated into ConfBridge
+ itself.
chan_local
------------------
Modified: team/mmichelson/queue_bugbug/UPGRADE.txt
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/UPGRADE.txt?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/UPGRADE.txt (original)
+++ team/mmichelson/queue_bugbug/UPGRADE.txt Tue Jul 16 12:01:15 2013
@@ -22,8 +22,8 @@
===========================================================
AgentMonitorOutgoing
- - The 'c' option has been removed. It is not possible to modify the name of a
- channel involved in a CDR.
+ - Application removed. It was a holdover from when AgentCallbackLogin was
+ removed.
NoCDR:
- This application is deprecated. Please use the CDR_PROP function instead.
@@ -140,6 +140,15 @@
and pretending otherwise helps no one.
- The AGENTUPDATECDR channel variable has also been removed, for the same
reason as the updatecdr option.
+ - chan_agent is removed and replaced with AgentLogin and AgentRequest dialplan
+ applications. Agents are connected with callers using the new AgentRequest
+ dialplan application. The Agents:<agent-id> device state is available to
+ monitor the status of an agent. See agents.conf.sample for valid
+ configuration options.
+
+chan_bridge
+ - chan_bridge is removed and its functionality is incorporated into ConfBridge
+ itself.
chan_dahdi:
- Analog port dialing and deferred DTMF dialing for PRI now distinguishes
Modified: team/mmichelson/queue_bugbug/configs/agents.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/configs/agents.conf.sample?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/configs/agents.conf.sample (original)
+++ team/mmichelson/queue_bugbug/configs/agents.conf.sample Tue Jul 16 12:01:15 2013
@@ -1,102 +1,70 @@
;
-; Agent configuration
+; Agent pool configuration
;
[general]
+; The general section of this config is not currently used, but reserved
+; for future use.
-[agents]
+;[agent-id]
+; Define ackcall to require the agent to give a DTMF acknowledgement
+; when the agent receives a call.
+; The channel variable AGENTACKCALL overrides on agent login.
+; Default is "no".
+;ackcall=no
;
-; Define maxlogintries to allow agent to try max logins before
-; failed.
-; default to 3
+; Set what DTMF key sequence the agent should use to acknowledge a call.
+; The channel variable AGENTACCEPTDTMF overrides on agent login.
+; This option is ignored unless ackcall is enabled.
+; Default is "#".
+;acceptdtmf=##
;
-;maxlogintries=5
-;
-;
-; Define autologoff times if appropriate. This is how long
-; the phone has to ring with no answer before the agent is
-; automatically logged off (in seconds)
-;
+; Set how many seconds a call for the agent has to wait for the agent to
+; acknowledge the call before the agent is automatically logged off. If
+; set to zero then the call will wait forever for the agent to acknowledge.
+; The channel variable AGENTAUTOLOGOFF overrides on agent login.
+; This option is ignored unless ackcall is enabled.
+; Default is 0.
;autologoff=15
;
-; Define autologoffunavail to have agents automatically logged
-; out when the extension that they are at returns a CHANUNAVAIL
-; status when a call is attempted to be sent there.
-; Default is "no".
-;
-;autologoffunavail=yes
-;
-; Define ackcall to require a DTMF acknowledgement when
-; a logged-in agent receives a call. Default is "no".
-; Use the acceptdtmf option to configure what DTMF key
-; press should be used to acknowledge the call. The
-; default is '#'.
-;
-;ackcall=no
-;acceptdtmf=#
-;
-; Define endcall to allow an agent to hangup a call with a
-; DTMF keypress. Default is "yes". Use the enddtmf option to
-; configure which DTMF key will end a call. The default is
-; '*'.
-;
-;endcall=yes
-;enddtmf=*
-;
-; Define wrapuptime. This is the minimum amount of time when
-; after disconnecting before the caller can receive a new call
-; note this is in milliseconds.
-;
+; Set the minimum amount of time after disconnecting a call before
+; the agent can receive a new call in milliseconds.
+; The channel variable AGENTWRAPUPTIME overrides on agent login.
+; Default is 0.
;wrapuptime=5000
;
-; Define the default musiconhold for agents
-; musiconhold => music_class
+; Set the musiconhold class for the agent.
+; Default is "default".
+;musiconhold=default
;
-;musiconhold => default
-;
-; Define the default good bye sound file for agents
-; default to vm-goodbye
-;
-;goodbye => goodbye_file
-;
-; Define updatecdr. This is whether or not to change the source
-; channel in the CDR record for this call to agent/agent_id so
-; that we know which agent generates the call
-;
-;updatecdr=no
-;
-; Group memberships for agents (may change in mid-file)
-;
-;group=3
-;group=1,2
-;group=
-;
-; --------------------------------------------------
-; This section is devoted to recording agent's calls
-; The keywords are global to the chan_agent channel driver
-;
-; Enable recording calls addressed to agents. It's turned off by default.
+; Enable recording calls the agent takes automatically by invoking the
+; DTMF automixmon feature when the agent connects to a caller.
+; See features.conf.sample for information about the automixmon feature.
+; Default is "no".
;recordagentcalls=yes
;
-; The format to be used to record the calls: wav, gsm, wav49.
-; By default its "wav".
-;recordformat=gsm
+; The sound file played to alert the agent when a call is present.
+; Default is "beep".
+;custom_beep=beep
;
-; The text to be added to the name of the recording. Allows forming a url link.
-;urlprefix=http://localhost/calls/
-;
-; The optional directory to save the conversations in. The default is
-; /var/spool/asterisk/monitor
-;savecallsin=/var/calls
-;
-; An optional custom beep sound file to play to always-connected agents.
-;custom_beep=beep
+; A friendly name for the agent used in log messages.
+; Default is "".
+;fullname=Mark Spencer
;
; --------------------------------------------------
;
-; This section contains the agent definitions, in the form:
+; This section contains example agent definitions:
;
-; agent => agentid,agentpassword,name
+; Define a template called my-agents:
+;[my-agents](!)
+;autologoff=15
+;ackcall=yes
+;acceptdtmf=##
;
-;agent => 1001,4321,Mark Spencer
-;agent => 1002,4321,Will Meadows
+; Define agent 1001 using the my-agents template:
+;[1001](my-agents)
+;fullname=Mark Spencer
+;
+; Define agent 1002 using the my-agents template:
+;[1002](my-agents)
+;fullname=Will Meadows
Modified: team/mmichelson/queue_bugbug/configs/queues.conf.sample
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/configs/queues.conf.sample?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/configs/queues.conf.sample (original)
+++ team/mmichelson/queue_bugbug/configs/queues.conf.sample Tue Jul 16 12:01:15 2013
@@ -543,18 +543,7 @@
;member => DAHDI/1
;member => DAHDI/2,10
;member => DAHDI/3,10,Bob Johnson
-;member => Agent/1001
-;member => Agent/1002
+;member => Local/1001 at agents,0,May Flowers,Agent:1001
+;member => Local/1002 at agents,0,John Doe,Agent:1002
;member => Local/1000 at default,0,John Smith,SIP/1000
;member => Local/2000 at default,0,Lorem Ipsum,SIP/2000,no
-
-;
-; Note that using agent groups is probably not what you want. Strategies do
-; not propagate down to the Agent system so if you want round robin, least
-; recent, etc, you should list all the agents in this file individually and not
-; use agent groups.
-;
-;member => Agent/@1 ; Any agent in group 1
-;member => Agent/:1,1 ; Any agent in group 1, wait for first
- ; available, but consider with penalty
-
Modified: team/mmichelson/queue_bugbug/include/asterisk/bridging.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/include/asterisk/bridging.h?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/include/asterisk/bridging.h (original)
+++ team/mmichelson/queue_bugbug/include/asterisk/bridging.h Tue Jul 16 12:01:15 2013
@@ -1651,7 +1651,7 @@
/*! Reason the the after bridge callback will not be called. */
enum ast_after_bridge_cb_reason {
- /*! The datastore is being destroyed. Likely due to hangup. */
+ /*! The datastore is being destroyed. Likely due to hangup. (Enum value must be zero.) */
AST_AFTER_BRIDGE_CB_REASON_DESTROY,
/*! Something else replaced the callback with another. */
AST_AFTER_BRIDGE_CB_REASON_REPLACED,
@@ -1670,6 +1670,9 @@
* \param reason Reason callback is failing.
* \param data Extra data what setup the callback wanted to pass.
*
+ * \note Called when the channel leaves the bridging system or
+ * is destroyed.
+ *
* \return Nothing
*/
typedef void (*ast_after_bridge_cb_failed)(enum ast_after_bridge_cb_reason reason, void *data);
@@ -1709,6 +1712,9 @@
*
* \note chan is locked by this function.
*
+ * \note failed is called when the channel leaves the bridging
+ * system or is destroyed.
+ *
* \retval 0 on success.
* \retval -1 on error.
*/
Modified: team/mmichelson/queue_bugbug/include/asterisk/config_options.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/include/asterisk/config_options.h?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/include/asterisk/config_options.h (original)
+++ team/mmichelson/queue_bugbug/include/asterisk/config_options.h Tue Jul 16 12:01:15 2013
@@ -461,7 +461,7 @@
/*! \brief Process a config info via the options registered with an aco_info
*
* \param info The config_options_info to be used for handling the config
- * \param reload Whether or not this is a reload
+ * \param reload Non-zero if this is for a reload.
*
* \retval ACO_PROCESS_OK Success
* \retval ACO_PROCESS_ERROR Failure
Modified: team/mmichelson/queue_bugbug/include/asterisk/stasis_channels.h
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/include/asterisk/stasis_channels.h?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/include/asterisk/stasis_channels.h (original)
+++ team/mmichelson/queue_bugbug/include/asterisk/stasis_channels.h Tue Jul 16 12:01:15 2013
@@ -145,7 +145,7 @@
*
* \param chan The channel from which to generate a snapshot
*
- * \retval pointer on success (must be ast_freed)
+ * \retval pointer on success (must be unreffed)
* \retval NULL on error
*/
struct ast_channel_snapshot *ast_channel_snapshot_create(
@@ -434,6 +434,22 @@
* \retval A stasis message type
*/
struct stasis_message_type *ast_channel_monitor_stop_type(void);
+
+/*!
+ * \since 12.0.0
+ * \brief Message type for agent login on a channel
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_channel_agent_login_type(void);
+
+/*!
+ * \since 12.0.0
+ * \brief Message type for agent logoff on a channel
+ *
+ * \retval A stasis message type
+ */
+struct stasis_message_type *ast_channel_agent_logoff_type(void);
/*!
* \since 12
Modified: team/mmichelson/queue_bugbug/main/bridging.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/main/bridging.c?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/main/bridging.c (original)
+++ team/mmichelson/queue_bugbug/main/bridging.c Tue Jul 16 12:01:15 2013
@@ -3242,14 +3242,69 @@
return bridge_channel;
}
-struct after_bridge_cb_ds {
+struct after_bridge_cb_node {
+ /*! Next list node. */
+ AST_LIST_ENTRY(after_bridge_cb_node) list;
/*! Desired callback function. */
ast_after_bridge_cb callback;
/*! After bridge callback will not be called and destroy any resources data may contain. */
ast_after_bridge_cb_failed failed;
/*! Extra data to pass to the callback. */
void *data;
+ /*! Reason the after bridge callback failed. */
+ enum ast_after_bridge_cb_reason reason;
};
+
+struct after_bridge_cb_ds {
+ /*! After bridge callbacks container. */
+ AST_LIST_HEAD(, after_bridge_cb_node) callbacks;
+};
+
+/*!
+ * \internal
+ * \brief Indicate after bridge callback failed.
+ * \since 12.0.0
+ *
+ * \param node After bridge callback node.
+ *
+ * \return Nothing
+ */
+static void after_bridge_cb_failed(struct after_bridge_cb_node *node)
+{
+ if (node->failed) {
+ node->failed(node->reason, node->data);
+ node->failed = NULL;
+ }
+}
+
+/*!
+ * \internal
+ * \brief Run discarding any after bridge callbacks.
+ * \since 12.0.0
+ *
+ * \param after_bridge After bridge callback container process.
+ * \param reason Why are we doing this.
+ *
+ * \return Nothing
+ */
+static void after_bridge_cb_run_discard(struct after_bridge_cb_ds *after_bridge, enum ast_after_bridge_cb_reason reason)
+{
+ struct after_bridge_cb_node *node;
+
+ for (;;) {
+ AST_LIST_LOCK(&after_bridge->callbacks);
+ node = AST_LIST_REMOVE_HEAD(&after_bridge->callbacks, list);
+ AST_LIST_UNLOCK(&after_bridge->callbacks);
+ if (!node) {
+ break;
+ }
+ if (!node->reason) {
+ node->reason = reason;
+ }
+ after_bridge_cb_failed(node);
+ ast_free(node);
+ }
+}
/*!
* \internal
@@ -3264,10 +3319,9 @@
{
struct after_bridge_cb_ds *after_bridge = data;
- if (after_bridge->failed) {
- after_bridge->failed(AST_AFTER_BRIDGE_CB_REASON_DESTROY, after_bridge->data);
- after_bridge->failed = NULL;
- }
+ after_bridge_cb_run_discard(after_bridge, AST_AFTER_BRIDGE_CB_REASON_DESTROY);
+
+ AST_LIST_HEAD_DESTROY(&after_bridge->callbacks);
ast_free(after_bridge);
}
@@ -3284,7 +3338,6 @@
*/
static void after_bridge_cb_fixup(void *data, struct ast_channel *old_chan, struct ast_channel *new_chan)
{
- /* There can be only one. Discard any already on the new channel. */
ast_after_bridge_callback_discard(new_chan, AST_AFTER_BRIDGE_CB_REASON_MASQUERADE);
}
@@ -3296,82 +3349,144 @@
/*!
* \internal
- * \brief Remove channel after the bridge callback and return it.
+ * \brief Setup/create an after bridge callback datastore container.
* \since 12.0.0
*
- * \param chan Channel to remove after bridge callback.
- *
- * \retval datastore on success.
- * \retval NULL on error or not found.
- */
-static struct ast_datastore *after_bridge_cb_remove(struct ast_channel *chan)
-{
- struct ast_datastore *datastore;
-
- ast_channel_lock(chan);
- datastore = ast_channel_datastore_find(chan, &after_bridge_cb_info, NULL);
- if (datastore && ast_channel_datastore_remove(chan, datastore)) {
- datastore = NULL;
- }
- ast_channel_unlock(chan);
-
- return datastore;
-}
-
-void ast_after_bridge_callback_discard(struct ast_channel *chan, enum ast_after_bridge_cb_reason reason)
-{
- struct ast_datastore *datastore;
-
- datastore = after_bridge_cb_remove(chan);
- if (datastore) {
- struct after_bridge_cb_ds *after_bridge = datastore->data;
-
- if (after_bridge && after_bridge->failed) {
- after_bridge->failed(reason, after_bridge->data);
- after_bridge->failed = NULL;
- }
- ast_datastore_free(datastore);
- }
-}
-
-/*!
- * \internal
- * \brief Run any after bridge callback if possible.
- * \since 12.0.0
- *
- * \param chan Channel to run after bridge callback.
- *
- * \return Nothing
- */
-static void after_bridge_callback_run(struct ast_channel *chan)
+ * \param chan Channel to setup/create the after bridge callback container on.
+ *
+ * \retval after_bridge datastore container on success.
+ * \retval NULL on error.
+ */
+static struct after_bridge_cb_ds *after_bridge_cb_setup(struct ast_channel *chan)
{
struct ast_datastore *datastore;
struct after_bridge_cb_ds *after_bridge;
-
- if (ast_check_hangup(chan)) {
+ SCOPED_CHANNELLOCK(lock, chan);
+
+ datastore = ast_channel_datastore_find(chan, &after_bridge_cb_info, NULL);
+ if (datastore) {
+ return datastore->data;
+ }
+
+ /* Create a new datastore. */
+ datastore = ast_datastore_alloc(&after_bridge_cb_info, NULL);
+ if (!datastore) {
+ return NULL;
+ }
+ after_bridge = ast_calloc(1, sizeof(*after_bridge));
+ if (!after_bridge) {
+ ast_datastore_free(datastore);
+ return NULL;
+ }
+ AST_LIST_HEAD_INIT(&after_bridge->callbacks);
+ datastore->data = after_bridge;
+ ast_channel_datastore_add(chan, datastore);
+
+ return datastore->data;
+}
+
+/*!
+ * \internal
+ * \brief Find an after bridge callback datastore container.
+ * \since 12.0.0
+ *
+ * \param chan Channel to find the after bridge callback container on.
+ *
+ * \retval after_bridge datastore container on success.
+ * \retval NULL on error.
+ */
+static struct after_bridge_cb_ds *after_bridge_cb_find(struct ast_channel *chan)
+{
+ struct ast_datastore *datastore;
+ SCOPED_CHANNELLOCK(lock, chan);
+
+ datastore = ast_channel_datastore_find(chan, &after_bridge_cb_info, NULL);
+ if (!datastore) {
+ return NULL;
+ }
+ return datastore->data;
+}
+
+/*!
+ * \internal
+ * \brief Run any after bridge callback.
+ * \since 12.0.0
+ *
+ * \param chan Channel to run after bridge callback.
+ *
+ * \return Nothing
+ */
+static void after_bridge_callback_run(struct ast_channel *chan)
+{
+ struct after_bridge_cb_ds *after_bridge;
+ struct after_bridge_cb_node *node;
+
+ after_bridge = after_bridge_cb_find(chan);
+ if (!after_bridge) {
return;
}
- /* Get after bridge goto datastore. */
- datastore = after_bridge_cb_remove(chan);
- if (!datastore) {
+ for (;;) {
+ AST_LIST_LOCK(&after_bridge->callbacks);
+ node = AST_LIST_REMOVE_HEAD(&after_bridge->callbacks, list);
+ AST_LIST_UNLOCK(&after_bridge->callbacks);
+ if (!node) {
+ break;
+ }
+ if (node->reason) {
+ after_bridge_cb_failed(node);
+ } else {
+ node->failed = NULL;
+ node->callback(chan, node->data);
+ }
+ ast_free(node);
+ }
+}
+
+/*!
+ * \internal
+ * \brief Run discarding any after bridge callbacks.
+ * \since 12.0.0
+ *
+ * \param chan Channel to run after bridge callback.
+ *
+ * \return Nothing
+ */
+static void after_bridge_callback_run_discard(struct ast_channel *chan, enum ast_after_bridge_cb_reason reason)
+{
+ struct after_bridge_cb_ds *after_bridge;
+
+ after_bridge = after_bridge_cb_find(chan);
+ if (!after_bridge) {
return;
}
- after_bridge = datastore->data;
- if (after_bridge) {
- after_bridge->failed = NULL;
- after_bridge->callback(chan, after_bridge->data);
- }
-
- /* Discard after bridge callback datastore. */
- ast_datastore_free(datastore);
+ after_bridge_cb_run_discard(after_bridge, reason);
+}
+
+void ast_after_bridge_callback_discard(struct ast_channel *chan, enum ast_after_bridge_cb_reason reason)
+{
+ struct after_bridge_cb_ds *after_bridge;
+ struct after_bridge_cb_node *node;
+
+ after_bridge = after_bridge_cb_find(chan);
+ if (!after_bridge) {
+ return;
+ }
+
+ AST_LIST_LOCK(&after_bridge->callbacks);
+ node = AST_LIST_LAST(&after_bridge->callbacks);
+ if (node && !node->reason) {
+ node->reason = reason;
+ }
+ AST_LIST_UNLOCK(&after_bridge->callbacks);
}
int ast_after_bridge_callback_set(struct ast_channel *chan, ast_after_bridge_cb callback, ast_after_bridge_cb_failed failed, void *data)
{
- struct ast_datastore *datastore;
struct after_bridge_cb_ds *after_bridge;
+ struct after_bridge_cb_node *new_node;
+ struct after_bridge_cb_node *last_node;
/* Sanity checks. */
ast_assert(chan != NULL);
@@ -3379,29 +3494,28 @@
return -1;
}
- /* Create a new datastore. */
- datastore = ast_datastore_alloc(&after_bridge_cb_info, NULL);
- if (!datastore) {
+ after_bridge = after_bridge_cb_setup(chan);
+ if (!after_bridge) {
return -1;
}
- after_bridge = ast_calloc(1, sizeof(*after_bridge));
- if (!after_bridge) {
- ast_datastore_free(datastore);
+
+ /* Create a new callback node. */
+ new_node = ast_calloc(1, sizeof(*new_node));
+ if (!new_node) {
return -1;
}
-
- /* Initialize it. */
- after_bridge->callback = callback;
- after_bridge->failed = failed;
- after_bridge->data = data;
- datastore->data = after_bridge;
-
- /* Put it on the channel replacing any existing one. */
- ast_channel_lock(chan);
- ast_after_bridge_callback_discard(chan, AST_AFTER_BRIDGE_CB_REASON_REPLACED);
- ast_channel_datastore_add(chan, datastore);
- ast_channel_unlock(chan);
-
+ new_node->callback = callback;
+ new_node->failed = failed;
+ new_node->data = data;
+
+ /* Put it in the container disabling any previously active one. */
+ AST_LIST_LOCK(&after_bridge->callbacks);
+ last_node = AST_LIST_LAST(&after_bridge->callbacks);
+ if (last_node && !last_node->reason) {
+ last_node->reason = AST_AFTER_BRIDGE_CB_REASON_REPLACED;
+ }
+ AST_LIST_INSERT_TAIL(&after_bridge->callbacks, new_node, list);
+ AST_LIST_UNLOCK(&after_bridge->callbacks);
return 0;
}
@@ -3866,7 +3980,7 @@
ast_bridge_features_destroy(bridge_channel->features);
bridge_channel->features = NULL;
- ast_after_bridge_callback_discard(bridge_channel->chan, AST_AFTER_BRIDGE_CB_REASON_DEPART);
+ after_bridge_callback_run_discard(bridge_channel->chan, AST_AFTER_BRIDGE_CB_REASON_DEPART);
ast_after_bridge_goto_discard(bridge_channel->chan);
return NULL;
Modified: team/mmichelson/queue_bugbug/main/stasis_channels.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/main/stasis_channels.c?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/main/stasis_channels.c (original)
+++ team/mmichelson/queue_bugbug/main/stasis_channels.c Tue Jul 16 12:01:15 2013
@@ -53,6 +53,35 @@
<para>The new value of the variable.</para>
</parameter>
</syntax>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="AgentLogin">
+ <managerEventInstance class="EVENT_FLAG_AGENT">
+ <synopsis>Raised when an Agent has logged in.</synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+ <parameter name="Agent">
+ <para>Agent ID of the agent.</para>
+ </parameter>
+ </syntax>
+ <see-also>
+ <ref type="application">AgentLogin</ref>
+ <ref type="managerEvent">AgentLogoff</ref>
+ </see-also>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="AgentLogoff">
+ <managerEventInstance class="EVENT_FLAG_AGENT">
+ <synopsis>Raised when an Agent has logged off.</synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='AgentLogin']/managerEventInstance/syntax/parameter)" />
+ <parameter name="Logintime">
+ <para>The number of seconds the agent was logged in.</para>
+ </parameter>
+ </syntax>
+ <see-also>
+ <ref type="managerEvent">AgentLogin</ref>
+ </see-also>
</managerEventInstance>
</managerEvent>
***/
@@ -625,6 +654,44 @@
"Variable: %s\r\n"
"Value: %s\r\n",
ast_str_buffer(channel_event_string), variable, value);
+}
+
+static struct ast_manager_event_blob *agent_login_to_ami(struct stasis_message *msg)
+{
+ RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
+ RAII_VAR(struct ast_str *, party_string, ast_str_create(256), ast_free);
+ struct ast_channel_blob *obj = stasis_message_data(msg);
+ const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
+
+ channel_string = ast_manager_build_channel_state_string(obj->snapshot);
+ if (!channel_string) {
+ return NULL;
+ }
+
+ return ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogin",
+ "%s"
+ "Agent: %s\r\n",
+ ast_str_buffer(channel_string), agent);
+}
+
+static struct ast_manager_event_blob *agent_logoff_to_ami(struct stasis_message *msg)
+{
+ RAII_VAR(struct ast_str *, channel_string, NULL, ast_free);
+ RAII_VAR(struct ast_str *, party_string, ast_str_create(256), ast_free);
+ struct ast_channel_blob *obj = stasis_message_data(msg);
+ const char *agent = ast_json_string_get(ast_json_object_get(obj->blob, "agent"));
+ long logintime = ast_json_integer_get(ast_json_object_get(obj->blob, "logintime"));
+
+ channel_string = ast_manager_build_channel_state_string(obj->snapshot);
+ if (!channel_string) {
+ return NULL;
+ }
+
+ return ast_manager_event_blob_create(EVENT_FLAG_AGENT, "AgentLogoff",
+ "%s"
+ "Agent: %s\r\n"
+ "Logintime: %ld\r\n",
+ ast_str_buffer(channel_string), agent, logintime);
}
void ast_publish_channel_state(struct ast_channel *chan)
@@ -827,6 +894,12 @@
STASIS_MESSAGE_TYPE_DEFN(ast_channel_moh_stop_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_start_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_stop_type);
+STASIS_MESSAGE_TYPE_DEFN(ast_channel_agent_login_type,
+ .to_ami = agent_login_to_ami,
+ );
+STASIS_MESSAGE_TYPE_DEFN(ast_channel_agent_logoff_type,
+ .to_ami = agent_logoff_to_ami,
+ );
/*! @} */
@@ -853,6 +926,8 @@
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_moh_stop_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_start_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_stop_type);
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_login_type);
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_logoff_type);
}
void ast_stasis_channels_init(void)
@@ -876,6 +951,8 @@
STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_stop_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_start_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_stop_type);
+ STASIS_MESSAGE_TYPE_INIT(ast_channel_agent_login_type);
+ STASIS_MESSAGE_TYPE_INIT(ast_channel_agent_logoff_type);
channel_topic_all = stasis_topic_create("ast_channel_topic_all");
channel_topic_all_cached = stasis_caching_topic_create(channel_topic_all, channel_snapshot_get_id);
Modified: team/mmichelson/queue_bugbug/res/res_http_websocket.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/res/res_http_websocket.c?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/res/res_http_websocket.c (original)
+++ team/mmichelson/queue_bugbug/res/res_http_websocket.c Tue Jul 16 12:01:15 2013
@@ -653,7 +653,7 @@
return 0;
}
- ast_verb(2, "WebSocket connection from '%s' for protocol '%s' accepted using version '%d'\n", ast_sockaddr_stringify(&ser->remote_address), protocol, version);
+ ast_verb(2, "WebSocket connection from '%s' for protocol '%s' accepted using version '%d'\n", ast_sockaddr_stringify(&ser->remote_address), protocol ? : "", version);
/* Populate the session with all the needed details */
session->f = ser->f;
Modified: team/mmichelson/queue_bugbug/res/res_stasis_http.c
URL: http://svnview.digium.com/svn/asterisk/team/mmichelson/queue_bugbug/res/res_stasis_http.c?view=diff&rev=394458&r1=394457&r2=394458
==============================================================================
--- team/mmichelson/queue_bugbug/res/res_stasis_http.c (original)
+++ team/mmichelson/queue_bugbug/res/res_stasis_http.c Tue Jul 16 12:01:15 2013
@@ -90,6 +90,9 @@
</configOption>
<configOption name="auth_realm">
<synopsis>Realm to use for authentication. Defaults to Asterisk REST Interface.</synopsis>
+ </configOption>
+ <configOption name="allowed_origins">
+ <synopsis>Comma separated list of allowed origins, for Cross-Origin Resource Sharing. May be set to * to allow all origins.</synopsis>
</configOption>
</configObject>
More information about the asterisk-commits
mailing list