diff --git a/CHANGES b/CHANGES index 3a491ce8e4308512c20896e08be8d0351e44afc0..7a36f96166478a9b3d0afba792c2c7339068e3c1 100644 --- a/CHANGES +++ b/CHANGES @@ -18,7 +18,7 @@ Channel Drivers chan_sip ------------------ * New 'rtpbindaddr' global setting. This allows a user to define which - ipaddress to bind the rtpengine too. For example, chan_sip might bind + ipaddress to bind the rtpengine to. For example, chan_sip might bind to eth0 (10.0.0.2) but rtpengine to eth1 (192.168.1.10). @@ -38,6 +38,9 @@ res_musiconhold ------------------ * Added sort=randstart to the sort options. It sorts the files by name and then chooses the first file to play at random. + * Added preferchannelclass=no option to prefer the application-passed class + over the channel-set musicclass. This allows separate hold-music from + application (e.g. Queue or Dial) specified music. ------------------------------------------------------------------------------ diff --git a/configs/samples/musiconhold.conf.sample b/configs/samples/musiconhold.conf.sample index 5987b36a8d69cdddc5525e8bf4c84ed572d7200b..3df29bf6973d93b3ef18d0776421470a09fdd19c 100644 --- a/configs/samples/musiconhold.conf.sample +++ b/configs/samples/musiconhold.conf.sample @@ -2,10 +2,13 @@ ; Music on Hold -- Sample Configuration ; [general] -;cachertclasses=yes ; use 1 instance of moh class for all users who are using it, - ; decrease consumable cpu cycles and memory - ; disabled by default +;cachertclasses=yes ; use 1 instance of moh class for all users who are using it, + ; decrease consumable cpu cycles and memory + ; disabled by default +;preferchannelclass=yes ; Prefer the musicclass as defined by CHANNEL(musicclass), + ; over a class set by an application (e.g. a musicclass set on a queue). + ; Defaults to yes. ; valid mode options: ; files -- read files from a directory in any Asterisk supported diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index 17b34c58e58c5a718423b362b6f683d69b9ab2da..14d4eb54782853846ddbbc393dbe011c0677a449 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -151,8 +151,9 @@ struct moh_files_state { #define MOH_RANDSTART (MOH_RANDOMIZE | MOH_SORTALPHA) /*!< Sorted but start at random position */ #define MOH_SORTMODE (3 << 3) -#define MOH_CACHERTCLASSES (1 << 5) /*!< Should we use a separate instance of MOH for each user or not */ -#define MOH_ANNOUNCEMENT (1 << 6) /*!< Do we play announcement files between songs on this channel? */ +#define MOH_CACHERTCLASSES (1 << 5) /*!< Should we use a separate instance of MOH for each user or not */ +#define MOH_ANNOUNCEMENT (1 << 6) /*!< Do we play announcement files between songs on this channel? */ +#define MOH_PREFERCHANNELCLASS (1 << 7) /*!< Should queue moh override channel moh */ /* Custom astobj2 flag */ #define MOH_NOTDELETED (1 << 30) /*!< Find only records that aren't deleted? */ @@ -1396,42 +1397,42 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con struct moh_files_state *state = ast_channel_music_state(chan); struct ast_variable *var = NULL; int res = 0; + int i; int realtime_possible = ast_check_realtime("musiconhold"); + const char *classes[] = {NULL, NULL, interpclass, "default"}; + + if (ast_test_flag(global_flags, MOH_PREFERCHANNELCLASS)) { + classes[0] = ast_channel_musicclass(chan); + classes[1] = mclass; + } else { + classes[0] = mclass; + classes[1] = ast_channel_musicclass(chan); + } /* The following is the order of preference for which class to use: * 1) The channels explicitly set musicclass, which should *only* be * set by a call to Set(CHANNEL(musicclass)=whatever) in the dialplan. + * Unless preferchannelclass in musiconhold.conf is false * 2) The mclass argument. If a channel is calling ast_moh_start() as the * result of receiving a HOLD control frame, this should be the * payload that came with the frame. - * 3) The interpclass argument. This would be from the mohinterpret + * 3) The channels explicitly set musicclass, which should *only* be + * set by a call to Set(CHANNEL(musicclass)=whatever) in the dialplan. + * 4) The interpclass argument. This would be from the mohinterpret * option from channel drivers. This is the same as the old musicclass * option. - * 4) The default class. + * 5) The default class. */ - if (!ast_strlen_zero(ast_channel_musicclass(chan))) { - mohclass = get_mohbyname(ast_channel_musicclass(chan), 1, 0); - if (!mohclass && realtime_possible) { - var = ast_load_realtime("musiconhold", "name", ast_channel_musicclass(chan), SENTINEL); - } - } - if (!mohclass && !var && !ast_strlen_zero(mclass)) { - mohclass = get_mohbyname(mclass, 1, 0); - if (!mohclass && realtime_possible) { - var = ast_load_realtime("musiconhold", "name", mclass, SENTINEL); - } - } - if (!mohclass && !var && !ast_strlen_zero(interpclass)) { - mohclass = get_mohbyname(interpclass, 1, 0); - if (!mohclass && realtime_possible) { - var = ast_load_realtime("musiconhold", "name", interpclass, SENTINEL); - } - } - if (!mohclass && !var) { - mohclass = get_mohbyname("default", 1, 0); - if (!mohclass && realtime_possible) { - var = ast_load_realtime("musiconhold", "name", "default", SENTINEL); + for (i = 0; i < ARRAY_LEN(classes); ++i) { + if (!ast_strlen_zero(classes[i])) { + mohclass = get_mohbyname(classes[i], 1, 0); + if (!mohclass && realtime_possible) { + var = ast_load_realtime("musiconhold", "name", classes[i], SENTINEL); + } + if (mohclass || var) { + break; + } } } @@ -1732,6 +1733,7 @@ static int load_moh_classes(int reload) } ast_clear_flag(global_flags, AST_FLAGS_ALL); + ast_set2_flag(global_flags, 1, MOH_PREFERCHANNELCLASS); cat = ast_category_browse(cfg, NULL); for (; cat; cat = ast_category_browse(cfg, cat)) { @@ -1740,6 +1742,8 @@ static int load_moh_classes(int reload) for (var = ast_variable_browse(cfg, cat); var; var = var->next) { if (!strcasecmp(var->name, "cachertclasses")) { ast_set2_flag(global_flags, ast_true(var->value), MOH_CACHERTCLASSES); + } else if (!strcasecmp(var->name, "preferchannelclass")) { + ast_set2_flag(global_flags, ast_true(var->value), MOH_PREFERCHANNELCLASS); } else { ast_log(LOG_WARNING, "Unknown option '%s' in [general] section of musiconhold.conf\n", var->name); }