Adding a new option 'n' to app_chanspy. This option allows for the name of the spied-on

party to be spoken instead of the channel name or number.

This was accomplished by adding a new function pointer to point to a function in app_voicemail
which retrieves the name file and plays it. This makes for an easy way that applications may play
a user's name should it be necessary. app_directory, in particular, can be simplified greatly by
this change.

This change comes as a suggestion from Switchvox, which already has this feature. AST-23


git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@114813 65c4cc65-6c06-0410-ace0-fbb531ad65f3
This commit is contained in:
Mark Michelson
2008-04-28 22:38:07 +00:00
parent eff8f552b6
commit 3aad03e5f0
5 changed files with 165 additions and 70 deletions

View File

@@ -69,32 +69,39 @@ static const char *desc_chan =
" exit to it. This also disables choosing a channel based on 'chanprefix'\n"
" and a digit sequence.\n"
" Options:\n"
" b - Only spy on channels involved in a bridged call.\n"
" g(grp) - Match only channels where their SPYGROUP variable is set to\n"
" contain 'grp' in an optional : delimited list.\n"
" q - Don't play a beep when beginning to spy on a channel, or speak the\n"
" selected channel name.\n"
" r[(basename)] - Record the session to the monitor spool directory. An\n"
" optional base for the filename may be specified. The\n"
" default is 'chanspy'.\n"
" s - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
" speaking the selected channel name.\n"
" v([value]) - Adjust the initial volume in the range from -4 to 4. A\n"
" negative value refers to a quieter setting.\n"
" w - Enable 'whisper' mode, so the spying channel can talk to\n"
" the spied-on channel.\n"
" W - Enable 'private whisper' mode, so the spying channel can\n"
" talk to the spied-on channel but cannot listen to that\n"
" channel.\n"
" o - Only listen to audio coming from this channel.\n"
" X - Allow the user to exit ChanSpy to a valid single digit\n"
" numeric extension in the current context or the context\n"
" specified by the SPY_EXIT_CONTEXT channel variable. The\n"
" name of the last channel that was spied on will be stored\n"
" in the SPY_CHANNEL variable.\n"
" e(ext) - Enable 'enforced' mode, so the spying channel can\n"
" only monitor extensions whose name is in the 'ext' : \n"
" delimited list.\n"
" b - Only spy on channels involved in a bridged call.\n"
" g(grp) - Match only channels where their SPYGROUP variable is set to\n"
" contain 'grp' in an optional : delimited list.\n"
" n([mailbox][@context]) - Say the name of the person being spied on if that person has recorded\n"
" his/her name. If a context is specified, then that voicemail context will\n"
" be searched when retrieving the name, otherwise the \"default\" context\n"
" will be searched. If no mailbox is specified, then the channel name will\n"
" be used when searching for the name (i.e. if SIP/1000 is the channel being\n"
" spied on and no mailbox is specified, then \"1000\" will be used when searching\n"
" for the name).\n"
" q - Don't play a beep when beginning to spy on a channel, or speak the\n"
" selected channel name.\n"
" r[(basename)] - Record the session to the monitor spool directory. An\n"
" optional base for the filename may be specified. The\n"
" default is 'chanspy'.\n"
" s - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
" speaking the selected channel name.\n"
" v([value]) - Adjust the initial volume in the range from -4 to 4. A\n"
" negative value refers to a quieter setting.\n"
" w - Enable 'whisper' mode, so the spying channel can talk to\n"
" the spied-on channel.\n"
" W - Enable 'private whisper' mode, so the spying channel can\n"
" talk to the spied-on channel but cannot listen to that\n"
" channel.\n"
" o - Only listen to audio coming from this channel.\n"
" X - Allow the user to exit ChanSpy to a valid single digit\n"
" numeric extension in the current context or the context\n"
" specified by the SPY_EXIT_CONTEXT channel variable. The\n"
" name of the last channel that was spied on will be stored\n"
" in the SPY_CHANNEL variable.\n"
" e(ext) - Enable 'enforced' mode, so the spying channel can\n"
" only monitor extensions whose name is in the 'ext' : \n"
" delimited list.\n"
;
static const char *app_ext = "ExtenSpy";
@@ -111,29 +118,36 @@ static const char *desc_ext =
" single digit extension exists in the correct context it ChanSpy will\n"
" exit to it.\n"
" Options:\n"
" b - Only spy on channels involved in a bridged call.\n"
" g(grp) - Match only channels where their ${SPYGROUP} variable is set to\n"
" contain 'grp' in an optional : delimited list.\n"
" q - Don't play a beep when beginning to spy on a channel, or speak the\n"
" selected channel name.\n"
" r[(basename)] - Record the session to the monitor spool directory. An\n"
" optional base for the filename may be specified. The\n"
" default is 'chanspy'.\n"
" s - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
" speaking the selected channel name.\n"
" v([value]) - Adjust the initial volume in the range from -4 to 4. A\n"
" negative value refers to a quieter setting.\n"
" w - Enable 'whisper' mode, so the spying channel can talk to\n"
" the spied-on channel.\n"
" W - Enable 'private whisper' mode, so the spying channel can\n"
" talk to the spied-on channel but cannot listen to that\n"
" channel.\n"
" o - Only listen to audio coming from this channel.\n"
" X - Allow the user to exit ChanSpy to a valid single digit\n"
" numeric extension in the current context or the context\n"
" specified by the SPY_EXIT_CONTEXT channel variable. The\n"
" name of the last channel that was spied on will be stored\n"
" in the SPY_CHANNEL variable.\n"
" b - Only spy on channels involved in a bridged call.\n"
" g(grp) - Match only channels where their ${SPYGROUP} variable is set to\n"
" contain 'grp' in an optional : delimited list.\n"
" n([mailbox][@context]) - Say the name of the person being spied on if that person has recorded\n"
" his/her name. If a context is specified, then that voicemail context will\n"
" be searched when retrieving the name, otherwise the \"default\" context\n"
" will be searched. If no mailbox is specified, then the channel name will\n"
" be used when searching for the name (i.e. if SIP/1000 is the channel being\n"
" spied on and no mailbox is specified, then \"1000\" will be used when searching\n"
" for the name).\n"
" q - Don't play a beep when beginning to spy on a channel, or speak the\n"
" selected channel name.\n"
" r[(basename)] - Record the session to the monitor spool directory. An\n"
" optional base for the filename may be specified. The\n"
" default is 'chanspy'.\n"
" s - Skip the playback of the channel type (i.e. SIP, IAX, etc) when\n"
" speaking the selected channel name.\n"
" v([value]) - Adjust the initial volume in the range from -4 to 4. A\n"
" negative value refers to a quieter setting.\n"
" w - Enable 'whisper' mode, so the spying channel can talk to\n"
" the spied-on channel.\n"
" W - Enable 'private whisper' mode, so the spying channel can\n"
" talk to the spied-on channel but cannot listen to that\n"
" channel.\n"
" o - Only listen to audio coming from this channel.\n"
" X - Allow the user to exit ChanSpy to a valid single digit\n"
" numeric extension in the current context or the context\n"
" specified by the SPY_EXIT_CONTEXT channel variable. The\n"
" name of the last channel that was spied on will be stored\n"
" in the SPY_CHANNEL variable.\n"
;
enum {
@@ -149,6 +163,7 @@ enum {
OPTION_ENFORCED = (1 << 9), /* Enforced mode */
OPTION_NOTECH = (1 << 10), /* Skip technology name playback */
OPTION_BARGE = (1 << 11), /* Barge mode (whisper to both channels) */
OPTION_NAME = (1 << 12), /* Say the name of the person on whom we will spy */
} chanspy_opt_flags;
enum {
@@ -156,6 +171,7 @@ enum {
OPT_ARG_GROUP,
OPT_ARG_RECORD,
OPT_ARG_ENFORCED,
OPT_ARG_NAME,
OPT_ARG_ARRAY_SIZE,
} chanspy_opt_args;
@@ -172,6 +188,7 @@ AST_APP_OPTIONS(spy_opts, {
AST_APP_OPTION('o', OPTION_READONLY),
AST_APP_OPTION('X', OPTION_EXIT),
AST_APP_OPTION('s', OPTION_NOTECH),
AST_APP_OPTION_ARG('n', OPTION_NAME, OPT_ARG_NAME),
});
@@ -554,7 +571,8 @@ redo:
static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
int volfactor, const int fd, const char *mygroup, const char *myenforced,
const char *spec, const char *exten, const char *context)
const char *spec, const char *exten, const char *context, const char *mailbox,
const char *name_context)
{
char nameprefix[AST_NAME_STRLEN];
char peer_name[AST_NAME_STRLEN + 5];
@@ -727,6 +745,7 @@ static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
strncat(peer_name, peer->name, AST_NAME_STRLEN - 4 - 1);
ptr = strchr(peer_name, '/');
*ptr++ = '\0';
ptr = strsep(&ptr, "-");
for (s = peer_name; s < ptr; s++)
*s = tolower(*s);
@@ -737,22 +756,29 @@ static int common_exec(struct ast_channel *chan, const struct ast_flags *flags,
ast_channel_unlock(peer);
if (!ast_test_flag(flags, OPTION_QUIET)) {
if (!ast_test_flag(flags, OPTION_NOTECH)) {
if (ast_fileexists(peer_name, NULL, NULL) != -1) {
res = ast_streamfile(chan, peer_name, chan->language);
if (!res) {
res = ast_waitstream(chan, "");
}
if (res) {
chanspy_ds_free(peer_chanspy_ds);
break;
}
} else {
res = ast_say_character_str(chan, peer_name, "", chan->language);
}
if (ast_test_flag(flags, OPTION_NAME)) {
const char *local_context = S_OR(name_context, "default");
const char *local_mailbox = S_OR(mailbox, ptr);
res = ast_app_sayname(chan, local_mailbox, local_context);
}
if (!ast_test_flag(flags, OPTION_NAME) || res < 0) {
if (!ast_test_flag(flags, OPTION_NOTECH)) {
if (ast_fileexists(peer_name, NULL, NULL) != -1) {
res = ast_streamfile(chan, peer_name, chan->language);
if (!res) {
res = ast_waitstream(chan, "");
}
if (res) {
chanspy_ds_free(peer_chanspy_ds);
break;
}
} else {
res = ast_say_character_str(chan, peer_name, "", chan->language);
}
}
if ((num = atoi(ptr)))
ast_say_digits(chan, atoi(ptr), "", chan->language);
}
if ((num = atoi(ptr)))
ast_say_digits(chan, atoi(ptr), "", chan->language);
}
res = channel_spy(chan, peer_chanspy_ds, &volfactor, fd, flags, exitcontext);
@@ -815,6 +841,8 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
int oldwf = 0;
int volfactor = 0;
int res;
char *mailbox = NULL;
char *name_context = NULL;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(spec);
AST_APP_ARG(options);
@@ -850,6 +878,20 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
if (ast_test_flag(&flags, OPTION_ENFORCED))
myenforced = opts[OPT_ARG_ENFORCED];
if (ast_test_flag(&flags, OPTION_NAME)) {
if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
char *delimiter;
if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
mailbox = opts[OPT_ARG_NAME];
*delimiter++ = '\0';
name_context = delimiter;
} else {
mailbox = opts[OPT_ARG_NAME];
}
}
}
} else
ast_clear_flag(&flags, AST_FLAGS_ALL);
@@ -870,7 +912,7 @@ static int chanspy_exec(struct ast_channel *chan, void *data)
}
}
res = common_exec(chan, &flags, volfactor, fd, mygroup, myenforced, args.spec, NULL, NULL);
res = common_exec(chan, &flags, volfactor, fd, mygroup, myenforced, args.spec, NULL, NULL, mailbox, name_context);
if (fd)
close(fd);
@@ -891,6 +933,8 @@ static int extenspy_exec(struct ast_channel *chan, void *data)
int oldwf = 0;
int volfactor = 0;
int res;
char *mailbox = NULL;
char *name_context = NULL;
AST_DECLARE_APP_ARGS(args,
AST_APP_ARG(context);
AST_APP_ARG(options);
@@ -930,6 +974,21 @@ static int extenspy_exec(struct ast_channel *chan, void *data)
if (ast_test_flag(&flags, OPTION_PRIVATE))
ast_set_flag(&flags, OPTION_WHISPER);
if (ast_test_flag(&flags, OPTION_NAME)) {
if (!ast_strlen_zero(opts[OPT_ARG_NAME])) {
char *delimiter;
if ((delimiter = strchr(opts[OPT_ARG_NAME], '@'))) {
mailbox = opts[OPT_ARG_NAME];
*delimiter++ = '\0';
name_context = delimiter;
} else {
mailbox = opts[OPT_ARG_NAME];
}
}
}
} else
ast_clear_flag(&flags, AST_FLAGS_ALL);
@@ -950,7 +1009,7 @@ static int extenspy_exec(struct ast_channel *chan, void *data)
}
res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, NULL, exten, args.context);
res = common_exec(chan, &flags, volfactor, fd, mygroup, NULL, NULL, exten, args.context, mailbox, name_context);
if (fd)
close(fd);