Asterisk - The Open Source Telephony Project GIT-master-4f2b068
Loading...
Searching...
No Matches
Macros | Functions | Variables
geoloc_eprofile.c File Reference
#include "asterisk.h"
#include "asterisk/pbx.h"
#include "asterisk/strings.h"
#include "asterisk/xml.h"
#include "geoloc_private.h"
Include dependency graph for geoloc_eprofile.c:

Go to the source code of this file.

Macros

#define CREATE_NODE_LIST(node)
 
#define DUP_VARS(_dest, _source)
 

Functions

struct ast_geoloc_eprofileast_geoloc_eprofile_alloc (const char *name)
 Geolocation Effective Profile Functions.
 
struct ast_geoloc_eprofileast_geoloc_eprofile_create_from_pidf (struct ast_xml_doc *pidf_xmldoc, const char *geoloc_uri, const char *ref_str)
 Allocate a new effective profile from an XML PIDF-LO document.
 
struct ast_geoloc_eprofileast_geoloc_eprofile_create_from_profile (struct ast_geoloc_profile *profile)
 Allocate a new effective profile from an existing profile.
 
struct ast_geoloc_eprofileast_geoloc_eprofile_create_from_uri (const char *uri, const char *ref_str)
 Allocate a new effective profile from a URI.
 
struct ast_geoloc_eprofileast_geoloc_eprofile_dup (struct ast_geoloc_eprofile *src)
 Duplicate an effective profile.
 
int ast_geoloc_eprofile_refresh_location (struct ast_geoloc_eprofile *eprofile)
 Refresh the effective profile with any changed info.
 
const char * ast_geoloc_eprofile_to_pidf (struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, struct ast_str **buf, const char *ref_string)
 Convert a single eprofile to a PIDF-LO document.
 
const char * ast_geoloc_eprofile_to_uri (struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, struct ast_str **buf, const char *ref_str)
 Convert a URI eprofile to a URI string.
 
const char * ast_geoloc_eprofiles_to_pidf (struct ast_datastore *ds, struct ast_channel *chan, struct ast_str **buf, const char *ref_string)
 Convert a datastore containing eprofiles to a PIDF-LO document.
 
static struct ast_geoloc_eprofilegeoloc_eprofile_create_from_xslt_result (struct ast_xml_doc *result_doc, const char *ref_str)
 
static void geoloc_eprofile_destructor (void *obj)
 
int geoloc_eprofile_load (void)
 
int geoloc_eprofile_reload (void)
 
char * geoloc_eprofile_resolve_string (const char *source, struct ast_variable *variables, struct ast_channel *chan)
 
struct ast_variablegeoloc_eprofile_resolve_varlist (struct ast_variable *source, struct ast_variable *variables, struct ast_channel *chan)
 
static struct ast_xml_node * geoloc_eprofile_to_intermediate (const char *element_name, struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, const char *ref_string)
 
static struct ast_xml_doc * geoloc_eprofile_to_xmldoc (struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, struct ast_str **buf, const char *ref_string)
 
int geoloc_eprofile_unload (void)
 
static int is_pidf_lo (struct ast_xml_doc *result_doc)
 
static void load_tests (void)
 
static int set_loc_src (struct ast_geoloc_eprofile *eprofile, const char *uri, const char *ref_str)
 
static void unload_tests (void)
 
static struct ast_variablevar_list_from_confidence (struct ast_xml_node *confidence, const char *ref_str)
 
static struct ast_variablevar_list_from_loc_info (struct ast_xml_node *locinfo, enum ast_geoloc_format format, const char *ref_str)
 
static struct ast_variablevar_list_from_node (struct ast_xml_node *node, const char *ref_str)
 

Variables

const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_end []
 
const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_start []
 
const uint8_t _binary_res_geolocation_pidf_lo_test_xml_end []
 
const uint8_t _binary_res_geolocation_pidf_lo_test_xml_start []
 
const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_end []
 
const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_start []
 
static struct ast_xslt_doc * eprofile_to_pidf_xslt
 
static size_t eprofile_to_pidf_xslt_size
 
static struct ast_sorcerygeoloc_sorcery
 
static size_t pidf_lo_test_xml_size
 
static struct ast_xslt_doc * pidf_to_eprofile_xslt
 
static size_t pidf_to_eprofile_xslt_size
 

Macro Definition Documentation

◆ CREATE_NODE_LIST

#define CREATE_NODE_LIST (   node)

Definition at line 1023 of file geoloc_eprofile.c.

1024 { \
1025 node = ast_xml_new_child(root_node, \
1026 geoloc_pidf_element_to_name(eprofile->pidf_element)); \
1027 if (!pidfs[eprofile->pidf_element]) { \
1028 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create pidf '%s' XML node\n", \
1029 ref_string, geoloc_pidf_element_to_name(eprofile->pidf_element)); \
1030 } \
1031 }
#define LOG_ERROR
#define NULL
Definition resample.c:96
struct ast_xml_node * ast_xml_new_child(struct ast_xml_node *parent, const char *child_name)
Add a child node inside a passed parent node.
Definition xml.c:156

◆ DUP_VARS

#define DUP_VARS (   _dest,
  _source 
)

Definition at line 42 of file geoloc_eprofile.c.

43 { \
44 int _rc = 0; \
45 if (_source) { \
46 struct ast_variable *_vars = ast_variables_dup(_source); \
47 if (!_vars) { \
48 _rc = -1; \
49 } else { \
50 _dest = _vars; \
51 } \
52 } \
53 (_rc); \
54})
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
Structure for variables, used for configurations and for channel variables.

Function Documentation

◆ ast_geoloc_eprofile_alloc()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_alloc ( const char *  name)

Geolocation Effective Profile Functions.

Allocate a new, empty effective profile.

Parameters
nameThe profile's name
Returns
The effective profile ao2 object.

Definition at line 69 of file geoloc_eprofile.c.

