42#define DUP_VARS(_dest, _source) \
46 struct ast_variable *_vars = ast_variables_dup(_source); \
99 ast_log(
LOG_ERROR,
"Profile '%s' referenced location '%s' does not exist!", eprofile->
id,
116 format = eprofile->
format;
128 rc =
DUP_VARS(temp_effloc, temp_locinfo);
145 eprofile->
format = format;
162 const char *profile_id;
229 const char *profile_id;
300 char *loc_src =
NULL;
302 loc_src = strchr(local_uri,
';');
316 " RFC8787 states that IP addresses MUST be dropped.\n",
339 if (local_uri[0] ==
'<') {
342 ra = strchr(local_uri,
'>');
370 if (!source || !chan) {
416 if (!source || !chan) {
447 const char *uri =
NULL;
450 int we_created_buf = 0;
452 if (!eprofile || !
buf || !chan) {
458 ref_str, eprofile->
id, ast_geoloc_format_to_name(eprofile->
format));
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);
487 if (we_created_buf) {
502 struct ast_xml_node *child;
514 char newval[strlen(
value) + 1 + strlen(uom) + 1];
515 sprintf(newval,
"%s %s",
value, uom);
580 if (locinfo_list ==
NULL) {
637 struct ast_xml_doc *result_doc,
const char *ref_str)
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;
650 struct ast_xml_node *note_well =
NULL;
651 struct ast_xml_node *device_id =
NULL;
656 const char *pidf_element_str;
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;
675 char *doc_str =
NULL;
679 ast_trace(5,
"xslt result doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
709 if (!location_info) {
720 if (strcasecmp(format_str,
"gml") == 0) {
722 }
else if (strcasecmp(format_str,
"civicAddress") == 0) {
735 eprofile->
pidf_element = ast_geoloc_pidf_element_str_to_enum(pidf_element_str);
741 "%s: Unable to create location variables\n", ref_str);
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;
798 if (!location_info) {
806 struct ast_xml_doc *pidf_xmldoc,
const char *geoloc_uri,
const char *ref_str)
808 struct ast_xml_doc *result_doc =
NULL;
836 char *doc_str =
NULL;
840 ast_trace(5,
"Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
849 if (eprofile && geoloc_uri) {
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;
887 struct tm tm = { 0, };
888 char timestr[32] = { 0, };
893 if (!eprofile || !chan) {
900 ref_string, element_name);
905 if (!resolved_pidf_element_id) {
936 ref_string, ast_geoloc_format_to_name(eprofile->
format));
941 ref_string, ast_geoloc_format_to_name(eprofile->
format));
949 if (!confidence_node) {
992 gmtime_r(&tv.tv_sec, &tm);
993 strftime(timestr,
sizeof(timestr),
"%FT%TZ", &tm);
995 if (!timestamp_node) {
1004 if (!resolved_device_id) {
1008 if (!device_id_node) {
1018 rtn_pidf_node = pidf_node;
1023#define CREATE_NODE_LIST(node) \
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)); \
1038 struct ast_xml_node *root_node;
1041 int eprofile_count = 0;
1043 char *doc_str =
NULL;
1054 if (!intermediate) {
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;
1080 if (has_no_entity) {
1088 eprofile, chan, ref_string);
1110 ast_trace(5,
"Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
1123 if (doc_len == 0 || !doc_str) {
1144 struct ast_xml_doc *pidf_doc =
NULL;
1145 struct ast_xml_node *root_node;
1146 char *doc_str =
NULL;
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 };
1163 ref_string, eprofile->
id);
1167 if (!intermediate) {
1179 if (has_no_entity) {
1187 ast_geoloc_pidf_element_to_name(eprofile->
pidf_element), eprofile, chan, ref_string);
1190 ref_string, eprofile->
id);
1197 ast_trace(5,
"Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
1204 params[1] =
"true()";
1220 char *doc_str =
NULL;
1232 if (doc_len == 0 || !doc_str) {
1250#ifdef TEST_FRAMEWORK
1316#ifdef TEST_FRAMEWORK
1323 const char *uri =
NULL;
1328 info->name =
"create_from_uri";
1329 info->category =
"/geoloc/";
1330 info->summary =
"Test create from uri";
1338 ast_test_validate(
test, eprofile !=
NULL);
1340 ast_test_validate(
test, eprofile->location_info !=
NULL);
1342 ast_test_validate(
test, uri !=
NULL);
1343 ast_test_validate(
test, strcmp(uri,
"http://some_uri&a=b") == 0);
1350 struct ast_xml_doc * pidf_xmldoc,
1352 const char *pidf_element_id,
1356 const char *location,
1358 const char *device_id
1366 ast_geoloc_pidf_element_to_name(eprofile->
pidf_element),
1368 ast_geoloc_format_to_name(eprofile->
format),
1372 ast_geoloc_pidf_element_to_name(pidf_element),
1374 ast_geoloc_format_to_name(format),
1380 ast_test_validate(
test, eprofile->
format == format);
1400static char *normalize_string(
char *
in)
1405 while (*ptr !=
'\0') {
1419struct test_xpath_element {
1421 int validate_content;
1426 struct ast_xml_doc * pidf_xmldoc,
1427 struct ast_xml_doc * eprofile_xmldoc
1441 struct test_xpath_element elements[] = {
1442 {
"//def:tuple/@id", 1},
1443 {
"//gml:Point/@srsName", 1},
1444 {
"//gml:pos/text()", 1},
1445 {
"//con:confidence/text()", 1},
1446 {
"//con:confidence/@pdf", 1},
1447 {
"//gp:usage-rules", 0},
1448 {
"//gbp:retransmission-allowed/text()", 1},
1449 {
"//gbp:retention-expiry/text()", 1},
1450 {
"//gp:method/text()", 1},
1451 {
"//gp:note-well/text()", 1},
1452 {
"//dm:deviceID/text()", 1},
1453 {
"//def:timestamp", 0},
1468 for (i = 0; i <
ARRAY_LEN(elements); i++) {
1471 if (aresults && bresults) {
1474 if (elements[i].validate_content) {
1479 elements[i].path, atext, btext,
pass ?
"pass" :
"FAIL");
1482 elements[i].path, atext, btext);
1486 int pass = !!anode && !!bnode;
1488 elements[i].path, anode ?
"exists" :
"doesn't exist", bnode ?
"exists" :
"doesn't exist",
1489 pass ?
"pass" :
"FAIL");
1492 elements[i].path, anode ?
"exists" :
"doesn't exist", bnode ?
"exists" :
"doesn't exist");
1523 info->name =
"create_from_pidf";
1524 info->category =
"/geoloc/";
1525 info->summary =
"Test create from pidf scenarios";
1533 ast_test_validate(
test, pidf_xmldoc !=
NULL);
1536 ast_test_validate(
test, eprofile !=
NULL);
1539 res = validate_eprofile(
test, eprofile, pidf_xmldoc,
1540 "pres:alice@asterisk.org",
1545 "shape=Point,crs=2d,pos=-34.410649 150.87651",
1546 "retransmission-allowed='no',retention-expiry='2010-11-14T20:00:00Z'",
1559 mock_channel =
ast_channel_alloc(0,
AST_STATE_DOWN,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL, 0,
"TestChannel");
1563 return validate_xml(
test, eprofile, pidf_xmldoc, eprofile_xmldoc);
Asterisk main include file. File version handling, generic pbx functions.
#define ast_strdup(str)
A wrapper for strdup()
#define ast_strdupa(s)
duplicate a string in memory from the stack
@ AO2_ALLOC_OPT_LOCK_NOLOCK
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
#define ao2_alloc_options(data_size, destructor_fn, options)
void ast_hangup(struct ast_channel *chan)
Hang up a channel.
#define ast_channel_alloc(needqueue, state, cid_num, cid_name, acctcode, exten, context, assignedids, requestor, amaflag,...)
Create a channel structure.
void ast_var_list_destroy(struct varshead *head)
static void AST_VAR_LIST_INSERT_TAIL(struct varshead *head, struct ast_var_t *var)
#define ast_var_assign(name, value)
struct varshead * ast_var_list_create(void)
struct ast_xml_node * geoloc_civicaddr_list_to_xml(const struct ast_variable *resolved_location, const char *ref_string)
struct ast_sorcery * geoloc_get_sorcery(void)
const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_start[]
struct ast_variable * geoloc_eprofile_resolve_varlist(struct ast_variable *source, struct ast_variable *variables, struct ast_channel *chan)
static size_t pidf_lo_test_xml_size
static void geoloc_eprofile_destructor(void *obj)
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_dup(struct ast_geoloc_eprofile *src)
Duplicate an effective profile.
static struct ast_xslt_doc * pidf_to_eprofile_xslt
int geoloc_eprofile_reload(void)
int geoloc_eprofile_unload(void)
static struct ast_variable * var_list_from_node(struct ast_xml_node *node, const char *ref_str)
static struct ast_sorcery * geoloc_sorcery
char * geoloc_eprofile_resolve_string(const char *source, struct ast_variable *variables, struct ast_channel *chan)
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_variable * var_list_from_confidence(struct ast_xml_node *confidence, const char *ref_str)
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 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[]
static int set_loc_src(struct ast_geoloc_eprofile *eprofile, const char *uri, const char *ref_str)
struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_uri(const char *uri, const char *ref_str)
Allocate a new effective profile from a URI.
const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_start[]
static int is_pidf_lo(struct ast_xml_doc *result_doc)
static void unload_tests(void)
struct ast_geoloc_eprofile * ast_geoloc_eprofile_alloc(const char *name)
Geolocation Effective Profile Functions.
struct ast_geoloc_eprofile * ast_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.
int geoloc_eprofile_load(void)
static struct ast_geoloc_eprofile * geoloc_eprofile_create_from_xslt_result(struct ast_xml_doc *result_doc, const char *ref_str)
const uint8_t _binary_res_geolocation_pidf_lo_test_xml_start[]
static size_t pidf_to_eprofile_xslt_size
static struct ast_xslt_doc * eprofile_to_pidf_xslt
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 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)
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.
static void load_tests(void)
static struct ast_variable * var_list_from_loc_info(struct ast_xml_node *locinfo, enum ast_geoloc_format format, const char *ref_str)
struct ast_geoloc_eprofile * ast_geoloc_eprofile_create_from_profile(struct ast_geoloc_profile *profile)
Allocate a new effective profile from an existing profile.
#define DUP_VARS(_dest, _source)
struct ast_xml_node * geoloc_gml_list_to_xml(struct ast_variable *resolved_location, const char *ref_string)
#define TRACE_ATLEAST(level)
#define SCOPE_EXIT_RTN_VALUE(__return_value,...)
#define SCOPE_EXIT_LOG_RTN_VALUE(__value, __log_level,...)
#define SCOPE_ENTER(level,...)
#define ast_trace(level,...)
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.
#define ast_variable_new(name, value, filename)
#define ast_variable_list_append(head, new_var)
struct ast_variable * ast_variables_dup(struct ast_variable *var)
Duplicate variable list.
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.
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.
@ AST_MODULE_LOAD_SUCCESS
@ AST_MODULE_LOAD_DECLINE
Module has failed to load, may be in an inconsistent state.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
Core PBX routines and definitions.
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.
struct ao2_container * container
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_GEOLOC_FORMAT_CIVIC_ADDRESS
int ast_geoloc_datastore_size(struct ast_datastore *ds)
Retrieves the number of eprofiles in the datastore.
#define ast_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
void * ast_sorcery_retrieve_by_id(const struct ast_sorcery *sorcery, const char *type, const char *id)
Retrieve an object using its unique identifier.
#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.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
String manipulation functions.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one.
static force_inline int attribute_pure ast_strlen_zero(const char *s)
#define ast_str_alloca(init_len)
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
char *attribute_pure ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
char *attribute_pure ast_skip_blanks(const char *str)
Gets a pointer to the first non-whitespace character in a string.
Main Channel structure associated with a channel.
Structure for a data store object.
struct ast_variable * effective_location
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
const ast_string_field id
int suppress_empty_ca_elements
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
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
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
int suppress_empty_ca_elements
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
Socket address structure.
Full structure for sorcery.
Support for dynamic strings.
Structure for variables, used for configurations and for channel variables.
struct ast_variable * next
#define AST_TEST_REGISTER(cb)
#define ast_test_status_update(a, b, c...)
#define AST_TEST_UNREGISTER(cb)
#define AST_TEST_DEFINE(hdr)
struct timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define AST_VECTOR_INIT(vec, size)
Initialize a vector.
#define AST_VECTOR_APPEND(vec, elem)
Append an element to a vector, growing the vector if needed.
Asterisk XML abstraction layer.
#define ast_xml_find_child_element(_parent_node, _name, _attrname, _attrvalue)
Find a direct child element by name.
struct ast_xml_node * ast_xml_copy_node_list(struct ast_xml_node *list)
Create a copy of a n ode list.
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.
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node's children.
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
const char * ast_xml_get_text(struct ast_xml_node *node)
Get an element content string.
struct ast_xml_xpath_results * ast_xml_query_with_namespaces(struct ast_xml_doc *doc, const char *xpath_str, struct ast_xml_namespace_def_vector *namespaces)
Execute an XPath query on an XML document with namespaces.
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.
struct ast_xml_node * ast_xml_new_node(const char *name)
Create a XML node.
struct ast_xml_node * ast_xml_xpath_get_first_result(struct ast_xml_xpath_results *results)
Return the first result node of an XPath query.
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length)
Dump the specified document to a buffer.
const char * ast_xml_node_get_name(struct ast_xml_node *node)
Get the name of a node.
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
struct ast_xml_node * ast_xml_node_get_next(struct ast_xml_node *node)
Get the next node in the same level.
struct ast_xml_doc * ast_xml_new(void)
Create a XML document.
int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
Set an attribute to a node.
void ast_xml_set_text(struct ast_xml_node *node, const char *content)
Set an element content string.
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.
void ast_xml_free_text(const char *text)
Free a content element that was returned by ast_xml_get_text()
void ast_xml_set_root(struct ast_xml_doc *doc, struct ast_xml_node *node)
Specify the root node of a XML document.
struct ast_xml_doc * ast_xml_read_memory(char *buffer, size_t size)
Open an XML document that resides in memory.
void ast_xml_free_node(struct ast_xml_node *node)
Free node.
struct ast_xml_node * ast_xml_get_root(struct ast_xml_doc *doc)
Get the document root node.