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:
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; \
|
||||
|
|
Loading…
Reference in New Issue