mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-19 11:42:27 +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
parent
08907bf6d8
commit
81ede203b6
@@ -170,8 +170,9 @@ location_source = sip1.myserver.net
|
|||||||
Defines the object type.
|
Defines the object type.
|
||||||
type = profile
|
type = profile
|
||||||
|
|
||||||
-- profile_precedence (optional) ------------------------------------------
|
-- profile_precedence (optional) --------------------------------------
|
||||||
Sets how to reconcile incoming and configured profiles.
|
Sets how to reconcile incoming and configured profiles.
|
||||||
|
|
||||||
profile_precedence = < prefer_incoming | prefer_config | discard_incoming
|
profile_precedence = < prefer_incoming | prefer_config | discard_incoming
|
||||||
| discard_config >
|
| discard_config >
|
||||||
|
|
||||||
@@ -202,7 +203,9 @@ profile_precedence = prefer_config
|
|||||||
|
|
||||||
-- pidf_element (optional) --------------------------------------------
|
-- pidf_element (optional) --------------------------------------------
|
||||||
PIDF-LO element in which to place the location description.
|
PIDF-LO element in which to place the location description.
|
||||||
|
|
||||||
pidf_element = < tuple | device | person >
|
pidf_element = < tuple | device | person >
|
||||||
|
Default: device
|
||||||
|
|
||||||
If the format is civicAddress or GML, this sets the PIDF element into
|
If the format is civicAddress or GML, this sets the PIDF element into
|
||||||
which the location information will be placed.
|
which the location information will be placed.
|
||||||
@@ -217,10 +220,12 @@ Per [RFC5491], "device" is preferred and therefore the default.
|
|||||||
Example:
|
Example:
|
||||||
pidf_element = tuple
|
pidf_element = tuple
|
||||||
|
|
||||||
-- allow_routing_use (optional) -------------------------------------
|
-- allow_routing_use (optional) ---------------------------------------
|
||||||
Sets whether the "Geolocation-Routing" header is added to outgoing
|
Sets whether the "Geolocation-Routing" header is added to outgoing
|
||||||
requests.
|
requests.
|
||||||
|
|
||||||
allow_routing_use = < yes | no >
|
allow_routing_use = < yes | no >
|
||||||
|
Default: no
|
||||||
|
|
||||||
Set to "yes" to indicate that servers later in the path
|
Set to "yes" to indicate that servers later in the path
|
||||||
can use the location information for routing purposes. Set to "no"
|
can use the location information for routing purposes. Set to "no"
|
||||||
@@ -253,7 +258,7 @@ floor and room just for this profile
|
|||||||
Example:
|
Example:
|
||||||
location_info_refinement = floor=20, room=20a2
|
location_info_refinement = floor=20, room=20a2
|
||||||
|
|
||||||
-- location_variables -------------------------------------------------
|
-- location_variables (optional) --------------------------------------
|
||||||
|
|
||||||
If the referenced Location object uses any replacement variables, they
|
If the referenced Location object uses any replacement variables, they
|
||||||
can be assigned here. There is no need to define variables that come
|
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
|
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 ----------------------------------------------------
|
-- Profile Example ----------------------------------------------------
|
||||||
|
|
||||||
[myprofile]
|
[myprofile]
|
||||||
|
@@ -29,3 +29,7 @@ Added 4 built-in profiles:
|
|||||||
"<discard_incoming>"
|
"<discard_incoming>"
|
||||||
The profiles are empty except for having their precedence
|
The profiles are empty except for having their precedence
|
||||||
set.
|
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_refinement;
|
||||||
struct ast_variable *location_variables;
|
struct ast_variable *location_variables;
|
||||||
struct ast_variable *usage_rules;
|
struct ast_variable *usage_rules;
|
||||||
|
int suppress_empty_ca_elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct ast_geoloc_eprofile {
|
struct ast_geoloc_eprofile {
|
||||||
@@ -102,6 +103,7 @@ struct ast_geoloc_eprofile {
|
|||||||
struct ast_variable *effective_location;
|
struct ast_variable *effective_location;
|
||||||
struct ast_variable *usage_rules;
|
struct ast_variable *usage_rules;
|
||||||
struct ast_variable *confidence;
|
struct ast_variable *confidence;
|
||||||
|
int suppress_empty_ca_elements;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
@@ -13,6 +13,7 @@
|
|||||||
|
|
||||||
<xsl:output method="xml" indent="yes"/>
|
<xsl:output method="xml" indent="yes"/>
|
||||||
<xsl:strip-space elements="*"/>
|
<xsl:strip-space elements="*"/>
|
||||||
|
<xsl:param name="suppress_empty_ca_elements" select="false()"/>
|
||||||
|
|
||||||
<!-- REMINDER: The "match" and "select" xpaths refer to the input document,
|
<!-- REMINDER: The "match" and "select" xpaths refer to the input document,
|
||||||
not the output document -->
|
not the output document -->
|
||||||
@@ -80,9 +81,11 @@
|
|||||||
each element, adding the "ca" namespace -->
|
each element, adding the "ca" namespace -->
|
||||||
|
|
||||||
<xsl:template match="civicAddress/*">
|
<xsl:template match="civicAddress/*">
|
||||||
<xsl:element name="ca:{name()}">
|
<xsl:if test="not($suppress_empty_ca_elements) or boolean(node())">
|
||||||
<xsl:value-of select="."/>
|
<xsl:element name="ca:{name()}">
|
||||||
</xsl:element>
|
<xsl:value-of select="."/>
|
||||||
|
</xsl:element>
|
||||||
|
</xsl:if>
|
||||||
</xsl:template>
|
</xsl:template>
|
||||||
|
|
||||||
<xsl:template match="location-info/civicAddress">
|
<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);
|
iter = ao2_iterator_init(sorted_container, AO2_ITERATOR_UNLINK);
|
||||||
for (; (profile = ao2_iterator_next(&iter)); ) {
|
for (; (profile = ao2_iterator_next(&iter)); ) {
|
||||||
char *action = NULL;
|
|
||||||
struct ast_str *loc_str = NULL;
|
struct ast_str *loc_str = NULL;
|
||||||
struct ast_str *refinement_str = NULL;
|
struct ast_str *refinement_str = NULL;
|
||||||
struct ast_str *variables_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);
|
variables_str = ast_variable_list_join(eprofile->location_variables, ",", "=", "\"", NULL);
|
||||||
usage_rules_str = ast_variable_list_join(eprofile->usage_rules, ",", "=", "\"", NULL);
|
usage_rules_str = ast_variable_list_join(eprofile->usage_rules, ",", "=", "\"", NULL);
|
||||||
|
|
||||||
precedence_to_str(eprofile, NULL, &action);
|
|
||||||
|
|
||||||
ast_cli(a->fd,
|
ast_cli(a->fd,
|
||||||
"id: %-s\n"
|
"id: %-s\n"
|
||||||
"profile_disposition: %-s\n"
|
"profile_precedence: %-s\n"
|
||||||
"pidf_element: %-s\n"
|
"pidf_element: %-s\n"
|
||||||
"location_reference: %-s\n"
|
"location_reference: %-s\n"
|
||||||
"Location_format: %-s\n"
|
"Location_format: %-s\n"
|
||||||
"location_details: %-s\n"
|
"location_details: %-s\n"
|
||||||
"location_method: %-s\n"
|
"location_method: %-s\n"
|
||||||
"location_refinement: %-s\n"
|
"location_refinement: %-s\n"
|
||||||
"location_variables: %-s\n"
|
"location_variables: %-s\n"
|
||||||
"allow_routing_use: %-s\n"
|
"allow_routing_use: %-s\n"
|
||||||
"effective_location: %-s\n"
|
"suppress_empty_elements: %-s\n"
|
||||||
"usage_rules: %-s\n"
|
"effective_location: %-s\n"
|
||||||
"notes: %-s\n",
|
"usage_rules: %-s\n"
|
||||||
|
"notes: %-s\n",
|
||||||
eprofile->id,
|
eprofile->id,
|
||||||
action,
|
precedence_names[eprofile->precedence],
|
||||||
pidf_element_names[eprofile->pidf_element],
|
pidf_element_names[eprofile->pidf_element],
|
||||||
S_OR(eprofile->location_reference, "<none>"),
|
S_OR(eprofile->location_reference, "<none>"),
|
||||||
format_names[eprofile->format],
|
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_OR(eprofile->method, "<none>"),
|
||||||
S_COR(refinement_str, ast_str_buffer(refinement_str), "<none>"),
|
S_COR(refinement_str, ast_str_buffer(refinement_str), "<none>"),
|
||||||
S_COR(variables_str, ast_str_buffer(variables_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(resolved_str, ast_str_buffer(resolved_str), "<none>"),
|
||||||
S_COR(usage_rules_str, ast_str_buffer(usage_rules_str), "<none>"),
|
S_COR(usage_rules_str, ast_str_buffer(usage_rules_str), "<none>"),
|
||||||
S_OR(eprofile->notes, "<none>")
|
S_OR(eprofile->notes, "<none>")
|
||||||
);
|
);
|
||||||
ao2_ref(eprofile, -1);
|
ao2_ref(eprofile, -1);
|
||||||
|
|
||||||
ast_free(action);
|
|
||||||
ast_free(loc_str);
|
ast_free(loc_str);
|
||||||
ast_free(refinement_str);
|
ast_free(refinement_str);
|
||||||
ast_free(variables_str);
|
ast_free(variables_str);
|
||||||
@@ -695,6 +693,8 @@ int geoloc_config_load(void)
|
|||||||
0, STRFLDSET(struct ast_geoloc_profile, notes));
|
0, STRFLDSET(struct ast_geoloc_profile, notes));
|
||||||
ast_sorcery_object_field_register(geoloc_sorcery, "profile", "allow_routing_use",
|
ast_sorcery_object_field_register(geoloc_sorcery, "profile", "allow_routing_use",
|
||||||
"no", OPT_BOOL_T, 1, FLDSET(struct ast_geoloc_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);
|
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);
|
ast_str_append(buf, len, "%s", eprofile->method);
|
||||||
} else if (ast_strings_equal(args.field, "allow_routing_use")) {
|
} else if (ast_strings_equal(args.field, "allow_routing_use")) {
|
||||||
ast_str_append(buf, len, "%s", eprofile->allow_routing_use ? "yes" : "no");
|
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")) {
|
} else if (ast_strings_equal(args.field, "profile_precedence")) {
|
||||||
ast_str_append(buf, len, "%s", ast_geoloc_precedence_to_name(eprofile->precedence));
|
ast_str_append(buf, len, "%s", ast_geoloc_precedence_to_name(eprofile->precedence));
|
||||||
} else if (ast_strings_equal(args.field, "format")) {
|
} 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);
|
ast_string_field_set(eprofile, location_reference, value);
|
||||||
} else if (ast_strings_equal(args.field, "method")) {
|
} else if (ast_strings_equal(args.field, "method")) {
|
||||||
ast_string_field_set(eprofile, method, value);
|
ast_string_field_set(eprofile, method, value);
|
||||||
|
|
||||||
} else if (ast_strings_equal(args.field, "allow_routing_use")) {
|
} else if (ast_strings_equal(args.field, "allow_routing_use")) {
|
||||||
eprofile->allow_routing_use = ast_true(value);
|
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")) {
|
} else if (ast_strings_equal(args.field, "profile_precedence")) {
|
||||||
TEST_ENUM_VALUE(chan_name, eprofile, precedence, value);
|
TEST_ENUM_VALUE(chan_name, eprofile, precedence, value);
|
||||||
|
|
||||||
} else if (ast_strings_equal(args.field, "format")) {
|
} else if (ast_strings_equal(args.field, "format")) {
|
||||||
TEST_ENUM_VALUE(chan_name, eprofile, format, value);
|
TEST_ENUM_VALUE(chan_name, eprofile, format, value);
|
||||||
|
|
||||||
} else if (ast_strings_equal(args.field, "pidf_element")) {
|
} else if (ast_strings_equal(args.field, "pidf_element")) {
|
||||||
TEST_ENUM_VALUE(chan_name, eprofile, pidf_element, value);
|
TEST_ENUM_VALUE(chan_name, eprofile, pidf_element, value);
|
||||||
|
|
||||||
} else if (ast_strings_equal(args.field, "location_info")) {
|
} else if (ast_strings_equal(args.field, "location_info")) {
|
||||||
TEST_VARLIST(chan_name, eprofile, location_info, value);
|
TEST_VARLIST(chan_name, eprofile, location_info, value);
|
||||||
} else if (ast_strings_equal(args.field, "location_source")) {
|
} else if (ast_strings_equal(args.field, "location_source")) {
|
||||||
|
@@ -175,6 +175,10 @@
|
|||||||
<configOption name="allow_routing_use">
|
<configOption name="allow_routing_use">
|
||||||
<synopsis>Sets the value of the Geolocation-Routing header.</synopsis>
|
<synopsis>Sets the value of the Geolocation-Routing header.</synopsis>
|
||||||
</configOption>
|
</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">
|
<configOption name="profile_precedence" default="discard_incoming">
|
||||||
<synopsis>Determine which profile on a channel should be used</synopsis>
|
<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);
|
ao2_lock(profile);
|
||||||
eprofile->allow_routing_use = profile->allow_routing_use;
|
eprofile->allow_routing_use = profile->allow_routing_use;
|
||||||
eprofile->pidf_element = profile->pidf_element;
|
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);
|
rc = ast_string_field_set(eprofile, location_reference, profile->location_reference);
|
||||||
if (rc == 0) {
|
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;
|
struct ast_xml_node *temp_node = NULL;
|
||||||
const char *entity = NULL;
|
const char *entity = NULL;
|
||||||
int has_no_entity = 0;
|
int has_no_entity = 0;
|
||||||
|
const char *params[] = { "suppress_empty_ca_elements", "false()", NULL };
|
||||||
|
|
||||||
SCOPE_ENTER(3, "%s\n", ref_string);
|
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;
|
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) {
|
if (!pidf_doc) {
|
||||||
SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate doc\n",
|
SCOPE_EXIT_LOG_RTN_VALUE(NULL, LOG_ERROR, "%s: Unable to create final PIDF-LO doc from intermediate doc\n",
|
||||||
ref_string);
|
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))) { \
|
while ((item = ast_strsep(&item_string, ',', AST_STRSEP_ALL))) { \
|
||||||
item_name = ast_strsep(&item, '=', AST_STRSEP_ALL); \
|
item_name = ast_strsep(&item, '=', AST_STRSEP_ALL); \
|
||||||
item_value = 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) { \
|
if (!new_var) { \
|
||||||
rc = -1; \
|
rc = -1; \
|
||||||
break; \
|
break; \
|
||||||
|
Reference in New Issue
Block a user