mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	Add channel events for res_stasis apps
This change adds a framework in res_stasis for handling events from channel topics. JSON event generation and validation code is created from event documentation in rest-api/api-docs/events.json to assist in JSON event generation, ensure consistency, and ensure that accurate documentation is available for ALL events that are received by res_stasis applications. The userevent application has been refactored along with the code that handles userevent channel blob events to pass the headers as key/value pairs in the JSON blob. As a side-effect, app_userevent now handles duplicate keys by overwriting the previous value. Review: https://reviewboard.asterisk.org/r/2428/ (closes issue ASTERISK-21180) Patch-By: Kinsey Moore <kmoore@digium.com> git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@388275 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -39,23 +39,28 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
| /*** DOCUMENTATION | ||||
| 	<application name="UserEvent" language="en_US"> | ||||
| 		<synopsis> | ||||
| 			Send an arbitrary event to the manager interface. | ||||
| 			Send an arbitrary user-defined event to parties interested in a channel (AMI users and relevant res_stasis applications). | ||||
| 		</synopsis> | ||||
| 		<syntax> | ||||
| 			<parameter name="eventname" required="true" /> | ||||
| 			<parameter name="body" /> | ||||
| 		</syntax> | ||||
| 		<description> | ||||
| 			<para>Sends an arbitrary event to the manager interface, with an optional | ||||
| 			<para>Sends an arbitrary event to interested parties, with an optional | ||||
| 			<replaceable>body</replaceable> representing additional arguments. The | ||||
| 			<replaceable>body</replaceable> may be specified as | ||||
| 			a <literal>,</literal> delimited list of headers. Each additional | ||||
| 			argument will be placed on a new line in the event. The format of the | ||||
| 			event will be:</para> | ||||
| 			a <literal>,</literal> delimited list of key:value pairs.</para> | ||||
| 			<para>For AMI, each additional argument will be placed on a new line in | ||||
| 			the event and the format of the event will be:</para> | ||||
| 			<para>    Event: UserEvent</para> | ||||
| 			<para>    UserEvent: <specified event name></para> | ||||
| 			<para>    [body]</para> | ||||
| 			<para>If no <replaceable>body</replaceable> is specified, only Event and UserEvent headers will be present.</para> | ||||
| 			<para>If no <replaceable>body</replaceable> is specified, only Event and | ||||
| 			UserEvent headers will be present.</para> | ||||
| 			<para>For res_stasis applications, the event will be provided as a JSON | ||||
| 			blob with additional arguments appearing as keys in the object and the | ||||
| 			<replaceable>eventname</replaceable> under the | ||||
| 			<literal>eventname</literal> key.</para> | ||||
| 		</description> | ||||
| 	</application> | ||||
|  ***/ | ||||
| @@ -70,7 +75,6 @@ static int userevent_exec(struct ast_channel *chan, const char *data) | ||||
| 		AST_APP_ARG(eventname); | ||||
| 		AST_APP_ARG(extra)[100]; | ||||
| 	); | ||||
| 	RAII_VAR(struct ast_str *, body, ast_str_create(16), ast_free); | ||||
| 	RAII_VAR(struct ast_json *, blob, NULL, ast_json_unref); | ||||
| 	RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); | ||||
|  | ||||
| @@ -79,25 +83,37 @@ static int userevent_exec(struct ast_channel *chan, const char *data) | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	if (!body) { | ||||
| 		ast_log(LOG_WARNING, "Unable to allocate buffer\n"); | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	parse = ast_strdupa(data); | ||||
|  | ||||
| 	AST_STANDARD_APP_ARGS(args, parse); | ||||
|  | ||||
| 	for (x = 0; x < args.argc - 1; x++) { | ||||
| 		ast_str_append(&body, 0, "%s\r\n", args.extra[x]); | ||||
| 	blob = ast_json_pack("{s: s, s: s}", | ||||
| 			     "type", "userevent", | ||||
| 			     "eventname", args.eventname); | ||||
| 	if (!blob) { | ||||
| 		return -1; | ||||
| 	} | ||||
|  | ||||
| 	blob = ast_json_pack("{s: s, s: s}", | ||||
| 			     "eventname", args.eventname, | ||||
| 			     "body", ast_str_buffer(body)); | ||||
| 	if (!blob) { | ||||
| 		ast_log(LOG_WARNING, "Unable to create message buffer\n"); | ||||
| 		return -1; | ||||
| 	for (x = 0; x < args.argc - 1; x++) { | ||||
| 		char *key, *value = args.extra[x]; | ||||
| 		struct ast_json *json_value; | ||||
|  | ||||
| 		key = strsep(&value, ":"); | ||||
| 		if (!value) { | ||||
| 			/* no ':' in string? */ | ||||
| 			continue; | ||||
| 		} | ||||
|  | ||||
| 		value = ast_strip(value); | ||||
| 		json_value = ast_json_string_create(value); | ||||
| 		if (!json_value) { | ||||
| 			return -1; | ||||
| 		} | ||||
|  | ||||
| 		/* ref stolen by ast_json_object_set */ | ||||
| 		if (ast_json_object_set(blob, key, json_value)) { | ||||
| 			return -1; | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	msg = ast_channel_blob_create( | ||||
|   | ||||
		Reference in New Issue
	
	Block a user