diff --git a/UPGRADE.txt b/UPGRADE.txt index d92c4496c9..c4e71c04fc 100644 --- a/UPGRADE.txt +++ b/UPGRADE.txt @@ -20,6 +20,10 @@ === =========================================================== +from 11.9 to 11.10 + - The asterisk command line -I option and the asterisk.conf internal_timing + option are removed and always enabled if any timing module is loaded. + from 11.8 to 11.9 - res_fax now returns the correct rates for V.27ter (4800 or 9600 bit/s). Because of this the default settings would not load, so the minrate (minimum diff --git a/channels/chan_sip.c b/channels/chan_sip.c index 018bd2d681..de078bfac0 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -13314,8 +13314,9 @@ static enum sip_result add_sdp(struct sip_request *resp, struct sip_pvt *p, int ast_debug(3, "-- Done with adding codecs to SDP\n"); - if (!p->owner || !ast_internal_timing_enabled(p->owner)) + if (!p->owner || ast_channel_timingfd(p->owner) == -1) { ast_str_append(&a_audio, 0, "a=silenceSupp:off - - - -\r\n"); + } if (min_audio_packet_size) ast_str_append(&a_audio, 0, "a=ptime:%d\r\n", min_audio_packet_size); diff --git a/configs/asterisk.conf.sample b/configs/asterisk.conf.sample index f7cda268f3..ddedcb9ce3 100644 --- a/configs/asterisk.conf.sample +++ b/configs/asterisk.conf.sample @@ -28,7 +28,6 @@ astsbindir => /usr/sbin ;dontwarn = yes ; Disable some warnings. ;dumpcore = yes ; Dump core on crash (same as -g at startup). ;languageprefix = yes ; Use the new sound prefix path syntax. -;internal_timing = yes ;systemname = my_system_name ; Prefix uniqueid with a system name for ; Global uniqueness issues. ;autosystemname = yes ; Automatically set systemname to hostname, diff --git a/include/asterisk/options.h b/include/asterisk/options.h index 749035ada7..c922631b64 100644 --- a/include/asterisk/options.h +++ b/include/asterisk/options.h @@ -76,7 +76,7 @@ enum ast_option_flags { AST_OPT_FLAG_DONT_WARN = (1 << 18), /*! End CDRs before the 'h' extension */ AST_OPT_FLAG_END_CDR_BEFORE_H_EXTEN = (1 << 19), - /*! Use DAHDI Timing for generators if available */ + /*! Use DAHDI Timing for generators if available (No longer used) */ AST_OPT_FLAG_INTERNAL_TIMING = (1 << 20), /*! Always fork, even if verbose or debug settings are non-zero */ AST_OPT_FLAG_ALWAYS_FORK = (1 << 21), @@ -101,11 +101,7 @@ enum ast_option_flags { }; /*! These are the options that set by default when Asterisk starts */ -#if (defined(HAVE_DAHDI_VERSION) && HAVE_DAHDI_VERSION >= 230) -#define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN | AST_OPT_FLAG_INTERNAL_TIMING -#else #define AST_DEFAULT_OPTIONS AST_OPT_FLAG_TRANSCODE_VIA_SLIN -#endif #define ast_opt_exec_includes ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) #define ast_opt_no_fork ast_test_flag(&ast_options, AST_OPT_FLAG_NO_FORK) diff --git a/main/asterisk.c b/main/asterisk.c index c6c741f220..fdbcef7e73 100644 --- a/main/asterisk.c +++ b/main/asterisk.c @@ -509,7 +509,6 @@ static char *handle_show_settings(struct ast_cli_entry *e, int cmd, struct ast_c ast_cli(a->fd, " User name and group: %s/%s\n", ast_config_AST_RUN_USER, ast_config_AST_RUN_GROUP); ast_cli(a->fd, " Executable includes: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_EXEC_INCLUDES) ? "Enabled" : "Disabled"); ast_cli(a->fd, " Transcode via SLIN: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSCODE_VIA_SLIN) ? "Enabled" : "Disabled"); - ast_cli(a->fd, " Internal timing: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING) ? "Enabled" : "Disabled"); ast_cli(a->fd, " Transmit silence during rec: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_TRANSMIT_SILENCE) ? "Enabled" : "Disabled"); ast_cli(a->fd, " Generic PLC: %s\n", ast_test_flag(&ast_options, AST_OPT_FLAG_GENERIC_PLC) ? "Enabled" : "Disabled"); ast_cli(a->fd, " Min DTMF duration:: %u\n", option_dtmfminduration); @@ -3228,7 +3227,6 @@ static int show_cli_help(void) printf(" -g Dump core in case of a crash\n"); printf(" -h This help screen\n"); printf(" -i Initialize crypto keys at startup\n"); - printf(" -I Enable internal timing if DAHDI timer is available\n"); printf(" -L Limit the maximum load average before rejecting new calls\n"); printf(" -M Limit the maximum number of calls to the specified value\n"); printf(" -m Mute debugging and console output on the console\n"); @@ -3402,9 +3400,6 @@ static void ast_readconfig(void) /* Transmit SLINEAR silence while a channel is being recorded or DTMF is being generated on a channel */ } else if (!strcasecmp(v->name, "transmit_silence_during_record") || !strcasecmp(v->name, "transmit_silence")) { ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_TRANSMIT_SILENCE); - /* Enable internal timing */ - } else if (!strcasecmp(v->name, "internal_timing")) { - ast_set2_flag(&ast_options, ast_true(v->value), AST_OPT_FLAG_INTERNAL_TIMING); } else if (!strcasecmp(v->name, "mindtmfduration")) { if (sscanf(v->value, "%30u", &option_dtmfminduration) != 1) { option_dtmfminduration = AST_MIN_DTMF_DURATION; @@ -3730,9 +3725,6 @@ int main(int argc, char *argv[]) case 'h': show_cli_help(); exit(0); - case 'I': - ast_set_flag(&ast_options, AST_OPT_FLAG_INTERNAL_TIMING); - break; case 'i': ast_set_flag(&ast_options, AST_OPT_FLAG_INIT_KEYS); break; diff --git a/main/channel.c b/main/channel.c index fb5ace9342..9b927300cb 100644 --- a/main/channel.c +++ b/main/channel.c @@ -3055,12 +3055,13 @@ int ast_answer(struct ast_channel *chan) return __ast_answer(chan, 0, 1); } -void ast_deactivate_generator(struct ast_channel *chan) +static void deactivate_generator_nolock(struct ast_channel *chan) { - ast_channel_lock(chan); if (ast_channel_generatordata(chan)) { - if (ast_channel_generator(chan) && ast_channel_generator(chan)->release) { - ast_channel_generator(chan)->release(chan, ast_channel_generatordata(chan)); + struct ast_generator *generator = ast_channel_generator(chan); + + if (generator && generator->release) { + generator->release(chan, ast_channel_generatordata(chan)); } ast_channel_generatordata_set(chan, NULL); ast_channel_generator_set(chan, NULL); @@ -3068,14 +3069,23 @@ void ast_deactivate_generator(struct ast_channel *chan) ast_clear_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT); ast_settimeout(chan, 0, NULL, NULL); } +} + +void ast_deactivate_generator(struct ast_channel *chan) +{ + ast_channel_lock(chan); + deactivate_generator_nolock(chan); ast_channel_unlock(chan); } static void generator_write_format_change(struct ast_channel *chan) { + struct ast_generator *generator; + ast_channel_lock(chan); - if (ast_channel_generator(chan) && ast_channel_generator(chan)->write_format_change) { - ast_channel_generator(chan)->write_format_change(chan, ast_channel_generatordata(chan)); + generator = ast_channel_generator(chan); + if (generator && generator->write_format_change) { + generator->write_format_change(chan, ast_channel_generatordata(chan)); } ast_channel_unlock(chan); } @@ -3121,8 +3131,10 @@ int ast_activate_generator(struct ast_channel *chan, struct ast_generator *gen, ast_channel_lock(chan); if (ast_channel_generatordata(chan)) { - if (ast_channel_generator(chan) && ast_channel_generator(chan)->release) { - ast_channel_generator(chan)->release(chan, ast_channel_generatordata(chan)); + struct ast_generator *generator_old = ast_channel_generator(chan); + + if (generator_old && generator_old->release) { + generator_old->release(chan, ast_channel_generatordata(chan)); } } if (gen->alloc && !(generatordata = gen->alloc(chan, params))) { @@ -3746,49 +3758,57 @@ static void send_dtmf_event(struct ast_channel *chan, const char *direction, con static void ast_read_generator_actions(struct ast_channel *chan, struct ast_frame *f) { - if (ast_channel_generator(chan) && ast_channel_generator(chan)->generate && ast_channel_generatordata(chan) && !ast_internal_timing_enabled(chan)) { - void *tmp = ast_channel_generatordata(chan); - int (*generate)(struct ast_channel *chan, void *tmp, int datalen, int samples) = ast_channel_generator(chan)->generate; - int res; - int samples; + struct ast_generator *generator; + void *gendata; + int res; + int samples; - if (ast_channel_timingfunc(chan)) { - ast_debug(1, "Generator got voice, switching to phase locked mode\n"); - ast_settimeout(chan, 0, NULL, NULL); - } + generator = ast_channel_generator(chan); + if (!generator + || !generator->generate + || f->frametype != AST_FRAME_VOICE + || !ast_channel_generatordata(chan) + || ast_channel_timingfunc(chan)) { + return; + } - ast_channel_generatordata_set(chan, NULL); /* reset, to let writes go through */ + /* + * We must generate frames in phase locked mode since + * we have no internal timer available. + */ - if (ast_format_cmp(&f->subclass.format, ast_channel_writeformat(chan)) == AST_FORMAT_CMP_NOT_EQUAL) { - float factor; - factor = ((float) ast_format_rate(ast_channel_writeformat(chan))) / ((float) ast_format_rate(&f->subclass.format)); - samples = (int) ( ((float) f->samples) * factor ); - } else { - samples = f->samples; - } + if (ast_format_cmp(&f->subclass.format, ast_channel_writeformat(chan)) == AST_FORMAT_CMP_NOT_EQUAL) { + float factor; - /* This unlock is here based on two assumptions that hold true at this point in the - * code. 1) this function is only called from within __ast_read() and 2) all generators - * call ast_write() in their generate callback. - * - * The reason this is added is so that when ast_write is called, the lock that occurs - * there will not recursively lock the channel. Doing this will cause intended deadlock - * avoidance not to work in deeper functions - */ - ast_channel_unlock(chan); - res = generate(chan, tmp, f->datalen, samples); - ast_channel_lock(chan); - ast_channel_generatordata_set(chan, tmp); + factor = ((float) ast_format_rate(ast_channel_writeformat(chan))) / ((float) ast_format_rate(&f->subclass.format)); + samples = (int) (((float) f->samples) * factor); + } else { + samples = f->samples; + } + + gendata = ast_channel_generatordata(chan); + ast_channel_generatordata_set(chan, NULL); /* reset, to let writes go through */ + + /* + * This unlock is here based on two assumptions that hold true at + * this point in the code. 1) this function is only called from + * within __ast_read() and 2) all generators call ast_write() in + * their generate callback. + * + * The reason this is added is so that when ast_write is called, + * the lock that occurs there will not recursively lock the + * channel. Doing this will allow deadlock avoidance to work in + * deeper functions. + */ + ast_channel_unlock(chan); + res = generator->generate(chan, gendata, f->datalen, samples); + ast_channel_lock(chan); + if (generator == ast_channel_generator(chan)) { + ast_channel_generatordata_set(chan, gendata); if (res) { ast_debug(1, "Auto-deactivating generator\n"); ast_deactivate_generator(chan); } - - } else if (f->frametype == AST_FRAME_CNG) { - if (ast_channel_generator(chan) && !ast_channel_timingfunc(chan) && (ast_channel_timingfd(chan) > -1)) { - ast_debug(1, "Generator got CNG, switching to timed mode\n"); - ast_settimeout(chan, 50, generator_force, chan); - } } } @@ -4380,7 +4400,7 @@ done: int ast_internal_timing_enabled(struct ast_channel *chan) { - return (ast_opt_internal_timing && ast_channel_timingfd(chan) > -1); + return ast_channel_timingfd(chan) > -1; } struct ast_frame *ast_read(struct ast_channel *chan) @@ -8800,30 +8820,24 @@ struct ast_silence_generator *ast_channel_start_silence_generator(struct ast_cha return state; } -static int internal_deactivate_generator(struct ast_channel *chan, void* generator) +static int deactivate_silence_generator(struct ast_channel *chan) { ast_channel_lock(chan); if (!ast_channel_generatordata(chan)) { - ast_debug(1, "Trying to stop silence generator when there is no " - "generator on '%s'\n", ast_channel_name(chan)); + ast_debug(1, "Trying to stop silence generator when there is no generator on '%s'\n", + ast_channel_name(chan)); ast_channel_unlock(chan); return 0; } - if (ast_channel_generator(chan) != generator) { - ast_debug(1, "Trying to stop silence generator when it is not the current " - "generator on '%s'\n", ast_channel_name(chan)); + if (ast_channel_generator(chan) != &silence_generator) { + ast_debug(1, "Trying to stop silence generator when it is not the current generator on '%s'\n", + ast_channel_name(chan)); ast_channel_unlock(chan); return 0; } - if (ast_channel_generator(chan) && ast_channel_generator(chan)->release) { - ast_channel_generator(chan)->release(chan, ast_channel_generatordata(chan)); - } - ast_channel_generatordata_set(chan, NULL); - ast_channel_generator_set(chan, NULL); - ast_channel_set_fd(chan, AST_GENERATOR_FD, -1); - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_WRITE_INT); - ast_settimeout(chan, 0, NULL, NULL); + deactivate_generator_nolock(chan); + ast_channel_unlock(chan); return 1; @@ -8831,10 +8845,11 @@ static int internal_deactivate_generator(struct ast_channel *chan, void* generat void ast_channel_stop_silence_generator(struct ast_channel *chan, struct ast_silence_generator *state) { - if (!state) + if (!state) { return; + } - if (internal_deactivate_generator(chan, &silence_generator)) { + if (deactivate_silence_generator(chan)) { ast_debug(1, "Stopped silence generator on '%s'\n", ast_channel_name(chan)); if (ast_set_write_format(chan, &state->old_write_format) < 0) ast_log(LOG_ERROR, "Could not return write format to its original state\n");