[Asterisk-code-review] func_query: Add function to retrieve remote text data. (asterisk[master])

N A asteriskteam at digium.com
Mon May 16 09:59:57 CDT 2022


N A has uploaded this change for review. ( https://gerrit.asterisk.org/c/asterisk/+/18566 )


Change subject: func_query: Add function to retrieve remote text data.
......................................................................

func_query: Add function to retrieve remote text data.

Adds the TEXT_QUERY function, which makes it easy for
users to be able to remotely query data available on
remote systems.

For example, the result of functions like DEVICE_STATE
can be made easily available to other systems through
this function, which presents such data as easily as if
it were available locally. As it is tech-agnostic, behind
the scenes, a call is initiated to the specified endpoint,
and then the buffer is filled with the results of the
data transfer.

Data transfer remains done using SendText; this function
merely makes it seamless to use such data from other systems.

ASTERISK-30066

Change-Id: I51cdfe2db398db15a67d7e2068cd95c6710ee33c
---
A doc/CHANGES-staging/func_query.txt
A funcs/func_query.c
2 files changed, 188 insertions(+), 0 deletions(-)



  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/66/18566/1

diff --git a/doc/CHANGES-staging/func_query.txt b/doc/CHANGES-staging/func_query.txt
new file mode 100644
index 0000000..e89ff04
--- /dev/null
+++ b/doc/CHANGES-staging/func_query.txt
@@ -0,0 +1,6 @@
+Subject: func_query
+
+Adds the TEXT_QUERY function, which can be used to
+retrieve textual data from a remote endpoint in a
+technology-agnostic way. This makes it easy to
+query functions available on remote Asterisk systems.
diff --git a/funcs/func_query.c b/funcs/func_query.c
new file mode 100644
index 0000000..c055218
--- /dev/null
+++ b/funcs/func_query.c
@@ -0,0 +1,182 @@
+/*
+ * Asterisk -- An open source telephony toolkit.
+ *
+ * Copyright (C) 2022, Naveen Albert
+ *
+ * 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 Remote text querying
+ *
+ * \author Naveen Albert <asterisk at phreaknet.org>
+ *
+ * \ingroup functions
+ */
+
+/*** MODULEINFO
+	<support_level>extended</support_level>
+ ***/
+
+#include "asterisk.h"
+
+#include "asterisk/module.h"
+#include "asterisk/pbx.h"	/* function register/unregister */
+#include "asterisk/utils.h"
+#include "asterisk/app.h"
+#include "asterisk/format_cache.h"
+#include "asterisk/frame.h"
+#include "asterisk/strings.h"
+#include "asterisk/conversions.h"
+
+/*** DOCUMENTATION
+	<function name="TEXT_QUERY" language="en_US">
+		<synopsis>
+			Remote string querying
+		</synopsis>
+		<syntax>
+			<parameter name="dialstr" required="true">
+				<para>Dial string, such as provided to the Dial application</para>
+			</parameter>
+			<parameter name="timeout" required="false">
+				<para>Timeout to wait, in seconds. Default is 5 seconds.</para>
+			</parameter>
+		</syntax>
+		<description>
+			<para>Initiate a call and receive a text data transfer.</para>
+			<para>This function can be used to implement simple remote procedure
+			calls between endpoints that support text frames. For example, you
+			can use this to retrieve the results of certain dialplan functions
+			on a different node as easily as if they were local.</para>
+			<para>The other end should use SendText to send the data transfer.</para>
+			<example title="Query device state of endpoints at the main branch office">
+			[rx-node] ; Node A
+			exten => rx,1,Set(remotestate=${QUERY(IAX2/mainbranch/2368 at device-state-context)})
+				same => n,ExecIf($[ "${remotestate}" = "NOT_INUSE" ]?Dial(IAX2/mainbranch/2368 at extensions))
+				same => n,Hangup()
+			[extensions] ; Node B: allow other Asterisk systems to query local device states.
+			exten => _2XXX,1,Dial(${HINT(${EXTEN})})
+				same => n,Hangup()
+			[device-state-context] ; Node B
+			exten => _2XXX,1,SendText(${DEVICE_STATE(${HINT(${EXTEN})})})
+				same => n,Hangup()
+			</example>
+		</description>
+	</function>
+ ***/
+
+static int acf_query_read(struct ast_channel *chan, const char *cmd, char *data, char *buf, size_t len)
+{
+	struct ast_format_cap *cap;
+	struct ast_channel *c;
+	char *parse, *rbuf;
+	char *tech, *destination;
+	int timeout_sec = 0, timeout_ms = 5000;
+	AST_DECLARE_APP_ARGS(args,
+		AST_APP_ARG(dialstr);
+		AST_APP_ARG(timeout);
+	);
+	struct ast_custom_function *cdr_prop_func = ast_custom_function_find("CDR_PROP");
+
+	if (ast_strlen_zero(data)) {
+		ast_log(LOG_WARNING, "Missing arguments: dialstring\n");
+		return -1;
+	}
+	if (!chan) {
+		ast_log(LOG_WARNING, "No channel was provided to %s function.\n", cmd);
+		return -1;
+	}
+
+	parse = ast_strdupa(data);
+	AST_STANDARD_APP_ARGS(args, parse);
+
+	if (ast_strlen_zero(args.dialstr)) {
+		ast_log(LOG_WARNING, "Missing arguments: dialstring\n");
+		return -1;
+	}
+	if (!ast_strlen_zero(args.timeout)) {
+		if ((ast_str_to_int(args.timeout, &timeout_sec) || timeout_sec < 0)) {
+			ast_log(LOG_WARNING, "Invalid timeout: %s\n", args.timeout);
+		} else {
+			timeout_ms *= 1000;
+		}
+	}
+
+	tech = args.dialstr;
+	destination = strchr(tech, '/');
+	if (destination) {
+		*destination = '\0';
+		destination++;
+	} else {
+		ast_log(LOG_WARNING, "Dial string must have technology/resource\n");
+		return -1;
+	}
+
+	cap = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);
+	if (!cap) {
+		return NULL;
+	}
+	ast_format_cap_append(cap, ast_format_slin, 0);
+
+	c = ast_request(tech, cap, NULL, chan, destination, NULL);
+	ao2_cleanup(cap);
+
+	if (!c) {
+		return NULL;
+	}
+
+	ast_channel_unlock(c);
+
+	/* Disable CDR for this temporary channel. */
+	if (cdr_prop_func) {
+		ast_func_write(c, "CDR_PROP(disable)", "1");
+	}
+
+	if (ast_call(c, destination, 0)) {
+		ast_log(LOG_ERROR, "Unable to place outbound call to %s\n", args.dialstr);
+		ast_hangup(c);
+		return -1;
+	}
+
+	/* Wait for data transfer */
+	ast_autoservice_start(chan);
+	ast_channel_ref(c);
+	rbuf = ast_recvtext(c, timeout_ms);
+	ast_channel_unref(c);
+	ast_autoservice_stop(chan);
+
+	if (!rbuf) {
+		ast_log(LOG_WARNING, "No data received before channel hung up\n");
+		return -1;
+	}
+
+	ast_copy_string(buf, rbuf, sizeof(buf));
+
+	return 0;
+}
+
+static struct ast_custom_function query_function = {
+	.name = "TEXT_QUERY",
+	.read = acf_query_read,
+};
+
+static int unload_module(void)
+{
+	return ast_custom_function_unregister(&query_function);
+}
+
+static int load_module(void)
+{
+	return ast_custom_function_register(&query_function);
+}
+
+AST_MODULE_INFO_STANDARD_EXTENDED(ASTERISK_GPL_KEY, "Remote text querying");

-- 
To view, visit https://gerrit.asterisk.org/c/asterisk/+/18566
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Change-Id: I51cdfe2db398db15a67d7e2068cd95c6710ee33c
Gerrit-Change-Number: 18566
Gerrit-PatchSet: 1
Gerrit-Owner: N A <mail at interlinked.x10host.com>
Gerrit-MessageType: newchange
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20220516/49572c18/attachment-0001.html>


More information about the asterisk-code-review mailing list