mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	func_channel: Read/Write after_bridge_goto option
Allows reading and setting of a channel's after_bridge_goto datastore (closes issue ASTERISK-21875) Reported by: Matt Jordan Review: https://reviewboard.asterisk.org/r/2628/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@393005 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
		| @@ -37,6 +37,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
|  | ||||
| #include "asterisk/module.h" | ||||
| #include "asterisk/channel.h" | ||||
| #include "asterisk/bridging.h" | ||||
| #include "asterisk/pbx.h" | ||||
| #include "asterisk/utils.h" | ||||
| #include "asterisk/app.h" | ||||
| @@ -118,6 +119,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") | ||||
| 					<enum name="checkhangup"> | ||||
| 						<para>R/O Whether the channel is hanging up (1/0)</para> | ||||
| 					</enum> | ||||
| 					<enum name="after_bridge_goto"> | ||||
| 						<para>R/W the parseable goto string indicating where the channel is | ||||
| 						expected to return to in the PBX after exiting the next bridge it joins | ||||
| 						on the condition that it doesn't hang up. The parseable goto string uses | ||||
| 						the same syntax as the <literal>Goto</literal> application.</para> | ||||
| 					</enum> | ||||
| 					<enum name="hangup_handler_pop"> | ||||
| 						<para>W/O Replace the most recently added hangup handler | ||||
| 						with a new hangup handler on the channel if supplied.  The | ||||
| @@ -475,6 +482,8 @@ static int func_channel_read(struct ast_channel *chan, const char *function, | ||||
| 		struct ast_str *tmp_str = ast_str_alloca(1024); | ||||
|  | ||||
| 		locked_copy_string(chan, buf,  ast_print_namedgroups(&tmp_str, ast_channel_named_pickupgroups(chan)), len); | ||||
| 	} else if (!strcasecmp(data, "after_bridge_goto")) { | ||||
| 		ast_after_bridge_goto_read(chan, buf, len); | ||||
| 	} else if (!strcasecmp(data, "amaflags")) { | ||||
| 		ast_channel_lock(chan); | ||||
| 		snprintf(buf, len, "%d", ast_channel_amaflags(chan)); | ||||
| @@ -516,7 +525,13 @@ static int func_channel_write_real(struct ast_channel *chan, const char *functio | ||||
| 		locked_string_field_set(chan, accountcode, value); | ||||
| 	else if (!strcasecmp(data, "userfield")) | ||||
| 		locked_string_field_set(chan, userfield, value); | ||||
| 	else if (!strcasecmp(data, "amaflags")) { | ||||
| 	else if (!strcasecmp(data, "after_bridge_goto")) { | ||||
| 		if (ast_strlen_zero(value)) { | ||||
| 			ast_after_bridge_goto_discard(chan); | ||||
| 		} else { | ||||
| 			ast_after_bridge_set_go_on(chan, ast_channel_context(chan), ast_channel_exten(chan), ast_channel_priority(chan), value); | ||||
| 		} | ||||
| 	} else if (!strcasecmp(data, "amaflags")) { | ||||
| 		ast_channel_lock(chan); | ||||
| 		if (isdigit(*value)) { | ||||
| 			int amaflags; | ||||
|   | ||||
| @@ -1634,6 +1634,16 @@ void ast_after_bridge_goto_run(struct ast_channel *chan); | ||||
|  */ | ||||
| void ast_after_bridge_goto_discard(struct ast_channel *chan); | ||||
|  | ||||
| /*! | ||||
|  * \brief Read after bridge goto if it exists | ||||
|  * \since 12.0.0 | ||||
|  * | ||||
|  * \param chan Channel to read the after bridge goto parseable goto string from | ||||
|  * \param buffer Buffer to write the after bridge goto data to | ||||
|  * \param buf_size size of the buffer being written to | ||||
|  */ | ||||
| void ast_after_bridge_goto_read(struct ast_channel *chan, char *buffer, size_t buf_size); | ||||
|  | ||||
| /*! Reason the the after bridge callback will not be called. */ | ||||
| enum ast_after_bridge_cb_reason { | ||||
| 	/*! The datastore is being destroyed.  Likely due to hangup. */ | ||||
|   | ||||
| @@ -3414,6 +3414,47 @@ void ast_after_bridge_goto_discard(struct ast_channel *chan) | ||||
| 	} | ||||
| } | ||||
|  | ||||
| void ast_after_bridge_goto_read(struct ast_channel *chan, char *buffer, size_t buf_size) | ||||
| { | ||||
| 	struct ast_datastore *datastore; | ||||
| 	struct after_bridge_goto_ds *after_bridge; | ||||
| 	char *current_pos = buffer; | ||||
| 	size_t remaining_size = buf_size; | ||||
|  | ||||
| 	SCOPED_CHANNELLOCK(lock, chan); | ||||
|  | ||||
| 	datastore = ast_channel_datastore_find(chan, &after_bridge_goto_info, NULL); | ||||
| 	if (!datastore) { | ||||
| 		buffer[0] = '\0'; | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	after_bridge = datastore->data; | ||||
|  | ||||
| 	if (after_bridge->parseable_goto) { | ||||
| 		snprintf(buffer, buf_size, "%s", after_bridge->parseable_goto); | ||||
| 		return; | ||||
| 	} | ||||
|  | ||||
| 	if (!ast_strlen_zero(after_bridge->context)) { | ||||
| 		snprintf(current_pos, remaining_size, "%s,", after_bridge->context); | ||||
| 		remaining_size = remaining_size - strlen(current_pos); | ||||
| 		current_pos += strlen(current_pos); | ||||
| 	} | ||||
|  | ||||
| 	if (after_bridge->run_h_exten) { | ||||
| 		snprintf(current_pos, remaining_size, "h,"); | ||||
| 		remaining_size = remaining_size - strlen(current_pos); | ||||
| 		current_pos += strlen(current_pos); | ||||
| 	} else if (!ast_strlen_zero(after_bridge->exten)) { | ||||
| 		snprintf(current_pos, remaining_size, "%s,", after_bridge->exten); | ||||
| 		remaining_size = remaining_size - strlen(current_pos); | ||||
| 		current_pos += strlen(current_pos); | ||||
| 	} | ||||
|  | ||||
| 	snprintf(current_pos, remaining_size, "%d", after_bridge->priority); | ||||
| } | ||||
|  | ||||
| int ast_after_bridge_goto_setup(struct ast_channel *chan) | ||||
| { | ||||
| 	struct ast_datastore *datastore; | ||||
| @@ -3479,6 +3520,10 @@ int ast_after_bridge_goto_setup(struct ast_channel *chan) | ||||
| 				after_bridge->exten, after_bridge->priority + 1); | ||||
| 		} | ||||
| 		if (!goto_failed) { | ||||
| 			if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_IN_AUTOLOOP)) { | ||||
| 				ast_channel_priority_set(chan, ast_channel_priority(chan) + 1); | ||||
| 			} | ||||
|  | ||||
| 			ast_debug(1, "Setup after bridge goto location to %s,%s,%d.\n", | ||||
| 				ast_channel_context(chan), | ||||
| 				ast_channel_exten(chan), | ||||
|   | ||||
		Reference in New Issue
	
	Block a user