[asterisk-commits] dlee: branch dlee/ari-async-bridge r395883 - in /team/dlee/ari-async-bridge: ...
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Wed Jul 31 10:38:58 CDT 2013
Author: dlee
Date: Wed Jul 31 10:38:56 2013
New Revision: 395883
URL: http://svnview.digium.com/svn/asterisk?view=rev&rev=395883
Log:
Holding bridge, and playing into a holding bridge, works as expected
Modified:
team/dlee/ari-async-bridge/include/asterisk/bridge_features.h
team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h
team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h
team/dlee/ari-async-bridge/res/res_stasis.c
team/dlee/ari-async-bridge/res/res_stasis_bridge.c
team/dlee/ari-async-bridge/res/res_stasis_playback.c
team/dlee/ari-async-bridge/res/stasis/control.c
team/dlee/ari-async-bridge/res/stasis/control.h
Modified: team/dlee/ari-async-bridge/include/asterisk/bridge_features.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/include/asterisk/bridge_features.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/include/asterisk/bridge_features.h (original)
+++ team/dlee/ari-async-bridge/include/asterisk/bridge_features.h Wed Jul 31 10:38:56 2013
@@ -24,6 +24,8 @@
#ifndef _ASTERISK_BRIDGING_FEATURES_H
#define _ASTERISK_BRIDGING_FEATURES_H
+
+#include "asterisk/channel.h"
#if defined(__cplusplus) || defined(c_plusplus)
extern "C" {
Modified: team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h (original)
+++ team/dlee/ari-async-bridge/include/asterisk/bridge_internal.h Wed Jul 31 10:38:56 2013
@@ -36,6 +36,7 @@
struct ast_bridge;
struct ast_bridge_channel;
+struct ast_bridge_methods;
/*!
* \brief Register the new bridge with the system.
Modified: team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h (original)
+++ team/dlee/ari-async-bridge/include/asterisk/stasis_app_impl.h Wed Jul 31 10:38:56 2013
@@ -87,17 +87,6 @@
/*!
* \since 12
- * \brief Changes the bridge currently associated with a control object.
- *
- * \param control Control object for the channel to query.
- * \param bridge New bridge to set on the control object. Or \c NULL to clear
- * the association.
- */
-void stasis_app_set_bridge(struct stasis_app_control *control,
- struct ast_bridge *bridge);
-
-/*!
- * \since 12
* \brief Gets the bridge currently associated with a control object.
*
* \param control Control object for the channel to query.
@@ -106,4 +95,17 @@
*/
struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control);
+
+/*!
+ * \since 12
+ * \brief Imparts the associated channel into the bridge.
+ *
+ * \param control Control object for the channel to query.
+ * \param bridge New bridge to set on the control object.
+ */
+void stasis_app_add_to_bridge(struct stasis_app_control *control,
+ struct ast_bridge *bridge);
+
+void stasis_app_remove_from_bridge(struct stasis_app_control *control);
+
#endif /* _ASTERISK_RES_STASIS_H */
Modified: team/dlee/ari-async-bridge/res/res_stasis.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/res_stasis.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/res_stasis.c (original)
+++ team/dlee/ari-async-bridge/res/res_stasis.c Wed Jul 31 10:38:56 2013
@@ -594,6 +594,13 @@
int r;
int command_count;
+ if (stasis_app_get_bridge(control)) {
+ /* Bridge is handling channel frames */
+ control_wait(control);
+ control_dispatch_all(control, chan);
+ continue;
+ }
+
r = ast_waitfor(chan, MAX_WAIT_MS);
if (r < 0) {
@@ -614,10 +621,6 @@
continue;
}
- if (stasis_app_get_bridge(control)) {
- /* Bridge is handling channel frames */
- continue;
- }
f = ast_read(chan);
if (!f) {
Modified: team/dlee/ari-async-bridge/res/res_stasis_bridge.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/res_stasis_bridge.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/res_stasis_bridge.c (original)
+++ team/dlee/ari-async-bridge/res/res_stasis_bridge.c Wed Jul 31 10:38:56 2013
@@ -40,23 +40,12 @@
struct stasis_app_control *control,
struct ast_channel *chan, void *data)
{
- struct ast_bridge_features *features;
struct ast_bridge *bridge = data;
ast_debug(3, "%s: Adding to bridge\n",
stasis_app_control_get_channel_id(control));
- features = ast_bridge_features_new();
- if (!features) {
- ast_log(LOG_ERROR,
- "Failed to allocate bridge features; proceeding without.\n");
- }
-
- ast_bridge_impart(bridge,
- chan,
- NULL, /* swap channel */
- features,
- 0); /* independent - false allows us to ast_bridge_depart() */
+ stasis_app_add_to_bridge(control, bridge);
return NULL;
}
@@ -85,7 +74,8 @@
return NULL;
}
- ast_bridge_depart(chan);
+ stasis_app_remove_from_bridge(control);
+
return NULL;
}
Modified: team/dlee/ari-async-bridge/res/res_stasis_playback.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/res_stasis_playback.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/res_stasis_playback.c (original)
+++ team/dlee/ari-async-bridge/res/res_stasis_playback.c Wed Jul 31 10:38:56 2013
@@ -34,6 +34,8 @@
#include "asterisk/app.h"
#include "asterisk/astobj2.h"
+#include "asterisk/bridge.h"
+#include "asterisk/bridge_internal.h"
#include "asterisk/file.h"
#include "asterisk/logger.h"
#include "asterisk/module.h"
@@ -200,6 +202,7 @@
RAII_VAR(char *, file, NULL, ast_free);
int res;
long offsetms;
+ struct ast_bridge *bridge;
/* Even though these local variables look fairly pointless, the avoid
* having a bunch of NULL's passed directly into
@@ -248,8 +251,19 @@
return NULL;
}
- res = ast_control_streamfile_lang(chan, file, fwd, rev, stop, pause,
- restart, playback->skipms, playback->language, &offsetms);
+ bridge = stasis_app_get_bridge(control);
+ if (bridge) {
+ struct ast_bridge_channel *bridge_chan;
+ ast_bridge_lock(bridge);
+ bridge_chan = bridge_find_channel(bridge, chan);
+ if (bridge_chan) {
+ res = ast_bridge_channel_queue_playfile(bridge_chan, NULL, file, NULL);
+ }
+ ast_bridge_unlock(bridge);
+ } else {
+ res = ast_control_streamfile_lang(chan, file, fwd, rev, stop, pause,
+ restart, playback->skipms, playback->language, &offsetms);
+ }
playback_final_update(playback, offsetms, res,
ast_channel_uniqueid(chan));
Modified: team/dlee/ari-async-bridge/res/stasis/control.c
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/stasis/control.c?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/stasis/control.c (original)
+++ team/dlee/ari-async-bridge/res/stasis/control.c Wed Jul 31 10:38:56 2013
@@ -40,6 +40,7 @@
#include "asterisk/musiconhold.h"
struct stasis_app_control {
+ ast_cond_t wait_cond;
/*! Queue of commands to dispatch on the channel */
struct ao2_container *command_queue;
/*!
@@ -53,17 +54,37 @@
*/
struct ast_bridge *bridge;
/*!
+ * Holding place for channel's PBX while imparted to a bridge.
+ */
+ struct ast_pbx *pbx;
+ /*!
* When set, /c app_stasis should exit and continue in the dialplan.
*/
int is_done:1;
};
+static void control_dtor(void *obj)
+{
+ struct stasis_app_control *control = obj;
+
+ ao2_cleanup(control->command_queue);
+ ast_cond_destroy(&control->wait_cond);
+}
+
struct stasis_app_control *control_create(struct ast_channel *channel)
{
- struct stasis_app_control *control;
-
- control = ao2_alloc(sizeof(*control), NULL);
+ RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup);
+ int res;
+
+ control = ao2_alloc(sizeof(*control), control_dtor);
if (!control) {
+ return NULL;
+ }
+
+ res = ast_cond_init(&control->wait_cond, NULL);
+ if (res != 0) {
+ ast_log(LOG_ERROR, "Error initializing ast_cond_t: %s\n",
+ strerror(errno));
return NULL;
}
@@ -71,12 +92,12 @@
AO2_ALLOC_OPT_LOCK_MUTEX, 0, NULL, NULL);
if (!control->command_queue) {
- ao2_cleanup(control);
return NULL;
}
control->channel = channel;
+ ao2_ref(control, +1);
return control;
}
@@ -93,7 +114,10 @@
}
/* command_queue is a thread safe list; no lock needed */
- ao2_link(control->command_queue, command);
+ ao2_lock(control->command_queue);
+ ao2_link_flags(control->command_queue, command, OBJ_NOLOCK);
+ ast_cond_signal(&control->wait_cond);
+ ao2_unlock(control->command_queue);
ao2_ref(command, +1);
return command;
@@ -421,21 +445,55 @@
return 0;
}
-void stasis_app_set_bridge(struct stasis_app_control *control,
+struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control)
+{
+ if (!control) {
+ return NULL;
+ }
+ return control->bridge;
+}
+
+void stasis_app_add_to_bridge(struct stasis_app_control *control,
struct ast_bridge *bridge)
+{
+ int res;
+
+ if (!control || !bridge) {
+ return;
+ }
+
+ /* Save off the channel's PBX */
+ ast_assert(!control->pbx || !ast_channel_pbx(control->channel));
+ if (!control->pbx) {
+ control->pbx = ast_channel_pbx(control->channel);
+ ast_channel_pbx_set(control->channel, NULL);
+ }
+
+ res = ast_bridge_impart(bridge,
+ control->channel,
+ NULL, /* swap channel */
+ NULL, /* features */
+ 0); /* independent - false allows us to ast_bridge_depart() */
+
+ if (res != 0) {
+ ast_log(LOG_ERROR, "Error adding channel to bridge\n");
+ ast_channel_pbx_set(control->channel, control->pbx);
+ control->pbx = NULL;
+ return;
+ }
+
+ control->bridge = bridge;
+}
+
+void stasis_app_remove_from_bridge(struct stasis_app_control *control)
{
if (!control) {
return;
}
- control->bridge = bridge;
-}
-
-struct ast_bridge *stasis_app_get_bridge(struct stasis_app_control *control)
-{
- if (!control) {
- return NULL;
- }
- return control->bridge;
+
+ ast_bridge_depart(control->channel);
+ ast_channel_pbx_set(control->channel, control->pbx);
+ control->pbx = NULL;
}
const char *stasis_app_control_get_channel_id(
@@ -479,3 +537,24 @@
ao2_iterator_destroy(&i);
return count;
}
+
+void control_wait(struct stasis_app_control *control)
+{
+ ast_mutex_t *queue_lock;
+ if (!control) {
+ return;
+ }
+
+ ast_assert(control->command_queue != NULL);
+
+ queue_lock = ao2_object_get_lockaddr(control->command_queue);
+ ao2_lock(control->command_queue);
+ while (ao2_container_count(control->command_queue) == 0) {
+ int r = ast_cond_wait(&control->wait_cond, queue_lock);
+ if (r < 0) {
+ ast_log(LOG_ERROR, "Error waiting on command queue\n");
+ break;
+ }
+ }
+ ao2_unlock(control->command_queue);
+}
Modified: team/dlee/ari-async-bridge/res/stasis/control.h
URL: http://svnview.digium.com/svn/asterisk/team/dlee/ari-async-bridge/res/stasis/control.h?view=diff&rev=395883&r1=395882&r2=395883
==============================================================================
--- team/dlee/ari-async-bridge/res/stasis/control.h (original)
+++ team/dlee/ari-async-bridge/res/stasis/control.h Wed Jul 31 10:38:56 2013
@@ -48,6 +48,8 @@
int control_dispatch_all(struct stasis_app_control *control,
struct ast_channel *chan);
+void control_wait(struct stasis_app_control *control);
+
int control_is_done(struct stasis_app_control *control);
void control_continue(struct stasis_app_control *control);
More information about the asterisk-commits
mailing list