mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 18:55:19 +00:00 
			
		
		
		
	res_geolocation: Add profile parameter suppress_empty_ca_elements
Added profile parameter "suppress_empty_ca_elements" that will cause Civic Address elements that are empty to be suppressed from the outgoing PIDF-LO document. Fixed a possible SEGV if a sub-parameter value didn't have a value. ASTERISK-30177 Change-Id: I924ccc5aa2f45110a3155b22e53dfaf3ef2092dd
This commit is contained in:
		
				
					committed by
					
						 Friendly Automation
						Friendly Automation
					
				
			
			
				
	
			
			
			
						parent
						
							2d5a6498dd
						
					
				
				
					commit
					4ffc5561c4
				
			| @@ -170,8 +170,9 @@ location_source = sip1.myserver.net | ||||
| Defines the object type. | ||||
| type = profile | ||||
|  | ||||
| -- profile_precedence (optional) ------------------------------------------ | ||||
| -- profile_precedence (optional) -------------------------------------- | ||||
| Sets how to reconcile incoming and configured profiles. | ||||
|  | ||||
| profile_precedence = < prefer_incoming | prefer_config | discard_incoming | ||||
|     | discard_config > | ||||
|  | ||||
| @@ -202,7 +203,9 @@ profile_precedence = prefer_config | ||||
|  | ||||
| -- pidf_element (optional) -------------------------------------------- | ||||
| PIDF-LO element in which to place the location description. | ||||
|  | ||||
| pidf_element = < tuple | device | person > | ||||
| Default: device | ||||
|  | ||||
| If the format is civicAddress or GML, this sets the PIDF element into | ||||
| which the location information will be placed. | ||||
| @@ -217,10 +220,12 @@ Per [RFC5491], "device" is preferred and therefore the default. | ||||
| Example: | ||||
| pidf_element = tuple | ||||
|  | ||||
| -- allow_routing_use (optional) ------------------------------------- | ||||
| -- allow_routing_use (optional) --------------------------------------- | ||||
| Sets whether the "Geolocation-Routing" header is added to outgoing | ||||
| requests. | ||||
|  | ||||
| allow_routing_use = < yes | no > | ||||
| Default: no | ||||
|  | ||||
| Set to "yes" to indicate that servers later in the path | ||||
| can use the location information for routing purposes.  Set to "no" | ||||
| @@ -253,7 +258,7 @@ floor and room just for this profile | ||||
| Example: | ||||
| location_info_refinement = floor=20, room=20a2 | ||||
|  | ||||
| -- location_variables ------------------------------------------------- | ||||
| -- location_variables (optional) -------------------------------------- | ||||
|  | ||||
| If the referenced Location object uses any replacement variables, they | ||||
| can be assigned here.  There is no need to define variables that come | ||||
| @@ -261,6 +266,26 @@ from the channel using this profile.  They get assigned automatically. | ||||
|  | ||||
| location_variables = myfloor=20, myroom=222 | ||||
|  | ||||
| -- suppress_empty_ca_elements (optional) ------------------------------ | ||||
| Sets whether empty values for Civic Address elements should be | ||||
| suppressed from the outgoing PIDF-LO document. | ||||
|  | ||||
| suppress_empty_ca_elements = < yes | no > | ||||
| Default: no | ||||
|  | ||||
| Setting to "yes" allows you to define a location info template | ||||
| with channel variables that may or may not exist. | ||||
|  | ||||
| For example, with: | ||||
| location_info_refinement = FLR=${MyFlr} | ||||
| suppress_empty_ca_elements = no ; the default | ||||
|  | ||||
| If the MyFlr channel variable weren't set, the outgoing PIDF-LO document | ||||
| would have an empty <FLR/> element in it.  If suppress_empty_ca_elements | ||||
| were set to "yes", the FLR element would be dropped from the PIDF-LO | ||||
| document altogether. | ||||
|  | ||||
|  | ||||
| -- Profile Example ---------------------------------------------------- | ||||
|  | ||||
| [myprofile] | ||||
|   | ||||
| @@ -30,3 +30,6 @@ Added 4 built-in profiles: | ||||
| The profiles are empty except for having their precedence | ||||
| set. | ||||
|  | ||||
| Added profile parameter "suppress_empty_ca_elements" that | ||||
| will cause Civic Address elements that are empty to be | ||||
| suppressed from the outgoing PIDF-LO document. | ||||
|   | ||||
| @@ -82,6 +82,7 @@ struct ast_geoloc_profile { | ||||
| 	struct ast_variable *location_refinement; | ||||
| 	struct ast_variable *location_variables; | ||||
| 	struct ast_variable *usage_rules; | ||||
| 	int suppress_empty_ca_elements; | ||||
| }; | ||||
|  | ||||
| struct ast_geoloc_eprofile { | ||||
| @@ -102,6 +103,7 @@ struct ast_geoloc_eprofile { | ||||
| 	struct ast_variable *effective_location; | ||||
| 	struct ast_variable *usage_rules; | ||||
| 	struct ast_variable *confidence; | ||||
| 	int suppress_empty_ca_elements; | ||||
| }; | ||||
|  | ||||
| /*! | ||||
|   | ||||
| @@ -13,6 +13,7 @@ | ||||
|  | ||||
| 	<xsl:output method="xml" indent="yes"/> | ||||
| 	<xsl:strip-space elements="*"/> | ||||
| 	<xsl:param name="suppress_empty_ca_elements" select="false()"/> | ||||
|  | ||||
| 	<!-- REMINDER:  The "match" and "select" xpaths refer to the input document, | ||||
| 		not the output document --> | ||||
| @@ -80,9 +81,11 @@ | ||||
| 		each element, adding the "ca" namespace --> | ||||
|  | ||||
| 	<xsl:template match="civicAddress/*"> | ||||
| 		<xsl:element name="ca:{name()}"> | ||||
| 			<xsl:value-of select="."/> | ||||
| 		</xsl:element> | ||||
| 		<xsl:if test="not($suppress_empty_ca_elements) or boolean(node())"> | ||||
| 			<xsl:element name="ca:{name()}"> | ||||
| 				<xsl:value-of select="."/> | ||||
| 			</xsl:element> | ||||
| 		</xsl:if> | ||||
| 	</xsl:template> | ||||
|  | ||||
| 	<xsl:template match="location-info/civicAddress"> | ||||
|   | ||||
| @@ -445,7 +445,6 @@ static char *geoloc_config_show_profiles(struct ast_cli_entry *e, int cmd, struc | ||||
|  | ||||
| 	iter = ao2_iterator_init(sorted_container, AO2_ITERATOR_UNLINK); | ||||
| 	for (; (profile = ao2_iterator_next(&iter)); ) { | ||||
| 		char *action = NULL; | ||||
| 		struct ast_str *loc_str = NULL; | ||||
| 		struct ast_str *refinement_str = NULL; | ||||
| 		struct ast_str *variables_str = NULL; | ||||
| @@ -463,24 +462,23 @@ static char *geoloc_config_show_profiles(struct ast_cli_entry *e, int cmd, struc | ||||
| 		variables_str = ast_variable_list_join(eprofile->location_variables, ",", "=", "\"", NULL); | ||||
| 		usage_rules_str = ast_variable_list_join(eprofile->usage_rules, ",", "=", "\"", NULL); | ||||
|  | ||||
| 		precedence_to_str(eprofile, NULL, &action); | ||||
|  | ||||
| 		ast_cli(a->fd, | ||||
| 			"id:                   %-s\n" | ||||
| 			"profile_disposition:  %-s\n" | ||||
| 			"pidf_element:         %-s\n" | ||||
| 			"location_reference:   %-s\n" | ||||
| 			"Location_format:      %-s\n" | ||||
| 			"location_details:     %-s\n" | ||||
| 			"location_method:      %-s\n" | ||||
| 			"location_refinement:  %-s\n" | ||||
| 			"location_variables:   %-s\n" | ||||
| 			"allow_routing_use:    %-s\n" | ||||
| 			"effective_location:   %-s\n" | ||||
| 			"usage_rules:          %-s\n" | ||||
| 			"notes:                %-s\n", | ||||
| 			"id:                      %-s\n" | ||||
| 			"profile_precedence:      %-s\n" | ||||
| 			"pidf_element:            %-s\n" | ||||
| 			"location_reference:      %-s\n" | ||||
| 			"Location_format:         %-s\n" | ||||
| 			"location_details:        %-s\n" | ||||
| 			"location_method:         %-s\n" | ||||
| 			"location_refinement:     %-s\n" | ||||
| 			"location_variables:      %-s\n" | ||||
| 			"allow_routing_use:       %-s\n" | ||||
| 			"suppress_empty_elements: %-s\n" | ||||
| 			"effective_location:      %-s\n" | ||||
| 			"usage_rules:             %-s\n" | ||||
| 			"notes:                   %-s\n", | ||||
| 			eprofile->id, | ||||
| 			action, | ||||
| 			precedence_names[eprofile->precedence], | ||||
| 			pidf_element_names[eprofile->pidf_element], | ||||
| 			S_OR(eprofile->location_reference, "<none>"), | ||||
| 			format_names[eprofile->format], | ||||
| @@ -488,14 +486,14 @@ static char *geoloc_config_show_profiles(struct ast_cli_entry *e, int cmd, struc | ||||
| 			S_OR(eprofile->method, "<none>"), | ||||
| 			S_COR(refinement_str, ast_str_buffer(refinement_str), "<none>"), | ||||
| 			S_COR(variables_str, ast_str_buffer(variables_str), "<none>"), | ||||
| 			S_COR(eprofile->precedence, "yes", "no"), | ||||
| 			S_COR(eprofile->allow_routing_use, "yes", "no"), | ||||
| 			S_COR(eprofile->suppress_empty_ca_elements, "yes", "no"), | ||||
| 			S_COR(resolved_str, ast_str_buffer(resolved_str), "<none>"), | ||||
| 			S_COR(usage_rules_str, ast_str_buffer(usage_rules_str), "<none>"), | ||||
| 			S_OR(eprofile->notes, "<none>") | ||||
| 			); | ||||
| 		ao2_ref(eprofile, -1); | ||||
|  | ||||
| 		ast_free(action); | ||||
| 		ast_free(loc_str); | ||||
| 		ast_free(refinement_str); | ||||
| 		ast_free(variables_str); | ||||
| @@ -695,6 +693,8 @@ int geoloc_config_load(void) | ||||
| 		0, STRFLDSET(struct ast_geoloc_profile, notes)); | ||||
| 	ast_sorcery_object_field_register(geoloc_sorcery, "profile", "allow_routing_use", | ||||
| 		"no", OPT_BOOL_T, 1, FLDSET(struct ast_geoloc_profile, allow_routing_use)); | ||||
| 	ast_sorcery_object_field_register(geoloc_sorcery, "profile", "suppress_empty_ca_elements", | ||||
| 		"no", OPT_BOOL_T, 1, FLDSET(struct ast_geoloc_profile, suppress_empty_ca_elements)); | ||||
|  | ||||
|  | ||||
| 	ast_sorcery_load(geoloc_sorcery); | ||||
|   | ||||
| @@ -88,6 +88,8 @@ static int geoloc_profile_read(struct ast_channel *chan, | ||||
| 		ast_str_append(buf, len, "%s", eprofile->method); | ||||
| 	} else if (ast_strings_equal(args.field, "allow_routing_use")) { | ||||
| 		ast_str_append(buf, len, "%s", eprofile->allow_routing_use ? "yes" : "no"); | ||||
| 	} else if (ast_strings_equal(args.field, "suppress_empty_ca_elements")) { | ||||
| 		ast_str_append(buf, len, "%s", eprofile->suppress_empty_ca_elements ? "yes" : "no"); | ||||
| 	} else if (ast_strings_equal(args.field, "profile_precedence")) { | ||||
| 		ast_str_append(buf, len, "%s", ast_geoloc_precedence_to_name(eprofile->precedence)); | ||||
| 	} else if (ast_strings_equal(args.field, "format")) { | ||||
| @@ -212,19 +214,16 @@ static int geoloc_profile_write(struct ast_channel *chan, const char *cmd, char | ||||
| 		ast_string_field_set(eprofile, location_reference, value); | ||||
| 	} else if (ast_strings_equal(args.field, "method")) { | ||||
| 		ast_string_field_set(eprofile, method, value); | ||||
|  | ||||
| 	} else if (ast_strings_equal(args.field, "allow_routing_use")) { | ||||
| 		eprofile->allow_routing_use = ast_true(value); | ||||
|  | ||||
| 	} else if (ast_strings_equal(args.field, "suppress_empty_ca_elements")) { | ||||
| 		eprofile->suppress_empty_ca_elements = ast_true(value); | ||||
| 	} else if (ast_strings_equal(args.field, "profile_precedence")) { | ||||
| 		TEST_ENUM_VALUE(chan_name, eprofile, precedence, value); | ||||
|  | ||||
| 	} else if (ast_strings_equal(args.field, "format")) { | ||||
| 		TEST_ENUM_VALUE(chan_name, eprofile, format, value); | ||||
|  | ||||
| 	} else if (ast_strings_equal(args.field, "pidf_element")) { | ||||
| 		TEST_ENUM_VALUE(chan_name, eprofile, pidf_element, value); | ||||
|  | ||||
| 	} else if (ast_strings_equal(args.field, "location_info")) { | ||||
| 		TEST_VARLIST(chan_name, eprofile, location_info, value); | ||||
| 	} else if (ast_strings_equal(args.field, "location_source")) { | ||||
|   | ||||
| @@ -175,6 +175,10 @@ | ||||
| 				<configOption name="allow_routing_use"> | ||||
| 					<synopsis>Sets the value of the Geolocation-Routing header.</synopsis> | ||||
| 				</configOption> | ||||
| 				<configOption name="suppress_empty_ca_elements"> | ||||
| 					<synopsis>Sets if empty Civic Address elements should be suppressed | ||||
| 					from the PIDF-LO document.</synopsis> | ||||
| 				</configOption> | ||||
|  | ||||
| 				<configOption name="profile_precedence" default="discard_incoming"> | ||||
| 					<synopsis>Determine which profile on a channel should be used</synopsis> | ||||
|   | ||||
| @@ -176,6 +176,7 @@ struct ast_geoloc_eprofile *ast_geoloc_eprofile_create_from_profile(struct ast_g | ||||
| 	ao2_lock(profile); | ||||
| 	eprofile->allow_routing_use = profile->allow_routing_use; | ||||
| 	eprofile->pidf_element = profile->pidf_element; | ||||
| 	eprofile->suppress_empty_ca_elements = profile->suppress_empty_ca_elements; | ||||
|  | ||||
| 	rc = ast_string_field_set(eprofile, location_reference, profile->location_reference); | ||||
| 	if (rc == 0) { | ||||
| @@ -988,6 +989,7 @@ const char *ast_geoloc_eprofile_to_pidf(struct ast_geoloc_eprofile *eprofile, | ||||
| 	struct ast_xml_node *temp_node = NULL; | ||||
| 	const char *entity = NULL; | ||||
| 	int has_no_entity = 0; | ||||
| 	const char *params[] = { "suppress_empty_ca_elements", "false()", NULL }; | ||||
|  | ||||
| 	SCOPE_ENTER(3, "%s\n", ref_string); | ||||
|  | ||||
| @@ -1038,7 +1040,10 @@ const char *ast_geoloc_eprofile_to_pidf(struct ast_geoloc_eprofile *eprofile, | ||||
| 		doc_len = 0; | ||||
| 	} | ||||
|  | ||||
| 	pidf_doc = ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, NULL); | ||||
| 	if (eprofile->suppress_empty_ca_elements) { | ||||
| 		params[1] = "true()"; | ||||
| 	} | ||||
| 	pidf_doc = ast_xslt_apply(eprofile_to_pidf_xslt, intermediate, params); | ||||
| 	if (!pidf_doc) { | ||||
| 		SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate doc\n", | ||||
| 			ref_string); | ||||
|   | ||||
| @@ -90,7 +90,7 @@ static int _stem ## _handler(const struct aco_option *opt, struct ast_variable * | ||||
| 	while ((item = ast_strsep(&item_string, ',', AST_STRSEP_ALL))) { \ | ||||
| 		item_name = ast_strsep(&item, '=', AST_STRSEP_ALL); \ | ||||
| 		item_value = ast_strsep(&item, '=', AST_STRSEP_ALL); \ | ||||
| 		new_var = ast_variable_new(item_name, item_value, ""); \ | ||||
| 		new_var = ast_variable_new(item_name, S_OR(item_value, ""), ""); \ | ||||
| 		if (!new_var) { \ | ||||
| 			rc = -1; \ | ||||
| 			break; \ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user