70{
71 struct ast_geoloc_eprofile *eprofile = ao2_alloc_options(sizeof(*eprofile),
73
74 ast_string_field_init(eprofile, 256);
75 ast_string_field_set(eprofile, id, name); /* SAFE string fields handle NULL */
76
77 return eprofile;
78}
@ AO2_ALLOC_OPT_LOCK_NOLOCK
Definition astobj2.h:367
#define ao2_alloc_options(data_size, destructor_fn, options)
Definition astobj2.h:404
static const char name[]
Definition format_mp3.c:68
static void geoloc_eprofile_destructor(void *obj)
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.

References AO2_ALLOC_OPT_LOCK_NOLOCK, ao2_alloc_options, ast_string_field_init, ast_string_field_set, geoloc_eprofile_destructor(), and name.

Referenced by ast_geoloc_eprofile_create_from_profile(), ast_geoloc_eprofile_create_from_uri(), ast_geoloc_eprofile_dup(), geoloc_eprofile_create_from_xslt_result(), and geoloc_profile_write().

◆ ast_geoloc_eprofile_create_from_pidf()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_pidf ( struct ast_xml_doc *  pidf_xmldoc,
const char *  geoloc_uri,
const char *  reference_string 
)

Allocate a new effective profile from an XML PIDF-LO document.

Parameters
pidf_xmldocThe ast_xml_doc to use.
geoloc_uriThe URI that referenced this document.
reference_stringAn identifying string to use in error messages.
Returns
The effective profile ao2 object.

Definition at line 805 of file geoloc_eprofile.c.

807{
808 struct ast_xml_doc *result_doc = NULL;
809 struct ast_geoloc_eprofile *eprofile = NULL;
810
811 SCOPE_ENTER(3, "%s\n", ref_str);
812
813 result_doc = ast_xslt_apply(pidf_to_eprofile_xslt, pidf_xmldoc, NULL);
814 if (!is_pidf_lo(result_doc)) {
815 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Not a PIDF-LO. Skipping.\n", ref_str);
816 }
817
818 /*
819 * The document returned from the stylesheet application looks like this...
820 * <presence id="presence-entity">
821 * <tuple id="element-id">
822 * <location-info format="gml">shape="Ellipsoid", crs="3d", ...</location-info>
823 * <usage-rules>retransmission-allowed="no", retention-expiry="2010-11-14T20:00:00Z"</usage-rules>
824 * <method>Hybrid_A-GPS</method>
825 * </tuple>
826 * </presence>
827 *
828 * Regardless of whether the pidf-element was tuple, device or person and whether
829 * the format is gml or civicAddress, the presence, pidf-element and location-info
830 * elements should be there.
831 *
832 * The confidence, usage-rules and note-well elements are optional.
833 */
834
835 if (TRACE_ATLEAST(5)) {
836 char *doc_str = NULL;
837 int doc_len = 0;
838
839 ast_xml_doc_dump_memory(result_doc, &doc_str, &doc_len);
840 ast_trace(5, "Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str : "<empty>");
841 ast_xml_free_text(doc_str);
842 doc_str = NULL;
843 doc_len = 0;
844 }
845
846 eprofile = geoloc_eprofile_create_from_xslt_result(result_doc, ref_str);
847 ast_xml_close(result_doc);
848
849 if (eprofile && geoloc_uri) {
850 set_loc_src(eprofile, geoloc_uri, ref_str);
851 }
852
853 SCOPE_EXIT_RTN_VALUE(eprofile, "%s: Done.\n", ref_str);
854}
static struct ast_xslt_doc * pidf_to_eprofile_xslt
static int set_loc_src(struct ast_geoloc_eprofile *eprofile, const char *uri, const char *ref_str)
static int is_pidf_lo(struct ast_xml_doc *result_doc)
static struct ast_geoloc_eprofile * geoloc_eprofile_create_from_xslt_result(struct ast_xml_doc *result_doc, const char *ref_str)
#define TRACE_ATLEAST(level)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_ENTER(level,...)
#define ast_trace(level,...)
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
Definition xml.c:211
void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length)
Dump the specified document to a buffer.
Definition xml.c:385
void ast_xml_free_text(const char *text)
Free a content element that was returned by ast_xml_get_text()
Definition xml.c:260

References ast_trace, ast_xml_close(), ast_xml_doc_dump_memory(), ast_xml_free_text(), geoloc_eprofile_create_from_xslt_result(), is_pidf_lo(), NULL, pidf_to_eprofile_xslt, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, set_loc_src(), and TRACE_ATLEAST.

Referenced by handle_incoming_request().

◆ ast_geoloc_eprofile_create_from_profile()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_profile ( struct ast_geoloc_profile profile)

Allocate a new effective profile from an existing profile.

Parameters
profileThe profile to use.
Returns
The effective profile ao2 object.

Definition at line 226 of file geoloc_eprofile.c.

227{
228 struct ast_geoloc_eprofile *eprofile;
229 const char *profile_id;
230 int rc = 0;
231
232 if (!profile) {
233 return NULL;
234 }
235
236 profile_id = ast_sorcery_object_get_id(profile);
237
238 eprofile = ast_geoloc_eprofile_alloc(profile_id);
239 if (!eprofile) {
240 return NULL;
241 }
242
243 ao2_lock(profile);
244 eprofile->allow_routing_use = profile->allow_routing_use;
245 eprofile->pidf_element = profile->pidf_element;
247 eprofile->format = profile->format;
248
250 if (rc == 0) {
251 rc = ast_string_field_set(eprofile, pidf_element_id, profile->pidf_element_id);
252 }
253 if (rc == 0) {
254 ast_string_field_set(eprofile, notes, profile->notes);
255 }
256 if (rc == 0) {
257 ast_string_field_set(eprofile, method, profile->method);
258 }
259 if (rc == 0) {
261 }
262 if (rc == 0) {
263 rc = DUP_VARS(eprofile->location_info, profile->location_info);
264 }
265 if (rc == 0) {
266 rc = DUP_VARS(eprofile->location_refinement, profile->location_refinement);
267 }
268 if (rc == 0) {
269 rc = DUP_VARS(eprofile->location_variables, profile->location_variables);
270 }
271 if (rc == 0) {
272 rc = DUP_VARS(eprofile->usage_rules, profile->usage_rules);
273 }
274 if (rc == 0) {
275 rc = DUP_VARS(eprofile->confidence, profile->confidence);
276 }
277 if (rc == 0) {
278 rc = ast_string_field_set(eprofile, device_id, profile->device_id);
279 }
280 if (rc != 0) {
281 ao2_unlock(profile);
282 ao2_ref(eprofile, -1);
283 return NULL;
284 }
285
286 eprofile->precedence = profile->precedence;
287 ao2_unlock(profile);
288
289 if (ast_geoloc_eprofile_refresh_location(eprofile) != 0) {
290 ao2_ref(eprofile, -1);
291 return NULL;
292 }
293
294 return eprofile;
295}
#define ao2_unlock(a)
Definition astobj2.h:729
#define ao2_lock(a)
Definition astobj2.h:717
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
Definition astobj2.h:459
int ast_geoloc_eprofile_refresh_location(struct ast_geoloc_eprofile *eprofile)
Refresh the effective profile with any changed info.
struct ast_geoloc_eprofile * ast_geoloc_eprofile_alloc(const char *name)
Geolocation Effective Profile Functions.
#define DUP_VARS(_dest, _source)
static int notes
Definition pval.c:66
const char * method
Definition res_pjsip.c:1273
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
Definition sorcery.c:2381
const ast_string_field location_reference
enum ast_geoloc_format format
enum ast_geoloc_pidf_element pidf_element
struct ast_variable * location_refinement
const ast_string_field device_id
enum ast_geoloc_precedence precedence
struct ast_variable * location_variables
struct ast_variable * confidence
struct ast_variable * usage_rules
const ast_string_field location_source
const ast_string_field pidf_element_id
struct ast_variable * location_info
const ast_string_field location_reference
enum ast_geoloc_format format
enum ast_geoloc_pidf_element pidf_element
const ast_string_field method
struct ast_variable * location_refinement
const ast_string_field device_id
enum ast_geoloc_precedence precedence
const ast_string_field notes
struct ast_variable * location_variables
struct ast_variable * confidence
struct ast_variable * usage_rules
const ast_string_field location_source
const ast_string_field pidf_element_id
struct ast_variable * location_info

References ast_geoloc_profile::allow_routing_use, ast_geoloc_eprofile::allow_routing_use, ao2_lock, ao2_ref, ao2_unlock, ast_geoloc_eprofile_alloc(), ast_geoloc_eprofile_refresh_location(), ast_sorcery_object_get_id(), ast_string_field_set, ast_geoloc_profile::confidence, ast_geoloc_eprofile::confidence, ast_geoloc_profile::device_id, ast_geoloc_eprofile::device_id, DUP_VARS, ast_geoloc_profile::format, ast_geoloc_eprofile::format, ast_geoloc_profile::location_info, ast_geoloc_eprofile::location_info, ast_geoloc_profile::location_reference, ast_geoloc_eprofile::location_reference, ast_geoloc_profile::location_refinement, ast_geoloc_eprofile::location_refinement, ast_geoloc_profile::location_source, ast_geoloc_eprofile::location_source, ast_geoloc_profile::location_variables, ast_geoloc_eprofile::location_variables, ast_geoloc_profile::method, method, ast_geoloc_profile::notes, notes, NULL, ast_geoloc_profile::pidf_element, ast_geoloc_eprofile::pidf_element, ast_geoloc_profile::pidf_element_id, ast_geoloc_eprofile::pidf_element_id, ast_geoloc_profile::precedence, ast_geoloc_eprofile::precedence, ast_geoloc_profile::suppress_empty_ca_elements, ast_geoloc_eprofile::suppress_empty_ca_elements, ast_geoloc_profile::usage_rules, and ast_geoloc_eprofile::usage_rules.

Referenced by ast_geoloc_datastore_create_from_profile_name(), geoloc_config_show_profiles(), handle_incoming_request(), and handle_outgoing_request().

◆ ast_geoloc_eprofile_create_from_uri()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_uri ( const char *  uri,
const char *  reference_string 
)

Allocate a new effective profile from a URI.

Parameters
uriThe URI to use.
reference_stringAn identifying string to use in error messages.
Returns
The effective profile ao2 object.

Definition at line 327 of file geoloc_eprofile.c.

329{
330 struct ast_geoloc_eprofile *eprofile = NULL;
331 char *ra = NULL;
332 char *local_uri;
333
334 if (ast_strlen_zero(uri)) {
335 return NULL;
336 }
337 local_uri = ast_strdupa(uri);
338
339 if (local_uri[0] == '<') {
340 local_uri++;
341 }
342 ra = strchr(local_uri, '>');
343 if (ra) {
344 *ra = '\0';
345 }
346
347 ast_strip(local_uri);
348
349 eprofile = ast_geoloc_eprofile_alloc(local_uri);
350 if (!eprofile) {
351 return NULL;
352 }
353
354 set_loc_src(eprofile, uri, ref_str);
355
356 eprofile->format = AST_GEOLOC_FORMAT_URI;
357 eprofile->location_info = ast_variable_new("URI", local_uri, "");
358
359 return eprofile;
360}
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition astmm.h:298
#define ast_variable_new(name, value, filename)
@ AST_GEOLOC_FORMAT_URI
static force_inline int attribute_pure ast_strlen_zero(const char *s)
Definition strings.h:65
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
Definition strings.h:223

References ast_geoloc_eprofile_alloc(), AST_GEOLOC_FORMAT_URI, ast_strdupa, ast_strip(), ast_strlen_zero(), ast_variable_new, ast_geoloc_eprofile::format, ast_geoloc_eprofile::location_info, NULL, and set_loc_src().

Referenced by handle_incoming_request().

◆ ast_geoloc_eprofile_dup()

struct ast_geoloc_eprofile * ast_geoloc_eprofile_dup ( struct ast_geoloc_eprofile src)

Duplicate an effective profile.

Parameters
srcThe eprofile to duplicate.
Returns
The duplicated effective profile ao2 object.

Definition at line 159 of file geoloc_eprofile.c.

160{
161 struct ast_geoloc_eprofile *eprofile;
162 const char *profile_id;
163 int rc = 0;
164
165 if (!src) {
166 return NULL;
167 }
168
169 profile_id = ast_strdupa(src->id);
170
171 eprofile = ast_geoloc_eprofile_alloc(profile_id);
172 if (!eprofile) {
173 return NULL;
174 }
175
176 eprofile->allow_routing_use = src->allow_routing_use;
177 eprofile->pidf_element = src->pidf_element;
179 eprofile->format = src->format;
180 eprofile->precedence = src->precedence;
181
182
184 if (rc == 0) {
186 }
187 if (rc == 0) {
188 ast_string_field_set(eprofile, notes, src->notes);
189 }
190 if (rc == 0) {
191 ast_string_field_set(eprofile, method, src->method);
192 }
193 if (rc == 0) {
195 }
196 if (rc == 0) {
197 rc = DUP_VARS(eprofile->location_info, src->location_info);
198 }
199 if (rc == 0) {
200 rc = DUP_VARS(eprofile->effective_location, src->effective_location);
201 }
202 if (rc == 0) {
204 }
205 if (rc == 0) {
206 rc = DUP_VARS(eprofile->location_variables, src->location_variables);
207 }
208 if (rc == 0) {
209 rc = DUP_VARS(eprofile->usage_rules, src->usage_rules);
210 }
211 if (rc == 0) {
212 rc = DUP_VARS(eprofile->confidence, src->confidence);
213 }
214 if (rc == 0) {
215 rc = ast_string_field_set(eprofile, device_id, src->device_id);
216 }
217 if (rc != 0) {
218 ao2_ref(eprofile, -1);
219 return NULL;
220 }
221
222
223 return eprofile;
224}
struct ast_variable * effective_location
const ast_string_field method
const ast_string_field notes
const ast_string_field id

References ast_geoloc_eprofile::allow_routing_use, ao2_ref, ast_geoloc_eprofile_alloc(), ast_strdupa, ast_string_field_set, ast_geoloc_eprofile::confidence, ast_geoloc_eprofile::device_id, DUP_VARS, ast_geoloc_eprofile::effective_location, ast_geoloc_eprofile::format, ast_geoloc_eprofile::id, ast_geoloc_eprofile::location_info, ast_geoloc_eprofile::location_reference, ast_geoloc_eprofile::location_refinement, ast_geoloc_eprofile::location_source, ast_geoloc_eprofile::location_variables, ast_geoloc_eprofile::method, method, ast_geoloc_eprofile::notes, notes, NULL, ast_geoloc_eprofile::pidf_element, ast_geoloc_eprofile::pidf_element_id, ast_geoloc_eprofile::precedence, ast_geoloc_eprofile::suppress_empty_ca_elements, and ast_geoloc_eprofile::usage_rules.

Referenced by geoloc_profile_read().

◆ ast_geoloc_eprofile_refresh_location()

int ast_geoloc_eprofile_refresh_location ( struct ast_geoloc_eprofile eprofile)

Refresh the effective profile with any changed info.

Parameters
eprofileThe eprofile to refresh.
Returns
0 on success, any other value on error.

Definition at line 80 of file geoloc_eprofile.c.

81{
82 struct ast_geoloc_location *loc = NULL;
83 RAII_VAR(struct ast_variable *, temp_locinfo, NULL, ast_variables_destroy);
84 RAII_VAR(struct ast_variable *, temp_effloc, NULL, ast_variables_destroy);
85 RAII_VAR(struct ast_variable *, temp_confidence, NULL, ast_variables_destroy);
86 const char *method = NULL;
87 const char *location_source = NULL;
89 struct ast_variable *var;
90 int rc = 0;
91
92 if (!eprofile) {
93 return -1;
94 }
95
96 if (!ast_strlen_zero(eprofile->location_reference)) {
98 if (!loc) {
99 ast_log(LOG_ERROR, "Profile '%s' referenced location '%s' does not exist!", eprofile->id,
100 eprofile->location_reference);
101 return -1;
102 }
103
104 format = loc->format;
105 method = loc->method;
106 location_source = loc->location_source;
107 rc = DUP_VARS(temp_locinfo, loc->location_info);
108 if (rc == 0) {
109 rc = DUP_VARS(temp_confidence, loc->confidence);
110 }
111 ao2_ref(loc, -1);
112 if (rc != 0) {
113 return -1;
114 }
115 } else {
116 format = eprofile->format;
117 method = eprofile->method;
118 location_source = eprofile->location_source;
119 rc = DUP_VARS(temp_locinfo, eprofile->location_info);
120 if (rc == 0) {
121 rc = DUP_VARS(temp_confidence, eprofile->confidence);
122 }
123 if (rc != 0) {
124 return -1;
125 }
126 }
127
128 rc = DUP_VARS(temp_effloc, temp_locinfo);
129 if (rc != 0) {
130 return -1;
131 }
132
133 if (eprofile->location_refinement) {
134 for (var = eprofile->location_refinement; var; var = var->next) {
135 struct ast_variable *newvar = ast_variable_new(var->name, var->value, "");
136 if (!newvar) {
137 return -1;
138 }
139 if (ast_variable_list_replace(&temp_effloc, newvar)) {
140 ast_variable_list_append(&temp_effloc, newvar);
141 }
142 }
143 }
144
145 eprofile->format = format;
147 ast_string_field_set(eprofile, location_source, location_source);
148
150 eprofile->location_info = temp_locinfo;
151 temp_locinfo = NULL;
153 eprofile->effective_location = temp_effloc;
154 temp_effloc = NULL;
155
156 return 0;
157}
#define var
Definition ast_expr2f.c:605
#define ast_log
Definition astobj2.c:42
static struct ast_sorcery * geoloc_sorcery
#define ast_variable_list_append(head, new_var)
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
Definition extconf.c:1260
ast_geoloc_format
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
Definition sorcery.c:1917
enum ast_geoloc_format format
const ast_string_field method
struct ast_variable * confidence
const ast_string_field location_source
struct ast_variable * location_info
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
Definition utils.h:981

References ao2_ref, ast_log, ast_sorcery_retrieve_by_id(), ast_string_field_set, ast_strlen_zero(), ast_variable_list_append, ast_variable_list_replace(), ast_variable_new, ast_variables_destroy(), ast_geoloc_location::confidence, ast_geoloc_eprofile::confidence, DUP_VARS, ast_geoloc_eprofile::effective_location, ast_geoloc_location::format, ast_geoloc_eprofile::format, geoloc_sorcery, ast_geoloc_eprofile::id, ast_geoloc_location::location_info, ast_geoloc_eprofile::location_info, ast_geoloc_eprofile::location_reference, ast_geoloc_eprofile::location_refinement, ast_geoloc_location::location_source, ast_geoloc_eprofile::location_source, LOG_ERROR, ast_geoloc_location::method, ast_geoloc_eprofile::method, method, NULL, RAII_VAR, and var.

Referenced by ast_geoloc_eprofile_create_from_profile(), geoloc_profile_read(), geoloc_profile_write(), and handle_outgoing_request().

◆ ast_geoloc_eprofile_to_pidf()

const char * ast_geoloc_eprofile_to_pidf ( struct ast_geoloc_eprofile eprofile,
struct ast_channel chan,
struct ast_str **  buf,
const char *  ref_string 
)

Convert a single eprofile to a PIDF-LO document.

Parameters
eprofileEffective profile to convert
chanChannel to use to resolve variables
bufPointer to ast_str pointer to use for work
ref_stringAn identifying string to use in error messages.
Returns
String representation PIDF-LO allocated from buf or NULL on failure.

Definition at line 1215 of file geoloc_eprofile.c.

1217{
1218
1219 RAII_VAR(struct ast_xml_doc *, pidf_doc, NULL, ast_xml_close);
1220 char *doc_str = NULL;
1221 int doc_len = 0;
1222 int rc = 0;
1223 SCOPE_ENTER(3, "%s\n", ref_string);
1224
1225 pidf_doc = geoloc_eprofile_to_xmldoc(eprofile, chan, buf, ref_string);
1226 if (!pidf_doc) {
1227 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate doc\n",
1228 ref_string);
1229 }
1230
1231 ast_xml_doc_dump_memory(pidf_doc, &doc_str, &doc_len);
1232 if (doc_len == 0 || !doc_str) {
1233 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to dump final PIDF-LO doc to string\n",
1234 ref_string);
1235 }
1236
1237 rc = ast_str_set(buf, 0, "%s", doc_str);
1238 ast_xml_free_text(doc_str);
1239 if (rc <= 0) {
1240 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to extend buffer (%d)\n",
1241 ref_string, rc);
1242 }
1243
1244 ast_trace(5, "Final doc:\n%s\n", ast_str_buffer(*buf));
1245
1246 SCOPE_EXIT_RTN_VALUE(ast_str_buffer(*buf), "%s: Done\n", ref_string);
1247
1248}
char buf[BUFSIZE]
Definition eagi_proxy.c:66
static struct ast_xml_doc * geoloc_eprofile_to_xmldoc(struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, struct ast_str **buf, const char *ref_string)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
Definition strings.h:1113
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
Definition strings.h:761

