23 #include "geoloc_private.h"
25 extern const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_start[];
26 extern const uint8_t _binary_res_geolocation_pidf_to_eprofile_xslt_end[];
27 static size_t pidf_to_eprofile_xslt_size;
29 extern const uint8_t _binary_res_geolocation_pidf_lo_test_xml_start[];
30 extern const uint8_t _binary_res_geolocation_pidf_lo_test_xml_end[];
31 static size_t pidf_lo_test_xml_size;
33 extern const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_start[];
34 extern const uint8_t _binary_res_geolocation_eprofile_to_pidf_xslt_end[];
35 static size_t eprofile_to_pidf_xslt_size;
37 static struct ast_xslt_doc *eprofile_to_pidf_xslt;
38 static struct ast_xslt_doc *pidf_to_eprofile_xslt;
42 #define DUP_VARS(_dest, _source) \
46 struct ast_variable *_vars = ast_variables_dup(_source); \
56 static void geoloc_eprofile_destructor(
void *obj)
86 const char *method = NULL;
87 const char *location_source = NULL;
88 enum ast_geoloc_format format;
96 if (!ast_strlen_zero(eprofile->location_reference)) {
99 ast_log(LOG_ERROR,
"Profile '%s' referenced location '%s' does not exist!", eprofile->id,
100 eprofile->location_reference);
104 format = loc->format;
105 method = loc->method;
106 location_source = loc->location_source;
107 rc = DUP_VARS(temp_locinfo, loc->location_info);
109 rc = DUP_VARS(temp_confidence, loc->confidence);
116 format = eprofile->format;
117 method = eprofile->method;
118 location_source = eprofile->location_source;
119 rc = DUP_VARS(temp_locinfo, eprofile->location_info);
121 rc = DUP_VARS(temp_confidence, eprofile->confidence);
128 rc = DUP_VARS(temp_effloc, temp_locinfo);
133 if (eprofile->location_refinement) {
134 for (var = eprofile->location_refinement; var; var = var->
next) {
140 ast_variable_list_append(&temp_effloc, newvar);
145 eprofile->format = format;
150 eprofile->location_info = temp_locinfo;
153 eprofile->effective_location = temp_effloc;
162 const char *profile_id;
171 eprofile = ast_geoloc_eprofile_alloc(profile_id);
176 eprofile->allow_routing_use = src->allow_routing_use;
177 eprofile->pidf_element = src->pidf_element;
178 eprofile->suppress_empty_ca_elements = src->suppress_empty_ca_elements;
179 eprofile->format = src->format;
180 eprofile->precedence = src->precedence;
194 rc = DUP_VARS(eprofile->location_info, src->location_info);
197 rc = DUP_VARS(eprofile->effective_location, src->effective_location);
200 rc = DUP_VARS(eprofile->location_refinement, src->location_refinement);
203 rc = DUP_VARS(eprofile->location_variables, src->location_variables);
206 rc = DUP_VARS(eprofile->usage_rules, src->usage_rules);
209 rc = DUP_VARS(eprofile->confidence, src->confidence);
223 const char *profile_id;
232 eprofile = ast_geoloc_eprofile_alloc(profile_id);
238 eprofile->allow_routing_use = profile->allow_routing_use;
239 eprofile->pidf_element = profile->pidf_element;
240 eprofile->suppress_empty_ca_elements = profile->suppress_empty_ca_elements;
241 eprofile->format = profile->format;
255 rc = DUP_VARS(eprofile->location_info, profile->location_info);
258 rc = DUP_VARS(eprofile->location_refinement, profile->location_refinement);
261 rc = DUP_VARS(eprofile->location_variables, profile->location_variables);
264 rc = DUP_VARS(eprofile->usage_rules, profile->usage_rules);
267 rc = DUP_VARS(eprofile->confidence, profile->confidence);
275 eprofile->precedence = profile->precedence;
278 if (ast_geoloc_eprofile_refresh_location(eprofile) != 0) {
286 static int set_loc_src(
struct ast_geoloc_eprofile *eprofile,
const char *uri,
const char *ref_str)
289 char *loc_src = NULL;
291 loc_src = strchr(local_uri,
';');
297 if (!ast_strlen_zero(loc_src)) {
304 ast_log(LOG_WARNING,
"%s: URI '%s' has an invalid 'loc-src' parameter."
305 " RFC8787 states that IP addresses MUST be dropped.\n",
323 if (ast_strlen_zero(uri)) {
328 if (local_uri[0] ==
'<') {
331 ra = strchr(local_uri,
'>');
338 eprofile = ast_geoloc_eprofile_alloc(local_uri);
343 set_loc_src(eprofile, uri, ref_str);
345 eprofile->format = AST_GEOLOC_FORMAT_URI;
346 eprofile->location_info = ast_variable_new(
"URI", local_uri,
"");
357 struct ast_str *buf = ast_str_alloca(256);
359 if (!source || !chan) {
370 vh = ast_var_list_create();
374 for ( ; var; var = var->
next) {
382 for ( ; var; var = var->
next) {
388 ast_var_list_destroy(vh);
391 ast_variable_list_append(&dest, newvar);
394 ast_var_list_destroy(vh);
403 const char *uri = NULL;
406 int we_created_buf = 0;
408 if (!eprofile || !buf || !chan) {
412 if (eprofile->format != AST_GEOLOC_FORMAT_URI) {
413 ast_log(LOG_ERROR,
"%s: '%s' is not a URI profile. It's '%s'\n",
414 ref_str, eprofile->id, ast_geoloc_format_to_name(eprofile->format));
418 resolved = geoloc_eprofile_resolve_varlist(eprofile->effective_location,
419 eprofile->location_variables, chan);
428 if (ast_strlen_zero(result)) {
429 ast_log(LOG_ERROR,
"%s: '%s' is a URI profile but had no, or an empty, 'URI' entry in location_info\n",
430 ref_str, eprofile->id);
443 if (we_created_buf) {
458 struct ast_xml_node *child;
460 SCOPE_ENTER(3,
"%s\n", ref_str);
470 char newval[strlen(value) + 1 + strlen(uom) + 1];
471 sprintf(newval,
"%s %s", value, uom);
472 var = ast_variable_new(name, newval,
"");
474 var = ast_variable_new(name, value,
"");
482 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Allocation failure\n", ref_str);
484 ast_variable_list_append(&list, var);
487 if (TRACE_ATLEAST(5)) {
494 SCOPE_EXIT_RTN_VALUE(list,
"%s: Done\n", ref_str);
497 static struct ast_variable *var_list_from_loc_info(
struct ast_xml_node *locinfo,
498 enum ast_geoloc_format format,
const char *ref_str)
505 SCOPE_ENTER(3,
"%s\n", ref_str);
508 if (format == AST_GEOLOC_FORMAT_CIVIC_ADDRESS) {
511 var = ast_variable_new(
"lang", attr,
"");
514 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Allocation failure\n", ref_str);
516 ast_variable_list_append(&list, var);
521 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Allocation failure\n", ref_str);
523 ast_variable_list_append(&list, var);
526 var = ast_variable_new(
"crs", attr,
"");
530 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Allocation failure\n", ref_str);
532 ast_variable_list_append(&list, var);
535 locinfo_list = var_list_from_node(container, ref_str);
536 if (locinfo_list == NULL) {
537 ast_log(LOG_WARNING,
"%s: There were no elements in the location info\n", ref_str);
538 SCOPE_EXIT_RTN_VALUE(list,
"%s: There were no elements in the location info\n", ref_str);
540 ast_variable_list_append(&list, locinfo_list);
542 if (TRACE_ATLEAST(5)) {
549 SCOPE_EXIT_RTN_VALUE(list,
"%s: Done\n", ref_str);
552 static struct ast_variable *var_list_from_confidence(
struct ast_xml_node *confidence,
559 SCOPE_ENTER(3,
"%s\n", ref_str);
562 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: No confidence\n", ref_str);
566 var = ast_variable_new(
"pdf",
S_OR(pdf,
"unknown"),
"");
569 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Allocation failure\n", ref_str);
571 ast_variable_list_append(&list, var);
574 var = ast_variable_new(
"value",
S_OR(value,
"95"),
"");
578 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Allocation failure\n", ref_str);
580 ast_variable_list_append(&list, var);
582 if (TRACE_ATLEAST(5)) {
589 SCOPE_EXIT_RTN_VALUE(list,
"%s: Done\n", ref_str);
593 struct ast_xml_doc *result_doc,
const char *ref_str)
600 struct ast_xml_node *presence = NULL;
601 struct ast_xml_node *pidf_element = NULL;
602 struct ast_xml_node *location_info = NULL;
603 struct ast_xml_node *confidence = NULL;
604 struct ast_xml_node *usage_rules = NULL;
605 struct ast_xml_node *method = NULL;
606 struct ast_xml_node *note_well = NULL;
611 const char *pidf_element_str;
616 const char *
id = NULL;
617 const char *format_str = NULL;
618 const char *method_str = NULL;
619 const char *note_well_str = NULL;
621 SCOPE_ENTER(3,
"%s\n", ref_str);
624 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: result_doc was NULL", ref_str);
627 if (TRACE_ATLEAST(5)) {
628 char *doc_str = NULL;
632 ast_trace(5,
"xslt result doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
638 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Can't find 'presence' root element\n",
644 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Can't find a device, tuple or person element\n",
649 if (ast_strlen_zero(
id)) {
654 if (ast_strlen_zero(
id)) {
655 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Unable to find 'id' attribute\n", ref_str);
658 eprofile = ast_geoloc_eprofile_alloc(
id);
661 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Allocation failure\n", ref_str);
665 if (!location_info) {
666 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Can't find a location-info element\n",
671 if (ast_strlen_zero(format_str)) {
672 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Unable to find 'format' attribute\n", ref_str);
675 eprofile->format = AST_GEOLOC_FORMAT_NONE;
676 if (strcasecmp(format_str,
"gml") == 0) {
677 eprofile->format = AST_GEOLOC_FORMAT_GML;
678 }
else if (strcasecmp(format_str,
"civicAddress") == 0) {
679 eprofile->format = AST_GEOLOC_FORMAT_CIVIC_ADDRESS;
682 if (eprofile->format == AST_GEOLOC_FORMAT_NONE) {
686 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unknown format '%s'\n", ref_str, dup_format_str);
691 eprofile->pidf_element = ast_geoloc_pidf_element_str_to_enum(pidf_element_str);
693 eprofile->location_info = var_list_from_loc_info(location_info, eprofile->format, ref_str);
694 if (!eprofile->location_info) {
696 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
697 "%s: Unable to create location variables\n", ref_str);
705 eprofile->usage_rules = var_list_from_node(usage_rules, ref_str);
707 eprofile->confidence = var_list_from_confidence(confidence, ref_str);
719 SCOPE_EXIT_RTN_VALUE(eprofile,
"%s: Done.\n", ref_str);
722 static int is_pidf_lo(
struct ast_xml_doc *result_doc)
724 struct ast_xml_node *presence;
725 struct ast_xml_node *pidf_element;
726 struct ast_xml_node *location_info;
727 const char *pidf_element_name;
749 if (!location_info) {
757 struct ast_xml_doc *pidf_xmldoc,
const char *geoloc_uri,
const char *ref_str)
759 struct ast_xml_doc *result_doc = NULL;
762 SCOPE_ENTER(3,
"%s\n", ref_str);
764 result_doc =
ast_xslt_apply(pidf_to_eprofile_xslt, pidf_xmldoc, NULL);
765 if (!is_pidf_lo(result_doc)) {
766 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Not a PIDF-LO. Skipping.\n", ref_str);
786 if (TRACE_ATLEAST(5)) {
787 char *doc_str = NULL;
791 ast_trace(5,
"Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
797 eprofile = geoloc_eprofile_create_from_xslt_result(result_doc, ref_str);
800 if (eprofile && geoloc_uri) {
801 set_loc_src(eprofile, geoloc_uri, ref_str);
804 SCOPE_EXIT_RTN_VALUE(eprofile,
"%s: Done.\n", ref_str);
821 static struct ast_xml_node *geoloc_eprofile_to_intermediate(
const char *element_name,
struct ast_geoloc_eprofile *eprofile,
828 struct ast_xml_node *rtn_pidf_node;
829 struct ast_xml_node *loc_node;
830 struct ast_xml_node *confidence_node;
831 struct ast_xml_node *info_node;
832 struct ast_xml_node *rules_node;
833 struct ast_xml_node *method_node;
834 struct ast_xml_node *notes_node;
835 struct ast_xml_node *timestamp_node;
837 struct tm tm = { 0, };
838 char timestr[32] = { 0, };
841 SCOPE_ENTER(3,
"%s\n", ref_string);
843 if (!eprofile || !chan) {
844 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Either or both eprofile or chan were NULL\n", ref_string);
849 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create '%s' XML node\n",
850 ref_string, element_name);
855 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create 'location-info' XML node\n",
860 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to set 'format' XML attribute\n", ref_string);
863 resolved_location = geoloc_eprofile_resolve_varlist(eprofile->effective_location,
864 eprofile->location_variables, chan);
865 if (eprofile->format == AST_GEOLOC_FORMAT_CIVIC_ADDRESS) {
866 info_node = geoloc_civicaddr_list_to_xml(resolved_location, ref_string);
868 info_node = geoloc_gml_list_to_xml(resolved_location, ref_string);
873 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create XML from '%s' list\n",
874 ref_string, ast_geoloc_format_to_name(eprofile->format));
878 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable add '%s' node to XML document\n",
879 ref_string, ast_geoloc_format_to_name(eprofile->format));
882 if (eprofile->confidence) {
887 if (!confidence_node) {
888 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create 'confidence' XML node\n",
893 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to set 'pdf' attribute on 'confidence' element\n", ref_string);
901 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create 'usage-rules' XML node\n",
904 resolved_usage = geoloc_eprofile_resolve_varlist(eprofile->usage_rules,
905 eprofile->location_variables, chan);
906 for (var = resolved_usage; var; var = var->
next) {
912 if (!ast_strlen_zero(eprofile->method)) {
915 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create 'method' XML node\n",
921 if (!ast_strlen_zero(eprofile->notes)) {
924 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create 'note-well' XML node\n",
930 gmtime_r(&tv.tv_sec, &tm);
931 strftime(timestr,
sizeof(timestr),
"%FT%TZ", &tm);
933 if (!timestamp_node) {
934 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create 'timestamp' XML node\n",
939 rtn_pidf_node = pidf_node;
941 SCOPE_EXIT_RTN_VALUE(rtn_pidf_node,
"%s: Done\n", ref_string);
944 #define CREATE_NODE_LIST(node) \
946 node = ast_xml_new_child(root_node, \
947 geoloc_pidf_element_to_name(eprofile->pidf_element)); \
948 if (!pidfs[eprofile->pidf_element]) { \
949 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create pidf '%s' XML node\n", \
950 ref_string, geoloc_pidf_element_to_name(eprofile->pidf_element)); \
954 const char *ast_geoloc_eprofiles_to_pidf(
struct ast_datastore *ds,
959 struct ast_xml_node *root_node;
960 struct ast_xml_node *pidfs[AST_PIDF_ELEMENT_LAST] = {NULL, };
962 int eprofile_count = 0;
964 char *doc_str = NULL;
967 SCOPE_ENTER(3,
"%s\n", ref_string);
969 if (!ds || !chan || !buf || !*buf || ast_strlen_zero(ref_string)) {
970 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: Either or both datastore or chan were NULL\n",
976 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create XML document\n", ref_string);
980 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create root XML node\n", ref_string);
984 eprofile_count = ast_geoloc_datastore_size(ds);
985 for (i = 0; i < eprofile_count; i++) {
986 struct ast_xml_node *temp_node = NULL;
987 struct ast_xml_node *curr_loc = NULL;
988 struct ast_xml_node *new_loc = NULL;
989 struct ast_xml_node *new_loc_child = NULL;
990 struct ast_xml_node *new_loc_child_dup = NULL;
991 const char *entity = NULL;
992 int has_no_entity = 0;
993 eprofile = ast_geoloc_datastore_get_eprofile(ds, i);
994 if (eprofile->format == AST_GEOLOC_FORMAT_URI) {
999 has_no_entity = ast_strlen_zero(entity);
1001 if (has_no_entity) {
1004 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to set 'entity' XML attribute\n", ref_string);
1008 temp_node = geoloc_eprofile_to_intermediate(ast_geoloc_pidf_element_to_name(eprofile->pidf_element),
1009 eprofile, chan, ref_string);
1011 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create temp_node\n", ref_string);
1014 if (!pidfs[eprofile->pidf_element]) {
1015 pidfs[eprofile->pidf_element] = temp_node;
1029 if (TRACE_ATLEAST(5)) {
1031 ast_trace(5,
"Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
1037 pidf_doc =
ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, NULL);
1039 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create final PIDF-LO doc from intermediate docs\n",
1044 if (doc_len == 0 || !doc_str) {
1045 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to dump final PIDF-LO doc to string\n",
1052 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to extend buffer (%d)\n",
1058 SCOPE_EXIT_RTN_VALUE(
ast_str_buffer(*buf),
"%s: Done\n", ref_string);
1066 struct ast_xml_node *root_node;
1067 char *doc_str = NULL;
1070 struct ast_xml_node *temp_node = NULL;
1071 const char *entity = NULL;
1072 int has_no_entity = 0;
1073 const char *params[] = {
"suppress_empty_ca_elements",
"false()", NULL };
1075 SCOPE_ENTER(3,
"%s\n", ref_string);
1077 if (!eprofile || !chan || !buf || !*buf || ast_strlen_zero(ref_string)) {
1078 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: One of eprofile, chan or buf was NULL\n",
1082 if (eprofile->format == AST_GEOLOC_FORMAT_URI) {
1083 SCOPE_EXIT_RTN_VALUE(NULL,
"%s: eprofile '%s' was a URI format\n",
1084 ref_string, eprofile->id);
1088 if (!intermediate) {
1089 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create XML document\n", ref_string);
1093 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create root XML node\n", ref_string);
1098 has_no_entity = ast_strlen_zero(entity);
1100 if (has_no_entity) {
1103 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to set 'entity' XML attribute\n", ref_string);
1107 temp_node = geoloc_eprofile_to_intermediate(
1108 ast_geoloc_pidf_element_to_name(eprofile->pidf_element), eprofile, chan, ref_string);
1110 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create temp_node for eprofile '%s'\n",
1111 ref_string, eprofile->id);
1116 if (TRACE_ATLEAST(5)) {
1118 ast_trace(5,
"Intermediate doc len: %d\n%s\n", doc_len, doc_len ? doc_str :
"<empty>");
1124 if (eprofile->suppress_empty_ca_elements) {
1125 params[1] =
"true()";
1127 pidf_doc =
ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, params);
1129 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to create final PIDF-LO doc from intermediate doc\n",
1134 if (doc_len == 0 || !doc_str) {
1135 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to dump final PIDF-LO doc to string\n",
1142 SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR,
"%s: Unable to extend buffer (%d)\n",
1148 SCOPE_EXIT_RTN_VALUE(
ast_str_buffer(*buf),
"%s: Done\n", ref_string);
1151 #ifdef TEST_FRAMEWORK
1152 static void load_tests(
void);
1153 static void unload_tests(
void);
1155 static void load_tests(
void) {}
1156 static void unload_tests(
void) {}
1160 int geoloc_eprofile_unload(
void)
1163 if (pidf_to_eprofile_xslt) {
1167 if (eprofile_to_pidf_xslt) {
1171 if (geoloc_sorcery) {
1178 int geoloc_eprofile_load(
void)
1180 pidf_to_eprofile_xslt_size =
1181 (_binary_res_geolocation_pidf_to_eprofile_xslt_end - _binary_res_geolocation_pidf_to_eprofile_xslt_start);
1183 pidf_lo_test_xml_size =
1184 (_binary_res_geolocation_pidf_lo_test_xml_end - _binary_res_geolocation_pidf_lo_test_xml_start);
1187 (
char *)_binary_res_geolocation_pidf_to_eprofile_xslt_start, pidf_to_eprofile_xslt_size);
1188 if (!pidf_to_eprofile_xslt) {
1189 ast_log(LOG_ERROR,
"Unable to read pidf_to_eprofile_xslt from memory\n");
1193 eprofile_to_pidf_xslt_size =
1194 (_binary_res_geolocation_eprofile_to_pidf_xslt_end - _binary_res_geolocation_eprofile_to_pidf_xslt_start);
1197 (
char *)_binary_res_geolocation_eprofile_to_pidf_xslt_start, eprofile_to_pidf_xslt_size);
1198 if (!eprofile_to_pidf_xslt) {
1199 ast_log(LOG_ERROR,
"Unable to read eprofile_to_pidf_xslt from memory\n");
1204 geoloc_sorcery = geoloc_get_sorcery();
1211 int geoloc_eprofile_reload(
void)
1217 #ifdef TEST_FRAMEWORK
1224 const char *uri = NULL;
1225 int rc = AST_TEST_PASS;
1229 info->name =
"create_from_uri";
1230 info->category =
"/geoloc/";
1231 info->summary =
"Test create from uri";
1232 info->description = info->summary;
1233 return AST_TEST_NOT_RUN;
1238 eprofile = ast_geoloc_eprofile_create_from_uri(
"http://some_uri&a=b", __func__);
1239 ast_test_validate(
test, eprofile != NULL);
1240 ast_test_validate(
test, eprofile->format == AST_GEOLOC_FORMAT_URI);
1241 ast_test_validate(
test, eprofile->location_info != NULL);
1243 ast_test_validate(
test, uri != NULL);
1244 ast_test_validate(
test, strcmp(uri,
"http://some_uri&a=b") == 0);
1249 static enum ast_test_result_state validate_eprofile(
struct ast_test *
test,
1250 struct ast_xml_doc * pidf_xmldoc,
1253 enum ast_geoloc_pidf_element pidf_element,
1254 enum ast_geoloc_format format,
1256 const char *location,
1264 if (!ast_strlen_zero(path)) {
1265 result_doc =
ast_xslt_apply(pidf_to_eprofile_xslt, pidf_xmldoc, NULL);
1268 eprofile = geoloc_eprofile_create_from_xslt_result(result_doc,
"test_create_from_xslt");
1270 eprofile = ast_geoloc_eprofile_create_from_pidf(pidf_xmldoc, NULL,
"test_create_from_pidf");
1273 ast_test_validate(test, eprofile != NULL);
1274 ast_test_status_update(test,
"ID: '%s' pidf_element: '%s' format: '%s' method: '%s'\n", eprofile->id,
1275 ast_geoloc_pidf_element_to_name(eprofile->pidf_element),
1276 ast_geoloc_format_to_name(eprofile->format),
1280 ast_test_validate(test, eprofile->pidf_element == pidf_element);
1281 ast_test_validate(test, eprofile->format == format);
1285 ast_test_validate(test, str != NULL);
1286 ast_test_status_update(test,
"location_vars expected: %s\n", location);
1287 ast_test_status_update(test,
"location_vars received: %s\n",
ast_str_buffer(str));
1292 ast_test_validate(test, str != NULL);
1293 ast_test_status_update(test,
"usage_rules expected: %s\n", usage);
1294 ast_test_status_update(test,
"usage_rules received: %s\n",
ast_str_buffer(str));
1297 return AST_TEST_PASS;
1304 enum ast_test_result_state res = AST_TEST_PASS;
1308 info->name =
"create_from_pidf";
1309 info->category =
"/geoloc/";
1310 info->summary =
"Test create from pidf scenarios";
1311 info->description = info->summary;
1312 return AST_TEST_NOT_RUN;
1317 pidf_xmldoc =
ast_xml_read_memory((
char *)_binary_res_geolocation_pidf_lo_test_xml_start, pidf_lo_test_xml_size);
1318 ast_test_validate(test, pidf_xmldoc != NULL);
1320 res = validate_eprofile(test, pidf_xmldoc,
1323 AST_PIDF_ELEMENT_TUPLE,
1324 AST_GEOLOC_FORMAT_GML,
1326 "shape=Point,crs=2d,pos=-34.410649 150.87651",
1327 "retransmission-allowed='no',retention-expiry='2010-11-14T20:00:00Z'"
1329 ast_test_validate(test, res == AST_TEST_PASS);
1334 static void load_tests(
void) {
1335 AST_TEST_REGISTER(test_create_from_uri);
1336 AST_TEST_REGISTER(test_create_from_pidf);
1338 static void unload_tests(
void) {
1339 AST_TEST_UNREGISTER(test_create_from_uri);
1340 AST_TEST_UNREGISTER(test_create_from_pidf);
struct ast_variable * next
Main Channel structure associated with a channel.
Asterisk main include file. File version handling, generic pbx functions.
String manipulation functions.
void ast_variables_destroy(struct ast_variable *var)
Free variable list.
int ast_sockaddr_parse(struct ast_sockaddr *addr, const char *str, int flags)
Parse an IPv4 or IPv6 address string.
char * ast_str_buffer(const struct ast_str *buf)
Returns the string buffer within the ast_str buf.
struct ast_xml_doc * ast_xml_new(void)
Create a XML document.
void ast_xml_free_node(struct ast_xml_node *node)
Free node.
Structure for variables, used for configurations and for channel variables.
Full structure for sorcery.
int ast_str_append(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Append to a thread local dynamic string.
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 timeval ast_tvnow(void)
Returns current timeval. Meant to replace calls to gettimeofday().
Structure for a data store object.
struct ast_xml_node * ast_xml_get_root(struct ast_xml_doc *doc)
Get the document root node.
Socket address structure.
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_doc * ast_xslt_apply(struct ast_xslt_doc *xslt, struct ast_xml_doc *doc, const char **params)
Apply an XSLT stylesheet to an XML document.
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_sorcery_unref(sorcery)
Decrease the reference count of a sorcery structure.
const char * ast_xml_get_attribute(struct ast_xml_node *node, const char *attrname)
Get a node attribute by name.
void ast_xml_free_attr(const char *attribute)
Free an attribute returned by ast_xml_get_attribute()
int ast_str_set(struct ast_str **buf, ssize_t max_len, const char *fmt,...)
Set a dynamic string using variable arguments.
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.
int ast_variable_list_replace(struct ast_variable **head, struct ast_variable *replacement)
Replace a variable in the given list with a new value.
#define ast_string_field_init(x, size)
Initialize a field pool and fields.
#define ast_strdupa(s)
duplicate a string in memory from the stack
#define ao2_ref(o, delta)
Reference/unreference an object and return the old refcount.
char * ast_strip(char *s)
Strip leading/trailing whitespace from a string.
const char * ast_sorcery_object_get_id(const void *object)
Get the unique identifier of a sorcery object.
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.
struct ao2_container * container
struct ast_xml_node * ast_xml_new_node(const char *name)
Create a XML node.
Asterisk XML abstraction layer.
Core PBX routines and definitions.
#define ast_xml_find_child_element(_parent_node, _name, _attrname, _attrvalue)
Find a direct child element by name.
void ast_xslt_close(struct ast_xslt_doc *xslt)
Close a stylesheet document and free its resources.
Support for dynamic strings.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
void ast_xml_doc_dump_memory(struct ast_xml_doc *doc, char **buffer, int *length)
Dump the specified document to a buffer.
void ast_xml_set_root(struct ast_xml_doc *doc, struct ast_xml_node *node)
Specify the root node of a XML document.
void ast_xml_set_text(struct ast_xml_node *node, const char *content)
Set an element content string.
struct ast_xml_node * ast_xml_copy_node_list(struct ast_xml_node *list)
Create a copy of a n ode list.
Module has failed to load, may be in an inconsistent state.
void ast_xml_close(struct ast_xml_doc *doc)
Close an already open document and free the used structure.
void ast_str_reset(struct ast_str *buf)
Reset the content of a dynamic string. Useful before a series of ast_str_append.
struct ast_xslt_doc * ast_xslt_read_memory(char *buffer, size_t size)
Open an XSLT document that resides in memory.
int ast_xml_set_attribute(struct ast_xml_node *node, const char *name, const char *value)
Set an attribute to a node.
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.
#define S_OR(a, b)
returns the equivalent of logic or for strings: first one if not empty, otherwise second one...
const char * ast_xml_get_text(struct ast_xml_node *node)
Get an element content string.
static int force_inline attribute_pure ast_begins_with(const char *str, const char *prefix)
Checks whether a string begins with another.
#define AST_TEST_DEFINE(hdr)
struct ast_xml_doc * ast_xml_read_memory(char *buffer, size_t size)
Open an XML document that resides in memory.
struct ast_xml_node * ast_xml_node_get_next(struct ast_xml_node *node)
Get the next node in the same level.
#define RAII_VAR(vartype, varname, initval, dtor)
Declare a variable that will call a destructor function when it goes out of scope.
#define ast_string_field_free_memory(x)
free all memory - to be called before destroying the object
struct ast_xml_node * ast_xml_node_get_children(struct ast_xml_node *node)
Get the node's children.
const char * ast_xml_node_get_name(struct ast_xml_node *node)
Get the name of a node.
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.
void ast_xml_free_text(const char *text)
Free a content element that was returned by ast_xml_get_text()
#define ast_str_create(init_len)
Create a malloc'ed dynamic length string.
#define ast_string_field_set(x, field, data)
Set a field to a simple string value.