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
1.6.1
Olle Johansson 17 years ago
parent 0fd94cb93d
commit 45e79490ba

@ -582,6 +582,12 @@ enum {
/*! This flag indicates that on a masquerade, an active stream should not /*! This flag indicates that on a masquerade, an active stream should not
* be carried over */ * be carried over */
AST_FLAG_MASQ_NOSTREAM = (1 << 16), 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 */ /*! \brief ast_bridge_config flags */

@ -998,6 +998,9 @@ struct ast_exten *pbx_find_extension(struct ast_channel *chan,
const char *context, const char *exten, int priority, const char *context, const char *exten, int priority,
const char *label, const char *callerid, enum ext_match_t action); 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, /* every time a write lock is obtained for contexts,
a counter is incremented. You can check this via the a counter is incremented. You can check this via the

@ -628,6 +628,20 @@ static char *handle_showcalls(struct ast_cli_entry *e, int cmd, struct ast_cli_a
return RESULT_SUCCESS; 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) 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" #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)) if (!ast_strlen_zero(c->context) && !ast_strlen_zero(c->exten))
snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority); snprintf(locbuf, sizeof(locbuf), "%s@%s:%d", c->exten, c->context, c->priority);
if (c->appl) 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); ast_cli(fd, FORMAT_STRING, c->name, locbuf, ast_state2str(c->_state), appdata);
} }
} }

@ -2718,9 +2718,13 @@ static int action_coreshowchannels(struct mansession *s, const struct message *m
"AccountCode: %s\r\n" "AccountCode: %s\r\n"
"BridgedChannel: %s\r\n" "BridgedChannel: %s\r\n"
"BridgedUniqueID: %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, ""): "", 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); ast_channel_unlock(c);
numchans++; numchans++;
} }

@ -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); 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: * \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" "Priority: %d\r\n"
"Application: %s\r\n" "Application: %s\r\n"
"AppData: %s\r\n" "AppData: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n"
c->name, c->context, c->exten, c->priority, app->name, passdata, c->uniqueid); "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 */ return pbx_exec(c, app, passdata); /* 0 on success, -1 on failure */
} }
} else if (q.swo) { /* not found here, but in another switch */ } else if (q.swo) { /* not found here, but in another switch */

@ -226,8 +226,9 @@ static int realtime_exec(struct ast_channel *chan, const char *context, const ch
"Priority: %d\r\n" "Priority: %d\r\n"
"Application: %s\r\n" "Application: %s\r\n"
"AppData: %s\r\n" "AppData: %s\r\n"
"Uniqueid: %s\r\n", "Uniqueid: %s\r\n"
chan->name, chan->context, chan->exten, chan->priority, app, !ast_strlen_zero(appdata) ? appdata : "(NULL)", chan->uniqueid); "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); res = pbx_exec(chan, a, appdata);
} else } else

@ -204,7 +204,7 @@ static struct agi_cmd *get_agi_cmd(struct ast_channel *chan)
return cmd; 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) static int add_agi_cmd(struct ast_channel *chan, const char *cmd_buff, const char *cmd_id)
{ {
struct ast_datastore *store; 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; returnstatus = AGI_RESULT_FAILURE;
goto quit; goto quit;
} }
ast_set_flag(chan, AST_FLAG_ASYNCAGI);
agi_buffer[res] = '\0'; agi_buffer[res] = '\0';
/* encode it and send it thru the manager so whoever is going to take /* 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 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; int pid, toast[2], fromast[2], audio[2], res;
struct stat st; 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); return launch_netscript(script, argv, fds, efd, opid);
}
if (!strncasecmp(script, "agi:async", sizeof("agi:async")-1)) if (!strncasecmp(script, "agi:async", sizeof("agi:async")-1))
return launch_asyncagi(chan, argv, efd); 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]); close(audio[0]);
*opid = pid; *opid = pid;
ast_set_flag(chan, AST_FLAG_AGI);
return AGI_RESULT_SUCCESS; return AGI_RESULT_SUCCESS;
} }
@ -2919,6 +2924,9 @@ static int agi_exec_full(struct ast_channel *chan, void *data, int enhanced, int
close(efd); close(efd);
} }
ast_safe_fork_cleanup(); 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) { switch (res) {
case AGI_RESULT_SUCCESS: case AGI_RESULT_SUCCESS:

Loading…
Cancel
Save