References ast_str_buffer(), ast_str_set(), ast_trace, ast_xml_close(), ast_xml_doc_dump_memory(), ast_xml_free_text(), buf, geoloc_eprofile_to_xmldoc(), LOG_ERROR, NULL, RAII_VAR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, and SCOPE_EXIT_RTN_VALUE.

Referenced by add_eprofile_to_tdata().

◆ ast_geoloc_eprofile_to_uri()

const char * ast_geoloc_eprofile_to_uri ( struct ast_geoloc_eprofile eprofile,
struct ast_channel chan,
struct ast_str **  buf,
const char *  ref_string 
)

Convert a URI eprofile to a URI string.

Parameters
eprofileEffective profile to convert
chanChannel to use to resolve variables
bufPointer to ast_str pointer to use for work
ref_stringAn identifying string to use in error messages.
Returns
String representation of URI allocated from buf or NULL on failure

Definition at line 444 of file geoloc_eprofile.c.

446{
447 const char *uri = NULL;
448 struct ast_variable *resolved = NULL;
449 char *result;
450 int we_created_buf = 0;
451
452 if (!eprofile || !buf || !chan) {
453 return NULL;
454 }
455
456 if (eprofile->format != AST_GEOLOC_FORMAT_URI) {
457 ast_log(LOG_ERROR, "%s: '%s' is not a URI profile. It's '%s'\n",
458 ref_str, eprofile->id, ast_geoloc_format_to_name(eprofile->format));
459 return NULL;
460 }
461
463 eprofile->location_variables, chan);
464 if (!resolved) {
465 return NULL;
466 }
467
468 uri = ast_variable_find_in_list(resolved, "URI");
469 result = uri ? ast_strdupa(uri) : NULL;
470 ast_variables_destroy(resolved);
471
472 if (ast_strlen_zero(result)) {
473 ast_log(LOG_ERROR, "%s: '%s' is a URI profile but had no, or an empty, 'URI' entry in location_info\n",
474 ref_str, eprofile->id);
475 return NULL;
476 }
477
478 if (!*buf) {
479 *buf = ast_str_create(256);
480 if (!*buf) {
481 return NULL;
482 }
483 we_created_buf = 1;
484 }
485
486 if (ast_str_append(buf, 0, "%s", result) <= 0) {
487 if (we_created_buf) {
488 ast_free(*buf);
489 *buf = NULL;
490 return NULL;
491 }
492 }
493
494 return ast_str_buffer(*buf);
495}
#define ast_free(a)
Definition astmm.h:180
static PGresult * result
Definition cel_pgsql.c:84
struct ast_variable * geoloc_eprofile_resolve_varlist(struct ast_variable *source, struct ast_variable *variables, struct ast_channel *chan)
const char * ast_variable_find_in_list(const struct ast_variable *list, const char *variable)
Gets the value of a variable from a variable list by name.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
Definition strings.h:1139
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
Definition strings.h:659

