123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570 |
- /*
- * Asterisk -- An open source telephony toolkit.
- *
- * Copyright (C) 2013, Digium, Inc.
- *
- * Jonathan Rose <jrose@digium.com>
- *
- * See http://www.asterisk.org for more information about
- * the Asterisk project. Please do not directly contact
- * any of the maintainers of this project for assistance;
- * the project provides a web site, mailing lists and IRC
- * channels for your use.
- *
- * This program is free software, distributed under the terms of
- * the GNU General Public License Version 2. See the LICENSE file
- * at the top of the source tree.
- */
- /*! \file
- *
- * \brief Confbridge manager events for stasis messages
- *
- * \author Jonathan Rose <jrose@digium.com>
- */
- #include "asterisk.h"
- ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
- #include "asterisk/channel.h"
- #include "asterisk/bridge.h"
- #include "asterisk/stasis.h"
- #include "asterisk/stasis_channels.h"
- #include "asterisk/stasis_bridges.h"
- #include "asterisk/manager.h"
- #include "asterisk/stasis_message_router.h"
- #include "include/confbridge.h"
- /*** DOCUMENTATION
- <managerEvent language="en_US" name="ConfbridgeStart">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a conference starts.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeEnd</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeEnd">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a conference ends.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeStart</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeJoin">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a channel joins a Confbridge conference.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- <channel_snapshot/>
- <parameter name="Admin">
- <para>Identifies this user as an admin user.</para>
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- <parameter name="Muted">
- <para>The joining mute status.</para>
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeLeave</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeLeave">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a channel leaves a Confbridge conference.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- <channel_snapshot/>
- <parameter name="Admin">
- <para>Identifies this user as an admin user.</para>
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeJoin</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeRecord">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a conference starts recording.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeStopRecord</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeStopRecord">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a conference that was recording stops recording.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeRecord</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeMute">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a Confbridge participant mutes.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- <channel_snapshot/>
- <parameter name="Admin">
- <para>Identifies this user as an admin user.</para>
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeUnmute</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeUnmute">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a confbridge participant unmutes.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- <channel_snapshot/>
- <parameter name="Admin">
- <para>Identifies this user as an admin user.</para>
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- </syntax>
- <see-also>
- <ref type="managerEvent">ConfbridgeMute</ref>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- <managerEvent language="en_US" name="ConfbridgeTalking">
- <managerEventInstance class="EVENT_FLAG_CALL">
- <synopsis>Raised when a confbridge participant begins or ends talking.</synopsis>
- <syntax>
- <parameter name="Conference">
- <para>The name of the Confbridge conference.</para>
- </parameter>
- <bridge_snapshot/>
- <channel_snapshot/>
- <parameter name="TalkingStatus">
- <enumlist>
- <enum name="on"/>
- <enum name="off"/>
- </enumlist>
- </parameter>
- <parameter name="Admin">
- <para>Identifies this user as an admin user.</para>
- <enumlist>
- <enum name="Yes"/>
- <enum name="No"/>
- </enumlist>
- </parameter>
- </syntax>
- <see-also>
- <ref type="application">ConfBridge</ref>
- </see-also>
- </managerEventInstance>
- </managerEvent>
- ***/
- static struct stasis_message_router *bridge_state_router;
- static struct stasis_message_router *channel_state_router;
- static void confbridge_publish_manager_event(
- struct stasis_message *message,
- const char *event,
- struct ast_str *extra_text)
- {
- struct ast_bridge_blob *blob = stasis_message_data(message);
- const char *conference_name;
- RAII_VAR(struct ast_str *, bridge_text, NULL, ast_free);
- RAII_VAR(struct ast_str *, channel_text, NULL, ast_free);
- ast_assert(blob != NULL);
- ast_assert(event != NULL);
- bridge_text = ast_manager_build_bridge_state_string(blob->bridge);
- if (!bridge_text) {
- return;
- }
- conference_name = ast_json_string_get(ast_json_object_get(blob->blob, "conference"));
- ast_assert(conference_name != NULL);
- if (blob->channel) {
- channel_text = ast_manager_build_channel_state_string(blob->channel);
- }
- manager_event(EVENT_FLAG_CALL, event,
- "Conference: %s\r\n"
- "%s"
- "%s"
- "%s",
- conference_name,
- ast_str_buffer(bridge_text),
- channel_text ? ast_str_buffer(channel_text) : "",
- extra_text ? ast_str_buffer(extra_text) : "");
- }
- static int get_bool_header(struct ast_str **extra_text, struct stasis_message *message,
- const char *json_key, const char *ami_header)
- {
- const struct ast_bridge_blob *blob = stasis_message_data(message);
- const struct ast_json *obj;
- obj = ast_json_object_get(blob->blob, json_key);
- if (!obj) {
- return -1;
- }
- return ast_str_append_event_header(extra_text, ami_header,
- AST_YESNO(ast_json_is_true(obj)));
- }
- static int get_admin_header(struct ast_str **extra_text, struct stasis_message *message)
- {
- return get_bool_header(extra_text, message, "admin", "Admin");
- }
- static int get_muted_header(struct ast_str **extra_text, struct stasis_message *message)
- {
- return get_bool_header(extra_text, message, "muted", "Muted");
- }
- static void confbridge_start_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- confbridge_publish_manager_event(message, "ConfbridgeStart", NULL);
- }
- static void confbridge_end_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- confbridge_publish_manager_event(message, "ConfbridgeEnd", NULL);
- }
- static void confbridge_leave_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- struct ast_str *extra_text = NULL;
- if (!get_admin_header(&extra_text, message)) {
- confbridge_publish_manager_event(message, "ConfbridgeLeave", extra_text);
- }
- ast_free(extra_text);
- }
- static void confbridge_join_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- struct ast_str *extra_text = NULL;
- if (!get_admin_header(&extra_text, message)
- && !get_muted_header(&extra_text, message)) {
- confbridge_publish_manager_event(message, "ConfbridgeJoin", extra_text);
- }
- ast_free(extra_text);
- }
- static void confbridge_start_record_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- confbridge_publish_manager_event(message, "ConfbridgeRecord", NULL);
- }
- static void confbridge_stop_record_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- confbridge_publish_manager_event(message, "ConfbridgeStopRecord", NULL);
- }
- static void confbridge_mute_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- struct ast_str *extra_text = NULL;
- if (!get_admin_header(&extra_text, message)) {
- confbridge_publish_manager_event(message, "ConfbridgeMute", extra_text);
- }
- ast_free(extra_text);
- }
- static void confbridge_unmute_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- struct ast_str *extra_text = NULL;
- if (!get_admin_header(&extra_text, message)) {
- confbridge_publish_manager_event(message, "ConfbridgeUnmute", extra_text);
- }
- ast_free(extra_text);
- }
- static void confbridge_talking_cb(void *data, struct stasis_subscription *sub,
- struct stasis_message *message)
- {
- RAII_VAR(struct ast_str *, extra_text, NULL, ast_free);
- const struct ast_bridge_blob *blob = stasis_message_data(message);
- const char *talking_status = ast_json_string_get(ast_json_object_get(blob->blob, "talking_status"));
- if (!talking_status) {
- return;
- }
- ast_str_append_event_header(&extra_text, "TalkingStatus", talking_status);
- if (!extra_text) {
- return;
- }
- if (!get_admin_header(&extra_text, message)) {
- confbridge_publish_manager_event(message, "ConfbridgeTalking", extra_text);
- }
- }
- STASIS_MESSAGE_TYPE_DEFN(confbridge_start_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_end_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_join_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_leave_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_start_record_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_stop_record_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_mute_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_unmute_type);
- STASIS_MESSAGE_TYPE_DEFN(confbridge_talking_type);
- void manager_confbridge_shutdown(void) {
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_start_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_end_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_join_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_leave_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_start_record_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_stop_record_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_mute_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_unmute_type);
- STASIS_MESSAGE_TYPE_CLEANUP(confbridge_talking_type);
- if (bridge_state_router) {
- stasis_message_router_unsubscribe(bridge_state_router);
- bridge_state_router = NULL;
- }
- if (channel_state_router) {
- stasis_message_router_unsubscribe(channel_state_router);
- channel_state_router = NULL;
- }
- }
- int manager_confbridge_init(void)
- {
- STASIS_MESSAGE_TYPE_INIT(confbridge_start_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_end_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_join_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_leave_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_start_record_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_stop_record_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_mute_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_unmute_type);
- STASIS_MESSAGE_TYPE_INIT(confbridge_talking_type);
- bridge_state_router = stasis_message_router_create(
- ast_bridge_topic_all_cached());
- if (!bridge_state_router) {
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_start_type(),
- confbridge_start_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_end_type(),
- confbridge_end_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_join_type(),
- confbridge_join_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_leave_type(),
- confbridge_leave_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_start_record_type(),
- confbridge_start_record_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_stop_record_type(),
- confbridge_stop_record_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_mute_type(),
- confbridge_mute_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_unmute_type(),
- confbridge_unmute_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(bridge_state_router,
- confbridge_talking_type(),
- confbridge_talking_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- channel_state_router = stasis_message_router_create(
- ast_channel_topic_all_cached());
- if (!channel_state_router) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_start_type(),
- confbridge_start_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_end_type(),
- confbridge_end_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_join_type(),
- confbridge_join_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_leave_type(),
- confbridge_leave_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_start_record_type(),
- confbridge_start_record_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_stop_record_type(),
- confbridge_stop_record_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_mute_type(),
- confbridge_mute_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_unmute_type(),
- confbridge_unmute_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- if (stasis_message_router_add(channel_state_router,
- confbridge_talking_type(),
- confbridge_talking_cb,
- NULL)) {
- manager_confbridge_shutdown();
- return -1;
- }
- return 0;
- }
|