]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_geolocation: Add two new options to GEOLOC_PROFILE
authorGeorge Joseph <gjoseph@digium.com>
Thu, 25 Aug 2022 13:00:33 +0000 (07:00 -0600)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Sat, 10 Sep 2022 17:53:49 +0000 (12:53 -0500)
Added an 'a' option to the GEOLOC_PROFILE function to allow
variable lists like location_info_refinement to be appended
to instead of replacing the entire list.

Added an 'r' option to the GEOLOC_PROFILE function to resolve all
variables before a read operation and after a Set operation.

Added a few missing parameters to the ones allowed for writing
with GEOLOC_PROFILE.

Fixed a bug where calling GEOLOC_PROFILE to read a parameter
might actually update the profile object.

Cleaned up XML documentation a bit.

ASTERISK-30190

Change-Id: I75f541db43345509a2e86225bfa4cf8e242e5b6c

doc/CHANGES-staging/res_geolocation.txt
include/asterisk/res_geolocation.h
res/res_geolocation/geoloc_dialplan.c
res/res_geolocation/geoloc_doc.xml
res/res_geolocation/geoloc_eprofile.c
res/res_geolocation/geoloc_private.h
res/res_pjsip_geolocation.c

index deda71ce5ee545f82f0e07083a6eb8c3c5fb6ca3..e8a99527109454bae292a3f6aa7da28141a47c94 100644 (file)
@@ -18,3 +18,10 @@ a profile object for simple scenarios where the location
 information isn't common with any other profiles.  This is
 mutually exclusive with setting location_reference on the
 profile.
+
+Added an 'a' option to the GEOLOC_PROFILE function to allow
+variable lists like location_info_refinement to be appended
+to instead of replacing the entire list.
+
+Added an 'r' option to the GEOLOC_PROFILE function to resolve all
+variables before a read operation and after a Set operation.
index 378a6c736a59f6d148d30cd32a677b5604c9bde1..0a5a61d11d730ab13dab79a55f187e8a58ce723c 100644 (file)
@@ -317,6 +317,15 @@ struct ast_datastore *ast_geoloc_datastore_find(struct ast_channel *chan);
  */
 struct ast_geoloc_eprofile *ast_geoloc_eprofile_alloc(const char *name);
 
+/*!
+ * \brief Duplicate an effective profile.
+ *
+ * \param src The eprofile to duplicate.
+ *
+ * \return The duplicated effective profile ao2 object.
+ */
+struct ast_geoloc_eprofile *ast_geoloc_eprofile_dup(struct ast_geoloc_eprofile *src);
+
 /*!
  * \brief Allocate a new effective profile from an existing profile.
  *
index 710daa65a28503c31bda002b452c4f801674cc9a..1d1346a30d28d9574f7e4dab58d49ca18ea54b8c 100644 (file)
@@ -25,7 +25,6 @@
 #include "asterisk/strings.h"
 #include "asterisk/utils.h"
 #include "asterisk/app.h"
-#include "asterisk/res_geolocation.h"
 #include "geoloc_private.h"
 
 static void varlist_to_str(struct ast_variable *list, struct ast_str** buf, size_t len)
@@ -37,20 +36,52 @@ static void varlist_to_str(struct ast_variable *list, struct ast_str** buf, size
        }
 }
 
+#define RESOLVE_FOR_READ(_param) \
+({ \
+       if (ast_test_flag(&opts, OPT_GEOLOC_RESOLVE)) { \
+               struct ast_variable *resolved = geoloc_eprofile_resolve_varlist( \
+                       eprofile->_param, eprofile->location_variables, chan); \
+               if (!resolved) { \
+                       ast_log(LOG_ERROR, "%s: Unable to resolve " #_param "\n", chan_name); \
+                       pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
+                       return 0; \
+               } \
+               varlist_to_str(resolved, buf, len); \
+               ast_variables_destroy(resolved); \
+       } else { \
+               varlist_to_str(eprofile->_param, buf, len); \
+       } \
+})
+
+enum my_app_option_flags {
+       OPT_GEOLOC_RESOLVE = (1 << 0),
+       OPT_GEOLOC_APPEND = (1 << 1),
+};
+
+AST_APP_OPTIONS(action_options, {
+       AST_APP_OPTION('r', OPT_GEOLOC_RESOLVE),
+       AST_APP_OPTION('a', OPT_GEOLOC_APPEND),
+});
+
+
 static int geoloc_profile_read(struct ast_channel *chan,
        const char *cmd, char *data, struct ast_str **buf, ssize_t len)
 {
        char *parsed_data = ast_strdupa(data);
+       const char *chan_name = ast_channel_name(chan);
        struct ast_datastore *ds;
+       struct ast_geoloc_eprofile *orig_eprofile = NULL;
        struct ast_geoloc_eprofile *eprofile = NULL;
+       struct ast_flags opts = { 0, };
 
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(field);
+               AST_APP_ARG(options);
        );
 
        /* Check for zero arguments */
        if (ast_strlen_zero(parsed_data)) {
-               ast_log(LOG_ERROR, "%s: Cannot call without arguments\n", cmd);
+               ast_log(LOG_ERROR, "%s: Cannot call without arguments\n", chan_name);
                pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-1");
                return 0;
        }
