mirror of https://github.com/asterisk/asterisk
				
				
				
			
			You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							439 lines
						
					
					
						
							14 KiB
						
					
					
				
			
		
		
	
	
							439 lines
						
					
					
						
							14 KiB
						
					
					
				| /*
 | |
|  * Asterisk -- An open source telephony toolkit.
 | |
|  *
 | |
|  * Copyright (C) 2013, Digium, Inc.
 | |
|  *
 | |
|  * Jason Parker <jparker@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 Stasis Messages and Data Types for System events
 | |
|  *
 | |
|  * \author Jason Parker <jparker@digium.com>
 | |
|  */
 | |
| 
 | |
| /*** MODULEINFO
 | |
| 	<support_level>core</support_level>
 | |
|  ***/
 | |
| 
 | |
| #include "asterisk.h"
 | |
| 
 | |
| #include "asterisk/astobj2.h"
 | |
| #include "asterisk/stasis.h"
 | |
| #include "asterisk/stasis_system.h"
 | |
| 
 | |
| /*** DOCUMENTATION
 | |
| 	<managerEvent language="en_US" name="Registry">
 | |
| 		<managerEventInstance class="EVENT_FLAG_SYSTEM">
 | |
| 			<since>
 | |
| 				<version>12.0.0</version>
 | |
| 			</since>
 | |
| 			<synopsis>Raised when an outbound registration completes.</synopsis>
 | |
| 			<syntax>
 | |
| 				<parameter name="ChannelType">
 | |
| 					<para>The type of channel that was registered (or not).</para>
 | |
| 				</parameter>
 | |
| 				<parameter name="Username">
 | |
| 					<para>The username portion of the registration.</para>
 | |
| 				</parameter>
 | |
| 				<parameter name="Domain">
 | |
| 					<para>The address portion of the registration.</para>
 | |
| 				</parameter>
 | |
| 				<parameter name="Status">
 | |
| 					<para>The status of the registration request.</para>
 | |
| 					<enumlist>
 | |
| 						<enum name="Registered"/>
 | |
| 						<enum name="Unregistered"/>
 | |
| 						<enum name="Rejected"/>
 | |
| 						<enum name="Failed"/>
 | |
| 					</enumlist>
 | |
| 				</parameter>
 | |
| 				<parameter name="Cause">
 | |
| 					<para>What caused the rejection of the request, if available.</para>
 | |
| 				</parameter>
 | |
| 			</syntax>
 | |
| 		</managerEventInstance>
 | |
| 	</managerEvent>
 | |
|  ***/
 | |
| 
 | |
| /*! \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;
 | |
| }
 |