From: Richard Mudgett Date: Wed, 12 Mar 2014 19:05:27 +0000 (+0000) Subject: res_musiconhold.c: Generate MOH start/stop events whenever the MOH stream is started... X-Git-Tag: 12.2.0-rc1~63 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2ac75e4bd927d64033904a8f13ba26864ade396;p=thirdparty%2Fasterisk.git res_musiconhold.c: Generate MOH start/stop events whenever the MOH stream is started/stopped. * Made res_musiconhold.c always post the MusicOnHoldStart/MusicOnHoldStop events when it actually starts/stops the music streams. This allows the events to always happen when MOH starts/stops. The event posting code was moved to the MOH alloc/release routines. * Made channel_do_masquerade() stop any MOH on the original channel before masquerading so the original channel will get a stop event with correct information. * Cleaned up a couple odd codings in moh_files_alloc() and moh_alloc() dealing with the music state variable. (issue ASTERISK-23311) Reported by: Benjamin Keith Ford Review: https://reviewboard.asterisk.org/r/3306/ git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/12@410493 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/main/channel.c b/main/channel.c index 0252bd8b7f..6145e35057 100644 --- a/main/channel.c +++ b/main/channel.c @@ -6404,6 +6404,10 @@ static void channel_do_masquerade(struct ast_channel *original, struct ast_chann ao2_unlink(channels, clonechan); moh_is_playing = ast_test_flag(ast_channel_flags(original), AST_FLAG_MOH); + if (moh_is_playing) { + /* Stop MOH on the old original channel. */ + ast_moh_stop(original); + } /* * Stop any visible indication on the original channel so we can @@ -6704,9 +6708,12 @@ static void channel_do_masquerade(struct ast_channel *original, struct ast_chann } } - /* if moh is playing on the original channel then it needs to be - maintained on the channel that is replacing it. */ + /* + * If MOH was playing on the original channel then it needs to be + * maintained on the channel that is replacing it. + */ if (moh_is_playing) { + /* Start MOH on the new original channel. */ ast_moh_start(original, NULL, NULL); } diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index b1237d1a14..a94c4c4b7a 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -264,6 +264,42 @@ static struct mohclass *_mohclass_unref(struct mohclass *class, const char *tag, } #endif +static void moh_post_start(struct ast_channel *chan, const char *moh_class_name) +{ + struct stasis_message *message; + struct ast_json *json_object; + + ast_verb(3, "Started music on hold, class '%s', on channel '%s'\n", + moh_class_name, ast_channel_name(chan)); + + json_object = ast_json_pack("{s: s}", "class", moh_class_name); + if (!json_object) { + return; + } + + message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), + ast_channel_moh_start_type(), json_object); + if (message) { + stasis_publish(ast_channel_topic(chan), message); + } + ao2_cleanup(message); + ast_json_unref(json_object); +} + +static void moh_post_stop(struct ast_channel *chan) +{ + struct stasis_message *message; + + ast_verb(3, "Stopped music on hold on %s\n", ast_channel_name(chan)); + + message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), + ast_channel_moh_stop_type(), NULL); + if (message) { + stasis_publish(ast_channel_topic(chan), message); + } + ao2_cleanup(message); +} + static void moh_files_release(struct ast_channel *chan, void *data) { struct moh_files_state *state; @@ -278,8 +314,8 @@ static void moh_files_release(struct ast_channel *chan, void *data) ast_closestream(ast_channel_stream(chan)); ast_channel_stream_set(chan, NULL); } - - ast_verb(3, "Stopped music on hold on %s\n", ast_channel_name(chan)); + + moh_post_stop(chan); ast_format_clear(&state->mohwfmt); /* make sure to clear this format before restoring the original format. */ if (state->origwfmt.id && ast_set_write_format(chan, &state->origwfmt)) { @@ -451,11 +487,11 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params) struct moh_files_state *state; struct mohclass *class = params; - if (!ast_channel_music_state(chan) && (state = ast_calloc(1, sizeof(*state)))) { + state = ast_channel_music_state(chan); + if (!state && (state = ast_calloc(1, sizeof(*state)))) { ast_channel_music_state_set(chan, state); ast_module_ref(ast_module_info->self); } else { - state = ast_channel_music_state(chan); if (!state) { return NULL; } @@ -485,9 +521,9 @@ static void *moh_files_alloc(struct ast_channel *chan, void *params) ast_copy_string(state->name, class->name, sizeof(state->name)); state->save_total = class->total_files; - ast_verb(3, "Started music on hold, class '%s', on %s\n", class->name, ast_channel_name(chan)); - - return ast_channel_music_state(chan); + moh_post_start(chan, class->name); + + return state; } static int moh_digit_match(void *obj, void *arg, int flags) @@ -518,8 +554,7 @@ static void moh_handle_digit(struct ast_channel *chan, char digit) } } -static struct ast_generator moh_file_stream = -{ +static struct ast_generator moh_file_stream = { .alloc = moh_files_alloc, .release = moh_files_release, .generate = moh_files_generator, @@ -977,7 +1012,7 @@ static void moh_release(struct ast_channel *chan, void *data) ast_channel_name(chan), ast_getformatname(&oldwfmt)); } - ast_verb(3, "Stopped music on hold on %s\n", ast_channel_name(chan)); + moh_post_stop(chan); } } @@ -988,11 +1023,11 @@ static void *moh_alloc(struct ast_channel *chan, void *params) struct moh_files_state *state; /* Initiating music_state for current channel. Channel should know name of moh class */ - if (!ast_channel_music_state(chan) && (state = ast_calloc(1, sizeof(*state)))) { + state = ast_channel_music_state(chan); + if (!state && (state = ast_calloc(1, sizeof(*state)))) { ast_channel_music_state_set(chan, state); ast_module_ref(ast_module_info->self); } else { - state = ast_channel_music_state(chan); if (!state) { return NULL; } @@ -1011,8 +1046,8 @@ static void *moh_alloc(struct ast_channel *chan, void *params) res = NULL; } else { state->class = mohclass_ref(class, "Placing reference into state container"); + moh_post_start(chan, class->name); } - ast_verb(3, "Started music on hold, class '%s', on channel '%s'\n", class->name, ast_channel_name(chan)); } return res; } @@ -1380,8 +1415,6 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con struct mohclass *mohclass = NULL; struct moh_files_state *state = ast_channel_music_state(chan); struct ast_variable *var = NULL; - struct stasis_message *message; - struct ast_json *json_object; int res; int realtime_possible = ast_check_realtime("musiconhold"); @@ -1570,30 +1603,15 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con } } - ast_channel_latest_musicclass_set(chan, mohclass->name); - ast_set_flag(ast_channel_flags(chan), AST_FLAG_MOH); - if (mohclass->total_files) { res = ast_activate_generator(chan, &moh_file_stream, mohclass); } else { res = ast_activate_generator(chan, &mohgen, mohclass); } - - json_object = ast_json_pack("{s: s}", - "class", mohclass->name); - if (!json_object) { - mohclass = mohclass_unref(mohclass, "unreffing local reference to mohclass in local_ast_moh_start"); - return -1; - } - - message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), - ast_channel_moh_start_type(), - json_object); - if (message) { - stasis_publish(ast_channel_topic(chan), message); + if (!res) { + ast_channel_latest_musicclass_set(chan, mohclass->name); + ast_set_flag(ast_channel_flags(chan), AST_FLAG_MOH); } - ao2_cleanup(message); - ast_json_unref(json_object); mohclass = mohclass_unref(mohclass, "unreffing local reference to mohclass in local_ast_moh_start"); @@ -1602,8 +1620,6 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con static void local_ast_moh_stop(struct ast_channel *chan) { - struct stasis_message *message; - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_MOH); ast_deactivate_generator(chan); @@ -1614,13 +1630,7 @@ static void local_ast_moh_stop(struct ast_channel *chan) ast_channel_stream_set(chan, NULL); } } - - message = ast_channel_blob_create_from_cache(ast_channel_uniqueid(chan), ast_channel_moh_stop_type(), NULL); - if (message) { - stasis_publish(ast_channel_topic(chan), message); - } ast_channel_unlock(chan); - ao2_cleanup(message); } static void moh_class_destructor(void *obj)