summaryrefslogtreecommitdiff
path: root/main
diff options
context:
space:
mode:
authorJason Parker <jparker@digium.com>2013-05-24 21:21:25 +0000
committerJason Parker <jparker@digium.com>2013-05-24 21:21:25 +0000
commit154fbf8cae866269cb2b64a5cb26cb4d435cf4df (patch)
treebdf1e07244cfee6526570c3b9357da9378981150 /main
parent1223199b3d18b82a931475f939170b9379e6afed (diff)
Split Hold event into Hold/Unhold, and move it into core.
(closes issue ASTERISK-21487) Review: https://reviewboard.asterisk.org/r/2565/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@389746 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'main')
-rw-r--r--main/channel.c41
-rw-r--r--main/manager_channels.c71
-rw-r--r--main/stasis_channels.c7
3 files changed, 116 insertions, 3 deletions
diff --git a/main/channel.c b/main/channel.c
index aec43edf7..f7aa0bf09 100644
--- a/main/channel.c
+++ b/main/channel.c
@@ -1353,9 +1353,11 @@ static void publish_channel_blob(struct ast_channel *chan,
struct stasis_message_type *type, struct ast_json *blob)
{
RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
- if (blob) {
- message = ast_channel_blob_create(chan, type, blob);
+ if (!blob) {
+ blob = ast_json_null();
}
+
+ message = ast_channel_blob_create(chan, type, blob);
if (message) {
stasis_publish(ast_channel_topic(chan), message);
}
@@ -1405,6 +1407,39 @@ int ast_queue_hangup_with_cause(struct ast_channel *chan, int cause)
return res;
}
+int ast_queue_hold(struct ast_channel *chan, const char *musicclass)
+{
+ RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref);
+ RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+ struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_HOLD };
+ int res;
+
+ if (!ast_strlen_zero(musicclass)) {
+ f.data.ptr = (void *) musicclass;
+ f.datalen = strlen(musicclass) + 1;
+
+ blob = ast_json_pack("{s: s}",
+ "musicclass", musicclass);
+ }
+
+ publish_channel_blob(chan, ast_channel_hold_type(), blob);
+
+ res = ast_queue_frame(chan, &f);
+ return res;
+}
+
+int ast_queue_unhold(struct ast_channel *chan)
+{
+ RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup);
+ struct ast_frame f = { AST_FRAME_CONTROL, .subclass.integer = AST_CONTROL_UNHOLD };
+ int res;
+
+ publish_channel_blob(chan, ast_channel_unhold_type(), NULL);
+
+ res = ast_queue_frame(chan, &f);
+ return res;
+}
+
/*! \brief Queue a control frame */
int ast_queue_control(struct ast_channel *chan, enum ast_control_frame_type control)
{
@@ -6694,7 +6729,7 @@ static void masquerade_colp_transfer(struct ast_channel *transferee, struct xfer
/* Release any hold on the target. */
if (colp->target_held) {
- ast_queue_control(transferee, AST_CONTROL_UNHOLD);
+ ast_queue_unhold(transferee);
}
/*
diff --git a/main/manager_channels.c b/main/manager_channels.c
index f3c72ec4c..a66080cba 100644
--- a/main/manager_channels.c
+++ b/main/manager_channels.c
@@ -228,6 +228,25 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
</see-also>
</managerEventInstance>
</managerEvent>
+ <managerEvent language="en_US" name="Hold">
+ <managerEventInstance class="EVENT_FLAG_CALL">
+ <synopsis>Raised when a channel goes on hold.</synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+ <parameter name="MusicClass">
+ <para>The suggested MusicClass, if provided.</para>
+ </parameter>
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
+ <managerEvent language="en_US" name="Unhold">
+ <managerEventInstance class="EVENT_FLAG_CALL">
+ <synopsis>Raised when a channel goes off hold.</synopsis>
+ <syntax>
+ <xi:include xpointer="xpointer(/docs/managerEvent[@name='Newchannel']/managerEventInstance/syntax/parameter)" />
+ </syntax>
+ </managerEventInstance>
+ </managerEvent>
<managerEvent language="en_US" name="ChanSpyStart">
<managerEventInstance class="EVENT_FLAG_CALL">
<synopsis>Raised when one channel begins spying on another channel.</synopsis>
@@ -1180,6 +1199,48 @@ static void channel_dial_cb(void *data, struct stasis_subscription *sub,
}
+static void channel_hold_cb(void *data, struct stasis_subscription *sub,
+ struct stasis_topic *topic, struct stasis_message *message)
+{
+ struct ast_channel_blob *obj = stasis_message_data(message);
+ const char *musicclass;
+ RAII_VAR(struct ast_str *, musicclass_string, NULL, ast_free);
+ RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
+
+ if (!(musicclass_string = ast_str_create(32))) {
+ return;
+ }
+
+ channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
+
+ if (obj->blob) {
+ musicclass = ast_json_string_get(ast_json_object_get(obj->blob, "musicclass"));
+
+ if (!ast_strlen_zero(musicclass)) {
+ ast_str_set(&musicclass_string, 0, "MusicClass: %s\r\n", musicclass);
+ }
+ }
+
+ manager_event(EVENT_FLAG_CALL, "Hold",
+ "%s"
+ "%s",
+ ast_str_buffer(channel_event_string),
+ ast_str_buffer(musicclass_string));
+}
+
+static void channel_unhold_cb(void *data, struct stasis_subscription *sub,
+ struct stasis_topic *topic, struct stasis_message *message)
+{
+ struct ast_channel_blob *obj = stasis_message_data(message);
+ RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free);
+
+ channel_event_string = ast_manager_build_channel_state_string(obj->snapshot);
+
+ manager_event(EVENT_FLAG_CALL, "Unhold",
+ "%s",
+ ast_str_buffer(channel_event_string));
+}
+
static void manager_channels_shutdown(void)
{
stasis_unsubscribe(topic_forwarder);
@@ -1249,6 +1310,16 @@ int manager_channels_init(void)
NULL);
ret |= stasis_message_router_add(message_router,
+ ast_channel_hold_type(),
+ channel_hold_cb,
+ NULL);
+
+ ret |= stasis_message_router_add(message_router,
+ ast_channel_unhold_type(),
+ channel_unhold_cb,
+ NULL);
+
+ ret |= stasis_message_router_add(message_router,
ast_channel_fax_type(),
channel_fax_cb,
NULL);
diff --git a/main/stasis_channels.c b/main/stasis_channels.c
index d3c543ac5..249576b49 100644
--- a/main/stasis_channels.c
+++ b/main/stasis_channels.c
@@ -48,6 +48,8 @@ STASIS_MESSAGE_TYPE_DEFN(ast_channel_user_event_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_hangup_request_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_dtmf_begin_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_dtmf_end_type);
+STASIS_MESSAGE_TYPE_DEFN(ast_channel_hold_type);
+STASIS_MESSAGE_TYPE_DEFN(ast_channel_unhold_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_chanspy_start_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_chanspy_stop_type);
STASIS_MESSAGE_TYPE_DEFN(ast_channel_fax_type);
@@ -585,6 +587,8 @@ void ast_stasis_channels_shutdown(void)
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_hangup_request_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_dtmf_begin_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_dtmf_end_type);
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_hold_type);
+ STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_unhold_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_chanspy_start_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_chanspy_stop_type);
STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_fax_type);
@@ -604,6 +608,8 @@ void ast_stasis_channels_init(void)
STASIS_MESSAGE_TYPE_INIT(ast_channel_hangup_request_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_dtmf_begin_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_dtmf_end_type);
+ STASIS_MESSAGE_TYPE_INIT(ast_channel_hold_type);
+ STASIS_MESSAGE_TYPE_INIT(ast_channel_unhold_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_chanspy_start_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_chanspy_stop_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_fax_type);
@@ -612,6 +618,7 @@ void ast_stasis_channels_init(void)
STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_stop_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_start_type);
STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_stop_type);
+
channel_topic_all = stasis_topic_create("ast_channel_topic_all");
channel_topic_all_cached = stasis_caching_topic_create(channel_topic_all, channel_snapshot_get_id);
}