diff options
-rw-r--r-- | CHANGES | 11 | ||||
-rw-r--r-- | apps/app_chanspy.c | 16 | ||||
-rw-r--r-- | apps/app_dial.c | 6 | ||||
-rw-r--r-- | apps/app_disa.c | 10 | ||||
-rw-r--r-- | apps/app_dumpchan.c | 4 | ||||
-rw-r--r-- | apps/app_externalivr.c | 6 | ||||
-rw-r--r-- | include/asterisk/channel.h | 25 | ||||
-rw-r--r-- | include/asterisk/test.h | 8 | ||||
-rw-r--r-- | main/autoservice.c | 2 | ||||
-rw-r--r-- | main/bridge_after.c | 2 | ||||
-rw-r--r-- | main/bridge_channel.c | 2 | ||||
-rw-r--r-- | main/channel.c | 37 | ||||
-rw-r--r-- | main/file.c | 20 | ||||
-rw-r--r-- | main/manager.c | 8 | ||||
-rw-r--r-- | main/pbx.c | 4 | ||||
-rw-r--r-- | main/test.c | 4 | ||||
-rw-r--r-- | res/res_agi.c | 34 | ||||
-rw-r--r-- | res/res_musiconhold.c | 4 | ||||
-rw-r--r-- | tests/test_pbx.c | 22 |
19 files changed, 163 insertions, 62 deletions
@@ -18,6 +18,17 @@ app_queue been defined. ------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 14.5.0 to Asterisk 14.6.0 ------------ +------------------------------------------------------------------------------ + +res_agi +------------------ + * The EAGI() application will now look for a dialplan variable named + EAGI_AUDIO_FORMAT and use that format with the 'enhanced' audio pipe that + EAGI provides. If not specified, it will continue to use the default signed + linear (slin). + +------------------------------------------------------------------------------ --- Functionality changes from Asterisk 14.4.0 to Asterisk 14.5.0 ------------ ------------------------------------------------------------------------------ diff --git a/apps/app_chanspy.c b/apps/app_chanspy.c index 4814f4ce5..354b9ea7d 100644 --- a/apps/app_chanspy.c +++ b/apps/app_chanspy.c @@ -693,9 +693,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto } } - ast_channel_lock(chan); - ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); - ast_channel_unlock(chan); + ast_channel_set_flag(chan, AST_FLAG_END_DTMF_ONLY); csth.volfactor = *volfactor; @@ -825,9 +823,7 @@ static int channel_spy(struct ast_channel *chan, struct ast_autochan *spyee_auto else ast_deactivate_generator(chan); - ast_channel_lock(chan); - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); - ast_channel_unlock(chan); + ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); if (ast_test_flag(flags, OPTION_WHISPER | OPTION_BARGE | OPTION_DTMF_SWITCH_MODES)) { ast_audiohook_lock(&csth.whisper_audiohook); @@ -921,7 +917,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags, if (ast_channel_state(chan) != AST_STATE_UP) ast_answer(chan); - ast_set_flag(ast_channel_flags(chan), AST_FLAG_SPYING); /* so nobody can spy on us while we are spying */ + ast_channel_set_flag(chan, AST_FLAG_SPYING); waitms = 100; @@ -934,7 +930,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags, if (!res) res = ast_waitstream(chan, ""); else if (res < 0) { - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING); + ast_channel_clear_flag(chan, AST_FLAG_SPYING); break; } if (!ast_strlen_zero(exitcontext)) { @@ -977,7 +973,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags, res = ast_waitfordigit(chan, waitms); if (res < 0) { iter = ast_channel_iterator_destroy(iter); - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING); + ast_channel_clear_flag(chan, AST_FLAG_SPYING); break; } if (!ast_strlen_zero(exitcontext)) { @@ -1196,7 +1192,7 @@ static int common_exec(struct ast_channel *chan, struct ast_flags *flags, } exit: - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_SPYING); + ast_channel_clear_flag(chan, AST_FLAG_SPYING); ast_channel_setoption(chan, AST_OPTION_TXGAIN, &zero_volume, sizeof(zero_volume), 0); diff --git a/apps/app_dial.c b/apps/app_dial.c index 79e2a9b0b..847a095f4 100644 --- a/apps/app_dial.c +++ b/apps/app_dial.c @@ -2855,7 +2855,7 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast ast_log(LOG_ERROR, "error streaming file '%s' to callee\n", opt_args[OPT_ARG_ANNOUNCE]); } - ast_set_flag(ast_channel_flags(peer), AST_FLAG_END_DTMF_ONLY); + ast_channel_set_flag(peer, AST_FLAG_END_DTMF_ONLY); while (ast_channel_stream(peer)) { int ms; @@ -2919,13 +2919,13 @@ static int dial_exec_full(struct ast_channel *chan, const char *data, struct ast } ast_sched_runq(ast_channel_sched(peer)); } - ast_clear_flag(ast_channel_flags(peer), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(peer, AST_FLAG_END_DTMF_ONLY); } if (chan && peer && ast_test_flag64(&opts, OPT_GOTO) && !ast_strlen_zero(opt_args[OPT_ARG_GOTO])) { /* chan and peer are going into the PBX; as such neither are considered * outgoing channels any longer */ - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING); + ast_channel_clear_flag(chan, AST_FLAG_OUTGOING); ast_replace_subargument_delimiter(opt_args[OPT_ARG_GOTO]); ast_parseable_goto(chan, opt_args[OPT_ARG_GOTO]); diff --git a/apps/app_disa.c b/apps/app_disa.c index 8dc61ff64..cceb5541d 100644 --- a/apps/app_disa.c +++ b/apps/app_disa.c @@ -208,7 +208,7 @@ static int disa_exec(struct ast_channel *chan, const char *data) play_dialtone(chan, args.mailbox); - ast_set_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); + ast_channel_set_flag(chan, AST_FLAG_END_DTMF_ONLY); for (;;) { /* if outa time, give em reorder */ @@ -224,7 +224,7 @@ static int disa_exec(struct ast_channel *chan, const char *data) } if (!(f = ast_read(chan))) { - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); return -1; } @@ -232,7 +232,7 @@ static int disa_exec(struct ast_channel *chan, const char *data) if (f->data.uint32) ast_channel_hangupcause_set(chan, f->data.uint32); ast_frfree(f); - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); return -1; } @@ -261,7 +261,7 @@ static int disa_exec(struct ast_channel *chan, const char *data) fp = fopen(args.passcode,"r"); if (!fp) { ast_log(LOG_WARNING,"DISA password file %s not found on chan %s\n",args.passcode,ast_channel_name(chan)); - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); return -1; } pwline[0] = 0; @@ -357,7 +357,7 @@ static int disa_exec(struct ast_channel *chan, const char *data) } } - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(chan, AST_FLAG_END_DTMF_ONLY); if (k == 3) { int recheck = 0; diff --git a/apps/app_dumpchan.c b/apps/app_dumpchan.c index 0789ce06e..bec778817 100644 --- a/apps/app_dumpchan.c +++ b/apps/app_dumpchan.c @@ -88,8 +88,6 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size) ast_channel_lock(c); bridge = ast_channel_get_bridge(c); - ast_channel_unlock(c); - snprintf(buf,size, "Name= %s\n" "Type= %s\n" @@ -166,7 +164,7 @@ static int serialize_showchan(struct ast_channel *c, char *buf, size_t size) ast_channel_appl(c) ? ast_channel_appl(c) : "(N/A)", ast_channel_data(c) ? S_OR(ast_channel_data(c), "(Empty)") : "(None)", (ast_test_flag(ast_channel_flags(c), AST_FLAG_BLOCKING) ? ast_channel_blockproc(c) : "(Not Blocking)")); - + ast_channel_unlock(c); ao2_cleanup(bridge); return 0; } diff --git a/apps/app_externalivr.c b/apps/app_externalivr.c index c2224b44b..84267a5ea 100644 --- a/apps/app_externalivr.c +++ b/apps/app_externalivr.c @@ -642,9 +642,9 @@ static int eivr_comm(struct ast_channel *chan, struct ivr_localuser *u, waitfds[0] = ast_iostream_get_fd(eivr_commands); waitfds[1] = eivr_errors ? ast_iostream_get_fd(eivr_errors) : -1; - while (1) { - if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) { - ast_chan_log(LOG_ERROR, chan, "Is a zombie\n"); + while (1) { + if (ast_test_flag(ast_channel_flags(chan), AST_FLAG_ZOMBIE)) { + ast_chan_log(LOG_ERROR, chan, "Is a zombie\n"); break; } if (!hangup_info_sent && !(ast_test_flag(&flags, run_dead)) && ast_check_hangup(chan)) { diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index fd339d974..005803d5c 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -4437,6 +4437,31 @@ void ast_channel_dialed_causes_clear(const struct ast_channel *chan); struct ast_flags *ast_channel_flags(struct ast_channel *chan); /*! + * \since 13.17.0 + * \brief Set a flag on a channel + * + * \param chan The channel to set the flag on + * \param flag The flag to set + * + * \note This will lock the channel internally. If the channel is already + * locked it is still safe to call. + */ + +void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag); + +/*! + * \since 13.17.0 + * \param Clear a flag on a channel + * + * \param chan The channel to clear the flag from + * \param flag The flag to clear + * + * \note This will lock the channel internally. If the channel is already + * locked it is still safe to call. + */ +void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag); + +/*! * \since 12.4.0 * \brief Return whether or not any manager variables have been set * diff --git a/include/asterisk/test.h b/include/asterisk/test.h index 49731feb6..90e772cbc 100644 --- a/include/asterisk/test.h +++ b/include/asterisk/test.h @@ -241,6 +241,14 @@ struct ast_test_info { * \note The description must not end with a newline. */ const char *description; + /*! + * \brief Only run if explicitly named + * + * \details + * Run this test only if it's explicitly named on the command line. + * Do NOT run it as part of an execute category or execute all command. + */ + unsigned int explicit_only; }; #ifdef TEST_FRAMEWORK diff --git a/main/autoservice.c b/main/autoservice.c index 11c9eab96..d1a0156ab 100644 --- a/main/autoservice.c +++ b/main/autoservice.c @@ -295,11 +295,11 @@ int ast_autoservice_stop(struct ast_channel *chan) res = 0; } + ast_channel_lock(chan); if (!as->orig_end_dtmf_flag) { ast_clear_flag(ast_channel_flags(chan), AST_FLAG_END_DTMF_ONLY); } - ast_channel_lock(chan); while ((f = AST_LIST_REMOVE_HEAD(&as->deferred_frames, frame_list))) { if (!((1 << f->frametype) & as->ignore_frame_types)) { ast_queue_frame_head(chan, f); diff --git a/main/bridge_after.c b/main/bridge_after.c index d649717e2..d4aec75d0 100644 --- a/main/bridge_after.c +++ b/main/bridge_after.c @@ -482,7 +482,7 @@ int ast_bridge_setup_after_goto(struct ast_channel *chan) } } else if (!ast_check_hangup(chan)) { /* Clear the outgoing flag */ - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_OUTGOING); + ast_channel_clear_flag(chan, AST_FLAG_OUTGOING); if (after_bridge->specific) { goto_failed = ast_explicit_goto(chan, after_bridge->context, diff --git a/main/bridge_channel.c b/main/bridge_channel.c index 4f166fff0..c6ea222ee 100644 --- a/main/bridge_channel.c +++ b/main/bridge_channel.c @@ -2101,7 +2101,7 @@ void bridge_channel_internal_pull(struct ast_bridge_channel *bridge_channel) && (ast_channel_is_leaving_bridge(bridge_channel->chan) || bridge_channel->state == BRIDGE_CHANNEL_STATE_WAIT)) { ast_debug(2, "Channel %s will survive this bridge; clearing outgoing (dialed) flag\n", ast_channel_name(bridge_channel->chan)); - ast_clear_flag(ast_channel_flags(bridge_channel->chan), AST_FLAG_OUTGOING); + ast_channel_clear_flag(bridge_channel->chan, AST_FLAG_OUTGOING); } bridge->reconfigured = 1; diff --git a/main/channel.c b/main/channel.c index 099e6f65a..1f97e651c 100644 --- a/main/channel.c +++ b/main/channel.c @@ -1288,8 +1288,10 @@ int ast_channel_defer_dtmf(struct ast_channel *chan) int pre = 0; if (chan) { + ast_channel_lock(chan); pre = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF); ast_set_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF); + ast_channel_unlock(chan); } return pre; } @@ -1297,8 +1299,9 @@ int ast_channel_defer_dtmf(struct ast_channel *chan) /*! \brief Unset defer DTMF flag on channel */ void ast_channel_undefer_dtmf(struct ast_channel *chan) { - if (chan) - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DEFER_DTMF); + if (chan) { + ast_channel_clear_flag(chan, AST_FLAG_DEFER_DTMF); + } } struct ast_channel *ast_channel_callback(ao2_callback_data_fn *cb_fn, void *arg, @@ -3223,7 +3226,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in return -1; /* Only look for the end of DTMF, don't bother with the beginning and don't emulate things */ - ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_set_flag(c, AST_FLAG_END_DTMF_ONLY); /* Wait for a digit, no more than timeout_ms milliseconds total. * Or, wait indefinitely if timeout_ms is <0. @@ -3242,12 +3245,12 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in if (errno == 0 || errno == EINTR) continue; ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return -1; } else if (outfd > -1) { /* The FD we were watching has something waiting */ ast_log(LOG_WARNING, "The FD we were waiting for has something waiting. Waitfordigit returning numeric 1\n"); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return 1; } else if (rchan) { int res; @@ -3261,13 +3264,13 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in case AST_FRAME_DTMF_END: res = f->subclass.integer; ast_frfree(f); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return res; case AST_FRAME_CONTROL: switch (f->subclass.integer) { case AST_CONTROL_HANGUP: ast_frfree(f); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return -1; case AST_CONTROL_STREAM_STOP: case AST_CONTROL_STREAM_SUSPEND: @@ -3278,7 +3281,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in * that perform stream control will handle this. */ res = f->subclass.integer; ast_frfree(f); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return res; case AST_CONTROL_PVT_CAUSE_CODE: case AST_CONTROL_RINGING: @@ -3313,7 +3316,7 @@ int ast_waitfordigit_full(struct ast_channel *c, int timeout_ms, int audiofd, in } } - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return 0; /* Time is up */ } @@ -5709,9 +5712,9 @@ struct ast_channel *ast_call_forward(struct ast_channel *caller, struct ast_chan } else if (caller) { /* no outgoing helper so use caller if available */ call_forward_inherit(new_chan, caller, orig); } - ast_set_flag(ast_channel_flags(new_chan), AST_FLAG_ORIGINATED); ast_channel_lock_both(orig, new_chan); + ast_channel_set_flag(new_chan, AST_FLAG_ORIGINATED); pbx_builtin_setvar_helper(new_chan, "FORWARDERNAME", forwarder); ast_party_connected_line_copy(ast_channel_connected(new_chan), ast_channel_connected(orig)); ast_party_redirecting_copy(ast_channel_redirecting(new_chan), ast_channel_redirecting(orig)); @@ -10947,3 +10950,17 @@ int ast_channel_stream_topology_changed(struct ast_channel *chan, struct ast_str return ast_channel_tech(chan)->indicate(chan, AST_CONTROL_STREAM_TOPOLOGY_CHANGED, topology, sizeof(topology)); } + +void ast_channel_set_flag(struct ast_channel *chan, unsigned int flag) +{ + ast_channel_lock(chan); + ast_set_flag(ast_channel_flags(chan), flag); + ast_channel_unlock(chan); +} + +void ast_channel_clear_flag(struct ast_channel *chan, unsigned int flag) +{ + ast_channel_lock(chan); + ast_clear_flag(ast_channel_flags(chan), flag); + ast_channel_unlock(chan); +} diff --git a/main/file.c b/main/file.c index fb4ede6c8..41131f9ee 100644 --- a/main/file.c +++ b/main/file.c @@ -1543,7 +1543,7 @@ static int waitstream_core(struct ast_channel *c, reverse = ""; /* Switch the channel to end DTMF frame only. waitstream_core doesn't care about the start of DTMF. */ - ast_set_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_set_flag(c, AST_FLAG_END_DTMF_ONLY); if (ast_test_flag(ast_channel_flags(c), AST_FLAG_MASQ_NOSTREAM)) orig_chan_name = ast_strdupa(ast_channel_name(c)); @@ -1575,7 +1575,7 @@ static int waitstream_core(struct ast_channel *c, res = ast_waitfor(c, ms); if (res < 0) { ast_log(LOG_WARNING, "Select failed (%s)\n", strerror(errno)); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return res; } } else { @@ -1586,11 +1586,11 @@ static int waitstream_core(struct ast_channel *c, if (errno == EINTR) continue; ast_log(LOG_WARNING, "Wait failed (%s)\n", strerror(errno)); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return -1; } else if (outfd > -1) { /* this requires cmdfd set */ /* The FD we were watching has something waiting */ - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return 1; } /* if rchan is set, it is 'c' */ @@ -1599,7 +1599,7 @@ static int waitstream_core(struct ast_channel *c, if (res > 0) { struct ast_frame *fr = ast_read(c); if (!fr) { - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return -1; } switch (fr->frametype) { @@ -1610,7 +1610,7 @@ static int waitstream_core(struct ast_channel *c, S_COR(ast_channel_caller(c)->id.number.valid, ast_channel_caller(c)->id.number.str, NULL))) { res = fr->subclass.integer; ast_frfree(fr); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return res; } } else { @@ -1626,7 +1626,7 @@ static int waitstream_core(struct ast_channel *c, "Break"); ast_frfree(fr); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return res; } } @@ -1643,7 +1643,7 @@ static int waitstream_core(struct ast_channel *c, "Break"); res = fr->subclass.integer; ast_frfree(fr); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return res; case AST_CONTROL_STREAM_REVERSE: if (!skip_ms) { @@ -1661,7 +1661,7 @@ static int waitstream_core(struct ast_channel *c, case AST_CONTROL_BUSY: case AST_CONTROL_CONGESTION: ast_frfree(fr); - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return -1; case AST_CONTROL_RINGING: case AST_CONTROL_ANSWER: @@ -1698,7 +1698,7 @@ static int waitstream_core(struct ast_channel *c, ast_sched_runq(ast_channel_sched(c)); } - ast_clear_flag(ast_channel_flags(c), AST_FLAG_END_DTMF_ONLY); + ast_channel_clear_flag(c, AST_FLAG_END_DTMF_ONLY); return (err || ast_channel_softhangup_internal_flag(c)) ? -1 : 0; } diff --git a/main/manager.c b/main/manager.c index c592fbd37..1bbd1bbe9 100644 --- a/main/manager.c +++ b/main/manager.c @@ -4847,14 +4847,10 @@ static int action_redirect(struct mansession *s, const struct message *m) /* Release the bridge wait. */ if (chan1_wait) { - ast_channel_lock(chan); - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT); - ast_channel_unlock(chan); + ast_channel_clear_flag(chan, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT); } if (chan2_wait) { - ast_channel_lock(chan2); - ast_clear_flag(ast_channel_flags(chan2), AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT); - ast_channel_unlock(chan2); + ast_channel_clear_flag(chan2, AST_FLAG_BRIDGE_DUAL_REDIRECT_WAIT); } chan2 = ast_channel_unref(chan2); diff --git a/main/pbx.c b/main/pbx.c index 28027c06b..ccfba054e 100644 --- a/main/pbx.c +++ b/main/pbx.c @@ -4300,8 +4300,10 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, ast_channel_pbx(c)->rtimeoutms = 10000; ast_channel_pbx(c)->dtimeoutms = 5000; + ast_channel_lock(c); autoloopflag = ast_test_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); /* save value to restore at the end */ ast_set_flag(ast_channel_flags(c), AST_FLAG_IN_AUTOLOOP); + ast_channel_unlock(c); if (ast_strlen_zero(ast_channel_exten(c))) { /* If not successful fall back to 's' - but only if there is no given exten */ @@ -4546,8 +4548,10 @@ static enum ast_pbx_result __ast_pbx_run(struct ast_channel *c, ast_pbx_hangup_handler_run(c); } + ast_channel_lock(c); ast_set2_flag(ast_channel_flags(c), autoloopflag, AST_FLAG_IN_AUTOLOOP); ast_clear_flag(ast_channel_flags(c), AST_FLAG_BRIDGE_HANGUP_RUN); /* from one round to the next, make sure this gets cleared */ + ast_channel_unlock(c); pbx_destroy(ast_channel_pbx(c)); ast_channel_pbx_set(c, NULL); diff --git a/main/test.c b/main/test.c index 062451fb6..f45ad9b62 100644 --- a/main/test.c +++ b/main/test.c @@ -344,7 +344,7 @@ static int test_execute_multiple(const char *name, const char *category, struct execute = 0; switch (mode) { case TEST_CATEGORY: - if (!test_cat_cmp(test->info.category, category)) { + if (!test_cat_cmp(test->info.category, category) && !test->info.explicit_only) { execute = 1; } break; @@ -354,7 +354,7 @@ static int test_execute_multiple(const char *name, const char *category, struct } break; case TEST_ALL: - execute = 1; + execute = !test->info.explicit_only; } if (execute) { diff --git a/res/res_agi.c b/res/res_agi.c index 0bf629004..e8497f7ca 100644 --- a/res/res_agi.c +++ b/res/res_agi.c @@ -3142,12 +3142,14 @@ static int handle_exec(struct ast_channel *chan, AGI *agi, int argc, const char ast_verb(3, "AGI Script Executing Application: (%s) Options: (%s)\n", argv[1], argc >= 3 ? argv[2] : ""); if ((app_to_exec = pbx_findapp(argv[1]))) { + ast_channel_lock(chan); if (!(workaround = ast_test_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS))) { ast_set_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS); } + ast_channel_unlock(chan); res = pbx_exec(chan, app_to_exec, argc == 2 ? "" : argv[2]); if (!workaround) { - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_DISABLE_WORKAROUNDS); + ast_channel_clear_flag(chan, AST_FLAG_DISABLE_WORKAROUNDS); } } else { ast_log(LOG_WARNING, "Could not find application (%s)\n", argv[1]); @@ -3206,6 +3208,10 @@ static int handle_channelstatus(struct ast_channel *chan, AGI *agi, int argc, co static int handle_setvariable(struct ast_channel *chan, AGI *agi, int argc, const char * const argv[]) { + if (argc != 4) { + return RESULT_SHOWUSAGE; + } + if (argv[3]) pbx_builtin_setvar_helper(chan, argv[2], argv[3]); @@ -4024,7 +4030,7 @@ static void publish_async_exec_end(struct ast_channel *chan, int command_id, con static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, char *buf, int dead) { - const char *argv[MAX_ARGS]; + const char *argv[MAX_ARGS] = {0}; int argc = MAX_ARGS; int res; agi_command *c; @@ -4060,7 +4066,7 @@ static enum agi_result agi_handle_command(struct ast_channel *chan, AGI *agi, ch ast_agi_send(agi->fd, chan, "520 Invalid command syntax. Proper usage not available.\n"); } else { ast_agi_send(agi->fd, chan, "520-Invalid command syntax. Proper usage follows:\n"); - ast_agi_send(agi->fd, chan, "%s", c->usage); + ast_agi_send(agi->fd, chan, "%s\n", c->usage); ast_agi_send(agi->fd, chan, "520 End of proper usage.\n"); } @@ -4575,15 +4581,30 @@ static int eagi_exec(struct ast_channel *chan, const char *data) { int res; struct ast_format *readformat; + struct ast_format *requested_format = NULL; + const char *requested_format_name; if (ast_check_hangup(chan)) { ast_log(LOG_ERROR, "EAGI cannot be run on a dead/hungup channel, please use AGI.\n"); return 0; } + + requested_format_name = pbx_builtin_getvar_helper(chan, "EAGI_AUDIO_FORMAT"); + if (requested_format_name) { + requested_format = ast_format_cache_get(requested_format_name); + if (requested_format) { + ast_verb(3, "<%s> Setting EAGI audio pipe format to %s\n", + ast_channel_name(chan), ast_format_get_name(requested_format)); + } else { + ast_log(LOG_ERROR, "Could not find requested format: %s\n", requested_format_name); + } + } + readformat = ao2_bump(ast_channel_readformat(chan)); - if (ast_set_read_format(chan, ast_format_slin)) { + if (ast_set_read_format(chan, requested_format ?: ast_format_slin)) { ast_log(LOG_WARNING, "Unable to set channel '%s' to linear mode\n", ast_channel_name(chan)); - ao2_ref(readformat, -1); + ao2_cleanup(requested_format); + ao2_cleanup(readformat); return -1; } res = agi_exec_full(chan, data, 1, 0); @@ -4593,7 +4614,8 @@ static int eagi_exec(struct ast_channel *chan, const char *data) ast_format_get_name(readformat)); } } - ao2_ref(readformat, -1); + ao2_cleanup(requested_format); + ao2_cleanup(readformat); return res; } diff --git a/res/res_musiconhold.c b/res/res_musiconhold.c index 71f4691af..be50e9cee 100644 --- a/res/res_musiconhold.c +++ b/res/res_musiconhold.c @@ -1558,8 +1558,10 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con } } if (!res) { + ast_channel_lock(chan); ast_channel_latest_musicclass_set(chan, mohclass->name); ast_set_flag(ast_channel_flags(chan), AST_FLAG_MOH); + ast_channel_unlock(chan); } mohclass = mohclass_unref(mohclass, "unreffing local reference to mohclass in local_ast_moh_start"); @@ -1569,10 +1571,10 @@ static int local_ast_moh_start(struct ast_channel *chan, const char *mclass, con static void local_ast_moh_stop(struct ast_channel *chan) { - ast_clear_flag(ast_channel_flags(chan), AST_FLAG_MOH); ast_deactivate_generator(chan); ast_channel_lock(chan); + ast_clear_flag(ast_channel_flags(chan), AST_FLAG_MOH); if (ast_channel_music_state(chan)) { if (ast_channel_stream(chan)) { ast_closestream(ast_channel_stream(chan)); diff --git a/tests/test_pbx.c b/tests/test_pbx.c index 576fe1fb8..00fa41130 100644 --- a/tests/test_pbx.c +++ b/tests/test_pbx.c @@ -321,8 +321,29 @@ cleanup: return res; } +AST_TEST_DEFINE(segv) +{ + switch (cmd) { + case TEST_INIT: + info->name = "RAISE_SEGV"; + info->category = "/DO_NOT_RUN/"; + info->summary = "RAISES SEGV!!! (will only be run if explicitly called)"; + info->description = "RAISES SEGV!!! (will only be run if explicitly called). " + "This test is mainly used for testing CI and tool failure scenarios."; + info->explicit_only = 1; + return AST_TEST_NOT_RUN; + case TEST_EXECUTE: + break; + } + + raise(SIGSEGV); + + return AST_TEST_FAIL; +} + static int unload_module(void) { + AST_TEST_UNREGISTER(segv); AST_TEST_UNREGISTER(pattern_match_test); return 0; } @@ -330,6 +351,7 @@ static int unload_module(void) static int load_module(void) { AST_TEST_REGISTER(pattern_match_test); + AST_TEST_REGISTER(segv); return AST_MODULE_LOAD_SUCCESS; } |