From 42525b0fe21736159a677520f241eeacbdc8b936 Mon Sep 17 00:00:00 2001 From: Naveen Albert <asterisk@phreaknet.org> Date: Thu, 6 Jan 2022 13:57:01 +0000 Subject: [PATCH] func_channel: Add lastcontext and lastexten. Adds the lastcontext and lastexten channel fields to allow users to access previous dialplan execution locations. ASTERISK-29840 #close Change-Id: Ib455fe300cc8e9a127686896ee2d0bd11e900307 --- doc/CHANGES-staging/channel_internal_api.txt | 4 ++++ funcs/func_channel.c | 10 ++++++++++ include/asterisk/channel.h | 2 ++ main/channel_internal_api.c | 18 ++++++++++++++++++ 4 files changed, 34 insertions(+) create mode 100644 doc/CHANGES-staging/channel_internal_api.txt diff --git a/doc/CHANGES-staging/channel_internal_api.txt b/doc/CHANGES-staging/channel_internal_api.txt new file mode 100644 index 0000000000..f40a4c70fe --- /dev/null +++ b/doc/CHANGES-staging/channel_internal_api.txt @@ -0,0 +1,4 @@ +Subject: channel_internal_api + +CHANNEL(lastcontext) and CHANNEL(lastexten) +are now available for use in the dialplan. diff --git a/funcs/func_channel.c b/funcs/func_channel.c index c6e5ec1a34..49c4b05779 100644 --- a/funcs/func_channel.c +++ b/funcs/func_channel.c @@ -234,6 +234,12 @@ <enum name="context"> <para>R/O returns the context for an outbound channel.</para> </enum> + <enum name="lastexten"> + <para>R/O returns the last unique extension for an outbound channel.</para> + </enum> + <enum name="lastcontext"> + <para>R/O returns the last unique context for an outbound channel.</para> + </enum> <enum name="channame"> <para>R/O returns the channel name for an outbound channel.</para> </enum> @@ -410,6 +416,10 @@ static int func_channel_read(struct ast_channel *chan, const char *function, locked_copy_string(chan, buf, ast_channel_exten(chan), len); else if (!strcasecmp(data, "context")) locked_copy_string(chan, buf, ast_channel_context(chan), len); + else if (!strcasecmp(data, "lastexten")) + locked_copy_string(chan, buf, ast_channel_lastexten(chan), len); + else if (!strcasecmp(data, "lastcontext")) + locked_copy_string(chan, buf, ast_channel_lastcontext(chan), len); else if (!strcasecmp(data, "userfield")) locked_copy_string(chan, buf, ast_channel_userfield(chan), len); else if (!strcasecmp(data, "channame")) diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 59d25a842e..1c56d20b17 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -4164,8 +4164,10 @@ void ast_channel_blockproc_set(struct ast_channel *chan, const char *value); const char *ast_channel_data(const struct ast_channel *chan); void ast_channel_data_set(struct ast_channel *chan, const char *value); +const char *ast_channel_lastcontext(const struct ast_channel *chan); const char *ast_channel_context(const struct ast_channel *chan); void ast_channel_context_set(struct ast_channel *chan, const char *value); +const char *ast_channel_lastexten(const struct ast_channel *chan); const char *ast_channel_exten(const struct ast_channel *chan); void ast_channel_exten_set(struct ast_channel *chan, const char *value); const char *ast_channel_macrocontext(const struct ast_channel *chan); diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index 9dd72ae0f7..131faae452 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -206,6 +206,8 @@ struct ast_channel { char context[AST_MAX_CONTEXT]; /*!< Dialplan: Current extension context */ char exten[AST_MAX_EXTENSION]; /*!< Dialplan: Current extension number */ + char lastcontext[AST_MAX_CONTEXT]; /*!< Dialplan: Previous extension context */ + char lastexten[AST_MAX_EXTENSION]; /*!< Dialplan: Previous extension number */ char macrocontext[AST_MAX_CONTEXT]; /*!< Macro: Current non-macro context. See app_macro.c */ char macroexten[AST_MAX_EXTENSION]; /*!< Macro: Current non-macro extension. See app_macro.c */ char unbridged; /*!< non-zero if the bridge core needs to re-evaluate the current @@ -345,8 +347,16 @@ const char *ast_channel_context(const struct ast_channel *chan) { return chan->context; } +const char *ast_channel_lastcontext(const struct ast_channel *chan) +{ + return chan->lastcontext; +} void ast_channel_context_set(struct ast_channel *chan, const char *value) { + if (!*chan->lastcontext || strcmp(value, chan->context)) { + /* only copy to last context when it changes, unless it's empty to begin with */ + ast_copy_string(chan->lastcontext, chan->context, sizeof(chan->lastcontext)); + } ast_copy_string(chan->context, value, sizeof(chan->context)); ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN); } @@ -354,8 +364,16 @@ const char *ast_channel_exten(const struct ast_channel *chan) { return chan->exten; } +const char *ast_channel_lastexten(const struct ast_channel *chan) +{ + return chan->lastexten; +} void ast_channel_exten_set(struct ast_channel *chan, const char *value) { + if (!*chan->lastexten || strcmp(value, chan->exten)) { + /* only copy to last exten when it changes, unless it's empty to begin with */ + ast_copy_string(chan->lastexten, chan->exten, sizeof(chan->lastexten)); + } ast_copy_string(chan->exten, value, sizeof(chan->exten)); ast_channel_snapshot_invalidate_segment(chan, AST_CHANNEL_SNAPSHOT_INVALIDATE_DIALPLAN); } -- GitLab