diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index 55a5b9f4c8ba0f3407d0d68bb4f71d4e4aa27c13..f5f0691869ad7a39dbb2940bdd8b5446d38f9b66 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -1272,6 +1272,22 @@ const char *ast_get_extension_cidmatch(struct ast_exten *e); const char *ast_get_extension_app(struct ast_exten *e); const char *ast_get_extension_label(struct ast_exten *e); void *ast_get_extension_app_data(struct ast_exten *e); + +/*! + * \brief Fill a string buffer with the data at a dialplan extension + * + * \param buf String buffer + * \param bufsize Size of buf + * \param c Channel + * \param context Dialplan context + * \param exten Dialplan extension + * \param priority Dialplan priority + * + * \retval -1 Failed to obtain extension data + * \retval 0 Successfully obtained extension data + */ +int ast_get_extension_data(char *buf, int bufsize, struct ast_channel *c, + const char *context, const char *exten, int priority); /*! @} */ /*! @name Registrar info functions ... */ @@ -1395,6 +1411,11 @@ int pbx_builtin_raise_exception(struct ast_channel *chan, const char *data); void pbx_substitute_variables_helper(struct ast_channel *c, const char *cp1, char *cp2, int count); void pbx_substitute_variables_varshead(struct varshead *headp, const char *cp1, char *cp2, int count); void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int cp2_size, size_t *used); + +/*! + * \brief Substitutes variables, similar to pbx_substitute_variables_helper_full, but allows passing the context, extension, and priority in. + */ +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); /*! @} */ /*! @name Substitution routines, using dynamic string buffers diff --git a/main/pbx.c b/main/pbx.c index 2ed1dd15cae7d1ed4377e463b3147d2b0cf2618b..07cf8e7567d914f70550810898faeb09f91b6220 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -8602,6 +8602,27 @@ void *ast_get_extension_app_data(struct ast_exten *e) return e ? e->data : NULL; } +int ast_get_extension_data(char *buf, int bufsize, struct ast_channel *c, + const char *context, const char *exten, int priority) +{ + struct ast_exten *e; + struct pbx_find_info q = { .stacklen = 0 }; /* the rest is set in pbx_find_context */ + ast_rdlock_contexts(); + e = pbx_find_extension(c, NULL, &q, context, exten, priority, NULL, "", E_MATCH); + if (e) { + if (buf) { + const char *tmp = ast_get_extension_app_data(e); + if (tmp) { + ast_copy_string(buf, tmp, bufsize); + } + } + ast_unlock_contexts(); + return 0; + } + ast_unlock_contexts(); + return -1; +} + /* * Walking functions ... */ diff --git a/main/pbx_variables.c b/main/pbx_variables.c index 91b5bbb2b451a0cf38cb73e97e01d72f24968b51..b6c0dd8d53b66aaf099785411a7566c71244578d 100644 --- a/main/pbx_variables.c +++ b/main/pbx_variables.c @@ -624,6 +624,11 @@ void ast_str_substitute_variables_varshead(struct ast_str **buf, ssize_t maxlen, } void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead *headp, const char *cp1, char *cp2, int count, size_t *used) +{ + pbx_substitute_variables_helper_full_location(c, headp, cp1, cp2, count, used, NULL, NULL, 0); +} + +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) { /* Substitutes variables into cp2, based on string cp1, cp2 NO LONGER NEEDS TO BE ZEROED OUT!!!! */ const char *whereweare; @@ -759,7 +764,16 @@ void pbx_substitute_variables_helper_full(struct ast_channel *c, struct varshead ast_debug(2, "Function %s result is '%s'\n", vars, cp4 ? cp4 : "(null)"); } else { /* Retrieve variable value */ - pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); + /* For dialplan location, if we were told what to substitute explicitly, use that instead */ + if (exten && !strcmp(vars, "EXTEN")) { + ast_copy_string(workspace, exten, VAR_BUF_SIZE); + } else if (context && !strcmp(vars, "CONTEXT")) { + ast_copy_string(workspace, context, VAR_BUF_SIZE); + } else if (pri && !strcmp(vars, "PRIORITY")) { + snprintf(workspace, VAR_BUF_SIZE, "%d", pri); + } else { + pbx_retrieve_variable(c, vars, &cp4, workspace, VAR_BUF_SIZE, headp); + } } if (cp4) { cp4 = substring(cp4, offset, offset2, workspace, VAR_BUF_SIZE);