diff options
author | Jonathan Rose <jrose@digium.com> | 2013-07-19 19:35:21 +0000 |
---|---|---|
committer | Jonathan Rose <jrose@digium.com> | 2013-07-19 19:35:21 +0000 |
commit | 17c546173fe1f24749af4643f19b40be180803de (patch) | |
tree | 46d8cf430d12142587196703c732d5e9ce9bba8e /main/core_unreal.c | |
parent | 5a8f32703c445f7d09b5e029e85d76692626a67f (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.c | 90 |
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; |