summaryrefslogtreecommitdiff
path: root/apps/app_chanspy.c
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2013-05-24 20:44:07 +0000
committerMatthew Jordan <mjordan@digium.com>2013-05-24 20:44:07 +0000
commit06be8463b683333c79845402d55168ef1b582fa9 (patch)
tree2fe0871cfec4d5edf3aae763541ff7efa32a444a /apps/app_chanspy.c
parentc1b51fd2654736fd7c614d1571f904e236006651 (diff)
Migrate a large number of AMI events over to Stasis-Core
This patch moves a number of AMI events over to the Stasis-Core message bus. This includes: * ChanSpyStart/Stop * MonitorStart/Stop * MusicOnHoldStart/Stop * FullyBooted/Reload * All Voicemail/MWI related events In addition, it adds some Stasis-Core and AMI support for generic AMI messages, refactors the message router in AMI to use a single router with topic forwarding for the topics that AMI cares about, and refactors MWI message types and topics to be more name compliant. Review: https://reviewboard.asterisk.org/r/2532 (closes issue ASTERISK-21462) git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389733 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'apps/app_chanspy.c')
-rw-r--r--apps/app_chanspy.c109
1 files changed, 78 insertions, 31 deletions
diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c
index 8e4590781..4e241b96f 100644
--- a/apps/app_chanspy.c
+++ b/apps/app_chanspy.c
@@ -55,6 +55,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#include "asterisk/lock.h"
#include "asterisk/options.h"
#include "asterisk/autochan.h"
+#include "asterisk/stasis_channels.h"
+#include "asterisk/json.h"
#define AST_NAME_STRLEN 256
#define NUM_SPYGROUPS 128
@@ -188,6 +190,8 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</description>
<see-also>
<ref type="application">ExtenSpy</ref>
+ <ref type="managerEvent">ChanSpyStart</ref>
+ <ref type="managerEvent">ChanSpyStop</ref>
</see-also>
</application>
<application name="ExtenSpy" language="en_US">
@@ -322,9 +326,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</description>
<see-also>
<ref type="application">ChanSpy</ref>
+ <ref type="managerEvent">ChanSpyStart</ref>
+ <ref type="managerEvent">ChanSpyStop</ref>
</see-also>
</application>
-
<application name="DAHDIScan" language="en_US">
<synopsis>
Scan DAHDI channels to monitor calls.
@@ -338,6 +343,10 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<para>Allows a call center manager to monitor DAHDI channels in a
convenient way. Use <literal>#</literal> to select the next channel and use <literal>*</literal> to exit.</para>
</description>
+ <see-also>
+ <ref type="managerEvent">ChanSpyStart</ref>
+ <ref type="managerEvent">ChanSpyStop</ref>
+ </see-also>
</application>
***/
@@ -512,6 +521,68 @@ static void change_spy_mode(const char digit, struct ast_flags *flags)
}
}
+static int pack_channel_into_message(struct ast_channel *chan, const char *role,
+ struct ast_multi_channel_blob *payload)
+{
+ RAII_VAR(struct ast_channel_snapshot *, snapshot,
+ ast_channel_snapshot_get_latest(ast_channel_uniqueid(chan)),
+ ao2_cleanup);
+
+ if (!snapshot) {
+ return -1;
+ }
+ ast_multi_channel_blob_add_channel(payload, role, snapshot);
+ return 0;
+}
+
+/*! \internal
+ * \brief Publish the chanspy message over Stasis-Core
+ * \param spyer The channel doing the spying
+ * \param spyee Who is being spied upon
+ * \start start If non-zero, the spying is starting. Otherwise, the spyer is
+ * finishing
+ */
+static void publish_chanspy_message(struct ast_channel *spyer,
+ struct ast_channel *spyee,
+ int start)
+{
+ RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+ RAII_VAR(struct ast_multi_channel_blob *, payload, NULL, ao2_cleanup);
+ RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+
+ if (!spyer) {
+ ast_log(AST_LOG_WARNING, "Attempt to publish ChanSpy message for NULL spyer channel\n");
+ return;
+ }
+ blob = ast_json_null();
+ if (!blob) {
+ return;
+ }
+
+ payload = ast_multi_channel_blob_create(blob);
+ if (!payload) {
+ return;
+ }
+
+ if (pack_channel_into_message(spyer, "spyer_channel", payload)) {
+ return;
+ }
+
+ if (spyee) {
+ if (pack_channel_into_message(spyee, "spyee_channel", payload)) {
+ return;
+ }
+ }
+
+ message = stasis_message_create(
+ start ? ast_channel_chanspy_start_type(): ast_channel_chanspy_stop_type(),
+ payload);
+ if (!message) {
+ return;
+ }
+ stasis_publish(ast_channel_topic(spyer), message);
+}
+
static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_autochan,
int *volfactor, int fd, struct spy_dtmf_options *user_options, struct ast_flags *flags,
char *exitcontext)
@@ -524,38 +595,22 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
struct ast_silence_generator *silgen = NULL;
struct ast_autochan *spyee_bridge_autochan = NULL;
const char *spyer_name;
- struct ast_channel *chans[] = { chan, spyee_autochan->chan };
-
- ast_channel_lock(chan);
- spyer_name = ast_strdupa(ast_channel_name(chan));
- ast_channel_unlock(chan);
-
- /* We now hold the channel lock on spyee */
if (ast_check_hangup(chan) || ast_check_hangup(spyee_autochan->chan) ||
ast_test_flag(ast_channel_flags(spyee_autochan->chan), AST_FLAG_ZOMBIE)) {
return 0;
}
+ ast_channel_lock(chan);
+ spyer_name = ast_strdupa(ast_channel_name(chan));
+ ast_channel_unlock(chan);
+
ast_channel_lock(spyee_autochan->chan);
name = ast_strdupa(ast_channel_name(spyee_autochan->chan));
ast_channel_unlock(spyee_autochan->chan);
ast_verb(2, "Spying on channel %s\n", name);
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when a channel has started spying on another channel.</synopsis>
- <see-also>
- <ref type="application">ChanSpy</ref>
- <ref type="application">ExtenSpy</ref>
- <ref type="managerEvent">ChanSpyStop</ref>
- </see-also>
- </managerEventInstance>
- ***/
- ast_manager_event_multichan(EVENT_FLAG_CALL, "ChanSpyStart", 2, chans,
- "SpyerChannel: %s\r\n"
- "SpyeeChannel: %s\r\n",
- spyer_name, name);
+ publish_chanspy_message(chan, spyee_autochan->chan, 1);
memset(&csth, 0, sizeof(csth));
ast_copy_flags(&csth.flags, flags, AST_FLAGS_ALL);
@@ -740,15 +795,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto
}
ast_verb(2, "Done Spying on channel %s\n", name);
- /*** DOCUMENTATION
- <managerEventInstance>
- <synopsis>Raised when a channel has stopped spying on another channel.</synopsis>
- <see-also>
- <ref type="managerEvent">ChanSpyStart</ref>
- </see-also>
- </managerEventInstance>
- ***/
- ast_manager_event(chan, EVENT_FLAG_CALL, "ChanSpyStop", "SpyeeChannel: %s\r\n", name);
+ publish_chanspy_message(chan, NULL, 0);
return running;
}