summaryrefslogtreecommitdiff
path: root/main/core_unreal.c
diff options
context:
space:
mode:
authorJonathan Rose <jrose@digium.com>2013-07-19 19:35:21 +0000
committerJonathan Rose <jrose@digium.com>2013-07-19 19:35:21 +0000
commit17c546173fe1f24749af4643f19b40be180803de (patch)
tree46d8cf430d12142587196703c732d5e9ce9bba8e /main/core_unreal.c
parent5a8f32703c445f7d09b5e029e85d76692626a67f (diff)
ARI: Bridge Playback, Bridge Record
Adds a new channel driver for creating channels for specific purposes in bridges, primarily to act as either recorders or announcers. Adds ARI commands for playing announcements to ever participant in a bridge as well as for recording a bridge. This patch also includes some documentation/reponse fixes to related ARI models such as playback controls. (closes issue ASTERISK-21592) Reported by: Matt Jordan (closes issue ASTERISK-21593) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/2670/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@394809 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main/core_unreal.c')
-rw-r--r--main/core_unreal.c90
1 files changed, 90 insertions, 0 deletions
diff --git a/main/core_unreal.c b/main/core_unreal.c
index 71d0f6c8f..3d14a716f 100644
--- a/main/core_unreal.c
+++ b/main/core_unreal.c
@@ -668,6 +668,96 @@ void ast_unreal_call_setup(struct ast_channel *semi1, struct ast_channel *semi2)
ast_channel_datastore_inherit(semi1, semi2);
}
+int ast_unreal_channel_push_to_bridge(struct ast_channel *ast, struct ast_bridge *bridge)
+{
+ struct ast_bridge_features *features;
+ struct ast_channel *chan;
+ struct ast_channel *owner;
+ RAII_VAR(struct ast_unreal_pvt *, p, NULL, ao2_cleanup);
+
+ RAII_VAR(struct ast_callid *, bridge_callid, NULL, ast_callid_cleanup);
+
+ ast_bridge_lock(bridge);
+ bridge_callid = bridge->callid ? ast_callid_ref(bridge->callid) : NULL;
+ ast_bridge_unlock(bridge);
+
+ {
+ SCOPED_CHANNELLOCK(lock, ast);
+ p = ast_channel_tech_pvt(ast);
+ if (!p) {
+ return -1;
+ }
+ ao2_ref(p, +1);
+ }
+
+ {
+ SCOPED_AO2LOCK(lock, p);
+ chan = p->chan;
+ if (!chan) {
+ return -1;
+ }
+
+ owner = p->owner;
+ if (!owner) {
+ return -1;
+ }
+
+ ast_channel_ref(chan);
+ ast_channel_ref(owner);
+ }
+
+ if (bridge_callid) {
+ struct ast_callid *chan_callid;
+ struct ast_callid *owner_callid;
+
+ /* chan side call ID setting */
+ ast_channel_lock(chan);
+
+ chan_callid = ast_channel_callid(chan);
+ if (!chan_callid) {
+ ast_channel_callid_set(chan, bridge_callid);
+ }
+ ast_channel_unlock(chan);
+ ast_callid_cleanup(chan_callid);
+
+ /* owner side call ID setting */
+ ast_channel_lock(owner);
+
+ owner_callid = ast_channel_callid(owner);
+ if (!owner_callid) {
+ ast_channel_callid_set(owner, bridge_callid);
+ }
+
+ ast_channel_unlock(owner);
+ ast_callid_cleanup(owner_callid);
+ }
+
+ /* We are done with the owner now that its call ID matches the bridge */
+ ast_channel_unref(owner);
+ owner = NULL;
+
+ features = ast_bridge_features_new();
+ if (!features) {
+ ast_channel_unref(chan);
+ return -1;
+ }
+ ast_set_flag(&features->feature_flags, AST_BRIDGE_CHANNEL_FLAG_IMMOVABLE);
+
+ /* Impart the semi2 channel into the bridge */
+ if (ast_bridge_impart(bridge, chan, NULL, features, 1)) {
+ ast_bridge_features_destroy(features);
+ ast_channel_unref(chan);
+ return -1;
+ }
+
+ ao2_lock(p);
+ ast_set_flag(p, AST_UNREAL_CARETAKER_THREAD);
+ ao2_unlock(p);
+ ast_channel_unref(chan);
+
+ return 0;
+}
+
int ast_unreal_hangup(struct ast_unreal_pvt *p, struct ast_channel *ast)
{
int hangup_chan = 0;