From 45e79490babaa8775aad1de72bad503aa2eb23f1 Mon Sep 17 00:00:00 2001 From: Olle Johansson <oej@edvina.net> Date: Sat, 5 Jul 2008 20:54:30 +0000 Subject: [PATCH] Implement flags for AGI in the channel structure so taht "show channels" and AMI commands can display that a channel is under control of an AGI. Work inspired by work at customer site, but paid for by Edvina AB git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@128240 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- include/asterisk/channel.h | 6 ++++++ include/asterisk/pbx.h | 3 +++ main/cli.c | 16 +++++++++++++++- main/manager.c | 8 ++++++-- main/pbx.c | 17 +++++++++++++++-- pbx/pbx_realtime.c | 5 +++-- res/res_agi.c | 12 ++++++++++-- 7 files changed, 58 insertions(+), 9 deletions(-) diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 5923f7cc1c..b2695ca603 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -582,6 +582,12 @@ enum { /*! This flag indicates that on a masquerade, an active stream should not * be carried over */ AST_FLAG_MASQ_NOSTREAM = (1 << 16), + /*! If the flag is controlled by AGI (not FastAGI) */ + AST_FLAG_AGI = (1 << 17), + /*! If the flag is controlled by FastAGI */ + AST_FLAG_FASTAGI = (1 << 18), + /*! If the flag is controlled by AsyncAGI */ + AST_FLAG_ASYNCAGI = (1 << 19), }; /*! \brief ast_bridge_config flags */ diff --git a/include/asterisk/pbx.h b/include/asterisk/pbx.h index b4bec238ec..bfa9d3bc96 100644 --- a/include/asterisk/pbx.h +++ b/include/asterisk/pbx.h @@ -998,6 +998,9 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan, const char *context, const char *exten, int priority, const char *label, const char *callerid, enum ext_match_t action); +/*! \brief Function in pbx.c that propably should be somewhere else, but not in res_agi, since it's a loadable module */ +const char *agi_state(struct ast_channel *chan); + /* every time a write lock is obtained for contexts, a counter is incremented. You can check this via the diff --git a/main/cli.c b/main/cli.c index 1335ec6b7c..6cbaf9a72e 100644 --- a/main/cli.c +++ b/main/cli.c @@ -628,6 +628,20 @@ static char *handle_showcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_a return RESULT_SUCCESS; } +/*! \brief Add a marker before the app if the channel is controlled by AGI/FastAGI or AsyncAGI + Used for "show channels" +*/ +static const char *agi_flag(struct ast_channel *chan) +{ + if (ast_test_flag(chan, AST_FLAG_AGI)) + return "[AGI] "; + if (ast_test_flag(chan, AST_FLAG_FASTAGI)) + return "[FAGI] "; + if (ast_test_flag(chan, AST_FLAG_ASYNCAGI)) + return "[AAGI] "; + return ""; +} + static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a) { #define FORMAT_STRING "%-20.20s %-20.20s %-7.7s %-30.30s\n" @@ -723,7 +737,7 @@ static char *handle_chanlist(struct ast_cli_entry *e, int cmd, struct ast_cli_ar if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten)) snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority); if (c->appl) - snprintf(appdata, sizeof(appdata), "%s(%s)", c->appl, S_OR(c->data, "")); + snprintf(appdata, sizeof(appdata), "%s%s(%s)", agi_flag(c), c->appl, S_OR(c->data, "")); ast_cli(fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata); } } diff --git a/main/manager.c b/main/manager.c index 15fbbc841f..fa92408178 100644 --- a/main/manager.c +++ b/main/manager.c @@ -2718,9 +2718,13 @@ static int action_coreshowchannels(struct mansession *s, const struct message *m "AccountCode: %s\r\n" "BridgedChannel: %s\r\n" "BridgedUniqueID: %s\r\n" - "\r\n", c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), + "AGIstate: %s\r\n" + "\r\n", + c->name, c->uniqueid, c->context, c->exten, c->priority, c->_state, ast_state2str(c->_state), c->appl ? c->appl : "", c->data ? S_OR(c->data, ""): "", - S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : ""); + S_OR(c->cid.cid_num, ""), durbuf, S_OR(c->accountcode, ""), bc ? bc->name : "", bc ? bc->uniqueid : "", + agi_state(c) + ); ast_channel_unlock(c); numchans++; } diff --git a/main/pbx.c b/main/pbx.c index 4bffe8665b..dfd4f5f0b9 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -2901,6 +2901,18 @@ static void pbx_substitute_variables(char *passdata, int datalen, struct ast_cha pbx_substitute_variables_helper(c, e->data, passdata, datalen - 1); } +/*! \brief report AGI state for channel */ +const char *agi_state(struct ast_channel *chan) +{ + if (ast_test_flag(chan, AST_FLAG_AGI)) + return "AGI"; + if (ast_test_flag(chan, AST_FLAG_FASTAGI)) + return "FASTAGI"; + if (ast_test_flag(chan, AST_FLAG_ASYNCAGI)) + return "ASYNCAGI"; + return ""; +} + /*! * \brief The return value depends on the action: * @@ -2981,8 +2993,9 @@ static int pbx_extension_helper(struct ast_channel *c, struct ast_context *con, "Priority: %d\r\n" "Application: %s\r\n" "AppData: %s\r\n" - "Uniqueid: %s\r\n", - c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid); + "Uniqueid: %s\r\n" + "AGIstate: %s\r\n", + c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid, agi_state(c)); return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */ } } else if (q.swo) { /* not found here, but in another switch */ diff --git a/pbx/pbx_realtime.c b/pbx/pbx_realtime.c index 536ed9d27e..2b7a0dd7f7 100644 --- a/pbx/pbx_realtime.c +++ b/pbx/pbx_realtime.c @@ -226,8 +226,9 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch "Priority: %d\r\n" "Application: %s\r\n" "AppData: %s\r\n" - "Uniqueid: %s\r\n", - chan->name, chan->context, chan->exten, chan->priority, app, !ast_strlen_zero(appdata) ? appdata : "(NULL)", chan->uniqueid); + "Uniqueid: %s\r\n" + "AGIstate: %s\r\n", + chan->name, chan->context, chan->exten, chan->priority, app, !ast_strlen_zero(appdata) ? appdata : "(NULL)", chan->uniqueid, agi_state(chan)); res = pbx_exec(chan, a, appdata); } else diff --git a/res/res_agi.c b/res/res_agi.c index b509ef67d7..521e47fcfc 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -204,7 +204,7 @@ static struct agi_cmd *get_agi_cmd(struct ast_channel *chan) return cmd; } -/* channel is locked when calling this one either from the CLI or manager thread */ +/*! \brief channel is locked when calling this one either from the CLI or manager thread */ static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id) { struct ast_datastore *store; @@ -424,6 +424,8 @@ static enum agi_result launch_asyncagi(struct ast_channel *chan, char *argv[], i returnstatus = AGI_RESULT_FAILURE; goto quit; } + ast_set_flag(chan, AST_FLAG_ASYNCAGI); + agi_buffer[res] = '\0'; /* encode it and send it thru the manager so whoever is going to take care of AGI commands on this channel can decide which AGI commands @@ -606,8 +608,10 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, cha int pid, toast[2], fromast[2], audio[2], res; struct stat st; - if (!strncasecmp(script, "agi://", 6)) + if (!strncasecmp(script, "agi://", 6)) { + ast_set_flag(chan, AST_FLAG_FASTAGI); return launch_netscript(script, argv, fds, efd, opid); + } if (!strncasecmp(script, "agi:async", sizeof("agi:async")-1)) return launch_asyncagi(chan, argv, efd); @@ -711,6 +715,7 @@ static enum agi_result launch_script(struct ast_channel *chan, char *script, cha close(audio[0]); *opid = pid; + ast_set_flag(chan, AST_FLAG_AGI); return AGI_RESULT_SUCCESS; } @@ -2919,6 +2924,9 @@ static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int close(efd); } ast_safe_fork_cleanup(); + ast_clear_flag(chan, AST_FLAG_AGI); + ast_clear_flag(chan, AST_FLAG_FASTAGI); + ast_clear_flag(chan, AST_FLAG_ASYNCAGI); switch (res) { case AGI_RESULT_SUCCESS: -- GitLab