mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +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