References ast_free, AST_GEOLOC_FORMAT_URI, ast_log, ast_str_append(), ast_str_buffer(), ast_str_create, ast_strdupa, ast_strlen_zero(), ast_variable_find_in_list(), ast_variables_destroy(), buf, ast_geoloc_eprofile::effective_location, ast_geoloc_eprofile::format, geoloc_eprofile_resolve_varlist(), ast_geoloc_eprofile::id, ast_geoloc_eprofile::location_variables, LOG_ERROR, NULL, and result.

Referenced by handle_outgoing_request().

◆ ast_geoloc_eprofiles_to_pidf()

const char * ast_geoloc_eprofiles_to_pidf ( struct ast_datastore ds,
struct ast_channel chan,
struct ast_str **  buf,
const char *  ref_string 
)

Convert a datastore containing eprofiles to a PIDF-LO document.

Parameters
dsDatastore containing effective profiles to convert
chanChannel to use to resolve variables
bufPointer to ast_str pointer to use for work
ref_stringAn identifying string to use in error messages.
Returns
String representation PIDF-LO allocated from buf or NULL on failure.

Definition at line 1033 of file geoloc_eprofile.c.

1035{
1036 RAII_VAR(struct ast_xml_doc *, intermediate, NULL, ast_xml_close);
1037 RAII_VAR(struct ast_xml_doc *, pidf_doc, NULL, ast_xml_close);
1038 struct ast_xml_node *root_node;
1039 struct ast_xml_node *pidfs[AST_PIDF_ELEMENT_LAST] = {NULL, };
1040 struct ast_geoloc_eprofile *eprofile;
1041 int eprofile_count = 0;
1042 int i;
1043 char *doc_str = NULL;
1044 int doc_len = 0;
1045 int rc = 0;
1046 SCOPE_ENTER(3, "%s\n", ref_string);
1047
1048 if (!ds || !chan || !buf || !*buf || ast_strlen_zero(ref_string)) {
1049 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Either or both datastore or chan were NULL\n",
1050 ref_string);
1051 }
1052
1053 intermediate = ast_xml_new();
1054 if (!intermediate) {
1055 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create XML document\n", ref_string);
1056 }
1057 root_node = ast_xml_new_node("presence");
1058 if (!root_node) {
1059 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create root XML node\n", ref_string);
1060 }
1061 ast_xml_set_root(intermediate, root_node);
1062
1063 eprofile_count = ast_geoloc_datastore_size(ds);
1064 for (i = 0; i < eprofile_count; i++) {
1065 struct ast_xml_node *temp_node = NULL;
1066 struct ast_xml_node *curr_loc = NULL;
1067 struct ast_xml_node *new_loc = NULL;
1068 struct ast_xml_node *new_loc_child = NULL;
1069 struct ast_xml_node *new_loc_child_dup = NULL;
1070 const char *entity = NULL;
1071 int has_no_entity = 0;
1072 eprofile = ast_geoloc_datastore_get_eprofile(ds, i);
1073 if (eprofile->format == AST_GEOLOC_FORMAT_URI) {
1074 continue;
1075 }
1076
1077 entity = ast_xml_get_attribute(root_node, "entity");
1078 has_no_entity = ast_strlen_zero(entity);
1079 ast_xml_free_attr(entity);
1080 if (has_no_entity) {
1081 rc = ast_xml_set_attribute(root_node, "entity", eprofile->id);
1082 if (rc != 0) {
1083 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to set 'entity' XML attribute\n", ref_string);
1084 }
1085 }
1086
1087 temp_node = geoloc_eprofile_to_intermediate(ast_geoloc_pidf_element_to_name(eprofile->pidf_element),
1088 eprofile, chan, ref_string);
1089 if (!temp_node) {
1090 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create temp_node\n", ref_string);
1091 }
1092
1093 if (!pidfs[eprofile->pidf_element]) {
1094 pidfs[eprofile->pidf_element] = temp_node;
1095 ast_xml_add_child(root_node, temp_node);
1096 continue;
1097 }
1098
1099 curr_loc = ast_xml_find_child_element(pidfs[eprofile->pidf_element], "location-info", NULL, NULL);
1100 new_loc = ast_xml_find_child_element(temp_node, "location-info", NULL, NULL);
1101 new_loc_child = ast_xml_node_get_children(new_loc);
1102 new_loc_child_dup = ast_xml_copy_node_list(new_loc_child);
1103 ast_xml_add_child_list(curr_loc, new_loc_child_dup);
1104
1105 ast_xml_free_node(temp_node);
1106 }
1107
1108 if (TRACE_ATLEAST(5)) {
1109 ast_xml_doc_dump_memory(intermediate, &doc_str, &doc_len);
1110 ast_trace(5, "Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str : "<empty>");
1111 ast_xml_free_text(doc_str);
1112 doc_str = NULL;
1113 doc_len = 0;
1114 }
1115
1116 pidf_doc = ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, NULL);
1117 if (!pidf_doc) {
1118 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate docs\n",
1119 ref_string);
1120 }
1121
1122 ast_xml_doc_dump_memory(pidf_doc, &doc_str, &doc_len);
1123 if (doc_len == 0 || !doc_str) {
1124 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to dump final PIDF-LO doc to string\n",
1125 ref_string);
1126 }
1127
1128 rc = ast_str_set(buf, 0, "%s", doc_str);
1129 ast_xml_free_text(doc_str);
1130 if (rc <= 0) {
1131 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to extend buffer (%d)\n",
1132 ref_string, rc);
1133 }
1134
1135 ast_trace(5, "Final doc:\n%s\n", ast_str_buffer(*buf));
1136
1137 SCOPE_EXIT_RTN_VALUE(ast_str_buffer(*buf), "%s: Done\n", ref_string);
1138}
static struct ast_xslt_doc * eprofile_to_pidf_xslt
static struct ast_xml_node * geoloc_eprofile_to_intermediate(const char *element_name, struct ast_geoloc_eprofile *eprofile, struct ast_channel *chan, const char *ref_string)
struct ast_geoloc_eprofile * ast_geoloc_datastore_get_eprofile(struct ast_datastore *ds, int ix)
Retrieve a specific eprofile from a datastore by index.
@ AST_PIDF_ELEMENT_LAST
int ast_geoloc_datastore_size(struct ast_datastore *ds)
Retrieves the number of eprofiles in the datastore.
#define ast_xml_find_child_element(_parent_node, _name, _attrname, _attrvalue)
Find a direct child element by name.
Definition xml.h:201
struct ast_xml_node * ast_xml_copy_node_list(struct ast_xml_node *list)
Create a copy of a n ode list.
Definition xml.c:184
struct ast_xml_node * ast_xml_add_child(struct ast_xml_node *parent, struct ast_xml_node *child)
Add a child node, to a specified parent node.
Definition xml.c:168
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node's children.
Definition xml.c:395
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
Definition xml.c:267
struct ast_xml_node * ast_xml_new_node(const char *name)
Create a XML node.
Definition xml.c:144
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
Definition xml.c:253
struct ast_xml_doc * ast_xml_new(void)
Create a XML document.
Definition xml.c:136
int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
Set an attribute to a node.
Definition xml.c:284
struct ast_xml_node * ast_xml_add_child_list(struct ast_xml_node *parent, struct ast_xml_node *child)
Add a list of child nodes, to a specified parent node.
Definition xml.c:176
void ast_xml_set_root(struct ast_xml_doc *doc, struct ast_xml_node *node)
Specify the root node of a XML document.
Definition xml.c:221
void ast_xml_free_node(struct ast_xml_node *node)
Free node.
Definition xml.c:243

