summaryrefslogtreecommitdiff
path: root/res/res_stasis.c
diff options
context:
space:
mode:
authorKinsey Moore <kmoore@digium.com>2014-08-11 18:37:14 +0000
committerKinsey Moore <kmoore@digium.com>2014-08-11 18:37:14 +0000
commit406dded64c3b4d71c394284c4f6ca12921a5320a (patch)
tree059193a34c83d53ce93ecbddc69f91bc4fac1876 /res/res_stasis.c
parentef70c08dc7e074bee599c01a6850499ce8889ed6 (diff)
Stasis: Allow internal channels directly into bridges
The patch to catch channels being shoehorned into Stasis() via external mechanisms also happens to catch Announcer and Recorder channels because they aren't known to be stasis-controlled channels in the usual sense. This marks those channels as Stasis()-internal channels and allows them directly into bridges. Review: https://reviewboard.asterisk.org/r/3903/ ........ Merged revisions 420795 from http://svn.asterisk.org/svn/asterisk/branches/12 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@420796 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res/res_stasis.c')
-rw-r--r--res/res_stasis.c68
1 files changed, 68 insertions, 0 deletions
diff --git a/res/res_stasis.c b/res/res_stasis.c
index 3480c9e23..0ef3d6e40 100644
--- a/res/res_stasis.c
+++ b/res/res_stasis.c
@@ -1901,6 +1901,74 @@ static void check_for_stasis_end(void *data, struct stasis_subscription *sub,
remove_masquerade_store_by_name(snapshot->name);
}
+static const struct ast_datastore_info stasis_internal_channel_info = {
+ .type = "stasis-internal-channel",
+};
+
+static int set_internal_datastore(struct ast_channel *chan)
+{
+ struct ast_datastore *datastore;
+
+ datastore = ast_channel_datastore_find(chan, &stasis_internal_channel_info, NULL);
+ if (!datastore) {
+ datastore = ast_datastore_alloc(&stasis_internal_channel_info, NULL);
+ if (!datastore) {
+ return -1;
+ }
+ ast_channel_datastore_add(chan, datastore);
+ }
+ return 0;
+}
+
+int stasis_app_channel_unreal_set_internal(struct ast_channel *chan)
+{
+ struct ast_channel *outchan = NULL, *outowner = NULL;
+ int res = 0;
+ struct ast_unreal_pvt *unreal_pvt = ast_channel_tech_pvt(chan);
+
+ ao2_ref(unreal_pvt, +1);
+ ast_unreal_lock_all(unreal_pvt, &outowner, &outchan);
+ if (outowner) {
+ res |= set_internal_datastore(outowner);
+ ast_channel_unlock(outowner);
+ ast_channel_unref(outowner);
+ }
+ if (outchan) {
+ res |= set_internal_datastore(outchan);
+ ast_channel_unlock(outchan);
+ ast_channel_unref(outchan);
+ }
+ ao2_unlock(unreal_pvt);
+ ao2_ref(unreal_pvt, -1);
+ return 0;
+}
+
+int stasis_app_channel_set_internal(struct ast_channel *chan)
+{
+ int res;
+
+ ast_channel_lock(chan);
+ res = set_internal_datastore(chan);
+ ast_channel_unlock(chan);
+
+ return res;
+}
+
+int stasis_app_channel_is_internal(struct ast_channel *chan)
+{
+ struct ast_datastore *datastore;
+ int res = 0;
+
+ ast_channel_lock(chan);
+ datastore = ast_channel_datastore_find(chan, &stasis_internal_channel_info, NULL);
+ if (datastore) {
+ res = 1;
+ }
+ ast_channel_unlock(chan);
+
+ return res;
+}
+
static int load_module(void)
{
if (STASIS_MESSAGE_TYPE_INIT(ast_stasis_end_message_type) != 0) {