<p>Friendly Automation <strong>submitted</strong> this change.</p><p><a href="https://gerrit.asterisk.org/c/asterisk/+/19184">View Change</a></p><pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span></span><br></pre><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_geolocation:  Allow location parameters on the profile object<br><br>You can now specify the location object's format, location_info,<br>method, location_source and confidence parameters directly on<br>a profile object for simple scenarios where the location<br>information isn't common with any other profiles.  This is<br>mutually exclusive with setting location_reference on the<br>profile.<br><br>Updated appdocsxml.dtd to allow xi:include in a configObject<br>element.  This makes it easier to link to complete configOptions<br>in another object.  This is used to add the above fields to the<br>profile object without having to maintain the option descriptions<br>in two places.<br><br>ASTERISK-30185<br><br>Change-Id: Ifd5f05be0a76f0a6ad49fa28d17c394027677569<br>---<br>M configs/samples/geolocation.conf.sample<br>M doc/CHANGES-staging/res_geolocation.txt<br>M doc/appdocsxml.dtd<br>M include/asterisk/res_geolocation.h<br>M res/res_geolocation/geoloc_config.c<br>M res/res_geolocation/geoloc_doc.xml<br>M res/res_geolocation/geoloc_eprofile.c<br>M res/res_geolocation/geoloc_private.h<br>8 files changed, 186 insertions(+), 81 deletions(-)<br><br></pre>
<pre style="font-family: monospace,monospace; white-space: pre-wrap;"><span>diff --git a/configs/samples/geolocation.conf.sample b/configs/samples/geolocation.conf.sample</span><br><span>index 305f087..5b0052f 100644</span><br><span>--- a/configs/samples/geolocation.conf.sample</span><br><span>+++ b/configs/samples/geolocation.conf.sample</span><br><span>@@ -285,6 +285,13 @@</span><br><span> were set to "yes", the FLR element would be dropped from the PIDF-LO</span><br><span> document altogether.</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+-- format, location_info, location_source, method, confidence ---------</span><br><span style="color: hsl(120, 100%, 40%);">+You can specify the location object's format, location_info,</span><br><span style="color: hsl(120, 100%, 40%);">+method, location_source and confidence parameters directly on</span><br><span style="color: hsl(120, 100%, 40%);">+a profile object for simple scenarios where the location</span><br><span style="color: hsl(120, 100%, 40%);">+information isn't common with any other profiles.  This is</span><br><span style="color: hsl(120, 100%, 40%);">+mutually exclusive with setting location_reference on the</span><br><span style="color: hsl(120, 100%, 40%);">+profile.</span><br><span> </span><br><span> -- Profile Example ----------------------------------------------------</span><br><span> </span><br><span>diff --git a/doc/CHANGES-staging/res_geolocation.txt b/doc/CHANGES-staging/res_geolocation.txt</span><br><span>index 837b09a..deda71c 100644</span><br><span>--- a/doc/CHANGES-staging/res_geolocation.txt</span><br><span>+++ b/doc/CHANGES-staging/res_geolocation.txt</span><br><span>@@ -11,3 +11,10 @@</span><br><span> Added profile parameter "suppress_empty_ca_elements" that</span><br><span> will cause Civic Address elements that are empty to be</span><br><span> suppressed from the outgoing PIDF-LO document.</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+You can now specify the location object's format, location_info,</span><br><span style="color: hsl(120, 100%, 40%);">+method, location_source and confidence parameters directly on</span><br><span style="color: hsl(120, 100%, 40%);">+a profile object for simple scenarios where the location</span><br><span style="color: hsl(120, 100%, 40%);">+information isn't common with any other profiles.  This is</span><br><span style="color: hsl(120, 100%, 40%);">+mutually exclusive with setting location_reference on the</span><br><span style="color: hsl(120, 100%, 40%);">+profile.</span><br><span>diff --git a/doc/appdocsxml.dtd b/doc/appdocsxml.dtd</span><br><span>index fbcad6d..426d959 100644</span><br><span>--- a/doc/appdocsxml.dtd</span><br><span>+++ b/doc/appdocsxml.dtd</span><br><span>@@ -69,10 +69,10 @@</span><br><span>   <!ATTLIST configInfo name CDATA #REQUIRED></span><br><span>   <!ATTLIST configInfo language CDATA #REQUIRED></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  <!ELEMENT configFile (configObject+)></span><br><span style="color: hsl(120, 100%, 40%);">+  <!ELEMENT configFile (configObject|xi:include)+></span><br><span>   <!ATTLIST configFile name CDATA #REQUIRED></span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-  <!ELEMENT configObject (synopsis?|description?|syntax?|see-also?|configOption)*></span><br><span style="color: hsl(120, 100%, 40%);">+  <!ELEMENT configObject (synopsis?|description?|syntax?|see-also?|(configOption|xi:include))*></span><br><span>   <!ATTLIST configObject name CDATA #REQUIRED></span><br><span> </span><br><span>   <!ELEMENT configOption (synopsis,description?,syntax?,see-also?)*></span><br><span>diff --git a/include/asterisk/res_geolocation.h b/include/asterisk/res_geolocation.h</span><br><span>index 87f89a2..378a6c7 100644</span><br><span>--- a/include/asterisk/res_geolocation.h</span><br><span>+++ b/include/asterisk/res_geolocation.h</span><br><span>@@ -75,6 +75,8 @@</span><br><span>   AST_DECLARE_STRING_FIELDS(</span><br><span>           AST_STRING_FIELD(location_reference);</span><br><span>                AST_STRING_FIELD(notes);</span><br><span style="color: hsl(120, 100%, 40%);">+              AST_STRING_FIELD(method);</span><br><span style="color: hsl(120, 100%, 40%);">+             AST_STRING_FIELD(location_source);</span><br><span>   );</span><br><span>   enum ast_geoloc_pidf_element pidf_element;</span><br><span>   enum ast_geoloc_precedence precedence;</span><br><span>@@ -83,6 +85,9 @@</span><br><span>   struct ast_variable *location_variables;</span><br><span>     struct ast_variable *usage_rules;</span><br><span>    int suppress_empty_ca_elements;</span><br><span style="color: hsl(120, 100%, 40%);">+       enum ast_geoloc_format format;</span><br><span style="color: hsl(120, 100%, 40%);">+        struct ast_variable *location_info;</span><br><span style="color: hsl(120, 100%, 40%);">+   struct ast_variable *confidence;</span><br><span> };</span><br><span> </span><br><span> struct ast_geoloc_eprofile {</span><br><span>diff --git a/res/res_geolocation/geoloc_config.c b/res/res_geolocation/geoloc_config.c</span><br><span>index ee542f0..dea7a22 100644</span><br><span>--- a/res/res_geolocation/geoloc_config.c</span><br><span>+++ b/res/res_geolocation/geoloc_config.c</span><br><span>@@ -67,13 +67,17 @@</span><br><span>    return location;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-</span><br><span> CONFIG_ENUM(profile, pidf_element)</span><br><span> CONFIG_ENUM(profile, precedence)</span><br><span> CONFIG_VAR_LIST(profile, location_refinement)</span><br><span> CONFIG_VAR_LIST(profile, location_variables)</span><br><span> CONFIG_VAR_LIST(profile, usage_rules)</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+CONFIG_ENUM_HANDLER(profile, format)</span><br><span style="color: hsl(120, 100%, 40%);">+CONFIG_ENUM_TO_STR(profile, format)</span><br><span style="color: hsl(120, 100%, 40%);">+CONFIG_VAR_LIST(profile, location_info)</span><br><span style="color: hsl(120, 100%, 40%);">+CONFIG_VAR_LIST(profile, confidence)</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> static void geoloc_profile_destructor(void *obj) {</span><br><span>  struct ast_geoloc_profile *profile = obj;</span><br><span> </span><br><span>@@ -81,6 +85,8 @@</span><br><span>    ast_variables_destroy(profile->location_refinement);</span><br><span>      ast_variables_destroy(profile->location_variables);</span><br><span>       ast_variables_destroy(profile->usage_rules);</span><br><span style="color: hsl(120, 100%, 40%);">+       ast_variables_destroy(profile->location_info);</span><br><span style="color: hsl(120, 100%, 40%);">+     ast_variables_destroy(profile->confidence);</span><br><span> }</span><br><span> </span><br><span> static void *geoloc_profile_alloc(const char *name)</span><br><span>@@ -94,60 +100,83 @@</span><br><span>        return profile;</span><br><span> }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-static int geoloc_location_apply_handler(const struct ast_sorcery *sorcery, void *obj)</span><br><span style="color: hsl(120, 100%, 40%);">+static enum ast_geoloc_validate_result validate_location_info(const char *id,</span><br><span style="color: hsl(120, 100%, 40%);">+ enum ast_geoloc_format format, struct ast_variable *location_info)</span><br><span> {</span><br><span style="color: hsl(0, 100%, 40%);">- struct ast_geoloc_location *location = obj;</span><br><span style="color: hsl(0, 100%, 40%);">-     const char *location_id = ast_sorcery_object_get_id(location);</span><br><span style="color: hsl(120, 100%, 40%);">+        enum ast_geoloc_validate_result result;</span><br><span>      const char *failed;</span><br><span>  const char *uri;</span><br><span style="color: hsl(0, 100%, 40%);">-        enum ast_geoloc_validate_result result;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-     switch (location->format) {</span><br><span style="color: hsl(120, 100%, 40%);">+        switch (format) {</span><br><span>    case AST_GEOLOC_FORMAT_NONE:</span><br><span>         case AST_GEOLOC_FORMAT_LAST:</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_log(LOG_ERROR, "Location '%s' must have a format\n", location_id);</span><br><span style="color: hsl(120, 100%, 40%);">+              ast_log(LOG_ERROR, "Location '%s' must have a format\n", id);</span><br><span>              return -1;</span><br><span>   case AST_GEOLOC_FORMAT_CIVIC_ADDRESS:</span><br><span style="color: hsl(0, 100%, 40%);">-           result = ast_geoloc_civicaddr_validate_varlist(location->location_info, &failed);</span><br><span style="color: hsl(120, 100%, 40%);">+              result = ast_geoloc_civicaddr_validate_varlist(location_info, &failed);</span><br><span>          if (result != AST_GEOLOC_VALIDATE_SUCCESS) {</span><br><span>                         ast_log(LOG_ERROR, "Location '%s' has invalid item '%s' in the location\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                           location_id, failed);</span><br><span style="color: hsl(0, 100%, 40%);">-                   return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                            id, failed);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return result;</span><br><span>               }</span><br><span>            break;</span><br><span>       case AST_GEOLOC_FORMAT_GML:</span><br><span style="color: hsl(0, 100%, 40%);">-             result = ast_geoloc_gml_validate_varlist(location->location_info, &failed);</span><br><span style="color: hsl(120, 100%, 40%);">+            result = ast_geoloc_gml_validate_varlist(location_info, &failed);</span><br><span>                if (result != AST_GEOLOC_VALIDATE_SUCCESS) {</span><br><span>                         ast_log(LOG_ERROR, "%s for item '%s' in location '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                             ast_geoloc_validate_result_to_str(result),      failed, location_id);</span><br><span style="color: hsl(0, 100%, 40%);">-                   return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                            ast_geoloc_validate_result_to_str(result),      failed, id);</span><br><span style="color: hsl(120, 100%, 40%);">+                  return result;</span><br><span>               }</span><br><span> </span><br><span>                break;</span><br><span>       case AST_GEOLOC_FORMAT_URI:</span><br><span style="color: hsl(0, 100%, 40%);">-             uri = ast_variable_find_in_list(location->location_info, "URI");</span><br><span style="color: hsl(120, 100%, 40%);">+         uri = ast_variable_find_in_list(location_info, "URI");</span><br><span>             if (!uri) {</span><br><span style="color: hsl(0, 100%, 40%);">-                     struct ast_str *str = ast_variable_list_join(location->location_info, ",", "=", "\"", NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+                    struct ast_str *str = ast_variable_list_join(location_info, ",", "=", "\"", NULL);</span><br><span> </span><br><span>                    ast_log(LOG_ERROR, "Geolocation location '%s' format is set to '%s' but no 'URI' was found in location parameter '%s'\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                             location_id, format_names[AST_GEOLOC_FORMAT_URI], ast_str_buffer(str));</span><br><span style="color: hsl(120, 100%, 40%);">+                               id, format_names[AST_GEOLOC_FORMAT_URI], ast_str_buffer(str));</span><br><span>                       ast_free(str);</span><br><span style="color: hsl(0, 100%, 40%);">-                  return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+                    return AST_GEOLOC_VALIDATE_NOT_ENOUGH_VARNAMES;</span><br><span>              }</span><br><span>            break;</span><br><span>       }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   if (!ast_strlen_zero(location->location_source)) {</span><br><span style="color: hsl(120, 100%, 40%);">+ return AST_GEOLOC_VALIDATE_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 int validate_location_source(const char *id, const char *location_source)</span><br><span style="color: hsl(120, 100%, 40%);">+{</span><br><span style="color: hsl(120, 100%, 40%);">+ if (!ast_strlen_zero(location_source)) {</span><br><span>             struct ast_sockaddr loc_source_addr;</span><br><span style="color: hsl(0, 100%, 40%);">-            int rc = ast_sockaddr_parse(&loc_source_addr, location->location_source, PARSE_PORT_FORBID);</span><br><span style="color: hsl(120, 100%, 40%);">+           int rc = ast_sockaddr_parse(&loc_source_addr, location_source, PARSE_PORT_FORBID);</span><br><span>               if (rc == 1) {</span><br><span>                       ast_log(LOG_ERROR, "Geolocation location '%s' location_source '%s' must be a FQDN."</span><br><span>                                " RFC8787 expressly forbids IP addresses.\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                         location_id, location->location_source);</span><br><span style="color: hsl(120, 100%, 40%);">+                           id, location_source);</span><br><span>                        return -1;</span><br><span>           }</span><br><span>    }</span><br><span> </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 geoloc_location_apply_handler(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 ast_geoloc_location *location = obj;</span><br><span style="color: hsl(120, 100%, 40%);">+   const char *location_id = ast_sorcery_object_get_id(location);</span><br><span style="color: hsl(120, 100%, 40%);">+        enum ast_geoloc_validate_result result;</span><br><span style="color: hsl(120, 100%, 40%);">+       int rc = 0;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span style="color: hsl(120, 100%, 40%);">+ result = validate_location_info(location_id, location->format, location->location_info);</span><br><span style="color: hsl(120, 100%, 40%);">+        if (result != AST_GEOLOC_VALIDATE_SUCCESS) {</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%);">+   rc = validate_location_source(location_id, location->location_source);</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc != 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    }</span><br><span> </span><br><span>        return 0;</span><br><span> }</span><br><span>@@ -156,48 +185,52 @@</span><br><span> {</span><br><span>  struct ast_geoloc_profile *profile = obj;</span><br><span>    struct ast_geoloc_location *location;</span><br><span style="color: hsl(0, 100%, 40%);">-   const char *profile_id = ast_sorcery_object_get_id(profile);</span><br><span style="color: hsl(0, 100%, 40%);">-    const char *failed;</span><br><span style="color: hsl(120, 100%, 40%);">+   const char *id = ast_sorcery_object_get_id(profile);</span><br><span>         enum ast_geoloc_validate_result result;</span><br><span style="color: hsl(120, 100%, 40%);">+       enum ast_geoloc_format format;</span><br><span style="color: hsl(120, 100%, 40%);">+        int rc = 0;</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">- if (ast_strlen_zero(profile->location_reference)) {</span><br><span style="color: hsl(0, 100%, 40%);">-          if (profile->location_refinement ||</span><br><span style="color: hsl(0, 100%, 40%);">-                  profile->location_variables) {</span><br><span style="color: hsl(0, 100%, 40%);">-                       ast_log(LOG_ERROR, "Profile '%s' can't have location_refinement or location_variables without a location_reference",</span><br><span style="color: hsl(0, 100%, 40%);">-                              profile_id);</span><br><span style="color: hsl(120, 100%, 40%);">+  if (!ast_strlen_zero(profile->location_reference)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               if (profile->location_info ||</span><br><span style="color: hsl(120, 100%, 40%);">+                      profile->format != AST_GEOLOC_FORMAT_NONE) {</span><br><span style="color: hsl(120, 100%, 40%);">+                       ast_log(LOG_ERROR, "Profile '%s' can't have location_reference and location_info or format at the same time",</span><br><span style="color: hsl(120, 100%, 40%);">+                           id);</span><br><span>                         return -1;</span><br><span>           }</span><br><span>            return 0;</span><br><span>    }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   location = ast_sorcery_retrieve_by_id(geoloc_sorcery, "location", profile->location_reference);</span><br><span style="color: hsl(0, 100%, 40%);">-    if (!location) {</span><br><span style="color: hsl(0, 100%, 40%);">-                ast_log(LOG_ERROR, "Profile '%s' has a location_reference '%s' that doesn't exist",</span><br><span style="color: hsl(0, 100%, 40%);">-                       profile_id, profile->location_reference);</span><br><span style="color: hsl(0, 100%, 40%);">-            return -1;</span><br><span style="color: hsl(120, 100%, 40%);">+    if (profile->location_info) {</span><br><span style="color: hsl(120, 100%, 40%);">+              result = validate_location_info(id, profile->format, profile->location_info);</span><br><span style="color: hsl(120, 100%, 40%);">+           if (result != AST_GEOLOC_VALIDATE_SUCCESS) {</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%);">+           rc = validate_location_source(id, profile->location_source);</span><br><span style="color: hsl(120, 100%, 40%);">+               if (rc != 0) {</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%);">+   if (!ast_strlen_zero(profile->location_reference)) {</span><br><span style="color: hsl(120, 100%, 40%);">+               location = ast_sorcery_retrieve_by_id(geoloc_sorcery, "location", profile->location_reference);</span><br><span style="color: hsl(120, 100%, 40%);">+          if (!location) {</span><br><span style="color: hsl(120, 100%, 40%);">+                      ast_log(LOG_ERROR, "Profile '%s' has a location_reference '%s' that doesn't exist",</span><br><span style="color: hsl(120, 100%, 40%);">+                             id, profile->location_reference);</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%);">+             format = location->format;</span><br><span style="color: hsl(120, 100%, 40%);">+         ao2_ref(location, -1);</span><br><span>       }</span><br><span> </span><br><span>        if (profile->location_refinement) {</span><br><span style="color: hsl(0, 100%, 40%);">-          switch (location->format) {</span><br><span style="color: hsl(0, 100%, 40%);">-          case AST_GEOLOC_FORMAT_NONE:</span><br><span style="color: hsl(0, 100%, 40%);">-            case AST_GEOLOC_FORMAT_LAST:</span><br><span style="color: hsl(0, 100%, 40%);">-                    break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case AST_GEOLOC_FORMAT_CIVIC_ADDRESS:</span><br><span style="color: hsl(0, 100%, 40%);">-                   result = ast_geoloc_civicaddr_validate_varlist(profile->location_refinement, &failed);</span><br><span style="color: hsl(0, 100%, 40%);">-                   if (result != AST_GEOLOC_VALIDATE_SUCCESS) {</span><br><span style="color: hsl(0, 100%, 40%);">-                            ast_log(LOG_ERROR, "Profile '%s' error: %s: for item '%s' in the location_refinement\n",</span><br><span style="color: hsl(0, 100%, 40%);">-                                      profile_id,     ast_geoloc_validate_result_to_str(result), failed);</span><br><span style="color: hsl(0, 100%, 40%);">-                             ao2_ref(location, -1);</span><br><span style="color: hsl(0, 100%, 40%);">-                          return -1;</span><br><span style="color: hsl(0, 100%, 40%);">-                      }</span><br><span style="color: hsl(0, 100%, 40%);">-                       break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case AST_GEOLOC_FORMAT_GML:</span><br><span style="color: hsl(0, 100%, 40%);">-                     break;</span><br><span style="color: hsl(0, 100%, 40%);">-          case AST_GEOLOC_FORMAT_URI:</span><br><span style="color: hsl(0, 100%, 40%);">-                     break;</span><br><span style="color: hsl(120, 100%, 40%);">+                result = validate_location_info(id, format, profile->location_refinement);</span><br><span style="color: hsl(120, 100%, 40%);">+         if (result != AST_GEOLOC_VALIDATE_SUCCESS) {</span><br><span style="color: hsl(120, 100%, 40%);">+                  return -1;</span><br><span>           }</span><br><span>    }</span><br><span style="color: hsl(0, 100%, 40%);">-       ao2_ref(location, -1);</span><br><span> </span><br><span>   return 0;</span><br><span> }</span><br><span>@@ -217,7 +250,6 @@</span><br><span>         int using_regex = 0;</span><br><span>         char *result = CLI_SUCCESS;</span><br><span>  int ret = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    char *format_name;</span><br><span>   int count = 0;</span><br><span> </span><br><span>   switch (cmd) {</span><br><span>@@ -285,14 +317,12 @@</span><br><span>                       break;</span><br><span>               }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-           format_to_str(loc, NULL, &format_name);</span><br><span>          ast_cli(a->fd, "%-46.46s %-13s %-s\n",</span><br><span>                  ast_sorcery_object_get_id(loc),</span><br><span style="color: hsl(0, 100%, 40%);">-                 format_name,</span><br><span style="color: hsl(120, 100%, 40%);">+                  format_names[loc->format],</span><br><span>                        ast_str_buffer(str));</span><br><span>                ao2_unlock(loc);</span><br><span>             ast_free(str);</span><br><span style="color: hsl(0, 100%, 40%);">-          ast_free(format_name);</span><br><span>               count++;</span><br><span>     }</span><br><span>    ao2_iterator_destroy(&iter);</span><br><span>@@ -311,7 +341,6 @@</span><br><span>       int using_regex = 0;</span><br><span>         char *result = CLI_SUCCESS;</span><br><span>  int ret = 0;</span><br><span style="color: hsl(0, 100%, 40%);">-    char *precedence;</span><br><span>    int count = 0;</span><br><span> </span><br><span>   switch (cmd) {</span><br><span>@@ -368,13 +397,11 @@</span><br><span>       for (; (profile = ao2_iterator_next(&iter)); ao2_ref(profile, -1)) {</span><br><span>             ao2_lock(profile);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          precedence_to_str(profile, NULL, &precedence);</span><br><span>           ast_cli(a->fd, "%-46.46s %-16s %-s\n",</span><br><span>                  ast_sorcery_object_get_id(profile),</span><br><span style="color: hsl(0, 100%, 40%);">-                     precedence,</span><br><span style="color: hsl(120, 100%, 40%);">+                   precedence_names[profile->precedence],</span><br><span>                    profile->location_reference);</span><br><span>             ao2_unlock(profile);</span><br><span style="color: hsl(0, 100%, 40%);">-            ast_free(precedence);</span><br><span>                count++;</span><br><span>     }</span><br><span>    ao2_iterator_destroy(&iter);</span><br><span>@@ -441,7 +468,7 @@</span><br><span>               return CLI_FAILURE;</span><br><span>  }</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-   ast_cli(a->fd, "Geolocation Profile Objects:\n\n");</span><br><span style="color: hsl(120, 100%, 40%);">+      ast_cli(a->fd, "Geolocation Profile Objects:\n");</span><br><span> </span><br><span>   iter = ao2_iterator_init(sorted_container, AO2_ITERATOR_UNLINK);</span><br><span>     for (; (profile = ao2_iterator_next(&iter)); ) {</span><br><span>@@ -450,26 +477,28 @@</span><br><span>                 struct ast_str *variables_str = NULL;</span><br><span>                struct ast_str *resolved_str = NULL;</span><br><span>                 struct ast_str *usage_rules_str = NULL;</span><br><span style="color: hsl(120, 100%, 40%);">+               struct ast_str *confidence_str = NULL;</span><br><span>               struct ast_geoloc_eprofile *eprofile = ast_geoloc_eprofile_create_from_profile(profile);</span><br><span>             ao2_ref(profile, -1);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-               if (!ast_strlen_zero(eprofile->location_reference)) {</span><br><span style="color: hsl(0, 100%, 40%);">-                        loc_str = ast_variable_list_join(eprofile->location_info, ",", "=", "\"", NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                  resolved_str = ast_variable_list_join(eprofile->effective_location, ",", "=", "\"", NULL);</span><br><span style="color: hsl(0, 100%, 40%);">-                }</span><br><span style="color: hsl(120, 100%, 40%);">+             loc_str = ast_variable_list_join(eprofile->location_info, ",", "=", "\"", NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+                resolved_str = ast_variable_list_join(eprofile->effective_location, ",", "=", "\"", NULL);</span><br><span> </span><br><span>                 refinement_str = ast_variable_list_join(eprofile->location_refinement, ",", "=", "\"", NULL);</span><br><span>          variables_str = ast_variable_list_join(eprofile->location_variables, ",", "=", "\"", NULL);</span><br><span>            usage_rules_str = ast_variable_list_join(eprofile->usage_rules, ",", "=", "\"", NULL);</span><br><span style="color: hsl(120, 100%, 40%);">+          confidence_str = ast_variable_list_join(eprofile->confidence, ",", "=", "\"", NULL);</span><br><span> </span><br><span style="color: hsl(0, 100%, 40%);">-          ast_cli(a->fd,</span><br><span style="color: hsl(120, 100%, 40%);">+             ast_cli(a->fd,"\n"</span><br><span>                      "id:                      %-s\n"</span><br><span>                   "profile_precedence:      %-s\n"</span><br><span>                   "pidf_element:            %-s\n"</span><br><span>                   "location_reference:      %-s\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                      "Location_format:         %-s\n"</span><br><span style="color: hsl(0, 100%, 40%);">-                      "location_details:        %-s\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                    "location_format:         %-s\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                    "location_info:           %-s\n"</span><br><span>                   "location_method:         %-s\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                    "location_source:         %-s\n"</span><br><span style="color: hsl(120, 100%, 40%);">+                    "location_confidence:     %-s\n"</span><br><span>                   "location_refinement:     %-s\n"</span><br><span>                   "location_variables:      %-s\n"</span><br><span>                   "allow_routing_use:       %-s\n"</span><br><span>@@ -484,6 +513,8 @@</span><br><span>                     format_names[eprofile->format],</span><br><span>                   S_COR(loc_str, ast_str_buffer(loc_str), "<none>"),</span><br><span>                   S_OR(eprofile->method, "<none>"),</span><br><span style="color: hsl(120, 100%, 40%);">+                  S_OR(eprofile->location_source, "<none>"),</span><br><span style="color: hsl(120, 100%, 40%);">+                 S_COR(confidence_str, ast_str_buffer(confidence_str), "<none>"),</span><br><span>                     S_COR(refinement_str, ast_str_buffer(refinement_str), "<none>"),</span><br><span>                     S_COR(variables_str, ast_str_buffer(variables_str), "<none>"),</span><br><span>                       S_COR(eprofile->allow_routing_use, "yes", "no"),</span><br><span>@@ -499,6 +530,7 @@</span><br><span>                ast_free(variables_str);</span><br><span>             ast_free(resolved_str);</span><br><span>              ast_free(usage_rules_str);</span><br><span style="color: hsl(120, 100%, 40%);">+            ast_free(confidence_str);</span><br><span>            count++;</span><br><span>     }</span><br><span>    ao2_iterator_destroy(&iter);</span><br><span>@@ -643,11 +675,11 @@</span><br><span> </span><br><span>         ast_sorcery_object_field_register(geoloc_sorcery, "location", "type", "", OPT_NOOP_T, 0, 0);</span><br><span>   ast_sorcery_object_field_register_custom(geoloc_sorcery, "location", "format", AST_GEOLOC_FORMAT_NONE,</span><br><span style="color: hsl(0, 100%, 40%);">-              format_handler, format_to_str, NULL, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           location_format_handler, location_format_to_str, NULL, 0, 0);</span><br><span>        ast_sorcery_object_field_register_custom(geoloc_sorcery, "location", "location_info", NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-         location_info_handler, location_info_to_str, location_info_dup, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+                location_location_info_handler, location_location_info_to_str, location_location_info_dup, 0, 0);</span><br><span>    ast_sorcery_object_field_register_custom(geoloc_sorcery, "location", "confidence", NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-            confidence_handler, confidence_to_str, confidence_dup, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+         location_confidence_handler, location_confidence_to_str, location_confidence_dup, 0, 0);</span><br><span>     ast_sorcery_object_field_register(geoloc_sorcery, "location", "location_source", "", OPT_STRINGFIELD_T,</span><br><span>                0, STRFLDSET(struct ast_geoloc_location, location_source));</span><br><span>  ast_sorcery_object_field_register(geoloc_sorcery, "location", "method", "", OPT_STRINGFIELD_T,</span><br><span>@@ -678,17 +710,17 @@</span><br><span> </span><br><span>     ast_sorcery_object_field_register(geoloc_sorcery, "profile", "type", "", OPT_NOOP_T, 0, 0);</span><br><span>    ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "pidf_element",</span><br><span style="color: hsl(0, 100%, 40%);">-         pidf_element_names[AST_PIDF_ELEMENT_DEVICE], pidf_element_handler, pidf_element_to_str, NULL, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+          pidf_element_names[AST_PIDF_ELEMENT_DEVICE], profile_pidf_element_handler, profile_pidf_element_to_str, NULL, 0, 0);</span><br><span>         ast_sorcery_object_field_register(geoloc_sorcery, "profile", "location_reference", "", OPT_STRINGFIELD_T,</span><br><span>              0, STRFLDSET(struct ast_geoloc_profile, location_reference));</span><br><span>        ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "profile_precedence", "discard_incoming",</span><br><span style="color: hsl(0, 100%, 40%);">-             precedence_handler, precedence_to_str, NULL, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+           profile_precedence_handler, profile_precedence_to_str, NULL, 0, 0);</span><br><span>  ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "usage_rules", NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-            usage_rules_handler, usage_rules_to_str, usage_rules_dup, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+              profile_usage_rules_handler, profile_usage_rules_to_str, profile_usage_rules_dup, 0, 0);</span><br><span>     ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "location_info_refinement", NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-               location_refinement_handler, location_refinement_to_str, location_refinement_dup, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+              profile_location_refinement_handler, profile_location_refinement_to_str, profile_location_refinement_dup, 0, 0);</span><br><span>     ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "location_variables", NULL,</span><br><span style="color: hsl(0, 100%, 40%);">-             location_variables_handler, location_variables_to_str, location_variables_dup, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+         profile_location_variables_handler, profile_location_variables_to_str, profile_location_variables_dup, 0, 0);</span><br><span>        ast_sorcery_object_field_register(geoloc_sorcery, "profile", "notes", "", OPT_STRINGFIELD_T,</span><br><span>           0, STRFLDSET(struct ast_geoloc_profile, notes));</span><br><span>     ast_sorcery_object_field_register(geoloc_sorcery, "profile", "allow_routing_use",</span><br><span>@@ -696,6 +728,17 @@</span><br><span>         ast_sorcery_object_field_register(geoloc_sorcery, "profile", "suppress_empty_ca_elements",</span><br><span>               "no", OPT_BOOL_T, 1, FLDSET(struct ast_geoloc_profile, suppress_empty_ca_elements));</span><br><span> </span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "format", AST_GEOLOC_FORMAT_NONE,</span><br><span style="color: hsl(120, 100%, 40%);">+             profile_format_handler, profile_format_to_str, NULL, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+   ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "location_info", NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+                profile_location_info_handler, profile_location_info_to_str, profile_location_info_dup, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+        ast_sorcery_object_field_register_custom(geoloc_sorcery, "profile", "confidence", NULL,</span><br><span style="color: hsl(120, 100%, 40%);">+           profile_confidence_handler, profile_confidence_to_str, profile_confidence_dup, 0, 0);</span><br><span style="color: hsl(120, 100%, 40%);">+ ast_sorcery_object_field_register(geoloc_sorcery, "profile", "location_source", "", OPT_STRINGFIELD_T,</span><br><span style="color: hsl(120, 100%, 40%);">+          0, STRFLDSET(struct ast_geoloc_profile, location_source));</span><br><span style="color: hsl(120, 100%, 40%);">+    ast_sorcery_object_field_register(geoloc_sorcery, "profile", "method", "", OPT_STRINGFIELD_T,</span><br><span style="color: hsl(120, 100%, 40%);">+           0, STRFLDSET(struct ast_geoloc_profile, method));</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span>      ast_sorcery_load(geoloc_sorcery);</span><br><span> </span><br><span>diff --git a/res/res_geolocation/geoloc_doc.xml b/res/res_geolocation/geoloc_doc.xml</span><br><span>index 0e1b31d..4f7cdc2 100644</span><br><span>--- a/res/res_geolocation/geoloc_doc.xml</span><br><span>+++ b/res/res_geolocation/geoloc_doc.xml</span><br><span>@@ -207,6 +207,11 @@</span><br><span>                                            </enumlist></span><br><span>                                    </description></span><br><span>                                 </configOption></span><br><span style="color: hsl(120, 100%, 40%);">+                         <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='format'])"/></span><br><span style="color: hsl(120, 100%, 40%);">+                         <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='location_info'])"/></span><br><span style="color: hsl(120, 100%, 40%);">+                          <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='confidence'])"/></span><br><span style="color: hsl(120, 100%, 40%);">+                             <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='location_source'])"/></span><br><span style="color: hsl(120, 100%, 40%);">+                                <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='method'])"/></span><br><span>                        </configObject></span><br><span>                </configFile></span><br><span>  </configInfo></span><br><span>diff --git a/res/res_geolocation/geoloc_eprofile.c b/res/res_geolocation/geoloc_eprofile.c</span><br><span>index 5f20612..1deb76e 100644</span><br><span>--- a/res/res_geolocation/geoloc_eprofile.c</span><br><span>+++ b/res/res_geolocation/geoloc_eprofile.c</span><br><span>@@ -177,12 +177,23 @@</span><br><span>         eprofile->allow_routing_use = profile->allow_routing_use;</span><br><span>      eprofile->pidf_element = profile->pidf_element;</span><br><span>        eprofile->suppress_empty_ca_elements = profile->suppress_empty_ca_elements;</span><br><span style="color: hsl(120, 100%, 40%);">+     eprofile->format = profile->format;</span><br><span style="color: hsl(120, 100%, 40%);">+</span><br><span> </span><br><span>      rc = ast_string_field_set(eprofile, location_reference, profile->location_reference);</span><br><span>     if (rc == 0) {</span><br><span>               ast_string_field_set(eprofile, notes, profile->notes);</span><br><span>    }</span><br><span>    if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_string_field_set(eprofile, method, profile->method);</span><br><span style="color: hsl(120, 100%, 40%);">+   }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                ast_string_field_set(eprofile, location_source, profile->location_source);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = DUP_VARS(eprofile->location_info, profile->location_info);</span><br><span style="color: hsl(120, 100%, 40%);">+ }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc == 0) {</span><br><span>               rc = DUP_VARS(eprofile->location_refinement, profile->location_refinement);</span><br><span>    }</span><br><span>    if (rc == 0) {</span><br><span>@@ -191,6 +202,9 @@</span><br><span>         if (rc == 0) {</span><br><span>               rc = DUP_VARS(eprofile->usage_rules, profile->usage_rules);</span><br><span>    }</span><br><span style="color: hsl(120, 100%, 40%);">+     if (rc == 0) {</span><br><span style="color: hsl(120, 100%, 40%);">+                rc = DUP_VARS(eprofile->confidence, profile->confidence);</span><br><span style="color: hsl(120, 100%, 40%);">+       }</span><br><span>    if (rc != 0) {</span><br><span>               ao2_unlock(profile);</span><br><span>                 ao2_ref(eprofile, -1);</span><br><span>diff --git a/res/res_geolocation/geoloc_private.h b/res/res_geolocation/geoloc_private.h</span><br><span>index ff5e2af..910dbc5 100644</span><br><span>--- a/res/res_geolocation/geoloc_private.h</span><br><span>+++ b/res/res_geolocation/geoloc_private.h</span><br><span>@@ -38,7 +38,7 @@</span><br><span> }</span><br><span> </span><br><span> #define CONFIG_ENUM_HANDLER(_object, _stem) \</span><br><span style="color: hsl(0, 100%, 40%);">-static int _stem ## _handler(const struct aco_option *opt, struct ast_variable *var, void *obj) \</span><br><span style="color: hsl(120, 100%, 40%);">+static int  _object ## _ ## _stem ## _handler(const struct aco_option *opt, struct ast_variable *var, void *obj) \</span><br><span> { \</span><br><span>        struct ast_geoloc_ ## _object *_thisobject = obj; \</span><br><span>  int enumval = ast_geoloc_ ## _stem ## _str_to_enum(var->value); \</span><br><span>@@ -61,7 +61,7 @@</span><br><span> }</span><br><span> </span><br><span> #define CONFIG_ENUM_TO_STR(_object, _stem) \</span><br><span style="color: hsl(0, 100%, 40%);">-static int _stem ## _to_str(const void *obj, const intptr_t *args, char **buf) \</span><br><span style="color: hsl(120, 100%, 40%);">+static int _object ## _ ## _stem ## _to_str(const void *obj, const intptr_t *args, char **buf) \</span><br><span> { \</span><br><span>   const struct ast_geoloc_ ## _object *_thisobject = obj; \</span><br><span>    if (!ARRAY_IN_BOUNDS(_thisobject->_stem, _stem ## _names)) { \</span><br><span>@@ -79,7 +79,7 @@</span><br><span> CONFIG_ENUM_TO_STR(_object, _stem)</span><br><span> </span><br><span> #define CONFIG_VAR_LIST_HANDLER(_object, _stem) \</span><br><span style="color: hsl(0, 100%, 40%);">-static int _stem ## _handler(const struct aco_option *opt, struct ast_variable *var, void *obj) \</span><br><span style="color: hsl(120, 100%, 40%);">+static int  _object ## _ ## _stem ## _handler(const struct aco_option *opt, struct ast_variable *var, void *obj) \</span><br><span> { \</span><br><span>     struct ast_geoloc_ ## _object *_thisobject = obj; \</span><br><span>  struct ast_variable *new_var; \</span><br><span>@@ -101,7 +101,7 @@</span><br><span> }</span><br><span> </span><br><span> #define CONFIG_VAR_LIST_DUP(_object, _stem) \</span><br><span style="color: hsl(0, 100%, 40%);">-static int _stem ## _dup(const void *obj, struct ast_variable **fields) \</span><br><span style="color: hsl(120, 100%, 40%);">+static int  _object ## _ ## _stem ## _dup(const void *obj, struct ast_variable **fields) \</span><br><span> { \</span><br><span>  const struct ast_geoloc_ ## _object *_thisobject = obj; \</span><br><span>    if (_thisobject->_stem) { \</span><br><span>@@ -111,7 +111,7 @@</span><br><span> }</span><br><span> </span><br><span> #define CONFIG_VAR_LIST_TO_STR(_object, _stem) \</span><br><span style="color: hsl(0, 100%, 40%);">-static int _stem ## _to_str(const void *obj, const intptr_t *args, char **buf) \</span><br><span style="color: hsl(120, 100%, 40%);">+static int  _object ## _ ## _stem ## _to_str(const void *obj, const intptr_t *args, char **buf) \</span><br><span> { \</span><br><span>  const struct ast_geoloc_ ## _object *_thisobject = obj; \</span><br><span>    struct ast_str *str = ast_variable_list_join(_thisobject->_stem, ",", "=", "\"", NULL); \</span><br><span></span><br></pre><p>To view, visit <a href="https://gerrit.asterisk.org/c/asterisk/+/19184">change 19184</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/+/19184"/><meta itemprop="name" content="View Change"/></div></div>

<div style="display:none"> Gerrit-Project: asterisk </div>
<div style="display:none"> Gerrit-Branch: 19 </div>
<div style="display:none"> Gerrit-Change-Id: Ifd5f05be0a76f0a6ad49fa28d17c394027677569 </div>
<div style="display:none"> Gerrit-Change-Number: 19184 </div>
<div style="display:none"> Gerrit-PatchSet: 2 </div>
<div style="display:none"> Gerrit-Owner: George Joseph <gjoseph@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-MessageType: merged </div>