References ast_geoloc_datastore_get_eprofile(), ast_geoloc_datastore_size(), AST_GEOLOC_FORMAT_URI, AST_PIDF_ELEMENT_LAST, ast_str_buffer(), ast_str_set(), ast_strlen_zero(), ast_trace, ast_xml_add_child(), ast_xml_add_child_list(), ast_xml_close(), ast_xml_copy_node_list(), ast_xml_doc_dump_memory(), ast_xml_find_child_element, ast_xml_free_attr(), ast_xml_free_node(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_new(), ast_xml_new_node(), ast_xml_node_get_children(), ast_xml_set_attribute(), ast_xml_set_root(), buf, eprofile_to_pidf_xslt, ast_geoloc_eprofile::format, geoloc_eprofile_to_intermediate(), ast_geoloc_eprofile::id, LOG_ERROR, NULL, ast_geoloc_eprofile::pidf_element, RAII_VAR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, and TRACE_ATLEAST.

◆ geoloc_eprofile_create_from_xslt_result()

static struct ast_geoloc_eprofile * geoloc_eprofile_create_from_xslt_result ( struct ast_xml_doc *  result_doc,
const char *  ref_str 
)
static

Definition at line 636 of file geoloc_eprofile.c.

638{
639 struct ast_geoloc_eprofile *eprofile;
640 /*
641 * None of the ast_xml_nodes needs to be freed
642 * because they're just pointers into result_doc.
643 */
644 struct ast_xml_node *presence = NULL;
645 struct ast_xml_node *pidf_element = NULL;
646 struct ast_xml_node *location_info = NULL;
647 struct ast_xml_node *confidence = NULL;
648 struct ast_xml_node *usage_rules = NULL;
649 struct ast_xml_node *method = NULL;
650 struct ast_xml_node *note_well = NULL;
651 struct ast_xml_node *device_id = NULL;
652 /*
653 * Like nodes, names of nodes are just
654 * pointers into result_doc and don't need to be freed.
655 */
656 const char *pidf_element_str;
657 /*
658 * Attributes and element text however are allocated on the fly
659 * so they DO need to be freed after use.
660 */
661 const char *id = NULL;
662 const char *pidf_element_id = NULL;
663 const char *format_str = NULL;
664 const char *method_str = NULL;
665 const char *note_well_str = NULL;
666 const char *device_id_str = NULL;
667
668 SCOPE_ENTER(3, "%s\n", ref_str);
669
670 if (!result_doc) {
671 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: result_doc was NULL", ref_str);
672 }
673
674 if (TRACE_ATLEAST(5)) {
675 char *doc_str = NULL;
676 int doc_len = 0;
677
678 ast_xml_doc_dump_memory(result_doc, &doc_str, &doc_len);
679 ast_trace(5, "xslt result doc len: %d\n%s\n", doc_len, doc_len ? doc_str : "<empty>");
680 ast_xml_free_text(doc_str);
681 }
682
683 presence = ast_xml_get_root(result_doc);
684 if (!presence) {
685 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Can't find 'presence' root element\n",
686 ref_str);
687 }
688 id = ast_xml_get_attribute(presence, "entity");
689
690 pidf_element = ast_xml_node_get_children(presence);
691 if (!pidf_element) {
692 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Can't find a device, tuple or person element\n",
693 ref_str);
694 }
695
696 eprofile = ast_geoloc_eprofile_alloc(S_OR(id, "unknown"));
698 if (!eprofile) {
699 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Allocation failure\n", ref_str);
700 }
701
702 pidf_element_id = ast_xml_get_attribute(pidf_element, "id");
703 if (!ast_strlen_zero(pidf_element_id)) {
704 ast_string_field_set(eprofile, pidf_element_id, pidf_element_id);
705 }
706 ast_xml_free_attr(pidf_element_id);
707
708 location_info = ast_xml_find_child_element(pidf_element, "location-info", NULL, NULL);
709 if (!location_info) {
710 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Can't find a location-info element\n",
711 ref_str);
712 }
713
714 format_str = ast_xml_get_attribute(location_info, "format");
715 if (ast_strlen_zero(format_str)) {
716 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Unable to find 'format' attribute\n", ref_str);
717 }
718
719 eprofile->format = AST_GEOLOC_FORMAT_NONE;
720 if (strcasecmp(format_str, "gml") == 0) {
721 eprofile->format = AST_GEOLOC_FORMAT_GML;
722 } else if (strcasecmp(format_str, "civicAddress") == 0) {
724 }
725
726 if (eprofile->format == AST_GEOLOC_FORMAT_NONE) {
727 char *dup_format_str = ast_strdupa(format_str);
728 ast_xml_free_attr(format_str);
729 ao2_ref(eprofile, -1);
730 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unknown format '%s'\n", ref_str, dup_format_str);
731 }
732 ast_xml_free_attr(format_str);
733
734 pidf_element_str = ast_xml_node_get_name(pidf_element);
735 eprofile->pidf_element = ast_geoloc_pidf_element_str_to_enum(pidf_element_str);
736
737 eprofile->location_info = var_list_from_loc_info(location_info, eprofile->format, ref_str);
738 if (!eprofile->location_info) {
739 ao2_ref(eprofile, -1);
741 "%s: Unable to create location variables\n", ref_str);
742 }
743
744 /*
745 * The function calls that follow are all NULL tolerant
746 * so no need for explicit error checking.
747 */
748 usage_rules = ast_xml_find_child_element(pidf_element, "usage-rules", NULL, NULL);
749 eprofile->usage_rules = var_list_from_node(usage_rules, ref_str);
750 confidence = ast_xml_find_child_element(location_info, "confidence", NULL, NULL);
751 eprofile->confidence = var_list_from_confidence(confidence, ref_str);
752
753 method = ast_xml_find_child_element(pidf_element, "method", NULL, NULL);
754 method_str = ast_xml_get_text(method);
755 ast_string_field_set(eprofile, method, method_str);
756 ast_xml_free_text(method_str);
757
758 note_well = ast_xml_find_child_element(pidf_element, "note-well", NULL, NULL);
759 note_well_str = ast_xml_get_text(note_well);
760 ast_string_field_set(eprofile, notes, note_well_str);
761 ast_xml_free_text(note_well_str);
762
763 device_id = ast_xml_find_child_element(pidf_element, "deviceID", NULL, NULL);
764 device_id_str = ast_xml_get_text(device_id);
765 ast_string_field_set(eprofile, device_id, device_id_str);
766 ast_xml_free_text(device_id_str);
767
768 SCOPE_EXIT_RTN_VALUE(eprofile, "%s: Done.\n", ref_str);
769}
static struct ast_variable * var_list_from_node(struct ast_xml_node *node, const char *ref_str)
static struct ast_variable * var_list_from_confidence(struct ast_xml_node *confidence, const char *ref_str)
static struct ast_variable * var_list_from_loc_info(struct ast_xml_node *locinfo, enum ast_geoloc_format format, const char *ref_str)
@ AST_GEOLOC_FORMAT_GML
@ AST_GEOLOC_FORMAT_CIVIC_ADDRESS
@ AST_GEOLOC_FORMAT_NONE
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
Definition strings.h:80
const char * ast_xml_get_text(struct ast_xml_node *node)
Get an element content string.
Definition xml.c:353
const char * ast_xml_node_get_name(struct ast_xml_node *node)
Get the name of a node.
Definition xml.c:390
struct ast_xml_node * ast_xml_get_root(struct ast_xml_doc *doc)
Get the document root node.
Definition xml.c:230

