mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-22 20:56:39 +00:00
Geolocation: Core Capability Preview
This commit adds res_geolocation which creates the core capabilities to manipulate Geolocation information on SIP INVITEs. An upcoming commit will add res_pjsip_geolocation which will allow the capabilities to be used with the pjsip channel driver. This commit message is intentionally short because this isn't a simple capability. See the documentation at https://wiki.asterisk.org/wiki/display/AST/Geolocation for more information. THE CAPABILITIES IMPLEMENTED HERE MAY CHANGE BASED ON USER FEEDBACK! ASTERISK-30127 Change-Id: Ibfde963121b1ecf57fd98ee7060c4f0808416303
This commit is contained in:
151
res/res_geolocation/geoloc_civicaddr.c
Normal file
151
res/res_geolocation/geoloc_civicaddr.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Asterisk -- An open source telephony toolkit.
|
||||
*
|
||||
* Copyright (C) 2022, Sangoma Technologies Corporation
|
||||
*
|
||||
* George Joseph <gjoseph@sangoma.com>
|
||||
*
|
||||
* See http://www.asterisk.org for more information about
|
||||
* the Asterisk project. Please do not directly contact
|
||||
* any of the maintainers of this project for assistance;
|
||||
* the project provides a web site, mailing lists and IRC
|
||||
* channels for your use.
|
||||
*
|
||||
* This program is free software, distributed under the terms of
|
||||
* the GNU General Public License Version 2. See the LICENSE file
|
||||
* at the top of the source tree.
|
||||
*/
|
||||
|
||||
#include "asterisk.h"
|
||||
#include "asterisk/config.h"
|
||||
#include "asterisk/cli.h"
|
||||
#include "asterisk/res_geolocation.h"
|
||||
#include "asterisk/xml.h"
|
||||
#include "geoloc_private.h"
|
||||
|
||||
static const char *addr_code_name_entries[] = {
|
||||
"country",
|
||||
"A1",
|
||||
"A2",
|
||||
"A3",
|
||||
"A4",
|
||||
"A5",
|
||||
"A6",
|
||||
"ADDCODE",
|
||||
"BLD",
|
||||
"FLR",
|
||||
"HNO",
|
||||
"HNS",
|
||||
"LMK",
|
||||
"LOC",
|
||||
"NAM",
|
||||
"PC",
|
||||
"PCN",
|
||||
"PLC",
|
||||
"POBOX",
|
||||
"POD",
|
||||
"POM",
|
||||
"PRD",
|
||||
"PRM",
|
||||
"RD",
|
||||
"RD",
|
||||
"RDBR",
|
||||
"RDSEC",
|
||||
"RDSUBBR",
|
||||
"ROOM",
|
||||
"SEAT",
|
||||
"STS",
|
||||
"UNIT",
|
||||
};
|
||||
|
||||
static int compare_civicaddr_codes(const void *_a, const void *_b)
|
||||
{
|
||||
/* See the man page for qsort(3) for an explanation of the casts */
|
||||
int rc = strcmp(*(const char **)_a, *(const char **)_b);
|
||||
return rc;
|
||||
}
|
||||
|
||||
int ast_geoloc_civicaddr_is_code_valid(const char *code)
|
||||
{
|
||||
const char **entry = bsearch(&code, addr_code_name_entries, ARRAY_LEN(addr_code_name_entries),
|
||||
sizeof(const char *), compare_civicaddr_codes);
|
||||
return (entry != NULL);
|
||||
}
|
||||
|
||||
enum ast_geoloc_validate_result ast_geoloc_civicaddr_validate_varlist(
|
||||
const struct ast_variable *varlist, const char **result)
|
||||
{
|
||||
const struct ast_variable *var = varlist;
|
||||
for (; var; var = var->next) {
|
||||
int valid = ast_geoloc_civicaddr_is_code_valid(var->name);
|
||||
if (!valid) {
|
||||
*result = var->name;
|
||||
return AST_GEOLOC_VALIDATE_INVALID_VARNAME;
|
||||
}
|
||||
}
|
||||
return AST_GEOLOC_VALIDATE_SUCCESS;
|
||||
}
|
||||
|
||||
struct ast_xml_node *geoloc_civicaddr_list_to_xml(const struct ast_variable *resolved_location,
|
||||
const char *ref_string)
|
||||
{
|
||||
char *lang = NULL;
|
||||
char *s = NULL;
|
||||
struct ast_variable *var;
|
||||
struct ast_xml_node *ca_node;
|
||||
struct ast_xml_node *child_node;
|
||||
int rc = 0;
|
||||
SCOPE_ENTER(3, "%s", ref_string);
|
||||
|
||||
lang = (char *)ast_variable_find_in_list(resolved_location, "lang");
|
||||
if (ast_strlen_zero(lang)) {
|
||||
lang = ast_strdupa(ast_defaultlanguage);
|
||||
for (s = lang; *s; s++) {
|
||||
if (*s == '_') {
|
||||
*s = '-';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ca_node = ast_xml_new_node("civicAddress");
|
||||
if (!ca_node) {
|
||||
SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'civicAddress' XML node\n", ref_string);
|
||||
}
|
||||
rc = ast_xml_set_attribute(ca_node, "lang", lang);
|
||||
if (rc != 0) {
|
||||
ast_xml_free_node(ca_node);
|
||||
SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create 'lang' XML attribute\n", ref_string);
|
||||
}
|
||||
|
||||
for (var = (struct ast_variable *)resolved_location; var; var = var->next) {
|
||||
if (ast_strings_equal(var->name, "lang")) {
|
||||
continue;
|
||||
}
|
||||
child_node = ast_xml_new_child(ca_node, var->name);
|
||||
if (!child_node) {
|
||||
ast_xml_free_node(ca_node);
|
||||
SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create '%s' XML node\n", var->name, ref_string);
|
||||
}
|
||||
ast_xml_set_text(child_node, var->value);
|
||||
}
|
||||
|
||||
SCOPE_EXIT_RTN_VALUE(ca_node, "%s: Done\n", ref_string);
|
||||
}
|
||||
|
||||
int geoloc_civicaddr_unload(void)
|
||||
{
|
||||
return AST_MODULE_LOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int geoloc_civicaddr_load(void)
|
||||
{
|
||||
qsort(addr_code_name_entries, ARRAY_LEN(addr_code_name_entries), sizeof(const char *),
|
||||
compare_civicaddr_codes);
|
||||
|
||||
return AST_MODULE_LOAD_SUCCESS;
|
||||
}
|
||||
|
||||
int geoloc_civicaddr_reload(void)
|
||||
{
|
||||
return AST_MODULE_LOAD_SUCCESS;
|
||||
}
|
Reference in New Issue
Block a user