<p>N A has uploaded this change for <strong>review</strong>.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18561">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_clioriginate: Add dialplan exec CLI command.<br><br>Adds a CLI command similar to "dialplan eval function" except for<br>applications: "dialplan exec application", useful for quickly<br>testing certain application behavior directly from the CLI<br>without writing any dialplan.<br><br>ASTERISK-30062 #close<br><br>Change-Id: I42e9fa9b60746c21450d40f99a026d48d2486dde<br>---<br>M res/res_clioriginate.c<br>1 file changed, 102 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;">git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/61/18561/1</pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/res/res_clioriginate.c b/res/res_clioriginate.c</span><br><span>index 3ea89d8..aeeeb88 100644</span><br><span>--- a/res/res_clioriginate.c</span><br><span>+++ b/res/res_clioriginate.c</span><br><span>@@ -229,9 +229,111 @@</span><br><span>         return res ? CLI_FAILURE : CLI_SUCCESS;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+static const struct ast_channel_tech mock_channel_tech = {</span><br><span style="color: hsl(120, 100%, 40%);">+};</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+static int cli_chan = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*! \brief CLI support for executing function */</span><br><span style="color: hsl(120, 100%, 40%);">+static char *handle_exec(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_channel *c = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+ RAII_VAR(struct ast_format_cap *, caps, NULL, ao2_cleanup);</span><br><span style="color: hsl(120, 100%, 40%);">+   char *app_name, *app_args;</span><br><span style="color: hsl(120, 100%, 40%);">+    int ret = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+  struct ast_app *app;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (cmd) {</span><br><span style="color: hsl(120, 100%, 40%);">+        case CLI_INIT:</span><br><span style="color: hsl(120, 100%, 40%);">+                e->command = "dialplan exec application";</span><br><span style="color: hsl(120, 100%, 40%);">+                e->usage =</span><br><span style="color: hsl(120, 100%, 40%);">+                 "Usage: dialplan exec application <appname> [<args>]\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                 "       Execute a single dialplan application call for\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                   "       testing. A dummy channel is used to execute\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                      "       the application, so it may not make\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                      "       sense to use all applications, and only\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                  "       global variables should be used.\n";</span><br><span style="color: hsl(120, 100%, 40%);">+                return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  case CLI_GENERATE:</span><br><span style="color: hsl(120, 100%, 40%);">+            return NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+  }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (a->argc != e->args + 1 && a->argc != e->args + 2) {</span><br><span style="color: hsl(120, 100%, 40%);">+           return CLI_SHOWUSAGE;</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   app_name = (char *) a->argv[3];</span><br><span style="color: hsl(120, 100%, 40%);">+    app_args = a->argc == e->args + 2 ? (char *) a->argv[4] : NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!app_name) {</span><br><span style="color: hsl(120, 100%, 40%);">+              return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   caps = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!caps) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ast_log(LOG_WARNING, "Could not allocate an empty format capabilities structure\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_format_cap_append(caps, ast_format_ulaw, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_log(LOG_WARNING, "Failed to append a ulaw format to capabilities for channel nativeformats\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_format_cap_append(caps, ast_format_alaw, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_log(LOG_WARNING, "Failed to append an alaw format to capabilities for channel nativeformats\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (ast_format_cap_append(caps, ast_format_h264, 0)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_log(LOG_WARNING, "Failed to append an h264 format to capabilities for channel nativeformats\n");</span><br><span style="color: hsl(120, 100%, 40%);">+                return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   c = ast_channel_alloc(0, AST_STATE_DOWN, NULL, NULL, NULL, NULL, NULL, NULL, NULL, 0, "CLIExec/%d", ++cli_chan);</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!c) {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_cli(a->fd, "Unable to allocate bogus channel for application execution.\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_channel_tech_set(c, &mock_channel_tech);</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_channel_nativeformats_set(c, caps);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_channel_set_writeformat(c, ast_format_slin);</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_channel_set_rawwriteformat(c, ast_format_slin);</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_channel_set_readformat(c, ast_format_slin);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_channel_set_rawreadformat(c, ast_format_slin);</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_channel_unlock(c);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      app = pbx_findapp(app_name);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!app) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_WARNING, "Could not find application (%s)\n", app_name);</span><br><span style="color: hsl(120, 100%, 40%);">+                c = ast_channel_unref(c);</span><br><span style="color: hsl(120, 100%, 40%);">+             return CLI_FAILURE;</span><br><span style="color: hsl(120, 100%, 40%);">+   } else {</span><br><span style="color: hsl(120, 100%, 40%);">+              struct ast_str *substituted_args = ast_str_create(16);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+              if (substituted_args) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       ast_str_substitute_variables(&substituted_args, 0, c, app_args);</span><br><span style="color: hsl(120, 100%, 40%);">+                  ast_cli(a->fd, "Executing: %s(%s)\n", app_name, ast_str_buffer(substituted_args));</span><br><span style="color: hsl(120, 100%, 40%);">+                       ret = pbx_exec(c, app, ast_str_buffer(substituted_args));</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_free(substituted_args);</span><br><span style="color: hsl(120, 100%, 40%);">+           } else {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ast_log(LOG_WARNING, "Could not substitute application argument variables for %s\n", app_name);</span><br><span style="color: hsl(120, 100%, 40%);">+                     ast_cli(a->fd, "Executing: %s(%s)\n", app_name, app_args);</span><br><span style="color: hsl(120, 100%, 40%);">+                       ret = pbx_exec(c, app, app_args);</span><br><span style="color: hsl(120, 100%, 40%);">+             }</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_hangup(c); /* no need to unref separately */</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_cli(a->fd, "Return Value: %s (%d)\n", ret ? "Failure" : "Success", ret);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+       return CLI_SUCCESS;</span><br><span style="color: hsl(120, 100%, 40%);">+}</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static struct ast_cli_entry cli_cliorig[] = {</span><br><span>    AST_CLI_DEFINE(handle_orig, "Originate a call"),</span><br><span>   AST_CLI_DEFINE(handle_redirect, "Redirect a call"),</span><br><span style="color: hsl(120, 100%, 40%);">+ AST_CLI_DEFINE(handle_exec, "Execute dialplan application"),</span><br><span> };</span><br><span> </span><br><span> static int unload_module(void)</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18561">change 18561</a>. To unsubscribe, or for help writing mail filters, visit <a href="https://gerrit.asterisk.org/settings">settings</a>.</p><div itemscope itemtype="http://schema.org/EmailMessage"><div itemscope itemprop="action" itemtype="http://schema.org/ViewAction"><link itemprop="url" href="https://gerrit.asterisk.org/c/asterisk/+/18561"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: master </div>
<div style="display:none"> Gerrit-Change-Id: I42e9fa9b60746c21450d40f99a026d48d2486dde </div>
<div style="display:none"> Gerrit-Change-Number: 18561 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: N A <mail@interlinked.x10host.com> </div>
<div style="display:none"> Gerrit-MessageType: newchange </div>