mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-04 12:12:48 +00:00
res_pjsip_config_wizard/config: Fix template processing
The config wizard was always pulling the first occurrence of a variable from an ast_variable list but this gets the template value from the list instead of any overridden value. This patch creates ast_variable_find_last_in_list() in config.c and updates res_pjsip_config_wizard to use it instead of ast_variable_find_in_list. Now the overridden values, where they exist, are used instead of template variables. Updated test_config to test the new API. ASTERISK-25089 #close Reported-by: George Joseph <george.joseph@fairview5.com> Tested-by: George Joseph <george.joseph@fairview5.com> Change-Id: Ifa7ddefc956a463923ee6839dd1ebe021c299de4
This commit is contained in:
@@ -334,6 +334,23 @@ const char *ast_variable_find(const struct ast_category *category, const char *v
|
|||||||
*/
|
*/
|
||||||
const char *ast_variable_find_in_list(const struct ast_variable *list, const char *variable);
|
const char *ast_variable_find_in_list(const struct ast_variable *list, const char *variable);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Gets the LAST occurrence of a variable from a variable list
|
||||||
|
*
|
||||||
|
* \param list The ast_variable list to search
|
||||||
|
* \param variable The name of the ast_variable you wish to fetch data for
|
||||||
|
*
|
||||||
|
* \details
|
||||||
|
* Iterates over a given ast_variable list to search for the last occurrence of an
|
||||||
|
* ast_variable entry with a name attribute matching the given name (variable).
|
||||||
|
* This is useful if the list has duplicate entries (such as in cases where entries
|
||||||
|
* are created by a template)
|
||||||
|
*
|
||||||
|
* \retval The variable value on success
|
||||||
|
* \retval NULL if unable to find it.
|
||||||
|
*/
|
||||||
|
const char *ast_variable_find_last_in_list(const struct ast_variable *list, const char *variable);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Retrieve a category if it exists
|
* \brief Retrieve a category if it exists
|
||||||
*
|
*
|
||||||
|
@@ -735,6 +735,19 @@ const char *ast_variable_find_in_list(const struct ast_variable *list, const cha
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const char *ast_variable_find_last_in_list(const struct ast_variable *list, const char *variable)
|
||||||
|
{
|
||||||
|
const struct ast_variable *v;
|
||||||
|
const char *found = NULL;
|
||||||
|
|
||||||
|
for (v = list; v; v = v->next) {
|
||||||
|
if (!strcasecmp(variable, v->name)) {
|
||||||
|
found = v->value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
static struct ast_variable *variable_clone(const struct ast_variable *old)
|
static struct ast_variable *variable_clone(const struct ast_variable *old)
|
||||||
{
|
{
|
||||||
struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
|
struct ast_variable *new = ast_variable_new(old->name, old->value, old->file);
|
||||||
|
@@ -334,10 +334,10 @@ static void *create_object(const struct ast_sorcery *sorcery,
|
|||||||
return obj;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Finds a variable in a list and tests it */
|
/*! \brief Finds the last variable in a list and tests it */
|
||||||
static int is_variable_true(struct ast_variable *vars, const char *name)
|
static int is_variable_true(struct ast_variable *vars, const char *name)
|
||||||
{
|
{
|
||||||
return ast_true(ast_variable_find_in_list(vars, name));
|
return ast_true(ast_variable_find_last_in_list(vars, name));
|
||||||
}
|
}
|
||||||
|
|
||||||
/*! \brief Appends a variable to the end of an existing list */
|
/*! \brief Appends a variable to the end of an existing list */
|
||||||
@@ -539,7 +539,7 @@ static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wiz
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (is_variable_true(wizvars, test_variable)) {
|
if (is_variable_true(wizvars, test_variable)) {
|
||||||
if (!ast_variable_find_in_list(vars, "username")) {
|
if (!ast_variable_find_last_in_list(vars, "username")) {
|
||||||
ast_log(LOG_ERROR,
|
ast_log(LOG_ERROR,
|
||||||
"Wizard '%s' must have '%s_auth/username' if it %s.\n", id, direction, test_variable);
|
"Wizard '%s' must have '%s_auth/username' if it %s.\n", id, direction, test_variable);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -557,7 +557,7 @@ static int handle_auth(const struct ast_sorcery *sorcery, struct object_type_wiz
|
|||||||
variable_list_append_return(&vars, "@pjsip_wizard", id);
|
variable_list_append_return(&vars, "@pjsip_wizard", id);
|
||||||
|
|
||||||
/* If the user set auth_type, don't override it. */
|
/* If the user set auth_type, don't override it. */
|
||||||
if (!ast_variable_find_in_list(vars, "auth_type")) {
|
if (!ast_variable_find_last_in_list(vars, "auth_type")) {
|
||||||
variable_list_append_return(&vars, "auth_type", "userpass");
|
variable_list_append_return(&vars, "auth_type", "userpass");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -599,8 +599,8 @@ static int handle_aor(const struct ast_sorcery *sorcery, struct object_type_wiza
|
|||||||
variable_list_append(&vars, "@pjsip_wizard", id);
|
variable_list_append(&vars, "@pjsip_wizard", id);
|
||||||
|
|
||||||
/* If the user explicitly specified an aor/contact, don't use remote hosts. */
|
/* If the user explicitly specified an aor/contact, don't use remote hosts. */
|
||||||
if (!ast_variable_find_in_list(vars, "contact")) {
|
if (!ast_variable_find_last_in_list(vars, "contact")) {
|
||||||
if (!(contact_pattern = ast_variable_find_in_list(wizvars, "contact_pattern"))) {
|
if (!(contact_pattern = ast_variable_find_last_in_list(wizvars, "contact_pattern"))) {
|
||||||
contact_pattern = "sip:${REMOTE_HOST}";
|
contact_pattern = "sip:${REMOTE_HOST}";
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -645,10 +645,10 @@ static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type
|
|||||||
struct ast_variable *wizvars = ast_category_first(wiz);
|
struct ast_variable *wizvars = ast_category_first(wiz);
|
||||||
struct ast_sorcery_object *obj = NULL;
|
struct ast_sorcery_object *obj = NULL;
|
||||||
const char *id = ast_category_get_name(wiz);
|
const char *id = ast_category_get_name(wiz);
|
||||||
const char *transport = ast_variable_find_in_list(wizvars, "transport");
|
const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
|
||||||
const char *hint_context = hint_context = ast_variable_find_in_list(wizvars, "hint_context");
|
const char *hint_context = hint_context = ast_variable_find_last_in_list(wizvars, "hint_context");
|
||||||
const char *hint_exten = ast_variable_find_in_list(wizvars, "hint_exten");
|
const char *hint_exten = ast_variable_find_last_in_list(wizvars, "hint_exten");
|
||||||
const char *hint_application= ast_variable_find_in_list(wizvars, "hint_application");
|
const char *hint_application= ast_variable_find_last_in_list(wizvars, "hint_application");
|
||||||
char new_id[strlen(id) + MAX_ID_SUFFIX];
|
char new_id[strlen(id) + MAX_ID_SUFFIX];
|
||||||
RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "endpoint/"), ast_variables_destroy);
|
RAII_VAR(struct ast_variable *, vars, get_object_variables(wizvars, "endpoint/"), ast_variables_destroy);
|
||||||
|
|
||||||
@@ -656,7 +656,7 @@ static int handle_endpoint(const struct ast_sorcery *sorcery, struct object_type
|
|||||||
variable_list_append_return(&vars, "aors", id);
|
variable_list_append_return(&vars, "aors", id);
|
||||||
|
|
||||||
if (ast_strlen_zero(hint_context)) {
|
if (ast_strlen_zero(hint_context)) {
|
||||||
hint_context = ast_variable_find_in_list(vars, "context");
|
hint_context = ast_variable_find_last_in_list(vars, "context");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ast_strlen_zero(hint_context)) {
|
if (ast_strlen_zero(hint_context)) {
|
||||||
@@ -737,7 +737,7 @@ static int handle_identify(const struct ast_sorcery *sorcery, struct object_type
|
|||||||
variable_list_append_return(&vars, "endpoint", id);
|
variable_list_append_return(&vars, "endpoint", id);
|
||||||
variable_list_append_return(&vars, "@pjsip_wizard", id);
|
variable_list_append_return(&vars, "@pjsip_wizard", id);
|
||||||
|
|
||||||
if (!ast_variable_find_in_list(vars, "match")) {
|
if (!ast_variable_find_last_in_list(vars, "match")) {
|
||||||
for (host_counter = 0; host_counter < host_count; host_counter++) {
|
for (host_counter = 0; host_counter < host_count; host_counter++) {
|
||||||
char *rhost = AST_VECTOR_GET(remote_hosts_vector, host_counter);
|
char *rhost = AST_VECTOR_GET(remote_hosts_vector, host_counter);
|
||||||
char host[strlen(rhost) + 1];
|
char host[strlen(rhost) + 1];
|
||||||
@@ -787,7 +787,7 @@ static int handle_phoneprov(const struct ast_sorcery *sorcery, struct object_typ
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ast_variable_find_in_list(wizvars, "phoneprov/MAC")) {
|
if (!ast_variable_find_last_in_list(wizvars, "phoneprov/MAC")) {
|
||||||
ast_log(LOG_ERROR,
|
ast_log(LOG_ERROR,
|
||||||
"Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n", id);
|
"Wizard '%s' must have 'phoneprov/MAC' if it has_phoneprov.\n", id);
|
||||||
return -1;
|
return -1;
|
||||||
@@ -834,7 +834,7 @@ static int handle_registrations(const struct ast_sorcery *sorcery, struct object
|
|||||||
const char *id = ast_category_get_name(wiz);
|
const char *id = ast_category_get_name(wiz);
|
||||||
const char *server_uri_pattern;
|
const char *server_uri_pattern;
|
||||||
const char *client_uri_pattern;
|
const char *client_uri_pattern;
|
||||||
const char *transport = ast_variable_find_in_list(wizvars, "transport");
|
const char *transport = ast_variable_find_last_in_list(wizvars, "transport");
|
||||||
const char *username;
|
const char *username;
|
||||||
char new_id[strlen(id) + MAX_ID_SUFFIX];
|
char new_id[strlen(id) + MAX_ID_SUFFIX];
|
||||||
int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
|
int host_count = AST_VECTOR_SIZE(remote_hosts_vector);
|
||||||
@@ -871,16 +871,16 @@ static int handle_registrations(const struct ast_sorcery *sorcery, struct object
|
|||||||
|
|
||||||
variable_list_append_return(&vars, "@pjsip_wizard", id);
|
variable_list_append_return(&vars, "@pjsip_wizard", id);
|
||||||
|
|
||||||
if (!(server_uri_pattern = ast_variable_find_in_list(wizvars, "server_uri_pattern"))) {
|
if (!(server_uri_pattern = ast_variable_find_last_in_list(wizvars, "server_uri_pattern"))) {
|
||||||
server_uri_pattern = "sip:${REMOTE_HOST}";
|
server_uri_pattern = "sip:${REMOTE_HOST}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!(client_uri_pattern = ast_variable_find_in_list(wizvars, "client_uri_pattern"))) {
|
if (!(client_uri_pattern = ast_variable_find_last_in_list(wizvars, "client_uri_pattern"))) {
|
||||||
client_uri_pattern = "sip:${USERNAME}@${REMOTE_HOST}";
|
client_uri_pattern = "sip:${USERNAME}@${REMOTE_HOST}";
|
||||||
}
|
}
|
||||||
|
|
||||||
if(is_variable_true(wizvars, "sends_auth")) {
|
if(is_variable_true(wizvars, "sends_auth")) {
|
||||||
username = ast_variable_find_in_list(wizvars, "outbound_auth/username");
|
username = ast_variable_find_last_in_list(wizvars, "outbound_auth/username");
|
||||||
} else {
|
} else {
|
||||||
username = id;
|
username = id;
|
||||||
}
|
}
|
||||||
@@ -958,7 +958,7 @@ static int wizard_apply_handler(const struct ast_sorcery *sorcery, struct object
|
|||||||
int rc = -1;
|
int rc = -1;
|
||||||
|
|
||||||
AST_VECTOR_INIT(&remote_hosts_vector, 16);
|
AST_VECTOR_INIT(&remote_hosts_vector, 16);
|
||||||
remote_hosts = ast_variable_find_in_list(wizvars, "remote_hosts");
|
remote_hosts = ast_variable_find_last_in_list(wizvars, "remote_hosts");
|
||||||
|
|
||||||
if (!ast_strlen_zero(remote_hosts)) {
|
if (!ast_strlen_zero(remote_hosts)) {
|
||||||
char *host;
|
char *host;
|
||||||
|
@@ -234,6 +234,7 @@ AST_TEST_DEFINE(config_basic_ops)
|
|||||||
struct ast_config *cfg = NULL;
|
struct ast_config *cfg = NULL;
|
||||||
struct ast_category *cat = NULL;
|
struct ast_category *cat = NULL;
|
||||||
struct ast_variable *var;
|
struct ast_variable *var;
|
||||||
|
struct ast_variable *varlist;
|
||||||
char temp[32];
|
char temp[32];
|
||||||
const char *cat_name;
|
const char *cat_name;
|
||||||
const char *var_value;
|
const char *var_value;
|
||||||
@@ -537,6 +538,22 @@ AST_TEST_DEFINE(config_basic_ops)
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
varlist = ast_variable_new("name1", "value1", "");
|
||||||
|
ast_variable_list_append_hint(&varlist, NULL, ast_variable_new("name1", "value2", ""));
|
||||||
|
ast_variable_list_append_hint(&varlist, NULL, ast_variable_new("name1", "value3", ""));
|
||||||
|
|
||||||
|
var_value = ast_variable_find_in_list(varlist, "name1");
|
||||||
|
if (strcmp(var_value, "value1") != 0) {
|
||||||
|
ast_test_status_update(test, "Wrong variable retrieved %s.\n", var_value);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
var_value = ast_variable_find_last_in_list(varlist, "name1");
|
||||||
|
if (strcmp(var_value, "value3") != 0) {
|
||||||
|
ast_test_status_update(test, "Wrong variable retrieved %s.\n", var_value);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
res = AST_TEST_PASS;
|
res = AST_TEST_PASS;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
Reference in New Issue
Block a user