Asterisk - The Open Source Telephony Project  21.4.1
geoloc_civicaddr.c
1 /*
2  * Asterisk -- An open source telephony toolkit.
3  *
4  * Copyright (C) 2022, Sangoma Technologies Corporation
5  *
6  * George Joseph <gjoseph@sangoma.com>
7  *
8  * See http://www.asterisk.org for more information about
9  * the Asterisk project. Please do not directly contact
10  * any of the maintainers of this project for assistance;
11  * the project provides a web site, mailing lists and IRC
12  * channels for your use.
13  *
14  * This program is free software, distributed under the terms of
15  * the GNU General Public License Version 2. See the LICENSE file
16  * at the top of the source tree.
17  */
18 
19 #include "asterisk.h"
20 #include "asterisk/config.h"
21 #include "asterisk/cli.h"
22 #include "asterisk/res_geolocation.h"
23 #include "asterisk/xml.h"
24 #include "geoloc_private.h"
25 
26 static const char *addr_code_name_entries[] = {
27  "country",
28  "A1",
29  "A2",
30  "A3",
31  "A4",
32  "A5",
33  "A6",
34  "ADDCODE",
35  "BLD",
36  "FLR",
37  "HNO",
38  "HNS",
39  "LMK",
40  "LOC",
41  "NAM",
42  "PC",
43  "PCN",
44  "PLC",
45  "POBOX",
46  "POD",
47  "POM",
48  "PRD",
49  "PRM",
50  "RD",
51  "RD",
52  "RDBR",
53  "RDSEC",
54  "RDSUBBR",
55  "ROOM",
56  "SEAT",
57  "STS",
58  "UNIT",
59 };
60 
61 static int compare_civicaddr_codes(const void *_a, const void *_b)
62 {
63  /* See the man page for qsort(3) for an explanation of the casts */
64  int rc = strcmp(*(const char **)_a, *(const char **)_b);
65  return rc;
66 }
67 
68 int ast_geoloc_civicaddr_is_code_valid(const char *code)
69 {
70  const char **entry = bsearch(&code, addr_code_name_entries, ARRAY_LEN(addr_code_name_entries),
71  sizeof(const char *), compare_civicaddr_codes);
72  return (entry != NULL);
73 }
74 
75 enum ast_geoloc_validate_result ast_geoloc_civicaddr_validate_varlist(
76  const struct ast_variable *varlist, const char **result)
77 {
78  const struct ast_variable *var = varlist;
79  for (; var; var = var->next) {
80  int valid = ast_geoloc_civicaddr_is_code_valid(var->name);
81  if (!valid) {
82  *result = var->name;
83  return AST_GEOLOC_VALIDATE_INVALID_VARNAME;
84  }
85  }
86  return AST_GEOLOC_VALIDATE_SUCCESS;
87 }
88 
89 struct ast_xml_node *geoloc_civicaddr_list_to_xml(const struct ast_variable *resolved_location,
90  const char *ref_string)
91 {
92  char *lang = NULL;
93  char *s = NULL;
94  struct ast_variable *var;
95  struct ast_xml_node *ca_node;
96  struct ast_xml_node *child_node;
97  int rc = 0;
98  SCOPE_ENTER(3, "%s", ref_string);
99 
100  lang = (char *)ast_variable_find_in_list(resolved_location, "lang");
101  if (ast_strlen_zero(lang)) {
102  lang = ast_strdupa(ast_defaultlanguage);
103  for (s = lang; *s; s++) {
104  if (*s == '_') {
105  *s = '-';
106  }
107  }
108  }
109 
110  ca_node = ast_xml_new_node("civicAddress");
111  if (!ca_node) {
112  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'civicAddress' XML node\n", ref_string);
113  }
114  rc = ast_xml_set_attribute(ca_node, "lang", lang);
115  if (rc != 0) {
116  ast_xml_free_node(ca_node);
117  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'lang' XML attribute\n", ref_string);
118  }
119 
120  for (var = (struct ast_variable *)resolved_location; var; var = var->next) {
121  if (ast_strings_equal(var->name, "lang")) {
122  continue;
123  }
124  child_node = ast_xml_new_child(ca_node, var->name);
125  if (!child_node) {
126  ast_xml_free_node(ca_node);
127  SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create '%s' XML node\n", var->name, ref_string);
128  }
129  ast_xml_set_text(child_node, var->value);
130  }
131 
132  SCOPE_EXIT_RTN_VALUE(ca_node, "%s: Done\n", ref_string);
133 }
134 
135 int geoloc_civicaddr_unload(void)
136 {
138 }
139 
140 int geoloc_civicaddr_load(void)
141 {
142  qsort(addr_code_name_entries, ARRAY_LEN(addr_code_name_entries), sizeof(const char *),
143  compare_civicaddr_codes);
144 
146 }
147 
148 int geoloc_civicaddr_reload(void)
149 {
151 }
struct ast_variable * next
Asterisk main include file. File version handling, generic pbx functions.
void ast_xml_free_node(struct ast_xml_node *node)
Free node.
Definition: xml.c:243
Structure for variables, used for configurations and for channel variables.
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
Configuration File Parser.
#define ast_strdupa(s)
duplicate a string in memory from the stack
Definition: astmm.h:298
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.
Definition: main/config.c:919
struct ast_xml_node * ast_xml_new_node(const char *name)
Create a XML node.
Definition: xml.c:144
Asterisk XML abstraction layer.
int ast_strings_equal(const char *str1, const char *str2)
Compare strings for equality checking for NULL.
Definition: strings.c:238
void ast_xml_set_text(struct ast_xml_node *node, const char *content)
Set an element content string.
Definition: xml.c:362
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
Standard Command Line Interface.
Definition: search.h:40