@@ -58,25 +89,45 @@ static int geoloc_profile_read(struct ast_channel *chan,
        AST_STANDARD_APP_ARGS(args, parsed_data);
 
        if (ast_strlen_zero(args.field)) {
-               ast_log(LOG_ERROR, "%s: Cannot call without a field to query\n", cmd);
+               ast_log(LOG_ERROR, "%s: Cannot call without a field to query\n", chan_name);
                pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-1");
                return 0;
        }
 
+       if (!ast_strlen_zero(args.options)) {
+               if (ast_app_parse_options(action_options, &opts, NULL, args.options)) {
+                       ast_log(LOG_ERROR, "%s: Invalid options: %s\n", chan_name, args.options);
+                       pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-1");
+                       return 0;
+               }
+       }
+
        ds = ast_geoloc_datastore_find(chan);
        if (!ds) {
-               ast_log(LOG_NOTICE, "%s: There is no geoloc profile on this channel\n", cmd);
+               ast_log(LOG_NOTICE, "%s: There is no geoloc profile on this channel\n", chan_name);
                pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-2");
                return 0;
        }
 
-       eprofile = ast_geoloc_datastore_get_eprofile(ds, 0);
+       orig_eprofile = ast_geoloc_datastore_get_eprofile(ds, 0);
+       if (!orig_eprofile) {
+               ast_log(LOG_NOTICE, "%s: There is no geoloc profile on this channel\n", chan_name);
+               pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-2");
+               return 0;
+       }
+
+       eprofile = ast_geoloc_eprofile_dup(orig_eprofile);
+       ao2_ref(orig_eprofile, -1);
        if (!eprofile) {
-               ast_log(LOG_NOTICE, "%s: There is no geoloc profile on this channel\n", cmd);
+               ast_log(LOG_ERROR, "%s: Unable to duplicate eprofile\n", chan_name);
                pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-2");
                return 0;
        }
 
+       if (!eprofile->effective_location) {
+               ast_geoloc_eprofile_refresh_location(eprofile);
+       }
+
        pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "0");
        if (ast_strings_equal(args.field, "inheritable")) {
                ast_str_append(buf, len, "%s", ds->inheritance ? "true" : "false");
@@ -101,19 +152,19 @@ static int geoloc_profile_read(struct ast_channel *chan,
        } else if (ast_strings_equal(args.field, "notes")) {
                ast_str_append(buf, len, "%s", eprofile->notes);
        } else if (ast_strings_equal(args.field, "location_info")) {
-               varlist_to_str(eprofile->location_info, buf, len);
+               RESOLVE_FOR_READ(location_info);
        } else if (ast_strings_equal(args.field, "location_info_refinement")) {
-               varlist_to_str(eprofile->location_refinement, buf, len);
+               RESOLVE_FOR_READ(location_refinement);
        } else if (ast_strings_equal(args.field, "location_variables")) {
-               varlist_to_str(eprofile->location_variables, buf, len);
+               RESOLVE_FOR_READ(location_variables);
        } else if (ast_strings_equal(args.field, "effective_location")) {
-               varlist_to_str(eprofile->effective_location, buf, len);
+               RESOLVE_FOR_READ(effective_location);
        } else if (ast_strings_equal(args.field, "usage_rules")) {
-               varlist_to_str(eprofile->usage_rules, buf, len);
+               RESOLVE_FOR_READ(usage_rules);
        } else if (ast_strings_equal(args.field, "confidence")) {
                varlist_to_str(eprofile->confidence, buf, len);
        } else {
-               ast_log(LOG_ERROR, "%s: Field '%s' is not valid\n", cmd, args.field);
+               ast_log(LOG_ERROR, "%s: Field '%s' is not valid\n", chan_name, args.field);
                pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3");
        }
 
@@ -121,6 +172,10 @@ static int geoloc_profile_read(struct ast_channel *chan,
        return 0;
 }
 
+#define VAR_LIST_REPLACE(_old, _new) \
+       ast_variables_destroy(_old); \
+       _old = _new;
+
 #define TEST_ENUM_VALUE(_chan_name, _ep, _field, _value) \
 ({ \
        enum ast_geoloc_ ## _field v; \
@@ -142,8 +197,26 @@ static int geoloc_profile_read(struct ast_channel *chan,
                pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
                return 0; \
        } \
-       ast_variables_destroy(_ep->_field); \
-       _ep->_field = _list; \
+       if (ast_test_flag(&opts, OPT_GEOLOC_APPEND)) { \
+               ast_variable_list_append(&_ep->_field, _list); \
+       } else {\
+               VAR_LIST_REPLACE(_ep->_field, _list); \
+       } \
+})
+
+
+#define RESOLVE_FOR_WRITE(_param) \
+({ \
+if (ast_test_flag(&opts, OPT_GEOLOC_RESOLVE)) { \
+       struct ast_variable *resolved = geoloc_eprofile_resolve_varlist( \
+               eprofile->_param, eprofile->location_variables, chan); \
+       if (!resolved) { \
+               ast_log(LOG_ERROR, "%s: Unable to resolve " #_param " %p %p\n", chan_name, eprofile->_param, eprofile->location_variables); \
+               pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
+               return 0; \
+       } \
+       VAR_LIST_REPLACE(eprofile->_param, resolved); \
+} \
 })
 
 static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char *data,
@@ -153,9 +226,11 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char
        const char *chan_name = ast_channel_name(chan);
        struct ast_datastore *ds; /* Reminder: datastores aren't ao2 objects */
        RAII_VAR(struct ast_geoloc_eprofile *, eprofile, NULL, ao2_cleanup);
+       struct ast_flags opts = { 0, };
 
        AST_DECLARE_APP_ARGS(args,
                AST_APP_ARG(field);
+               AST_APP_ARG(options);
        );
 
        /* Check for zero arguments */
@@ -173,6 +248,18 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char
                return 0;
        }
 
+       if (!ast_strlen_zero(args.options)) {
+               if (ast_app_parse_options(action_options, &opts, NULL, args.options)) {
+                       ast_log(LOG_ERROR, "%s: Invalid options: %s\n", chan_name, args.options);
+                       pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-1");
+                       return 0;
+               }
+       }
+
+       ast_debug(1, "%s: name: %s value: %s  options: %s append: %s resolve: %s\n", chan_name,
+               args.field, value, args.options, ast_test_flag(&opts, OPT_GEOLOC_APPEND) ? "yes" : "no",
+                       ast_test_flag(&opts, OPT_GEOLOC_RESOLVE) ? "yes" : "no");
+
        ds = ast_geoloc_datastore_find(chan);
        if (!ds) {
                ds = ast_geoloc_datastore_create(ast_channel_name(chan));
@@ -203,6 +290,8 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char
 
        if (ast_strings_equal(args.field, "inheritable")) {
                ast_geoloc_datastore_set_inheritance(ds, ast_true(value));
+       } else if (ast_strings_equal(args.field, "id")) {
+               ast_string_field_set(eprofile, id, value);
        } else if (ast_strings_equal(args.field, "location_reference")) {
                struct ast_geoloc_location *loc = ast_geoloc_get_location(value);
                ao2_cleanup(loc);
@@ -224,18 +313,25 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char
                TEST_ENUM_VALUE(chan_name, eprofile, format, value);
        } else if (ast_strings_equal(args.field, "pidf_element")) {
                TEST_ENUM_VALUE(chan_name, eprofile, pidf_element, value);
-       } else if (ast_strings_equal(args.field, "location_info")) {
-               TEST_VARLIST(chan_name, eprofile, location_info, value);
        } else if (ast_strings_equal(args.field, "location_source")) {
                ast_string_field_set(eprofile, location_source, value);
+       } else if (ast_strings_equal(args.field, "notes")) {
+               ast_string_field_set(eprofile, notes, value);
+       } else if (ast_strings_equal(args.field, "location_info")) {
+               TEST_VARLIST(chan_name, eprofile, location_info, value);
+               RESOLVE_FOR_WRITE(location_info);
        } else if (ast_strings_equal(args.field, "location_info_refinement")) {
                TEST_VARLIST(chan_name, eprofile, location_refinement, value);
+               RESOLVE_FOR_WRITE(location_refinement);
        } else if (ast_strings_equal(args.field, "location_variables")) {
                TEST_VARLIST(chan_name, eprofile, location_variables, value);
+               RESOLVE_FOR_WRITE(location_variables);
        } else if (ast_strings_equal(args.field, "effective_location")) {
                TEST_VARLIST(chan_name, eprofile, effective_location, value);
+               RESOLVE_FOR_WRITE(effective_location);
        } else if (ast_strings_equal(args.field, "usage_rules")) {
                TEST_VARLIST(chan_name, eprofile, usage_rules, value);
+               RESOLVE_FOR_WRITE(usage_rules);
        } else if (ast_strings_equal(args.field, "confidence")) {
                TEST_VARLIST(chan_name, eprofile, confidence, value);
        } else {
@@ -245,6 +341,7 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char
        }
 
        ast_geoloc_eprofile_refresh_location(eprofile);
+
        pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "0");
 
        return 0;
index 4f7cdc2339ec26c697e407255c99c2dd4b9b2772..b5713362f2405294487c26a15ea1fd436b486a45 100644 (file)
@@ -7,12 +7,14 @@
                        <configObject name="location">
                                <synopsis>Location</synopsis>
                                <description>
-                                       <para>cffdffff</para>
+                                       <para>Parameters for defining a Location object</para>
                                </description>
+
                                <configOption name="type">
                                        <synopsis>Must be of type 'location'.</synopsis>
                                </configOption>
-                               <configOption name="format" default="">
+
+                               <configOption name="format" default="none">
                                        <synopsis>Location specification type</synopsis>
                                        <description>
                                                <enumlist>
@@ -42,7 +44,8 @@
                                                </enumlist>
                                        </description>
                                </configOption>
-                               <configOption name="location_info" default="">
+
+                               <configOption name="location_info" default="none">
                                        <synopsis>Location information</synopsis>
                                        <description>
                                                <para>The contents of this parameter are specific to the
@@ -68,7 +71,8 @@
                                                </enumlist>
                                        </description>
                                </configOption>
-                               <configOption name="location_source" default="">
+
+                               <configOption name="location_source" default="none">
                                        <synopsis>Fully qualified host name</synopsis>
                                        <description>
                                                <para>This parameter isn't required but if provided, RFC8787 says it MUST be a fully
@@ -77,7 +81,8 @@
                                                Geolocation</literal> header.</para>
                                        </description>
                                </configOption>
-                               <configOption name="method" default="">
+
+                               <configOption name="method" default="none">
                                        <synopsis>Location determination method</synopsis>
                                        <description>
                                                <para>This is a rarely used field in the specification that would
@@ -94,7 +99,8 @@
                                                </enumlist>
                                        </description>
                                </configOption>
-                               <configOption name="confidence" default="">
+
+                               <configOption name="confidence" default="none">
                                        <synopsis>Level of confidence</synopsis>
                                        <description>
                                                <para>This is a rarely used field in the specification that would
                                        </see-also>
                                </configOption>
                        </configObject>
+
                        <configObject name="profile">
                                <synopsis>Profile</synopsis>
                                <description>
-                                       <para>cffdffff</para>
+                                       <para>Parameters for defining a Profile object</para>
                                </description>
                                <configOption name="type">
                                        <synopsis>Must be of type 'profile'.</synopsis>
                                </configOption>
+
                                <configOption name="pidf_element" default="device">
                                        <synopsis>PIDF-LO element to place this profile in</synopsis>
                                        <description>
                                                <ref type="link">https://www.rfc-editor.org/rfc/rfc5491.html#section-3.4</ref>
                                        </see-also>
                                </configOption>
-                               <configOption name="location_reference" default="">
+
+                               <configOption name="location_reference" default="none">
                                        <synopsis>Reference to a location object</synopsis>
                                </configOption>
-                               <configOption name="location_info_refinement" default="">
+
+                               <configOption name="location_info_refinement" default="none">
                                        <synopsis>Reference to a location object</synopsis>
                                </configOption>
-                               <configOption name="location_variables" default="">
+                               <configOption name="location_variables" default="none">
                                        <synopsis>Reference to a location object</synopsis>
                                </configOption>
-                               <configOption name="usage_rules" default="yes">
+
+                               <configOption name="usage_rules" default="empty &lt;usage_rules&gt; element">
                                        <synopsis>location specification type</synopsis>
                                        <description>
                                                <para>xxxx</para>
                                        </description>
                                </configOption>
+
                                <configOption name="notes" default="">
                                        <synopsis>Notes to be added to the outgoing PIDF-LO document</synopsis>
                                        <description>
                                                outgoing PIDF-LO document.  Its usage should be pre-negotiated with
                                                any recipients.</para>
                                        </description>
+
                                </configOption>
-                               <configOption name="allow_routing_use">
+                               <configOption name="allow_routing_use" default="no">
                                        <synopsis>Sets the value of the Geolocation-Routing header.</synopsis>
                                </configOption>
-                               <configOption name="suppress_empty_ca_elements">
+
+                               <configOption name="suppress_empty_ca_elements" default="no">
                                        <synopsis>Sets if empty Civic Address elements should be suppressed
                                        from the PIDF-LO document.</synopsis>
                                </configOption>
                                                </enumlist>
                                        </description>
                                </configOption>
+
                                <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='format'])"/>
                                <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='location_info'])"/>
                                <xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='confidence'])"/>
                        Get or Set a field in a geolocation profile
                </synopsis>
                <syntax>