References ao2_ref, ast_geoloc_eprofile_alloc(), AST_GEOLOC_FORMAT_CIVIC_ADDRESS, AST_GEOLOC_FORMAT_GML, AST_GEOLOC_FORMAT_NONE, ast_strdupa, ast_string_field_set, ast_strlen_zero(), ast_trace, ast_xml_doc_dump_memory(), ast_xml_find_child_element, ast_xml_free_attr(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_get_root(), ast_xml_get_text(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_geoloc_eprofile::confidence, ast_geoloc_eprofile::format, ast_geoloc_eprofile::location_info, LOG_ERROR, method, notes, NULL, ast_geoloc_eprofile::pidf_element, S_OR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, TRACE_ATLEAST, ast_geoloc_eprofile::usage_rules, var_list_from_confidence(), var_list_from_loc_info(), and var_list_from_node().

Referenced by ast_geoloc_eprofile_create_from_pidf().

◆ geoloc_eprofile_destructor()

static void geoloc_eprofile_destructor ( void *  obj)
static

◆ geoloc_eprofile_load()

int geoloc_eprofile_load ( void  )

Definition at line 1277 of file geoloc_eprofile.c.

1278{
1281
1284
1285 pidf_to_eprofile_xslt = ast_xslt_read_memory(
1287 if (!pidf_to_eprofile_xslt) {
1288 ast_log(LOG_ERROR, "Unable to read pidf_to_eprofile_xslt from memory\n");
1290 }
1291
1294
1295 eprofile_to_pidf_xslt = ast_xslt_read_memory(
1297 if (!eprofile_to_pidf_xslt) {
1298 ast_log(LOG_ERROR, "Unable to read eprofile_to_pidf_xslt from memory\n");
1299// geoloc_eprofile_unload();
1301 }
1302
1304
1305 load_tests();
1306
1308}
struct ast_sorcery * geoloc_get_sorcery(void)
const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_start[]
static size_t pidf_lo_test_xml_size
const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_end[]
const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_end[]
static size_t eprofile_to_pidf_xslt_size
const uint8_t _binary_res_geolocation_pidf_lo_test_xml_end[]
const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_start[]
const uint8_t _binary_res_geolocation_pidf_lo_test_xml_start[]
static size_t pidf_to_eprofile_xslt_size
static void load_tests(void)
@ AST_MODULE_LOAD_SUCCESS
Definition module.h:70
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
Definition module.h:78

References _binary_res_geolocation_eprofile_to_pidf_xslt_end, _binary_res_geolocation_eprofile_to_pidf_xslt_start, _binary_res_geolocation_pidf_lo_test_xml_end, _binary_res_geolocation_pidf_lo_test_xml_start, _binary_res_geolocation_pidf_to_eprofile_xslt_end, _binary_res_geolocation_pidf_to_eprofile_xslt_start, ast_log, AST_MODULE_LOAD_DECLINE, AST_MODULE_LOAD_SUCCESS, eprofile_to_pidf_xslt, eprofile_to_pidf_xslt_size, geoloc_get_sorcery(), geoloc_sorcery, load_tests(), LOG_ERROR, pidf_lo_test_xml_size, pidf_to_eprofile_xslt, and pidf_to_eprofile_xslt_size.

Referenced by load_module().

◆ geoloc_eprofile_reload()

int geoloc_eprofile_reload ( void  )

Definition at line 1310 of file geoloc_eprofile.c.

1311{
1313}

References AST_MODULE_LOAD_SUCCESS.

Referenced by reload_module().

◆ geoloc_eprofile_resolve_string()

char * geoloc_eprofile_resolve_string ( const char *  source,
struct ast_variable variables,
struct ast_channel chan 
)

Definition at line 410 of file geoloc_eprofile.c.

412{
413 struct varshead *vh = NULL;
414 struct ast_str *buf = ast_str_alloca(256);
415
416 if (!source || !chan) {
417 return NULL;
418 }
419
420 /*
421 * ast_str_substitute_variables does only minimal recursive resolution so we need to
422 * pre-resolve each variable in the "variables" list, then use that result to
423 * do the final pass on the "source" variable list.
424 */
425 if (variables) {
426 struct ast_variable *var = variables;
427 vh = ast_var_list_create();
428 if (!vh) {
429 return NULL;
430 }
431 for ( ; var; var = var->next) {
432 ast_str_substitute_variables_full2(&buf, 0, chan, vh, var->value, NULL, 1);
435 }
436 }
437
438 ast_str_substitute_variables_full2(&buf, 0, chan, vh, source, NULL, 1);
440
442}
#define ast_strdup(str)
A wrapper for strdup()
Definition astmm.h:241
void ast_var_list_destroy(struct varshead *head)
Definition chanvars.c:109
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
Definition chanvars.h:51
#define ast_var_assign(name, value)
Definition chanvars.h:40
struct varshead * ast_var_list_create(void)
Definition chanvars.c:97
void ast_str_substitute_variables_full2(struct ast_str **buf, ssize_t maxlen, struct ast_channel *c, struct varshead *headp, const char *templ, size_t *used, int use_both)
Perform variable/function/expression substitution on an ast_str.
#define ast_str_alloca(init_len)
Definition strings.h:848
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
Definition strings.h:693
Support for dynamic strings.
Definition strings.h:623

References ast_str_alloca, ast_str_buffer(), ast_str_reset(), ast_str_substitute_variables_full2(), ast_strdup, ast_var_assign, ast_var_list_create(), ast_var_list_destroy(), AST_VAR_LIST_INSERT_TAIL(), buf, NULL, and var.

Referenced by geoloc_eprofile_to_intermediate().

◆ geoloc_eprofile_resolve_varlist()

struct ast_variable * geoloc_eprofile_resolve_varlist ( struct ast_variable source,
struct ast_variable variables,
struct ast_channel chan 
)

Definition at line 362 of file geoloc_eprofile.c.

364{
365 struct ast_variable *dest = NULL;
366 struct ast_variable *var = NULL;
367 struct varshead *vh = NULL;
368 struct ast_str *buf = ast_str_alloca(256);
369
370 if (!source || !chan) {
371 return NULL;
372 }
373
374 /*
375 * ast_str_substitute_variables does only minimal recursive resolution so we need to
376 * pre-resolve each variable in the "variables" list, then use that result to
377 * do the final pass on the "source" variable list.
378 */
379 if (variables) {
380 var = variables;
381 vh = ast_var_list_create();
382 if (!vh) {
383 return NULL;
384 }
385 for ( ; var; var = var->next) {
386 ast_str_substitute_variables_full2(&buf, 0, chan, vh, var->value, NULL, 1);
389 }
390 }
391
392 var = source;
393 for ( ; var; var = var->next) {
394 struct ast_variable *newvar = NULL;
395 ast_str_substitute_variables_full2(&buf, 0, chan, vh, var->value, NULL, 1);
396 newvar = ast_variable_new(var->name, ast_str_buffer(buf), "");
397 if (!newvar) {
400 return NULL;
401 }
402 ast_variable_list_append(&dest, newvar);
404 }
406
407 return dest;
408}

References ast_str_alloca, ast_str_buffer(), ast_str_reset(), ast_str_substitute_variables_full2(), ast_var_assign, ast_var_list_create(), ast_var_list_destroy(), AST_VAR_LIST_INSERT_TAIL(), ast_variable_list_append, ast_variable_new, ast_variables_destroy(), buf, NULL, and var.

Referenced by ast_geoloc_eprofile_to_uri(), and geoloc_eprofile_to_intermediate().

◆ geoloc_eprofile_to_intermediate()

static struct ast_xml_node * geoloc_eprofile_to_intermediate ( const char *  element_name,
struct ast_geoloc_eprofile eprofile,
struct ast_channel chan,
const char *  ref_string 
)
static

Definition at line 870 of file geoloc_eprofile.c.

872{
873 struct ast_variable *resolved_location = NULL;
874 struct ast_variable *resolved_usage = NULL;
875 struct ast_variable *var = NULL;
876 RAII_VAR(struct ast_xml_node *, pidf_node, NULL, ast_xml_free_node);
877 struct ast_xml_node *rtn_pidf_node;
878 struct ast_xml_node *loc_node;
879 struct ast_xml_node *confidence_node;
880 struct ast_xml_node *info_node;
881 struct ast_xml_node *rules_node;
882 struct ast_xml_node *method_node;
883 struct ast_xml_node *notes_node;
884 struct ast_xml_node *timestamp_node;
885 struct ast_xml_node *device_id_node;
886 struct timeval tv = ast_tvnow();
887 struct tm tm = { 0, };
888 char timestr[32] = { 0, };
889 int rc = 0;
890
891 SCOPE_ENTER(3, "%s\n", ref_string);
892
893 if (!eprofile || !chan) {
894 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Either or both eprofile or chan were NULL\n", ref_string);
895 }
896
897 pidf_node = ast_xml_new_node(element_name);
898 if (!pidf_node) {
899 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create '%s' XML node\n",
900 ref_string, element_name);
901 }
902 if (!ast_strlen_zero(eprofile->pidf_element_id)) {
903 char *resolved_pidf_element_id = geoloc_eprofile_resolve_string(eprofile->pidf_element_id,
904 eprofile->location_variables, chan);
905 if (!resolved_pidf_element_id) {
907 }
908 rc = ast_xml_set_attribute(pidf_node, "id", resolved_pidf_element_id);
909 ast_free(resolved_pidf_element_id);
910 if (rc != 0) {
911 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'id' XML attribute\n", ref_string);
912 }
913 }
914
915 loc_node = ast_xml_new_child(pidf_node, "location-info");
916 if (!loc_node) {
917 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'location-info' XML node\n",
918 ref_string);
919 }
920 rc = ast_xml_set_attribute(loc_node, "format", ast_geoloc_format_to_name(eprofile->format));
921 if (rc != 0) {
922 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to set 'format' XML attribute\n", ref_string);
923 }
924
925 resolved_location = geoloc_eprofile_resolve_varlist(eprofile->effective_location,
926 eprofile->location_variables, chan);
927 if (eprofile->format == AST_GEOLOC_FORMAT_CIVIC_ADDRESS) {
928 info_node = geoloc_civicaddr_list_to_xml(resolved_location, ref_string);
929 } else {
930 info_node = geoloc_gml_list_to_xml(resolved_location, ref_string);
931 }
932 ast_variables_destroy(resolved_location);
933
934 if (!info_node) {
935 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create XML from '%s' list\n",
936 ref_string, ast_geoloc_format_to_name(eprofile->format));
937 }
938 if (!ast_xml_add_child(loc_node, info_node)) {
939 ast_xml_free_node(info_node);
940 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable add '%s' node to XML document\n",
941 ref_string, ast_geoloc_format_to_name(eprofile->format));
942 }
943
944 if (eprofile->confidence) {
945 const char *value = S_OR(ast_variable_find_in_list(eprofile->confidence, "value"), "95");
946 const char *pdf = S_OR(ast_variable_find_in_list(eprofile->confidence, "pdf"), "unknown");
947
948 confidence_node = ast_xml_new_child(loc_node, "confidence");
949 if (!confidence_node) {
950 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'confidence' XML node\n",
951 ref_string);
952 }
953 rc = ast_xml_set_attribute(confidence_node, "pdf", pdf);
954 if (rc != 0) {
955 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to set 'pdf' attribute on 'confidence' element\n", ref_string);
956 }
957
958 ast_xml_set_text(confidence_node, value);
959 }
960
961 rules_node = ast_xml_new_child(pidf_node, "usage-rules");
962 if (!rules_node) {
963 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'usage-rules' XML node\n",
964 ref_string);
965 }
966 resolved_usage = geoloc_eprofile_resolve_varlist(eprofile->usage_rules,
967 eprofile->location_variables, chan);
968 for (var = resolved_usage; var; var = var->next) {
969 struct ast_xml_node *ur = ast_xml_new_child(rules_node, var->name);
970 ast_xml_set_text(ur, var->value);
971 }
972 ast_variables_destroy(resolved_usage);
973
974 if (!ast_strlen_zero(eprofile->method)) {
975 method_node = ast_xml_new_child(pidf_node, "method");
976 if (!method_node) {
977 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'method' XML node\n",
978 ref_string);
979 }
980 ast_xml_set_text(method_node, eprofile->method);
981 };
982
983 if (!ast_strlen_zero(eprofile->notes)) {
984 notes_node = ast_xml_new_child(pidf_node, "note-well");
985 if (!notes_node) {
986 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'note-well' XML node\n",
987 ref_string);
988 }
989 ast_xml_set_text(notes_node, eprofile->notes);
990 };
991
992 gmtime_r(&tv.tv_sec, &tm);
993 strftime(timestr, sizeof(timestr), "%FT%TZ", &tm);
994 timestamp_node = ast_xml_new_child(pidf_node, "timestamp");
995 if (!timestamp_node) {
996 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'timestamp' XML node\n",
997 ref_string);
998 }
999 ast_xml_set_text(timestamp_node, timestr);
1000
1001 if (!ast_strlen_zero(eprofile->device_id)) {
1002 char *resolved_device_id = geoloc_eprofile_resolve_string(eprofile->device_id,
1003 eprofile->location_variables, chan);
1004 if (!resolved_device_id) {
1006 }
1007 device_id_node = ast_xml_new_child(pidf_node, "deviceID");
1008 if (!device_id_node) {
1009 ast_free(resolved_device_id);
1010 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'deviceID' XML node\n",
1011 ref_string);
1012 }
1013 ast_xml_set_text(device_id_node, resolved_device_id);
1014 ast_free(resolved_device_id);
1015 }
1016
1017
1018 rtn_pidf_node = pidf_node;
1019 pidf_node = NULL;
1020 SCOPE_EXIT_RTN_VALUE(rtn_pidf_node, "%s: Done\n", ref_string);
1021}
struct ast_xml_node * geoloc_civicaddr_list_to_xml(const struct ast_variable *resolved_location, const char *ref_string)
char * geoloc_eprofile_resolve_string(const char *source, struct ast_variable *variables, struct ast_channel *chan)
struct ast_xml_node * geoloc_gml_list_to_xml(struct ast_variable *resolved_location, const char *ref_string)
Definition geoloc_gml.c:349
int value
Definition syslog.c:37
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Definition time.h:159
void ast_xml_set_text(struct ast_xml_node *node, const char *content)
Set an element content string.
Definition xml.c:362

