<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/18444">View Change</a></p><div style="white-space:pre-wrap">Approvals:
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit

</div><pre style="font-family: monospace,monospace; white-space: pre-wrap;">res_aeap: Add basic config skeleton and CLI commands.<br><br>Added support for a basic AEAP configuration read from aeap.conf.<br>Also added 2 CLI commands for showing individual configurations as<br>well as all of them: aeap show server <id> and aeap show servers.<br><br>Only one configuration option is required at the moment, and that one is<br>server_url. It must be a websocket URL. The other option, codecs, is<br>optional and will be used over the codecs specified on the endpoint if<br>provided.<br><br>https://wiki.asterisk.org/wiki/pages/viewpage.action?pageId=45482453<br><br>Change-Id: I567ac5148c92b98d29d2ad83421b416b75ffdaa3<br>(cherry picked from commit 45a1977de49f56de5875a2cde951780de146762d)<br>---<br>A configs/samples/aeap.conf.sample<br>A res/res_aeap.c<br>2 files changed, 313 insertions(+), 0 deletions(-)<br><br></pre><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/aeap.conf.sample b/configs/samples/aeap.conf.sample</span><br><span>new file mode 100644</span><br><span>index 0000000..8941dd1</span><br><span>--- /dev/null</span><br><span>+++ b/configs/samples/aeap.conf.sample</span><br><span>@@ -0,0 +1,15 @@</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span style="color: hsl(120, 100%, 40%);">+; This file is used by the res_aeap module to configure parameters</span><br><span style="color: hsl(120, 100%, 40%);">+; used for AEAP applications.</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span style="color: hsl(120, 100%, 40%);">+;[myserver]</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span style="color: hsl(120, 100%, 40%);">+; type must be "server".</span><br><span style="color: hsl(120, 100%, 40%);">+;type=server</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span style="color: hsl(120, 100%, 40%);">+; server_url must be a websocket URL (ws or wss).</span><br><span style="color: hsl(120, 100%, 40%);">+;server_url</span><br><span style="color: hsl(120, 100%, 40%);">+;</span><br><span style="color: hsl(120, 100%, 40%);">+; codecs is an optional list of codecs that will be used over the codecs</span><br><span style="color: hsl(120, 100%, 40%);">+; specified on an endpoint if this option is present.</span><br><span style="color: hsl(120, 100%, 40%);">+;codecs=ulaw,alaw,g722,opus</span><br><span>diff --git a/res/res_aeap.c b/res/res_aeap.c</span><br><span>new file mode 100644</span><br><span>index 0000000..b6c5841</span><br><span>--- /dev/null</span><br><span>+++ b/res/res_aeap.c</span><br><span>@@ -0,0 +1,298 @@</span><br><span style="color: hsl(120, 100%, 40%);">+/*</span><br><span style="color: hsl(120, 100%, 40%);">+ * Asterisk -- An open source telephony toolkit.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Copyright (C) 2021, Sangoma Technologies Corporation</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * Ben Ford <bford@sangoma.com></span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * See http://www.asterisk.org for more information about</span><br><span style="color: hsl(120, 100%, 40%);">+ * the Asterisk project. Please do not directly contact</span><br><span style="color: hsl(120, 100%, 40%);">+ * any of the maintainers of this project for assistance;</span><br><span style="color: hsl(120, 100%, 40%);">+ * the project provides a web site, mailing lists and IRC</span><br><span style="color: hsl(120, 100%, 40%);">+ * channels for your use.</span><br><span style="color: hsl(120, 100%, 40%);">+ *</span><br><span style="color: hsl(120, 100%, 40%);">+ * This program is free software, distributed under the terms of</span><br><span style="color: hsl(120, 100%, 40%);">+ * the GNU General Public License Version 2. See the LICENSE file</span><br><span style="color: hsl(120, 100%, 40%);">+ * at the top of the source tree.</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%);">+/*** MODULEINFO</span><br><span style="color: hsl(120, 100%, 40%);">+ <support_level>core</support_level></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%);">+#include "asterisk.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/module.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/sorcery.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/cli.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/format.h"</span><br><span style="color: hsl(120, 100%, 40%);">+#include "asterisk/format_cap.h"</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+/*** DOCUMENTATION</span><br><span style="color: hsl(120, 100%, 40%);">+   <configInfo name="res_aeap" language="en_US"></span><br><span style="color: hsl(120, 100%, 40%);">+               <synopsis>Asterisk External Application Protocol (AEAP) module for Asterisk</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+            <configFile name="aeap.conf"></span><br><span style="color: hsl(120, 100%, 40%);">+                 <configObject name="server"></span><br><span style="color: hsl(120, 100%, 40%);">+                          <synopsis>AEAP server options</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                          <configOption name="type"></span><br><span style="color: hsl(120, 100%, 40%);">+                                    <synopsis>Must be of type 'server'.</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                            </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+                         <configOption name="server_url"></span><br><span style="color: hsl(120, 100%, 40%);">+                                      <synopsis>The URL of the server to connect to.</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                         </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+                         <configOption name="codecs"></span><br><span style="color: hsl(120, 100%, 40%);">+                                  <synopsis>Optional media codec(s)</synopsis></span><br><span style="color: hsl(120, 100%, 40%);">+                                      <description><para></span><br><span style="color: hsl(120, 100%, 40%);">+                                       If this is specified, Asterisk will use this for codec related negotiations</span><br><span style="color: hsl(120, 100%, 40%);">+                                   with the external application. Otherwise, Asterisk will default to using the</span><br><span style="color: hsl(120, 100%, 40%);">+                                  codecs configured on the endpoint.</span><br><span style="color: hsl(120, 100%, 40%);">+                                    </para></description></span><br><span style="color: hsl(120, 100%, 40%);">+                             </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+                 </configObject></span><br><span style="color: hsl(120, 100%, 40%);">+         </configFile></span><br><span style="color: hsl(120, 100%, 40%);">+   </configInfo></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%);">+/* Asterisk External Application Protocol sorcery object */</span><br><span style="color: hsl(120, 100%, 40%);">+static struct ast_sorcery *aeap_sorcery;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+struct aeap_server</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+  SORCERY_OBJECT(details);</span><br><span style="color: hsl(120, 100%, 40%);">+      AST_DECLARE_STRING_FIELDS(</span><br><span style="color: hsl(120, 100%, 40%);">+            /*! The URL of the server to connect to */</span><br><span style="color: hsl(120, 100%, 40%);">+            AST_STRING_FIELD(server_url);</span><br><span style="color: hsl(120, 100%, 40%);">+ );</span><br><span style="color: hsl(120, 100%, 40%);">+    /*! An optional list of codecs that will be used if provided */</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_format_cap *codecs;</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 void aeap_server_destructor(void *obj)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct aeap_server *cfg = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_string_field_free_memory(cfg);</span><br><span style="color: hsl(120, 100%, 40%);">+    ao2_cleanup(cfg->codecs);</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 void *aeap_server_alloc(const char *name)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+        struct aeap_server *cfg;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    cfg = ast_sorcery_generic_alloc(sizeof(*cfg), aeap_server_destructor);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (!cfg) {</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 (ast_string_field_init(cfg, 512)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ao2_ref(cfg, -1);</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 (!(cfg->codecs = ast_format_cap_alloc(AST_FORMAT_CAP_FLAG_DEFAULT))) {</span><br><span style="color: hsl(120, 100%, 40%);">+          ao2_ref(cfg, -1);</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%);">+   return cfg;</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 aeap_server_apply(const struct ast_sorcery *sorcery, void *obj)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct aeap_server *cfg = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+      if (ast_strlen_zero(cfg->server_url)) {</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_log(LOG_ERROR, "AEAP - Server URL must be present for server '%s'\n", ast_sorcery_object_get_id(cfg));</span><br><span style="color: hsl(120, 100%, 40%);">+          return -1;</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_begins_with(cfg->server_url, "ws")) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_ERROR, "AEAP - Server URL must be ws or wss for server '%s'\n", ast_sorcery_object_get_id(cfg));</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</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%);">+   return 0;</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 struct aeap_server *aeap_server_get(const char *id)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ return ast_sorcery_retrieve_by_id(aeap_sorcery, "server", id);</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 struct ao2_container *aeap_server_get_all(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+      return ast_sorcery_retrieve_by_fields(aeap_sorcery, "server",</span><br><span style="color: hsl(120, 100%, 40%);">+               AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, 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%);">+static char *aeap_tab_complete_name(const char *word, struct ao2_container *container)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+    void *obj;</span><br><span style="color: hsl(120, 100%, 40%);">+    struct ao2_iterator it;</span><br><span style="color: hsl(120, 100%, 40%);">+       int wordlen = strlen(word);</span><br><span style="color: hsl(120, 100%, 40%);">+   int ret;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    it = ao2_iterator_init(container, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ while ((obj = ao2_iterator_next(&it))) {</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!strncasecmp(word, ast_sorcery_object_get_id(obj), wordlen)) {</span><br><span style="color: hsl(120, 100%, 40%);">+                    ret = ast_cli_completion_add(ast_strdup(ast_sorcery_object_get_id(obj)));</span><br><span style="color: hsl(120, 100%, 40%);">+                     if (ret) {</span><br><span style="color: hsl(120, 100%, 40%);">+                            ao2_ref(obj, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+                             break;</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%);">+             ao2_ref(obj, -1);</span><br><span style="color: hsl(120, 100%, 40%);">+     }</span><br><span style="color: hsl(120, 100%, 40%);">+     ao2_iterator_destroy(&it);</span><br><span style="color: hsl(120, 100%, 40%);">+</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%);">+static int aeap_cli_show(void *obj, void *arg, int flags)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       struct ast_cli_args *a = arg;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_variable *options;</span><br><span style="color: hsl(120, 100%, 40%);">+ struct ast_variable *i;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     if (!obj) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_cli(a->fd, "No AEAP configuration found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+         return 0;</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%);">+   options = ast_variable_list_sort(ast_sorcery_objectset_create2(</span><br><span style="color: hsl(120, 100%, 40%);">+               aeap_sorcery, obj, AST_HANDLER_ONLY_STRING));</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!options) {</span><br><span style="color: hsl(120, 100%, 40%);">+               return 0;</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_cli(a->fd, "%s: %s\n", ast_sorcery_object_get_type(obj),</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_sorcery_object_get_id(obj));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+    for (i = options; i; i = i->next) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_cli(a->fd, "\t%s: %s\n", i->name, i->value);</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_cli(a->fd, "\n");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_variables_destroy(options);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     return 0;</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 char *aeap_server_show(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 aeap_server *cfg;</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 = "aeap show server";</span><br><span style="color: hsl(120, 100%, 40%);">+         e->usage =</span><br><span style="color: hsl(120, 100%, 40%);">+                 "Usage: aeap show server <id>\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                      "       Show the AEAP settings for a given server\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%);">+            if (a->pos == 3) {</span><br><span style="color: hsl(120, 100%, 40%);">+                 return aeap_tab_complete_name(a->word, aeap_server_get_all());</span><br><span style="color: hsl(120, 100%, 40%);">+             } else {</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%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   if (a->argc != 4) {</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%);">+   cfg = aeap_server_get(a->argv[3]);</span><br><span style="color: hsl(120, 100%, 40%);">+ aeap_cli_show(cfg, a, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+     ao2_cleanup(cfg);</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 style="color: hsl(120, 100%, 40%);">+static char *aeap_server_show_all(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 ao2_container *container;</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 = "aeap show servers";</span><br><span style="color: hsl(120, 100%, 40%);">+                e->usage =</span><br><span style="color: hsl(120, 100%, 40%);">+                 "Usage: aeap show servers\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                        "       Show all configured AEAP servers\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 != 3) {</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%);">+   container = aeap_server_get_all();</span><br><span style="color: hsl(120, 100%, 40%);">+    if (!container || ao2_container_count(container) == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_cli(a->fd, "No AEAP servers found\n");</span><br><span style="color: hsl(120, 100%, 40%);">+               ao2_cleanup(container);</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 style="color: hsl(120, 100%, 40%);">+   ao2_callback(container, OBJ_NODATA, aeap_cli_show, a);</span><br><span style="color: hsl(120, 100%, 40%);">+        ao2_ref(container, -1);</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 style="color: hsl(120, 100%, 40%);">+static struct ast_cli_entry aeap_cli[] = {</span><br><span style="color: hsl(120, 100%, 40%);">+  AST_CLI_DEFINE(aeap_server_show, "Show AEAP server configuration by id"),</span><br><span style="color: hsl(120, 100%, 40%);">+   AST_CLI_DEFINE(aeap_server_show_all, "Show all AEAP server configurations"),</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 reload_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       return 0;</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 unload_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_sorcery_unref(aeap_sorcery);</span><br><span style="color: hsl(120, 100%, 40%);">+      aeap_sorcery = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_cli_unregister_multiple(aeap_cli, ARRAY_LEN(aeap_cli));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ return 0;</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 load_module(void)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+       if (!(aeap_sorcery = ast_sorcery_open()))</span><br><span style="color: hsl(120, 100%, 40%);">+     {</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_log(LOG_ERROR, "AEAP - failed to open sorcery\n");</span><br><span style="color: hsl(120, 100%, 40%);">+              return AST_MODULE_LOAD_DECLINE;</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_sorcery_apply_default(aeap_sorcery, "server", "config", "aeap.conf,criteria=type=server");</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+        if (ast_sorcery_object_register(aeap_sorcery, "server", aeap_server_alloc,</span><br><span style="color: hsl(120, 100%, 40%);">+          NULL, aeap_server_apply)) {</span><br><span style="color: hsl(120, 100%, 40%);">+           ast_log(LOG_ERROR, "AEAP - failed to register server sorcery object\n");</span><br><span style="color: hsl(120, 100%, 40%);">+            return AST_MODULE_LOAD_DECLINE;</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_sorcery_object_field_register(aeap_sorcery, "server", "type", "", OPT_NOOP_T, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_sorcery_object_field_register(aeap_sorcery, "server", "server_url", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct aeap_server, server_url));</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_sorcery_object_field_register(aeap_sorcery, "server", "codecs", "", OPT_CODEC_T, 1, FLDSET(struct aeap_server, codecs));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+  ast_sorcery_load(aeap_sorcery);</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_cli_register_multiple(aeap_cli, ARRAY_LEN(aeap_cli));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+   return 0;</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_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_GLOBAL_SYMBOLS | AST_MODFLAG_LOAD_ORDER,</span><br><span style="color: hsl(120, 100%, 40%);">+        "Asterisk External Application Protocol Module for Asterisk",</span><br><span style="color: hsl(120, 100%, 40%);">+       .support_level = AST_MODULE_SUPPORT_CORE,</span><br><span style="color: hsl(120, 100%, 40%);">+     .load = load_module,</span><br><span style="color: hsl(120, 100%, 40%);">+  .unload = unload_module,</span><br><span style="color: hsl(120, 100%, 40%);">+      .reload = reload_module,</span><br><span style="color: hsl(120, 100%, 40%);">+      .load_pri = AST_MODPRI_CHANNEL_DEPEND,</span><br><span style="color: hsl(120, 100%, 40%);">+);</span><br><span></span><br></pre><div style="white-space:pre-wrap"></div><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/18444">change 18444</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/+/18444"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 18 </div>
<div style="display:none"> Gerrit-Change-Id: I567ac5148c92b98d29d2ad83421b416b75ffdaa3 </div>
<div style="display:none"> Gerrit-Change-Number: 18444 </div>
<div style="display:none"> Gerrit-PatchSet: 1 </div>
<div style="display:none"> Gerrit-Owner: Kevin Harwell <kharwell@digium.com> </div>
<div style="display:none"> Gerrit-Reviewer: Friendly Automation </div>
<div style="display:none"> Gerrit-Reviewer: George Joseph <gjoseph@digium.com> </div>
<div style="display:none"> Gerrit-CC: Benjamin Keith Ford <bford@digium.com> </div>
<div style="display:none"> Gerrit-MessageType: merged </div>