mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-04 03:50:31 +00:00
res_geolocation: Add two new options to GEOLOC_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. 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
This commit is contained in:
committed by
Friendly Automation
parent
dbdd26e867
commit
f500a87bb4
@@ -18,3 +18,10 @@ a profile object for simple scenarios where the location
|
|||||||
information isn't common with any other profiles. This is
|
information isn't common with any other profiles. This is
|
||||||
mutually exclusive with setting location_reference on the
|
mutually exclusive with setting location_reference on the
|
||||||
profile.
|
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.
|
||||||
|
@@ -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);
|
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.
|
* \brief Allocate a new effective profile from an existing profile.
|
||||||
*
|
*
|
||||||
|
@@ -25,7 +25,6 @@
|
|||||||
#include "asterisk/strings.h"
|
#include "asterisk/strings.h"
|
||||||
#include "asterisk/utils.h"
|
#include "asterisk/utils.h"
|
||||||
#include "asterisk/app.h"
|
#include "asterisk/app.h"
|
||||||
#include "asterisk/res_geolocation.h"
|
|
||||||
#include "geoloc_private.h"
|
#include "geoloc_private.h"
|
||||||
|
|
||||||
static void varlist_to_str(struct ast_variable *list, struct ast_str** buf, size_t len)
|
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,
|
static int geoloc_profile_read(struct ast_channel *chan,
|
||||||
const char *cmd, char *data, struct ast_str **buf, ssize_t len)
|
const char *cmd, char *data, struct ast_str **buf, ssize_t len)
|
||||||
{
|
{
|
||||||
char *parsed_data = ast_strdupa(data);
|
char *parsed_data = ast_strdupa(data);
|
||||||
|
const char *chan_name = ast_channel_name(chan);
|
||||||
struct ast_datastore *ds;
|
struct ast_datastore *ds;
|
||||||
|
struct ast_geoloc_eprofile *orig_eprofile = NULL;
|
||||||
struct ast_geoloc_eprofile *eprofile = NULL;
|
struct ast_geoloc_eprofile *eprofile = NULL;
|
||||||
|
struct ast_flags opts = { 0, };
|
||||||
|
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(field);
|
AST_APP_ARG(field);
|
||||||
|
AST_APP_ARG(options);
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Check for zero arguments */
|
/* Check for zero arguments */
|
||||||
if (ast_strlen_zero(parsed_data)) {
|
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");
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-1");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -58,25 +89,45 @@ static int geoloc_profile_read(struct ast_channel *chan,
|
|||||||
AST_STANDARD_APP_ARGS(args, parsed_data);
|
AST_STANDARD_APP_ARGS(args, parsed_data);
|
||||||
|
|
||||||
if (ast_strlen_zero(args.field)) {
|
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");
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-1");
|
||||||
return 0;
|
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);
|
ds = ast_geoloc_datastore_find(chan);
|
||||||
if (!ds) {
|
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");
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-2");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
eprofile = ast_geoloc_datastore_get_eprofile(ds, 0);
|
orig_eprofile = ast_geoloc_datastore_get_eprofile(ds, 0);
|
||||||
if (!eprofile) {
|
if (!orig_eprofile) {
|
||||||
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");
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-2");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eprofile = ast_geoloc_eprofile_dup(orig_eprofile);
|
||||||
|
ao2_ref(orig_eprofile, -1);
|
||||||
|
if (!eprofile) {
|
||||||
|
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");
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "0");
|
||||||
if (ast_strings_equal(args.field, "inheritable")) {
|
if (ast_strings_equal(args.field, "inheritable")) {
|
||||||
ast_str_append(buf, len, "%s", ds->inheritance ? "true" : "false");
|
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")) {
|
} else if (ast_strings_equal(args.field, "notes")) {
|
||||||
ast_str_append(buf, len, "%s", eprofile->notes);
|
ast_str_append(buf, len, "%s", eprofile->notes);
|
||||||
} else if (ast_strings_equal(args.field, "location_info")) {
|
} 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")) {
|
} 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")) {
|
} 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")) {
|
} 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")) {
|
} 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")) {
|
} else if (ast_strings_equal(args.field, "confidence")) {
|
||||||
varlist_to_str(eprofile->confidence, buf, len);
|
varlist_to_str(eprofile->confidence, buf, len);
|
||||||
} else {
|
} 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");
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,6 +172,10 @@ static int geoloc_profile_read(struct ast_channel *chan,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define VAR_LIST_REPLACE(_old, _new) \
|
||||||
|
ast_variables_destroy(_old); \
|
||||||
|
_old = _new;
|
||||||
|
|
||||||
#define TEST_ENUM_VALUE(_chan_name, _ep, _field, _value) \
|
#define TEST_ENUM_VALUE(_chan_name, _ep, _field, _value) \
|
||||||
({ \
|
({ \
|
||||||
enum ast_geoloc_ ## _field v; \
|
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"); \
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
|
||||||
return 0; \
|
return 0; \
|
||||||
} \
|
} \
|
||||||
ast_variables_destroy(_ep->_field); \
|
if (ast_test_flag(&opts, OPT_GEOLOC_APPEND)) { \
|
||||||
_ep->_field = _list; \
|
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,
|
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);
|
const char *chan_name = ast_channel_name(chan);
|
||||||
struct ast_datastore *ds; /* Reminder: datastores aren't ao2 objects */
|
struct ast_datastore *ds; /* Reminder: datastores aren't ao2 objects */
|
||||||
RAII_VAR(struct ast_geoloc_eprofile *, eprofile, NULL, ao2_cleanup);
|
RAII_VAR(struct ast_geoloc_eprofile *, eprofile, NULL, ao2_cleanup);
|
||||||
|
struct ast_flags opts = { 0, };
|
||||||
|
|
||||||
AST_DECLARE_APP_ARGS(args,
|
AST_DECLARE_APP_ARGS(args,
|
||||||
AST_APP_ARG(field);
|
AST_APP_ARG(field);
|
||||||
|
AST_APP_ARG(options);
|
||||||
);
|
);
|
||||||
|
|
||||||
/* Check for zero arguments */
|
/* Check for zero arguments */
|
||||||
@@ -173,6 +248,18 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char
|
|||||||
return 0;
|
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);
|
ds = ast_geoloc_datastore_find(chan);
|
||||||
if (!ds) {
|
if (!ds) {
|
||||||
ds = ast_geoloc_datastore_create(ast_channel_name(chan));
|
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")) {
|
if (ast_strings_equal(args.field, "inheritable")) {
|
||||||
ast_geoloc_datastore_set_inheritance(ds, ast_true(value));
|
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")) {
|
} else if (ast_strings_equal(args.field, "location_reference")) {
|
||||||
struct ast_geoloc_location *loc = ast_geoloc_get_location(value);
|
struct ast_geoloc_location *loc = ast_geoloc_get_location(value);
|
||||||
ao2_cleanup(loc);
|
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);
|
TEST_ENUM_VALUE(chan_name, eprofile, format, value);
|
||||||
} else if (ast_strings_equal(args.field, "pidf_element")) {
|
} else if (ast_strings_equal(args.field, "pidf_element")) {
|
||||||
TEST_ENUM_VALUE(chan_name, eprofile, pidf_element, value);
|
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")) {
|
} else if (ast_strings_equal(args.field, "location_source")) {
|
||||||
ast_string_field_set(eprofile, location_source, value);
|
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")) {
|
} else if (ast_strings_equal(args.field, "location_info_refinement")) {
|
||||||
TEST_VARLIST(chan_name, eprofile, location_refinement, value);
|
TEST_VARLIST(chan_name, eprofile, location_refinement, value);
|
||||||
|
RESOLVE_FOR_WRITE(location_refinement);
|
||||||
} else if (ast_strings_equal(args.field, "location_variables")) {
|
} else if (ast_strings_equal(args.field, "location_variables")) {
|
||||||
TEST_VARLIST(chan_name, eprofile, location_variables, value);
|
TEST_VARLIST(chan_name, eprofile, location_variables, value);
|
||||||
|
RESOLVE_FOR_WRITE(location_variables);
|
||||||
} else if (ast_strings_equal(args.field, "effective_location")) {
|
} else if (ast_strings_equal(args.field, "effective_location")) {
|
||||||
TEST_VARLIST(chan_name, eprofile, effective_location, value);
|
TEST_VARLIST(chan_name, eprofile, effective_location, value);
|
||||||
|
RESOLVE_FOR_WRITE(effective_location);
|
||||||
} else if (ast_strings_equal(args.field, "usage_rules")) {
|
} else if (ast_strings_equal(args.field, "usage_rules")) {
|
||||||
TEST_VARLIST(chan_name, eprofile, usage_rules, value);
|
TEST_VARLIST(chan_name, eprofile, usage_rules, value);
|
||||||
|
RESOLVE_FOR_WRITE(usage_rules);
|
||||||
} else if (ast_strings_equal(args.field, "confidence")) {
|
} else if (ast_strings_equal(args.field, "confidence")) {
|
||||||
TEST_VARLIST(chan_name, eprofile, confidence, value);
|
TEST_VARLIST(chan_name, eprofile, confidence, value);
|
||||||
} else {
|
} else {
|
||||||
@@ -245,6 +341,7 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char
|
|||||||
}
|
}
|
||||||
|
|
||||||
ast_geoloc_eprofile_refresh_location(eprofile);
|
ast_geoloc_eprofile_refresh_location(eprofile);
|
||||||
|
|
||||||
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "0");
|
pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "0");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@@ -7,12 +7,14 @@
|
|||||||
<configObject name="location">
|
<configObject name="location">
|
||||||
<synopsis>Location</synopsis>
|
<synopsis>Location</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<para>cffdffff</para>
|
<para>Parameters for defining a Location object</para>
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
<configOption name="type">
|
<configOption name="type">
|
||||||
<synopsis>Must be of type 'location'.</synopsis>
|
<synopsis>Must be of type 'location'.</synopsis>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="format" default="">
|
|
||||||
|
<configOption name="format" default="none">
|
||||||
<synopsis>Location specification type</synopsis>
|
<synopsis>Location specification type</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<enumlist>
|
<enumlist>
|
||||||
@@ -42,7 +44,8 @@
|
|||||||
</enumlist>
|
</enumlist>
|
||||||
</description>
|
</description>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="location_info" default="">
|
|
||||||
|
<configOption name="location_info" default="none">
|
||||||
<synopsis>Location information</synopsis>
|
<synopsis>Location information</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<para>The contents of this parameter are specific to the
|
<para>The contents of this parameter are specific to the
|
||||||
@@ -68,7 +71,8 @@
|
|||||||
</enumlist>
|
</enumlist>
|
||||||
</description>
|
</description>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="location_source" default="">
|
|
||||||
|
<configOption name="location_source" default="none">
|
||||||
<synopsis>Fully qualified host name</synopsis>
|
<synopsis>Fully qualified host name</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<para>This parameter isn't required but if provided, RFC8787 says it MUST be a fully
|
<para>This parameter isn't required but if provided, RFC8787 says it MUST be a fully
|
||||||
@@ -77,7 +81,8 @@
|
|||||||
Geolocation</literal> header.</para>
|
Geolocation</literal> header.</para>
|
||||||
</description>
|
</description>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="method" default="">
|
|
||||||
|
<configOption name="method" default="none">
|
||||||
<synopsis>Location determination method</synopsis>
|
<synopsis>Location determination method</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<para>This is a rarely used field in the specification that would
|
<para>This is a rarely used field in the specification that would
|
||||||
@@ -94,7 +99,8 @@
|
|||||||
</enumlist>
|
</enumlist>
|
||||||
</description>
|
</description>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="confidence" default="">
|
|
||||||
|
<configOption name="confidence" default="none">
|
||||||
<synopsis>Level of confidence</synopsis>
|
<synopsis>Level of confidence</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<para>This is a rarely used field in the specification that would
|
<para>This is a rarely used field in the specification that would
|
||||||
@@ -123,14 +129,16 @@
|
|||||||
</see-also>
|
</see-also>
|
||||||
</configOption>
|
</configOption>
|
||||||
</configObject>
|
</configObject>
|
||||||
|
|
||||||
<configObject name="profile">
|
<configObject name="profile">
|
||||||
<synopsis>Profile</synopsis>
|
<synopsis>Profile</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<para>cffdffff</para>
|
<para>Parameters for defining a Profile object</para>
|
||||||
</description>
|
</description>
|
||||||
<configOption name="type">
|
<configOption name="type">
|
||||||
<synopsis>Must be of type 'profile'.</synopsis>
|
<synopsis>Must be of type 'profile'.</synopsis>
|
||||||
</configOption>
|
</configOption>
|
||||||
|
|
||||||
<configOption name="pidf_element" default="device">
|
<configOption name="pidf_element" default="device">
|
||||||
<synopsis>PIDF-LO element to place this profile in</synopsis>
|
<synopsis>PIDF-LO element to place this profile in</synopsis>
|
||||||
<description>
|
<description>
|
||||||
@@ -148,21 +156,25 @@
|
|||||||
<ref type="link">https://www.rfc-editor.org/rfc/rfc5491.html#section-3.4</ref>
|
<ref type="link">https://www.rfc-editor.org/rfc/rfc5491.html#section-3.4</ref>
|
||||||
</see-also>
|
</see-also>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="location_reference" default="">
|
|
||||||
|
<configOption name="location_reference" default="none">
|
||||||
<synopsis>Reference to a location object</synopsis>
|
<synopsis>Reference to a location object</synopsis>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="location_info_refinement" default="">
|
|
||||||
|
<configOption name="location_info_refinement" default="none">
|
||||||
<synopsis>Reference to a location object</synopsis>
|
<synopsis>Reference to a location object</synopsis>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="location_variables" default="">
|
<configOption name="location_variables" default="none">
|
||||||
<synopsis>Reference to a location object</synopsis>
|
<synopsis>Reference to a location object</synopsis>
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="usage_rules" default="yes">
|
|
||||||
|
<configOption name="usage_rules" default="empty <usage_rules> element">
|
||||||
<synopsis>location specification type</synopsis>
|
<synopsis>location specification type</synopsis>
|
||||||
<description>
|
<description>
|
||||||
<para>xxxx</para>
|
<para>xxxx</para>
|
||||||
</description>
|
</description>
|
||||||
</configOption>
|
</configOption>
|
||||||
|
|
||||||
<configOption name="notes" default="">
|
<configOption name="notes" default="">
|
||||||
<synopsis>Notes to be added to the outgoing PIDF-LO document</synopsis>
|
<synopsis>Notes to be added to the outgoing PIDF-LO document</synopsis>
|
||||||
<description>
|
<description>
|
||||||
@@ -171,11 +183,13 @@
|
|||||||
outgoing PIDF-LO document. Its usage should be pre-negotiated with
|
outgoing PIDF-LO document. Its usage should be pre-negotiated with
|
||||||
any recipients.</para>
|
any recipients.</para>
|
||||||
</description>
|
</description>
|
||||||
|
|
||||||
</configOption>
|
</configOption>
|
||||||
<configOption name="allow_routing_use">
|
<configOption name="allow_routing_use" default="no">
|
||||||
<synopsis>Sets the value of the Geolocation-Routing header.</synopsis>
|
<synopsis>Sets the value of the Geolocation-Routing header.</synopsis>
|
||||||
</configOption>
|
</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
|
<synopsis>Sets if empty Civic Address elements should be suppressed
|
||||||
from the PIDF-LO document.</synopsis>
|
from the PIDF-LO document.</synopsis>
|
||||||
</configOption>
|
</configOption>
|
||||||
@@ -207,6 +221,7 @@
|
|||||||
</enumlist>
|
</enumlist>
|
||||||
</description>
|
</description>
|
||||||
</configOption>
|
</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='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='location_info'])"/>
|
||||||
<xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='confidence'])"/>
|
<xi:include xpointer="xpointer(/docs/configInfo[@name='res_geolocation']/configFile[@name='geolocation.conf']/configObject[@name='location']/configOption[@name='confidence'])"/>
|
||||||
@@ -220,8 +235,8 @@
|
|||||||
Get or Set a field in a geolocation profile
|
Get or Set a field in a geolocation profile
|
||||||
</synopsis>
|
</synopsis>
|
||||||
<syntax>
|
<syntax>
|
||||||
<parameter name="field" required="true">
|
<parameter name="parameter" required="true">
|
||||||
<para>The profile field to operate on. The following fields from the
|
<para>The profile parameter to operate on. The following fields from the
|
||||||
Location and Profile objects are supported.</para>
|
Location and Profile objects are supported.</para>
|
||||||
<enumlist>
|
<enumlist>
|
||||||
<enum name="id"/>
|
<enum name="id"/>
|
||||||
@@ -244,10 +259,38 @@
|
|||||||
set to <literal>true</literal> or <literal>false</literal> to control
|
set to <literal>true</literal> or <literal>false</literal> to control
|
||||||
whether the profile will be passed to the outgoing channel.
|
whether the profile will be passed to the outgoing channel.
|
||||||
</para>
|
</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>
|
</parameter>
|
||||||
</syntax>
|
</syntax>
|
||||||
<description><para>
|
<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.
|
one will be created automatically.
|
||||||
</para>
|
</para>
|
||||||
<para>
|
<para>
|
||||||
@@ -258,8 +301,8 @@
|
|||||||
<enum name="0"><para>Success</para></enum>
|
<enum name="0"><para>Success</para></enum>
|
||||||
<enum name="-1"><para>No or not enough parameters were supplied</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="-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
|
<enum name="-3"><para>There was an issue specific to the parameter specified
|
||||||
(value not valid or field name not found)</para></enum>
|
(value not valid or parameter name not found, etc.)</para></enum>
|
||||||
</enumlist>
|
</enumlist>
|
||||||
</description>
|
</description>
|
||||||
</function>
|
</function>
|
||||||
|
@@ -156,6 +156,67 @@ int ast_geoloc_eprofile_refresh_location(struct ast_geoloc_eprofile *eprofile)
|
|||||||
return 0;
|
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 *ast_geoloc_eprofile_create_from_profile(struct ast_geoloc_profile *profile)
|
||||||
{
|
{
|
||||||
struct ast_geoloc_eprofile *eprofile;
|
struct ast_geoloc_eprofile *eprofile;
|
||||||
@@ -287,7 +348,7 @@ struct ast_geoloc_eprofile *ast_geoloc_eprofile_create_from_uri(const char *uri,
|
|||||||
return eprofile;
|
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 *variables, struct ast_channel *chan)
|
||||||
{
|
{
|
||||||
struct ast_variable *dest = NULL;
|
struct ast_variable *dest = NULL;
|
||||||
|
@@ -155,4 +155,8 @@ int geoloc_eprofile_reload(void);
|
|||||||
|
|
||||||
struct ast_sorcery *geoloc_get_sorcery(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_ */
|
#endif /* GEOLOC_PRIVATE_H_ */
|
||||||
|
@@ -574,7 +574,10 @@ static void handle_outgoing_request(struct ast_sip_session *session, struct pjsi
|
|||||||
session_name);
|
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) {
|
if (final_eprofile->format == AST_GEOLOC_FORMAT_URI) {
|
||||||
uri = ast_geoloc_eprofile_to_uri(final_eprofile, channel, &buf, session_name);
|
uri = ast_geoloc_eprofile_to_uri(final_eprofile, channel, &buf, session_name);
|
||||||
if (!uri) {
|
if (!uri) {
|
||||||
|
Reference in New Issue
Block a user