/* * Asterisk -- An open source telephony toolkit. * * Copyright (C) 2013, Digium, Inc. * * Jason Parker * * 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 Stasis Messages and Data Types for System events * * \author Jason Parker */ /*** MODULEINFO core ***/ #include "asterisk.h" #include "asterisk/astobj2.h" #include "asterisk/stasis.h" #include "asterisk/stasis_system.h" /*** DOCUMENTATION Raised when an outbound registration completes. The type of channel that was registered (or not). The username portion of the registration. The address portion of the registration. The status of the registration request. What caused the rejection of the request, if available. ***/ /*! \brief The \ref stasis topic for system level changes */ static struct stasis_topic *system_topic; static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_available_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_offertimerstart_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_requested_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_requestacknowledged_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_callerstopmonitoring_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_callerstartmonitoring_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_callerrecalling_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_recallcomplete_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_failure_to_ami(struct stasis_message *message); static struct ast_manager_event_blob *cc_monitorfailed_to_ami(struct stasis_message *message); STASIS_MESSAGE_TYPE_DEFN(ast_network_change_type); STASIS_MESSAGE_TYPE_DEFN(ast_system_registry_type, .to_ami = system_registry_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_available_type, .to_ami = cc_available_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_offertimerstart_type, .to_ami = cc_offertimerstart_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_requested_type, .to_ami = cc_requested_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_requestacknowledged_type, .to_ami = cc_requestacknowledged_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerstopmonitoring_type, .to_ami = cc_callerstopmonitoring_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerstartmonitoring_type, .to_ami = cc_callerstartmonitoring_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_callerrecalling_type, .to_ami = cc_callerrecalling_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_recallcomplete_type, .to_ami = cc_recallcomplete_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_failure_type, .to_ami = cc_failure_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cc_monitorfailed_type, .to_ami = cc_monitorfailed_to_ami, ); STASIS_MESSAGE_TYPE_DEFN(ast_cluster_discovery_type); void ast_system_publish_registry(const char *channeltype, const char *username, const char *domain, const char *status, const char *cause) { struct ast_json *registry; struct ast_json_payload *payload; struct stasis_message *message; if (!ast_system_registry_type()) { return; } registry = ast_json_pack("{s: s, s: s, s: s, s: s, s: s, s: s}", "type", "registry", "channeltype", channeltype, "username", username, "domain", domain, "status", status, "cause", S_OR(cause, "")); payload = ast_json_payload_create(registry); ast_json_unref(registry); if (!payload) { return; } message = stasis_message_create(ast_system_registry_type(), payload); ao2_ref(payload, -1); if (!message) { return; } stasis_publish(ast_system_topic(), message); ao2_ref(message, -1); } static struct ast_manager_event_blob *system_registry_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); const char *channeltype; const char *username; const char *domain; const char *status; const char *cause; RAII_VAR(struct ast_str *, cause_string, ast_str_create(32), ast_free); if (!cause_string) { return NULL; } channeltype = ast_json_string_get(ast_json_object_get(payload->json, "channeltype")); username = ast_json_string_get(ast_json_object_get(payload->json, "username")); domain = ast_json_string_get(ast_json_object_get(payload->json, "domain")); status = ast_json_string_get(ast_json_object_get(payload->json, "status")); cause = ast_json_string_get(ast_json_object_get(payload->json, "cause")); if (!ast_strlen_zero(cause)) { ast_str_set(&cause_string, 0, "Cause: %s\r\n", cause); } return ast_manager_event_blob_create(EVENT_FLAG_SYSTEM, "Registry", "ChannelType: %s\r\n" "Username: %s\r\n" "Domain: %s\r\n" "Status: %s\r\n" "%s", channeltype, username, domain, status, ast_str_buffer(cause_string)); } static struct ast_manager_event_blob *cc_available_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *callee; const char *service; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); callee = ast_json_string_get(ast_json_object_get(payload->json, "callee")); service = ast_json_string_get(ast_json_object_get(payload->json, "service")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCAvailable", "CoreID: %d\r\n" "Callee: %s\r\n" "Service: %s\r\n", core_id, callee, service); } static struct ast_manager_event_blob *cc_offertimerstart_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; unsigned int expires; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); expires = ast_json_integer_get(ast_json_object_get(payload->json, "expires")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCOfferTimerStart", "CoreID: %d\r\n" "Caller: %s\r\n" "Expires: %u\r\n", core_id, caller, expires); } static struct ast_manager_event_blob *cc_requested_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; const char *callee; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); callee = ast_json_string_get(ast_json_object_get(payload->json, "callee")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequested", "CoreID: %d\r\n" "Caller: %s\r\n" "Callee: %s\r\n", core_id, caller, callee); } static struct ast_manager_event_blob *cc_requestacknowledged_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRequestAcknowledged", "CoreID: %d\r\n" "Caller: %s\r\n", core_id, caller); } static struct ast_manager_event_blob *cc_callerstopmonitoring_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStopMonitoring", "CoreID: %d\r\n" "Caller: %s\r\n", core_id, caller); } static struct ast_manager_event_blob *cc_callerstartmonitoring_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerStartMonitoring", "CoreID: %d\r\n" "Caller: %s\r\n", core_id, caller); } static struct ast_manager_event_blob *cc_callerrecalling_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCCallerRecalling", "CoreID: %d\r\n" "Caller: %s\r\n", core_id, caller); } static struct ast_manager_event_blob *cc_recallcomplete_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCRecallComplete", "CoreID: %d\r\n" "Caller: %s\r\n", core_id, caller); } static struct ast_manager_event_blob *cc_failure_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *caller; const char *reason; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); caller = ast_json_string_get(ast_json_object_get(payload->json, "caller")); reason = ast_json_string_get(ast_json_object_get(payload->json, "reason")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCFailure", "CoreID: %d\r\n" "Caller: %s\r\n" "Reason: %s\r\n", core_id, caller, reason); } static struct ast_manager_event_blob *cc_monitorfailed_to_ami(struct stasis_message *message) { struct ast_json_payload *payload = stasis_message_data(message); int core_id; const char *callee; core_id = ast_json_integer_get(ast_json_object_get(payload->json, "core_id")); callee = ast_json_string_get(ast_json_object_get(payload->json, "callee")); return ast_manager_event_blob_create(EVENT_FLAG_CC, "CCMonitorFailed", "CoreID: %d\r\n" "Callee: %s\r\n", core_id, callee); } struct stasis_topic *ast_system_topic(void) { return system_topic; } /*! \brief Cleanup the \ref stasis system level items */ static void stasis_system_cleanup(void) { ao2_cleanup(system_topic); system_topic = NULL; STASIS_MESSAGE_TYPE_CLEANUP(ast_network_change_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_system_registry_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_available_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_offertimerstart_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requested_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_requestacknowledged_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstopmonitoring_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerstartmonitoring_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_callerrecalling_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_recallcomplete_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_failure_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cc_monitorfailed_type); STASIS_MESSAGE_TYPE_CLEANUP(ast_cluster_discovery_type); } /*! \brief Initialize the system level items for \ref stasis */ int ast_stasis_system_init(void) { ast_register_cleanup(stasis_system_cleanup); system_topic = stasis_topic_create("system:all"); if (!system_topic) { return 1; } if (STASIS_MESSAGE_TYPE_INIT(ast_network_change_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_system_registry_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_available_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_offertimerstart_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requested_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_requestacknowledged_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstopmonitoring_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerstartmonitoring_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_callerrecalling_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_recallcomplete_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_failure_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cc_monitorfailed_type) != 0) { return -1; } if (STASIS_MESSAGE_TYPE_INIT(ast_cluster_discovery_type) != 0) { return -1; } return 0; }