References ast_free, AST_GEOLOC_FORMAT_CIVIC_ADDRESS, ast_strlen_zero(), ast_tvnow(), ast_variable_find_in_list(), ast_variables_destroy(), ast_xml_add_child(), ast_xml_free_node(), ast_xml_new_child(), ast_xml_new_node(), ast_xml_set_attribute(), ast_xml_set_text(), ast_geoloc_eprofile::confidence, ast_geoloc_eprofile::device_id, ast_geoloc_eprofile::effective_location, ast_geoloc_eprofile::format, geoloc_civicaddr_list_to_xml(), geoloc_eprofile_resolve_string(), geoloc_eprofile_resolve_varlist(), geoloc_gml_list_to_xml(), ast_geoloc_eprofile::location_variables, LOG_ERROR, ast_geoloc_eprofile::method, ast_variable::next, ast_geoloc_eprofile::notes, NULL, ast_geoloc_eprofile::pidf_element_id, RAII_VAR, S_OR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, ast_geoloc_eprofile::usage_rules, value, and var.

Referenced by ast_geoloc_eprofiles_to_pidf(), and geoloc_eprofile_to_xmldoc().

◆ geoloc_eprofile_to_xmldoc()

static struct ast_xml_doc * geoloc_eprofile_to_xmldoc ( struct ast_geoloc_eprofile eprofile,
struct ast_channel chan,
struct ast_str **  buf,
const char *  ref_string 
)
static

Definition at line 1140 of file geoloc_eprofile.c.

1142{
1143 RAII_VAR(struct ast_xml_doc *, intermediate, NULL, ast_xml_close);
1144 struct ast_xml_doc *pidf_doc = NULL;
1145 struct ast_xml_node *root_node;
1146 char *doc_str = NULL;
1147 int doc_len;
1148 int rc = 0;
1149 struct ast_xml_node *temp_node = NULL;
1150 const char *entity = NULL;
1151 int has_no_entity = 0;
1152 const char *params[] = { "suppress_empty_ca_elements", "false()", NULL };
1153
1154 SCOPE_ENTER(3, "%s\n", ref_string);
1155
1156 if (!eprofile || !chan || !buf || !*buf || ast_strlen_zero(ref_string)) {
1157 SCOPE_EXIT_RTN_VALUE(NULL, "%s: One of eprofile, chan or buf was NULL\n",
1158 ref_string);
1159 }
1160
1161 if (eprofile->format == AST_GEOLOC_FORMAT_URI) {
1162 SCOPE_EXIT_RTN_VALUE(NULL, "%s: eprofile '%s' was a URI format\n",
1163 ref_string, eprofile->id);
1164 }
1165
1166 intermediate = ast_xml_new();
1167 if (!intermediate) {
1168 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create XML document\n", ref_string);
1169 }
1170 root_node = ast_xml_new_node("presence");
1171 if (!root_node) {
1172 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create root XML node\n", ref_string);
1173 }
1174 ast_xml_set_root(intermediate, root_node);
1175
1176 entity = ast_xml_get_attribute(root_node, "entity");
1177 has_no_entity = ast_strlen_zero(entity);
1178 ast_xml_free_attr(entity);
1179 if (has_no_entity) {
1180 rc = ast_xml_set_attribute(root_node, "entity", eprofile->id);
1181 if (rc != 0) {
1182 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to set 'entity' XML attribute\n", ref_string);
1183 }
1184 }
1185
1187 ast_geoloc_pidf_element_to_name(eprofile->pidf_element), eprofile, chan, ref_string);
1188 if (!temp_node) {
1189 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create temp_node for eprofile '%s'\n",
1190 ref_string, eprofile->id);
1191 }
1192
1193 ast_xml_add_child(root_node, temp_node);
1194
1195 if (TRACE_ATLEAST(5)) {
1196 ast_xml_doc_dump_memory(intermediate, &doc_str, &doc_len);
1197 ast_trace(5, "Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str : "<empty>");
1198 ast_xml_free_text(doc_str);
1199 doc_str = NULL;
1200 doc_len = 0;
1201 }
1202
1203 if (eprofile->suppress_empty_ca_elements) {
1204 params[1] = "true()";
1205 }
1206 pidf_doc = ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, params);
1207 if (!pidf_doc) {
1208 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate doc\n",
1209 ref_string);
1210 }
1211
1212 SCOPE_EXIT_RTN_VALUE(pidf_doc, "%s: Done\n", ref_string);
1213}

References AST_GEOLOC_FORMAT_URI, ast_strlen_zero(), ast_trace, ast_xml_add_child(), ast_xml_close(), ast_xml_doc_dump_memory(), ast_xml_free_attr(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_new(), ast_xml_new_node(), ast_xml_set_attribute(), ast_xml_set_root(), buf, eprofile_to_pidf_xslt, ast_geoloc_eprofile::format, geoloc_eprofile_to_intermediate(), ast_geoloc_eprofile::id, LOG_ERROR, NULL, ast_geoloc_eprofile::pidf_element, RAII_VAR, SCOPE_ENTER, SCOPE_EXIT_LOG_RTN_VALUE, SCOPE_EXIT_RTN_VALUE, ast_geoloc_eprofile::suppress_empty_ca_elements, and TRACE_ATLEAST.

Referenced by ast_geoloc_eprofile_to_pidf().

◆ geoloc_eprofile_unload()

int geoloc_eprofile_unload ( void  )

Definition at line 1259 of file geoloc_eprofile.c.

1260{
1261 unload_tests();
1263 ast_xslt_close(pidf_to_eprofile_xslt);
1264 }
1265
1267 ast_xslt_close(eprofile_to_pidf_xslt);
1268 }
1269
1270 if (geoloc_sorcery) {
1272 }
1273
1275}
static void unload_tests(void)
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
Definition sorcery.h:1500

References AST_MODULE_LOAD_SUCCESS, ast_sorcery_unref, eprofile_to_pidf_xslt, geoloc_sorcery, pidf_to_eprofile_xslt, and unload_tests().

Referenced by unload_module().

◆ is_pidf_lo()

static int is_pidf_lo ( struct ast_xml_doc *  result_doc)
static

Definition at line 771 of file geoloc_eprofile.c.

772{
773 struct ast_xml_node *presence;
774 struct ast_xml_node *pidf_element;
775 struct ast_xml_node *location_info;
776 const char *pidf_element_name;
777
778 if (!result_doc) {
779 return 0;
780 }
781 presence = ast_xml_get_root(result_doc);
782 if (!presence || !ast_strings_equal("presence", ast_xml_node_get_name(presence))) {
783 return 0;
784 }
785
786 pidf_element = ast_xml_node_get_children(presence);
787 if (!pidf_element) {
788 return 0;
789 }
790 pidf_element_name = ast_xml_node_get_name(pidf_element);
791 if (!ast_strings_equal(pidf_element_name, "device") &&
792 !ast_strings_equal(pidf_element_name, "tuple") &&
793 !ast_strings_equal(pidf_element_name, "person")) {
794 return 0;
795 }
796
797 location_info = ast_xml_find_child_element(pidf_element, "location-info", NULL, NULL);
798 if (!location_info) {
799 return 0;
800 }
801
802 return 1;
803}
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition strings.c:238

References ast_strings_equal(), ast_xml_find_child_element, ast_xml_get_root(), ast_xml_node_get_children(), ast_xml_node_get_name(), and NULL.

Referenced by ast_geoloc_eprofile_create_from_pidf().

◆ load_tests()

static void load_tests ( void  )
static

Definition at line 1254 of file geoloc_eprofile.c.

1254{}

Referenced by geoloc_eprofile_load().

◆ set_loc_src()

static int set_loc_src ( struct ast_geoloc_eprofile eprofile,
const char *  uri,
const char *  ref_str 
)
static

Definition at line 297 of file geoloc_eprofile.c.

298{
299 char *local_uri = ast_strdupa(uri);
300 char *loc_src = NULL;
301
302 loc_src = strchr(local_uri, ';');
303 if (loc_src) {
304 *loc_src = '\0';
305 loc_src++;
306 }
307
308 if (!ast_strlen_zero(loc_src)) {
309 if (ast_begins_with(loc_src, "loc-src=")) {
310 struct ast_sockaddr loc_source_addr;
311 int rc = 0;
312 loc_src += 8;
313 rc = ast_sockaddr_parse(&loc_source_addr, loc_src, PARSE_PORT_FORBID);
314 if (rc == 1) {
315 ast_log(LOG_WARNING, "%s: URI '%s' has an invalid 'loc-src' parameter."
316 " RFC8787 states that IP addresses MUST be dropped.\n",
317 ref_str, uri);
318 return -1;
319 } else {
320 ast_string_field_set(eprofile, location_source, loc_src);
321 }
322 }
323 }
324 return 0;
325}
#define LOG_WARNING
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Definition netsock2.c:230
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
Definition strings.h:97
Socket address structure.
Definition netsock2.h:97

