Skip to content

Commit 23a4a12

Browse files
InterLinked1Friendly Automation
authored and
Friendly Automation
committed
pbx: Add variable substitution API for extensions
Currently, variable substitution involving dialplan extensions is quite clunky since it entails obtaining the current dialplan location, backing it up, storing the desired variables for substitution on the channel, performing substitution, then restoring the original location. In addition to being clunky, things could also go wrong if an async goto were to occur and change the dialplan location during a substitution. Fundamentally, there's no reason it needs to be done this way, so new API is added to allow for directly passing in the dialplan location for the purposes of variable substitution so we don't need to mess with the channel information anymore. Existing API is not changed. ASTERISK-29745 #close Change-Id: I23273bf27fa0efb64a606eebf9aa8e2f41a065e4
1 parent 6a6967b commit 23a4a12

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

include/asterisk/pbx.h

+21
Original file line numberDiff line numberDiff line change
@@ -1272,6 +1272,22 @@ const char *ast_get_extension_cidmatch(struct ast_exten *e);
12721272
const char *ast_get_extension_app(struct ast_exten *e);
12731273
const char *ast_get_extension_label(struct ast_exten *e);
12741274
void *ast_get_extension_app_data(struct ast_exten *e);
1275+
1276+
/*!
1277+
* \brief Fill a string buffer with the data at a dialplan extension
1278+
*
1279+
* \param buf String buffer
1280+
* \param bufsize Size of buf
1281+
* \param c Channel
1282+
* \param context Dialplan context
1283+
* \param exten Dialplan extension
1284+
* \param priority Dialplan priority
1285+
*
1286+
* \retval -1 Failed to obtain extension data
1287+
* \retval 0 Successfully obtained extension data
1288+
*/
1289+
int ast_get_extension_data(char *buf, int bufsize, struct ast_channel *c,
1290+
const char *context, const char *exten, int priority);
12751291
/*! @} */
12761292

12771293
/*! @name Registrar info functions ... */
@@ -1395,6 +1411,11 @@ int pbx_builtin_raise_exception(struct ast_channel *chan, const char *data);
13951411
void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count);
13961412
void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count);
13971413
void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used);
1414+
1415+
/*!
1416+
* \brief Substitutes variables, similar to pbx_substitute_variables_helper_full, but allows passing the context, extension, and priority in.
1417+
*/
1418+
void pbx_substitute_variables_helper_full_location(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used, char *context, char *exten, int pri);
13981419
/*! @} */
13991420

14001421
/*! @name Substitution routines, using dynamic string buffers

main/pbx.c

+21
Original file line numberDiff line numberDiff line change
@@ -8602,6 +8602,27 @@ void *ast_get_extension_app_data(struct ast_exten *e)
86028602
return e ? e->data : NULL;
86038603
}
86048604

8605+
int ast_get_extension_data(char *buf, int bufsize, struct ast_channel *c,
8606+
const char *context, const char *exten, int priority)
8607+
{
8608+
struct ast_exten *e;
8609+
struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */
8610+
ast_rdlock_contexts();
8611+
e = pbx_find_extension(c, NULL, &q, context, exten, priority, NULL, "", E_MATCH);
8612+
if (e) {
8613+
if (buf) {
8614+
const char *tmp = ast_get_extension_app_data(e);
8615+
if (tmp) {
8616+
ast_copy_string(buf, tmp, bufsize);
8617+
}
8618+
}
8619+
ast_unlock_contexts();
8620+
return 0;
8621+
}
8622+
ast_unlock_contexts();
8623+
return -1;
8624+
}
8625+
86058626
/*
86068627
* Walking functions ...
86078628
*/

main/pbx_variables.c

+15-1
Original file line numberDiff line numberDiff line change
@@ -624,6 +624,11 @@ void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen,
624624
}
625625

626626
void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used)
627+
{
628+
pbx_substitute_variables_helper_full_location(c, headp, cp1, cp2, count, used, NULL, NULL, 0);
629+
}
630+
631+
void pbx_substitute_variables_helper_full_location(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used, char *context, char *exten, int pri)
627632
{
628633
/* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */
629634
const char *whereweare;
@@ -759,7 +764,16 @@ void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead
759764
ast_debug(2, "Function %s result is '%s'\n", vars, cp4 ? cp4 : "(null)");
760765
} else {
761766
/* Retrieve variable value */
762-
pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
767+
/* For dialplan location, if we were told what to substitute explicitly, use that instead */
768+
if (exten && !strcmp(vars, "EXTEN")) {
769+
ast_copy_string(workspace, exten, VAR_BUF_SIZE);
770+
} else if (context && !strcmp(vars, "CONTEXT")) {
771+
ast_copy_string(workspace, context, VAR_BUF_SIZE);
772+
} else if (pri && !strcmp(vars, "PRIORITY")) {
773+
snprintf(workspace, VAR_BUF_SIZE, "%d", pri);
774+
} else {
775+
pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp);
776+
}
763777
}
764778
if (cp4) {
765779
cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);

0 commit comments

Comments
 (0)