diff options
author | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-05-22 18:52:59 +0000 |
---|---|---|
committer | russell <russell@f38db490-d61c-443f-a65b-d21fe96a405b> | 2007-05-22 18:52:59 +0000 |
commit | 1006ff5169db3009dc9393e6fcec86cc237f9d70 (patch) | |
tree | 0b80c8fbda6ded9579e3eb8fe8e9928fc7a8d1e3 /res | |
parent | d555f6d9759e1a16a092330d346c098b8a45ce23 (diff) |
Add a new feature for Music on Hold. If you set the "digit" option for a
class in musiconhold.conf, a caller on hold may press this digit to switch
to listening to that music class.
This involved adding a new callback for generators, which allow generators
to get notified of DTMF from the channel they are running on. Then, a callback
was implemented for the music on hold generators.
(patch from bbryant)
git-svn-id: http://svn.digium.com/svn/asterisk/trunk@65505 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'res')
-rw-r--r-- | res/res_musiconhold.c | 42 |
1 files changed, 40 insertions, 2 deletions
diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index 42c171c43..6b27a084b 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -36,6 +36,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include <stdlib.h> #include <errno.h> +#include <ctype.h> #include <unistd.h> #include <string.h> #include <signal.h> @@ -130,6 +131,7 @@ struct mohclass { char dir[256]; char args[256]; char mode[80]; + char digit; /*! A dynamically sized array to hold the list of filenames in "files" mode */ char **filearray; /*! The current size of the filearray */ @@ -324,11 +326,42 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params) return chan->music_state; } +/*! \note This function should be called with the mohclasses list locked */ +static struct mohclass *get_mohbydigit(char digit) +{ + struct mohclass *moh = NULL; + + AST_RWLIST_TRAVERSE(&mohclasses, moh, list) { + if (digit == moh->digit) + break; + } + + return moh; +} + +static void moh_handle_digit(struct ast_channel *chan, char digit) +{ + struct mohclass *moh; + const char *classname; + + AST_RWLIST_RDLOCK(&mohclasses); + if ((moh = get_mohbydigit(digit))) + classname = ast_strdupa(moh->name); + AST_RWLIST_UNLOCK(&mohclasses); + + if (!moh) + return; + + ast_moh_stop(chan); + ast_moh_start(chan, classname, NULL); +} + static struct ast_generator moh_file_stream = { alloc: moh_files_alloc, release: moh_files_release, generate: moh_files_generator, + digit: moh_handle_digit, }; static int spawn_mp3(struct mohclass *class) @@ -742,6 +775,7 @@ static struct ast_generator mohgen = alloc: moh_alloc, release: moh_release, generate: moh_generate, + digit: moh_handle_digit }; static int moh_add_file(struct mohclass *class, const char *filepath) @@ -996,9 +1030,9 @@ static int load_moh_classes(int reload) for (; cat; cat = ast_category_browse(cfg, cat)) { /* These names were deprecated in 1.4 and should not be used until after the next major release. */ if (strcasecmp(cat, "classes") && strcasecmp(cat, "moh_files")) { - if (!(class = moh_class_malloc())) { + if (!(class = moh_class_malloc())) break; - } + ast_copy_string(class->name, cat, sizeof(class->name)); var = ast_variable_browse(cfg, cat); while (var) { @@ -1008,6 +1042,8 @@ static int load_moh_classes(int reload) ast_copy_string(class->dir, var->value, sizeof(class->dir)); else if (!strcasecmp(var->name, "application")) ast_copy_string(class->args, var->value, sizeof(class->args)); + else if (!strcasecmp(var->name, "digit") && (isdigit(*var->value) || strchr("*#", *var->value))) + class->digit = *var->value; else if (!strcasecmp(var->name, "random")) ast_set2_flag(class, ast_true(var->value), MOH_RANDOMIZE); else if (!strcasecmp(var->name, "format")) { @@ -1143,6 +1179,8 @@ static int moh_classes_show(int fd, int argc, char *argv[]) ast_cli(fd, "Class: %s\n", class->name); ast_cli(fd, "\tMode: %s\n", S_OR(class->mode, "<none>")); ast_cli(fd, "\tDirectory: %s\n", S_OR(class->dir, "<none>")); + if (class->digit) + ast_cli(fd, "\tDigit: %c\n", class->digit); if (ast_test_flag(class, MOH_CUSTOM)) ast_cli(fd, "\tApplication: %s\n", S_OR(class->args, "<none>")); if (strcasecmp(class->mode, "files")) |