References ast_begins_with(), ast_log, ast_sockaddr_parse(), ast_strdupa, ast_string_field_set, ast_strlen_zero(), LOG_WARNING, NULL, and PARSE_PORT_FORBID.

Referenced by ast_geoloc_eprofile_create_from_pidf(), and ast_geoloc_eprofile_create_from_uri().

◆ unload_tests()

static void unload_tests ( void  )
static

Definition at line 1255 of file geoloc_eprofile.c.

1255{}

Referenced by geoloc_eprofile_unload().

◆ var_list_from_confidence()

static struct ast_variable * var_list_from_confidence ( struct ast_xml_node *  confidence,
const char *  ref_str 
)
static

Definition at line 596 of file geoloc_eprofile.c.

598{
599 struct ast_variable *list = NULL;
600 struct ast_variable *var;
601 const char *pdf;
602 const char *value;
603 SCOPE_ENTER(3, "%s\n", ref_str);
604
605 if (!confidence) {
606 SCOPE_EXIT_RTN_VALUE(NULL, "%s: No confidence\n", ref_str);
607 }
608
609 pdf = ast_xml_get_attribute(confidence, "pdf");
610 var = ast_variable_new("pdf", S_OR(pdf, "unknown"), "");
612 if (!var) {
613 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Allocation failure\n", ref_str);
614 }
616
617 value = ast_xml_get_text(confidence);
618 var = ast_variable_new("value", S_OR(value, "95"), "");
620 if (!var) {
622 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Allocation failure\n", ref_str);
623 }
625
626 if (TRACE_ATLEAST(5)) {
627 struct ast_str *buf = NULL;
628 ast_variable_list_join(list, ", ", "=", "\"", &buf);
629 ast_trace(5, "%s: Result: %s\n", ref_str, ast_str_buffer(buf));
630 ast_free(buf);
631 }
632
633 SCOPE_EXIT_RTN_VALUE(list, "%s: Done\n", ref_str);
634}
struct ast_str * ast_variable_list_join(const struct ast_variable *head, const char *item_separator, const char *name_value_separator, const char *quote_char, struct ast_str **str)
Join an ast_variable list with specified separators and quoted values.

References ast_free, ast_str_buffer(), ast_trace, ast_variable_list_append, ast_variable_list_join(), ast_variable_new, ast_variables_destroy(), ast_xml_free_attr(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_get_text(), buf, NULL, S_OR, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, TRACE_ATLEAST, value, and var.

Referenced by geoloc_eprofile_create_from_xslt_result().

◆ var_list_from_loc_info()

static struct ast_variable * var_list_from_loc_info ( struct ast_xml_node *  locinfo,
enum ast_geoloc_format  format,
const char *  ref_str 
)
static

Definition at line 541 of file geoloc_eprofile.c.

543{
544 struct ast_variable *list = NULL;
545 struct ast_variable *locinfo_list = NULL;
546 struct ast_xml_node *container;
547 struct ast_variable *var = NULL;
548 const char *attr;
549 SCOPE_ENTER(3, "%s\n", ref_str);
550
552 if (format == AST_GEOLOC_FORMAT_CIVIC_ADDRESS) {
553 attr = ast_xml_get_attribute(container, "lang");
554 if (attr) {
555 var = ast_variable_new("lang", attr, "");
556 ast_xml_free_attr(attr);
557 if (!var) {
558 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Allocation failure\n", ref_str);
559 }
561 }
562 } else {
564 if (!var) {
565 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Allocation failure\n", ref_str);
566 }
568
569 attr = ast_xml_get_attribute(container, "srsName");
570 var = ast_variable_new("crs", attr, "");
571 ast_xml_free_attr(attr);
572 if (!var) {
574 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Allocation failure\n", ref_str);
575 }
577 }
578
579 locinfo_list = var_list_from_node(container, ref_str);
580 if (locinfo_list == NULL) {
581 ast_log(LOG_WARNING, "%s: There were no elements in the location info\n", ref_str);
582 SCOPE_EXIT_RTN_VALUE(list, "%s: There were no elements in the location info\n", ref_str);
583 }
584 ast_variable_list_append(&list, locinfo_list);
585
586 if (TRACE_ATLEAST(5)) {
587 struct ast_str *buf = NULL;
588 ast_variable_list_join(list, ", ", "=", "\"", &buf);
589 ast_trace(5, "%s: Result: %s\n", ref_str, ast_str_buffer(buf));
590 ast_free(buf);
591 }
592
593 SCOPE_EXIT_RTN_VALUE(list, "%s: Done\n", ref_str);
594}
struct ao2_container * container
Definition res_fax.c:603

References ast_free, AST_GEOLOC_FORMAT_CIVIC_ADDRESS, ast_log, ast_str_buffer(), ast_trace, ast_variable_list_append, ast_variable_list_join(), ast_variable_new, ast_variables_destroy(), ast_xml_free_attr(), ast_xml_get_attribute(), ast_xml_node_get_children(), ast_xml_node_get_name(), buf, container, LOG_WARNING, NULL, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, TRACE_ATLEAST, var, and var_list_from_node().

Referenced by geoloc_eprofile_create_from_xslt_result().

◆ var_list_from_node()

static struct ast_variable * var_list_from_node ( struct ast_xml_node *  node,
const char *  ref_str 
)
static

Definition at line 497 of file geoloc_eprofile.c.

499{
500 struct ast_variable *list = NULL;
501 struct ast_xml_node *container;
502 struct ast_xml_node *child;
503 struct ast_variable *var;
504 SCOPE_ENTER(3, "%s\n", ref_str);
505
507 for (child = container; child; child = ast_xml_node_get_next(child)) {
508 const char *name = ast_xml_node_get_name(child);
509 const char *value = ast_xml_get_text(child);
510 const char *uom = ast_xml_get_attribute(child, "uom");
511
512 if (uom) {
513 /* '20 radians\0' */
514 char newval[strlen(value) + 1 + strlen(uom) + 1];
515 sprintf(newval, "%s %s", value, uom);
516 var = ast_variable_new(name, newval, "");
517 } else {
519 }
520
523
524 if (!var) {
526 SCOPE_EXIT_RTN_VALUE(NULL, "%s: Allocation failure\n", ref_str);
527 }
529 }
530
531 if (TRACE_ATLEAST(5)) {
532 struct ast_str *buf = NULL;
533 ast_variable_list_join(list, ", ", "=", "\"", &buf);
534 ast_trace(5, "%s: Result: %s\n", ref_str, ast_str_buffer(buf));
535 ast_free(buf);
536 }
537
538 SCOPE_EXIT_RTN_VALUE(list, "%s: Done\n", ref_str);
539}
struct ast_xml_node * ast_xml_node_get_next(struct ast_xml_node *node)
Get the next node in the same level.
Definition xml.c:400

References ast_free, ast_str_buffer(), ast_trace, ast_variable_list_append, ast_variable_list_join(), ast_variable_new, ast_variables_destroy(), ast_xml_free_attr(), ast_xml_free_text(), ast_xml_get_attribute(), ast_xml_get_text(), ast_xml_node_get_children(), ast_xml_node_get_name(), ast_xml_node_get_next(), buf, container, name, NULL, SCOPE_ENTER, SCOPE_EXIT_RTN_VALUE, TRACE_ATLEAST, value, and var.

Referenced by geoloc_eprofile_create_from_xslt_result(), and var_list_from_loc_info().

Variable Documentation

◆ _binary_res_geolocation_eprofile_to_pidf_xslt_end

const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_end[]
extern

Referenced by geoloc_eprofile_load().

◆ _binary_res_geolocation_eprofile_to_pidf_xslt_start

const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_start[]
extern

Referenced by geoloc_eprofile_load().

◆ _binary_res_geolocation_pidf_lo_test_xml_end

const uint8_t _binary_res_geolocation_pidf_lo_test_xml_end[]
extern

Referenced by geoloc_eprofile_load().

◆ _binary_res_geolocation_pidf_lo_test_xml_start

const uint8_t _binary_res_geolocation_pidf_lo_test_xml_start[]
extern

Referenced by geoloc_eprofile_load().

◆ _binary_res_geolocation_pidf_to_eprofile_xslt_end

const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_end[]
extern

Referenced by geoloc_eprofile_load().

◆ _binary_res_geolocation_pidf_to_eprofile_xslt_start

const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_start[]
extern

Referenced by geoloc_eprofile_load().

◆ eprofile_to_pidf_xslt

struct ast_xslt_doc* eprofile_to_pidf_xslt
static

◆ eprofile_to_pidf_xslt_size

size_t eprofile_to_pidf_xslt_size
static

Definition at line 35 of file geoloc_eprofile.c.

Referenced by geoloc_eprofile_load().

◆ geoloc_sorcery

struct ast_sorcery* geoloc_sorcery
static

◆ pidf_lo_test_xml_size

size_t pidf_lo_test_xml_size
static

Definition at line 31 of file geoloc_eprofile.c.

Referenced by geoloc_eprofile_load().

◆ pidf_to_eprofile_xslt

struct ast_xslt_doc* pidf_to_eprofile_xslt
static

◆ pidf_to_eprofile_xslt_size

size_t pidf_to_eprofile_xslt_size
static

Definition at line 27 of file geoloc_eprofile.c.

Referenced by geoloc_eprofile_load().