28 #include "geoloc_private.h"
34 for (; var; var = var->
next) {
39 #define RESOLVE_FOR_READ(_param) \
41 if (ast_test_flag(&opts, OPT_GEOLOC_RESOLVE)) { \
42 struct ast_variable *resolved = geoloc_eprofile_resolve_varlist( \
43 eprofile->_param, eprofile->location_variables, chan); \
45 ast_log(LOG_ERROR, "%s: Unable to resolve " #_param "\n", chan_name); \
46 pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
49 varlist_to_str(resolved, buf, len); \
50 ast_variables_destroy(resolved); \
52 varlist_to_str(eprofile->_param, buf, len); \
56 enum my_app_option_flags {
57 OPT_GEOLOC_RESOLVE = (1 << 0),
58 OPT_GEOLOC_APPEND = (1 << 1),
67 static int geoloc_profile_read(
struct ast_channel *chan,
68 const char *cmd,
char *data,
struct ast_str **buf, ssize_t len)
71 const char *chan_name = ast_channel_name(chan);
83 if (ast_strlen_zero(parsed_data)) {
84 ast_log(LOG_ERROR,
"%s: Cannot call without arguments\n", chan_name);
91 if (ast_strlen_zero(args.field)) {
92 ast_log(LOG_ERROR,
"%s: Cannot call without a field to query\n", chan_name);
97 if (!ast_strlen_zero(args.options)) {
99 ast_log(LOG_ERROR,
"%s: Invalid options: %s\n", chan_name, args.options);
105 ds = ast_geoloc_datastore_find(chan);
107 ast_log(LOG_NOTICE,
"%s: There is no geoloc profile on this channel\n", chan_name);
112 orig_eprofile = ast_geoloc_datastore_get_eprofile(ds, 0);
113 if (!orig_eprofile) {
114 ast_log(LOG_NOTICE,
"%s: There is no geoloc profile on this channel\n", chan_name);
119 eprofile = ast_geoloc_eprofile_dup(orig_eprofile);
122 ast_log(LOG_ERROR,
"%s: Unable to duplicate eprofile\n", chan_name);
127 if (!eprofile->effective_location) {
128 ast_geoloc_eprofile_refresh_location(eprofile);
141 ast_str_append(buf, len,
"%s", eprofile->allow_routing_use ?
"yes" :
"no");
143 ast_str_append(buf, len,
"%s", eprofile->suppress_empty_ca_elements ?
"yes" :
"no");
145 ast_str_append(buf, len,
"%s", ast_geoloc_precedence_to_name(eprofile->precedence));
147 ast_str_append(buf, len,
"%s", ast_geoloc_format_to_name(eprofile->format));
149 ast_str_append(buf, len,
"%s", ast_geoloc_pidf_element_to_name(eprofile->pidf_element));
155 RESOLVE_FOR_READ(location_info);
157 RESOLVE_FOR_READ(location_refinement);
159 RESOLVE_FOR_READ(location_variables);
161 RESOLVE_FOR_READ(effective_location);
163 RESOLVE_FOR_READ(usage_rules);
165 varlist_to_str(eprofile->confidence, buf, len);
167 ast_log(LOG_ERROR,
"%s: Field '%s' is not valid\n", chan_name, args.field);
175 #define VAR_LIST_REPLACE(_old, _new) \
176 ast_variables_destroy(_old); \
179 #define TEST_ENUM_VALUE(_chan_name, _ep, _field, _value) \
181 enum ast_geoloc_ ## _field v; \
182 v = ast_geoloc_ ## _field ## _str_to_enum(_value); \
183 if (v == AST_GEOLOC_INVALID_VALUE) { \
184 ast_log(LOG_ERROR, "%s: %s '%s' is invalid\n", _chan_name, #_field, value); \
185 pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
191 #define TEST_VARLIST(_chan_name, _ep, _field, _value) \
193 struct ast_variable *_list; \
194 _list = ast_variable_list_from_quoted_string(_value, ",", "=", "\"" ); \
196 ast_log(LOG_ERROR, "%s: %s '%s' is malformed or contains invalid values", _chan_name, #_field, _value); \
197 pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
200 if (ast_test_flag(&opts, OPT_GEOLOC_APPEND)) { \
201 ast_variable_list_append(&_ep->_field, _list); \
203 VAR_LIST_REPLACE(_ep->_field, _list); \
208 #define RESOLVE_FOR_WRITE(_param) \
210 if (ast_test_flag(&opts, OPT_GEOLOC_RESOLVE)) { \
211 struct ast_variable *resolved = geoloc_eprofile_resolve_varlist( \
212 eprofile->_param, eprofile->location_variables, chan); \
214 ast_log(LOG_ERROR, "%s: Unable to resolve " #_param " %p %p\n", chan_name, eprofile->_param, eprofile->location_variables); \
215 pbx_builtin_setvar_helper(chan, "GEOLOCPROFILESTATUS", "-3"); \
218 VAR_LIST_REPLACE(eprofile->_param, resolved); \
222 static int geoloc_profile_write(
struct ast_channel *chan,
const char *cmd,
char *data,
226 const char *chan_name = ast_channel_name(chan);
237 if (ast_strlen_zero(parsed_data)) {
238 ast_log(LOG_ERROR,
"%s: Cannot call without arguments\n", chan_name);
245 if (ast_strlen_zero(args.field)) {
246 ast_log(LOG_ERROR,
"%s: Cannot call without a field to set\n", chan_name);
251 if (!ast_strlen_zero(args.options)) {
253 ast_log(LOG_ERROR,
"%s: Invalid options: %s\n", chan_name, args.options);
259 ast_debug(1,
"%s: name: %s value: %s options: %s append: %s resolve: %s\n", chan_name,
260 args.field, value, args.options, ast_test_flag(&opts, OPT_GEOLOC_APPEND) ?
"yes" :
"no",
261 ast_test_flag(&opts, OPT_GEOLOC_RESOLVE) ?
"yes" :
"no");
263 ds = ast_geoloc_datastore_find(chan);
265 ds = ast_geoloc_datastore_create(ast_channel_name(chan));
267 ast_log(LOG_WARNING,
"%s: Unable to create geolocation datastore\n", chan_name);
274 eprofile = ast_geoloc_datastore_get_eprofile(ds, 0);
277 eprofile = ast_geoloc_eprofile_alloc(chan_name);
279 ast_log(LOG_ERROR,
"%s: Could not allocate eprofile\n", chan_name);
283 rc = ast_geoloc_datastore_add_eprofile(ds, eprofile);
285 ast_log(LOG_ERROR,
"%s: Could not add eprofile to datastore\n", chan_name);
292 ast_geoloc_datastore_set_inheritance(ds,
ast_true(value));
299 ast_log(LOG_ERROR,
"%s: Location reference '%s' doesn't exist\n", chan_name, value);
307 eprofile->allow_routing_use =
ast_true(value);
309 eprofile->suppress_empty_ca_elements =
ast_true(value);
311 TEST_ENUM_VALUE(chan_name, eprofile, precedence, value);
313 TEST_ENUM_VALUE(chan_name, eprofile, format, value);
315 TEST_ENUM_VALUE(chan_name, eprofile, pidf_element, value);
321 TEST_VARLIST(chan_name, eprofile, location_info, value);
322 RESOLVE_FOR_WRITE(location_info);
324 TEST_VARLIST(chan_name, eprofile, location_refinement, value);
325 RESOLVE_FOR_WRITE(location_refinement);
327 TEST_VARLIST(chan_name, eprofile, location_variables, value);
328 RESOLVE_FOR_WRITE(location_variables);
330 TEST_VARLIST(chan_name, eprofile, effective_location, value);
331 RESOLVE_FOR_WRITE(effective_location);
333 TEST_VARLIST(chan_name, eprofile, usage_rules, value);
334 RESOLVE_FOR_WRITE(usage_rules);
336 TEST_VARLIST(chan_name, eprofile, confidence, value);
338 ast_log(LOG_ERROR,
"%s: Field '%s' is not valid\n", chan_name, args.field);
343 ast_geoloc_eprofile_refresh_location(eprofile);
351 .
name =
"GEOLOC_PROFILE",
352 .read2 = geoloc_profile_read,
353 .write = geoloc_profile_write,
356 int geoloc_dialplan_unload(
void)
363 int geoloc_dialplan_load(
void)
372 int geoloc_dialplan_reload(
void)
struct ast_variable * next
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
String manipulation functions.
#define AST_STANDARD_APP_ARGS(args, parse)
Performs the 'standard' argument separation process for an application.
Structure for variables, used for configurations and for channel variables.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Structure for a data store object.
int ast_custom_function_unregister(struct ast_custom_function *acf)
Unregister a custom function.
#define AST_APP_OPTIONS(holder, options...)
Declares an array of options for an application.
Configuration File Parser.
General Asterisk PBX channel definitions.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Data structure associated with a custom dialplan function.
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ast_debug(level,...)
Log a DEBUG message.
int ast_app_parse_options(const struct ast_app_option *options, struct ast_flags *flags, char **args, char *optstr)
Parses a string containing application options and sets flags/arguments.
Core PBX routines and definitions.
int attribute_pure ast_true(const char *val)
Make sure something is true. Determine if a string containing a boolean value is "true". This function checks to see whether a string passed to it is an indication of an "true" value. It checks to see if the string is "yes", "true", "y", "t", "on" or "1".
Support for dynamic strings.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Module has failed to load, may be in an inconsistent state.
Structure used to handle boolean flags.
int pbx_builtin_setvar_helper(struct ast_channel *chan, const char *name, const char *value)
Add a variable to the channel variable stack, removing the most recently set value for the same name...
Standard Command Line Interface.
#define AST_APP_OPTION(option, flagno)
Declares an application option that does not accept an argument.
Asterisk module definitions.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
int ast_channel_datastore_add(struct ast_channel *chan, struct ast_datastore *datastore)
Add a datastore to a channel.
#define AST_DECLARE_APP_ARGS(name, arglist)
Declare a structure to hold an application's arguments.
Application convenience functions, designed to give consistent look and feel to Asterisk apps...
#define ast_custom_function_register(acf)
Register a custom function.
#define AST_APP_ARG(name)
Define an application argument.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.