-                       <parameter name="field" required="true">
-                               <para>The profile field to operate on. The following fields from the
+                       <parameter name="parameter" required="true">
+                               <para>The profile parameter to operate on. The following fields from the
                                Location and Profile objects are supported.</para>
                                <enumlist>
                                        <enum name="id"/>
                                set to <literal>true</literal> or <literal>false</literal> to control
                                whether the profile will be passed to the outgoing channel.
                                </para>
+                               <para>
+                               </para>
+                       </parameter>
+
+                       <parameter name="options" required="false">
+                               <optionlist>
+                               <option name="a">
+                                       <para>Append provided value to the specified parameter
+                                       instead of replacing the existing value.  This only applies
+                                       to variable list parameters like
+                                       <literal>location_info_refinement</literal>.
+                                       </para>
+                               </option>
+                               <option name="r">
+                                       <para>Before reading or after writing the specified parameter,
+                                       re-resolve the <literal>effective_location</literal> and
+                                       <literal>usage_rules</literal> parameters using the
+                                       <literal>location_variables</literal> parameter and the variables
+                                       set on the channel in effect at the time this function is called.
+                                       </para>
+                                       <note><para>On a read operation, this does not alter the actual profile
+                                               in any way.  On a write operation however, the
+                                               <literal>effective_location</literal> and/or <literal>usage_rules</literal>
+                                               parameters may indeed change and those changes will be passed on
+                                               to any outgoing channel.
+                                       </para></note>
+                               </option>
+                               </optionlist>
                        </parameter>
                </syntax>
                <description><para>
