diff --git a/apps/app_mixmonitor.c b/apps/app_mixmonitor.c index 239901f0acb733f2ecd8f599952c0dfb22d2d3ad..374c567a997c725647f88100b836dd66045bc4ce 100644 --- a/apps/app_mixmonitor.c +++ b/apps/app_mixmonitor.c @@ -51,6 +51,8 @@ #include "asterisk/channel.h" #include "asterisk/autochan.h" #include "asterisk/manager.h" +#include "asterisk/stasis.h" +#include "asterisk/stasis_channels.h" #include "asterisk/callerid.h" #include "asterisk/mod_format.h" #include "asterisk/linkedlists.h" @@ -295,6 +297,51 @@ </parameter> </syntax> </function> + <managerEvent language="en_US" name="MixMonitorStart"> + <managerEventInstance class="EVENT_FLAG_CALL"> + <synopsis>Raised when monitoring has started on a channel.</synopsis> + <syntax> + <channel_snapshot/> + </syntax> + <see-also> + <ref type="managerEvent">MixMonitorStop</ref> + <ref type="application">MixMonitor</ref> + <ref type="manager">MixMonitor</ref> + </see-also> + </managerEventInstance> + </managerEvent> + <managerEvent language="en_US" name="MixMonitorStop"> + <managerEventInstance class="EVENT_FLAG_CALL"> + <synopsis>Raised when monitoring has stopped on a channel.</synopsis> + <syntax> + <channel_snapshot/> + </syntax> + <see-also> + <ref type="managerEvent">MixMonitorStart</ref> + <ref type="application">StopMixMonitor</ref> + <ref type="manager">StopMixMonitor</ref> + </see-also> + </managerEventInstance> + </managerEvent> + <managerEvent language="en_US" name="MixMonitorMute"> + <managerEventInstance class="EVENT_FLAG_CALL"> + <synopsis>Raised when monitoring is muted or unmuted on a channel.</synopsis> + <syntax> + <channel_snapshot/> + <parameter name="Direction"> + <para>Which part of the recording was muted or unmuted: read, write or both + (from channel, to channel or both directions).</para> + </parameter> + <parameter name="State"> + <para>If the monitoring was muted or unmuted: 1 when muted, 0 when unmuted.</para> + </parameter> + </syntax> + <see-also> + <ref type="manager">MixMonitorMute</ref> + </see-also> + </managerEventInstance> + </managerEvent> + ***/ @@ -1077,6 +1124,7 @@ static int mixmonitor_exec(struct ast_channel *chan, const char *data) struct ast_flags flags = { 0 }; char *recipients = NULL; char *parse; + RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); AST_DECLARE_APP_ARGS(args, AST_APP_ARG(filename); AST_APP_ARG(options); @@ -1197,6 +1245,12 @@ static int mixmonitor_exec(struct ast_channel *chan, const char *data) ast_module_unref(ast_module_info->self); } + message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), + ast_channel_mixmonitor_start_type(), NULL); + if (message) { + stasis_publish(ast_channel_topic(chan), message); + } + return 0; } @@ -1206,6 +1260,7 @@ static int stop_mixmonitor_full(struct ast_channel *chan, const char *data) char *parse = ""; struct mixmonitor_ds *mixmonitor_ds; const char *beep_id = NULL; + RAII_VAR(struct stasis_message *, message, NULL, ao2_cleanup); AST_DECLARE_APP_ARGS(args, AST_APP_ARG(mixmonid); @@ -1263,6 +1318,13 @@ static int stop_mixmonitor_full(struct ast_channel *chan, const char *data) ast_beep_stop(chan, beep_id); } + message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), + ast_channel_mixmonitor_stop_type(), + NULL); + if (message) { + stasis_publish(ast_channel_topic(chan), message); + } + return 0; } @@ -1350,6 +1412,8 @@ static int manager_mute_mixmonitor(struct mansession *s, const struct message *m const char *direction = astman_get_header(m,"Direction"); int clearmute = 1; enum ast_audiohook_flags flag; + RAII_VAR(struct stasis_message *, stasis_message, NULL, ao2_cleanup); + RAII_VAR(struct ast_json *, stasis_message_blob, NULL, ast_json_unref); if (ast_strlen_zero(direction)) { astman_send_error(s, m, "No direction specified. Must be read, write or both"); @@ -1391,6 +1455,17 @@ static int manager_mute_mixmonitor(struct mansession *s, const struct message *m return AMI_SUCCESS; } + stasis_message_blob = ast_json_pack("{s: s, s: b}", + "direction", direction, + "state", ast_true(state)); + + stasis_message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(c), + ast_channel_mixmonitor_mute_type(), stasis_message_blob); + + if (stasis_message) { + stasis_publish(ast_channel_topic(c), stasis_message); + } + astman_append(s, "Response: Success\r\n"); if (!ast_strlen_zero(id)) { diff --git a/configs/samples/stasis.conf.sample b/configs/samples/stasis.conf.sample index e591e7637fd651b0146cfa95574c3ad695288c2e..46a240eb25e75f57fd2b76b22f2edea5c5a00db5 100644 --- a/configs/samples/stasis.conf.sample +++ b/configs/samples/stasis.conf.sample @@ -63,6 +63,8 @@ ; decline=ast_channel_moh_stop_type ; decline=ast_channel_monitor_start_type ; decline=ast_channel_monitor_stop_type +; decline=ast_channel_mixmonitor_start_type +; decline=ast_channel_mixmonitor_stop_type ; decline=ast_channel_agent_login_type ; decline=ast_channel_agent_logoff_type ; decline=ast_channel_talking_start diff --git a/doc/CHANGES-staging/mixmonitor_manager_events.txt b/doc/CHANGES-staging/mixmonitor_manager_events.txt new file mode 100644 index 0000000000000000000000000000000000000000..64b63e52e795283df3f9d922cc15b5bab6d51d6b --- /dev/null +++ b/doc/CHANGES-staging/mixmonitor_manager_events.txt @@ -0,0 +1,5 @@ +Subject: app_mixmonitor + +app_mixmonitor now sends manager events MixMonitorStart, MixMonitorStop and +MixMonitorMute when the channel monitoring is started, stopped and muted (or +unmuted) respectively. diff --git a/include/asterisk/stasis_channels.h b/include/asterisk/stasis_channels.h index 9c4798496709518d0a34f56c105f9b9fcaa77866..02654e91be24376bf78521e007759223357aad02 100644 --- a/include/asterisk/stasis_channels.h +++ b/include/asterisk/stasis_channels.h @@ -590,7 +590,31 @@ struct stasis_message_type *ast_channel_monitor_start_type(void); struct stasis_message_type *ast_channel_monitor_stop_type(void); /*! - * \since 12.0.0 + * \since 18 + * \brief Message type for starting mixmonitor on a channel + * + * \retval A stasis message type + */ +struct stasis_message_type *ast_channel_mixmonitor_start_type(void); + +/*! + * \since 18 + * \brief Message type for stopping mixmonitor on a channel + * + * \retval A stasis message type + */ +struct stasis_message_type *ast_channel_mixmonitor_stop_type(void); + +/*! + * \since 18 + * \brief Message type for muting or unmuting mixmonitor on a channel + * + * \retval A stasis message type + */ +struct stasis_message_type *ast_channel_mixmonitor_mute_type(void); + +/*! + * \since 18.0.0 * \brief Message type for agent login on a channel * * \retval A stasis message type diff --git a/main/manager_channels.c b/main/manager_channels.c index 73b76c88b9fae2bc430932f41a86a4a5ebfc8708..7f40efe54cdcaf1b566bb494f0111b728551f6bf 100644 --- a/main/manager_channels.c +++ b/main/manager_channels.c @@ -1116,6 +1116,53 @@ static void channel_monitor_stop_cb(void *data, struct stasis_subscription *sub, publish_basic_channel_event("MonitorStop", EVENT_FLAG_CALL, payload->snapshot); } +static void channel_mixmonitor_start_cb(void *data, struct stasis_subscription *sub, + struct stasis_message *message) +{ + struct ast_channel_blob *payload = stasis_message_data(message); + + publish_basic_channel_event("MixMonitorStart", EVENT_FLAG_CALL, payload->snapshot); +} + +static void channel_mixmonitor_stop_cb(void *data, struct stasis_subscription *sub, + struct stasis_message *message) +{ + struct ast_channel_blob *payload = stasis_message_data(message); + + publish_basic_channel_event("MixMonitorStop", EVENT_FLAG_CALL, payload->snapshot); +} + +static void channel_mixmonitor_mute_cb(void *data, struct stasis_subscription *sub, + struct stasis_message *message) +{ + RAII_VAR(struct ast_str *, channel_event_string, NULL, ast_free); + RAII_VAR(struct ast_str *, event_buffer, ast_str_create(64), ast_free); + struct ast_channel_blob *payload = stasis_message_data(message); + struct ast_json *direction = ast_json_object_get(payload->blob, "direction"); + const int state = ast_json_is_true(ast_json_object_get(payload->blob, "state")); + + if (!event_buffer) { + return; + } + + channel_event_string = ast_manager_build_channel_state_string(payload->snapshot); + if (!channel_event_string) { + return; + } + + if (direction) { + ast_str_append(&event_buffer, 0, "Direction: %s\r\n", ast_json_string_get(direction)); + } + ast_str_append(&event_buffer, 0, "State: %s\r\n", state ? "1" : "0"); + + manager_event(EVENT_FLAG_CALL, "MixMonitorMute", + "%s" + "%s", + ast_str_buffer(channel_event_string), + ast_str_buffer(event_buffer)); + +} + static int dial_status_end(const char *dialstatus) { return (strcmp(dialstatus, "RINGING") && @@ -1320,6 +1367,15 @@ int manager_channels_init(void) ret |= stasis_message_router_add(message_router, ast_channel_monitor_stop_type(), channel_monitor_stop_cb, NULL); + ret |= stasis_message_router_add(message_router, + ast_channel_mixmonitor_start_type(), channel_mixmonitor_start_cb, NULL); + + ret |= stasis_message_router_add(message_router, + ast_channel_mixmonitor_stop_type(), channel_mixmonitor_stop_cb, NULL); + + ret |= stasis_message_router_add(message_router, + ast_channel_mixmonitor_mute_type(), channel_mixmonitor_mute_cb, NULL); + /* If somehow we failed to add any routes, just shut down the whole * thing and fail it. */ diff --git a/main/stasis.c b/main/stasis.c index 44d5973fc0b788fe24dd29dc57ff88ec0b3f7901..4ae6d6a357da0b082b8fe08bcc28dc8d6312057d 100644 --- a/main/stasis.c +++ b/main/stasis.c @@ -130,6 +130,9 @@ <enum name="ast_channel_moh_stop_type" /> <enum name="ast_channel_monitor_start_type" /> <enum name="ast_channel_monitor_stop_type" /> + <enum name="ast_channel_mixmonitor_start_type" /> + <enum name="ast_channel_mixmonitor_stop_type" /> + <enum name="ast_channel_mixmonitor_mute_type" /> <enum name="ast_channel_agent_login_type" /> <enum name="ast_channel_agent_logoff_type" /> <enum name="ast_channel_talking_start" /> diff --git a/main/stasis_channels.c b/main/stasis_channels.c index 3d213c745eb79b85f03e5b5b26a043ebbd390826..3f3312be1a0850c2a8efe9fcfe26d5545a210f44 100644 --- a/main/stasis_channels.c +++ b/main/stasis_channels.c @@ -1606,6 +1606,9 @@ STASIS_MESSAGE_TYPE_DEFN(ast_channel_moh_start_type); STASIS_MESSAGE_TYPE_DEFN(ast_channel_moh_stop_type); STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_start_type); STASIS_MESSAGE_TYPE_DEFN(ast_channel_monitor_stop_type); +STASIS_MESSAGE_TYPE_DEFN(ast_channel_mixmonitor_start_type); +STASIS_MESSAGE_TYPE_DEFN(ast_channel_mixmonitor_stop_type); +STASIS_MESSAGE_TYPE_DEFN(ast_channel_mixmonitor_mute_type); STASIS_MESSAGE_TYPE_DEFN(ast_channel_agent_login_type, .to_ami = agent_login_to_ami, ); @@ -1649,6 +1652,9 @@ static void stasis_channels_cleanup(void) STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_moh_stop_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_start_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_monitor_stop_type); + STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_mixmonitor_start_type); + STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_mixmonitor_stop_type); + STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_mixmonitor_mute_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_login_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_agent_logoff_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_channel_talking_start); @@ -1699,6 +1705,9 @@ int ast_stasis_channels_init(void) res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_moh_stop_type); res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_start_type); res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_monitor_stop_type); + res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_mixmonitor_start_type); + res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_mixmonitor_stop_type); + res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_mixmonitor_mute_type); res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_talking_start); res |= STASIS_MESSAGE_TYPE_INIT(ast_channel_talking_stop);