-               When used to set a field on a profile, if the profile doesn't already exist, a new
+               When used to set a parameter on a profile, if the profile doesn't already exist, a new
                one will be created automatically.
                </para>
                <para>
                        <enum name="0"><para>Success</para></enum>
                        <enum name="-1"><para>No or not enough parameters were supplied</para></enum>
                        <enum name="-2"><para>There was an internal error finding or creating a profile</para></enum>
-                       <enum name="-3"><para>There was an issue specific to the field specified
-                       (value not valid or field name not found)</para></enum>
+                       <enum name="-3"><para>There was an issue specific to the parameter specified
+                       (value not valid or parameter name not found, etc.)</para></enum>
                </enumlist>
                </description>
        </function>
index 1deb76e654d88e7ade4c48213d0280db3d4fa176..864dd23b244919a749f4694dd2d17d08649a5662 100644 (file)
@@ -156,6 +156,67 @@ int ast_geoloc_eprofile_refresh_location(struct ast_geoloc_eprofile *eprofile)
        return 0;
 }
 
+struct ast_geoloc_eprofile *ast_geoloc_eprofile_dup(struct ast_geoloc_eprofile *src)
+{
+       struct ast_geoloc_eprofile *eprofile;
+       const char *profile_id;
+       int rc = 0;
+
+       if (!src) {
+               return NULL;
+       }
+
+       profile_id = ast_strdupa(src->id);
+
+       eprofile = ast_geoloc_eprofile_alloc(profile_id);
+       if (!eprofile) {
+               return NULL;
+       }
+
+       eprofile->allow_routing_use = src->allow_routing_use;
+       eprofile->pidf_element = src->pidf_element;
+       eprofile->suppress_empty_ca_elements = src->suppress_empty_ca_elements;
+       eprofile->format = src->format;
+       eprofile->precedence = src->precedence;
+
+
+       rc = ast_string_field_set(eprofile, location_reference, src->location_reference);
+       if (rc == 0) {
+               ast_string_field_set(eprofile, notes, src->notes);
+       }
+       if (rc == 0) {
+               ast_string_field_set(eprofile, method, src->method);
+       }
+       if (rc == 0) {
+               ast_string_field_set(eprofile, location_source, src->location_source);
+       }
+       if (rc == 0) {
+               rc = DUP_VARS(eprofile->location_info, src->location_info);
+       }
+       if (rc == 0) {
+               rc = DUP_VARS(eprofile->effective_location, src->effective_location);
+       }
+       if (rc == 0) {
+               rc = DUP_VARS(eprofile->location_refinement, src->location_refinement);
+       }
+       if (rc == 0) {
+               rc = DUP_VARS(eprofile->location_variables, src->location_variables);
+       }
+       if (rc == 0) {
+               rc = DUP_VARS(eprofile->usage_rules, src->usage_rules);
+       }
+       if (rc == 0) {
+               rc = DUP_VARS(eprofile->confidence, src->confidence);
+       }
+       if (rc != 0) {
+               ao2_ref(eprofile, -1);
+               return NULL;
+       }
+
+
+       return eprofile;
+}
+
 struct ast_geoloc_eprofile *ast_geoloc_eprofile_create_from_profile(struct ast_geoloc_profile *profile)
 {
        struct ast_geoloc_eprofile *eprofile;
@@ -287,7 +348,7 @@ struct ast_geoloc_eprofile *ast_geoloc_eprofile_create_from_uri(const char *uri,
        return eprofile;
 }
 
-static struct ast_variable *geoloc_eprofile_resolve_varlist(struct ast_variable *source,
+struct ast_variable *geoloc_eprofile_resolve_varlist(struct ast_variable *source,
        struct ast_variable *variables, struct ast_channel *chan)
 {
        struct ast_variable *dest = NULL;
index 910dbc5a3a3e86c46e4014b77926bd6c8f71faea..0bd0797cb7dcb17ac249f075102fc6177ac3f417 100644 (file)
@@ -155,4 +155,8 @@ int geoloc_eprofile_reload(void);
 
 struct ast_sorcery *geoloc_get_sorcery(void);
 
+struct ast_variable *geoloc_eprofile_resolve_varlist(struct ast_variable *source,
+       struct ast_variable *variables, struct ast_channel *chan);
+
+
 #endif /* GEOLOC_PRIVATE_H_ */
index 0ca1e589809f03d1bb271da594e6d787a3305d9a..d0e8d465d35b832c750415c7834ac2e9358c07c3 100644 (file)
@@ -574,7 +574,10 @@ static void handle_outgoing_request(struct ast_sip_session *session, struct pjsi
                        session_name);
        }
 
-       ast_geoloc_eprofile_refresh_location(final_eprofile);
+       if (!final_eprofile->effective_location) {
+               ast_geoloc_eprofile_refresh_location(final_eprofile);
+       }
+
        if (final_eprofile->format == AST_GEOLOC_FORMAT_URI) {
                uri = ast_geoloc_eprofile_to_uri(final_eprofile, channel, &buf, session_name);
                if (!uri) {