From: Richard Mudgett Date: Wed, 13 Jun 2018 18:05:03 +0000 (-0500) Subject: AMI PlayDTMF Action: Make not compete with channel's media thread. X-Git-Tag: 13.22.0-rc1~21^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=6a1626c26540f15757f10962fd82aa4955c6f08c;p=thirdparty%2Fasterisk.git AMI PlayDTMF Action: Make not compete with channel's media thread. There can be one and only one thread handling a channel's media at a time. Otherwise, we don't know which thread is going to handle the media frames. ASTERISK-27625 Change-Id: Ia341f1a6f4d54f2022261abec9021fe5b2eb4905 --- diff --git a/apps/app_senddtmf.c b/apps/app_senddtmf.c index 25444a323a..5dde8dc336 100644 --- a/apps/app_senddtmf.c +++ b/apps/app_senddtmf.c @@ -169,7 +169,7 @@ static int manager_play_dtmf(struct mansession *s, const struct message *m) return 0; } - ast_senddigit(chan, *digit, duration_ms); + ast_senddigit_external(chan, *digit, duration_ms); chan = ast_channel_unref(chan); diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 8ec74e6136..0fc236af4b 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -2111,13 +2111,31 @@ int ast_recvchar(struct ast_channel *chan, int timeout); /*! * \brief Send a DTMF digit to a channel. + * * \param chan channel to act upon * \param digit the DTMF digit to send, encoded in ASCII * \param duration the duration of the digit ending in ms + * + * \pre This must only be called by the channel's media handler thread. + * * \return 0 on success, -1 on failure */ int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration); +/*! + * \brief Send a DTMF digit to a channel from an external thread. + * + * \param chan channel to act upon + * \param digit the DTMF digit to send, encoded in ASCII + * \param duration the duration of the digit ending in ms + * + * \pre This must only be called by threads that are not the channel's + * media handler thread. + * + * \return 0 on success, -1 on failure + */ +int ast_senddigit_external(struct ast_channel *chan, char digit, unsigned int duration); + /*! * \brief Send a DTMF digit to a channel. * \param chan channel to act upon diff --git a/main/channel.c b/main/channel.c index a5cc4e7e9f..27a959a4b9 100644 --- a/main/channel.c +++ b/main/channel.c @@ -5029,12 +5029,28 @@ int ast_senddigit_end(struct ast_channel *chan, char digit, unsigned int duratio int ast_senddigit(struct ast_channel *chan, char digit, unsigned int duration) { + if (duration < AST_DEFAULT_EMULATE_DTMF_DURATION) { + duration = AST_DEFAULT_EMULATE_DTMF_DURATION; + } + if (ast_channel_tech(chan)->send_digit_begin) { + ast_senddigit_begin(chan, digit); + ast_safe_sleep(chan, duration); + } + + return ast_senddigit_end(chan, digit, duration); +} + +int ast_senddigit_external(struct ast_channel *chan, char digit, unsigned int duration) +{ + if (duration < AST_DEFAULT_EMULATE_DTMF_DURATION) { + duration = AST_DEFAULT_EMULATE_DTMF_DURATION; + } if (ast_channel_tech(chan)->send_digit_begin) { ast_senddigit_begin(chan, digit); - ast_safe_sleep(chan, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); + usleep(duration * 1000); } - return ast_senddigit_end(chan, digit, (duration >= AST_DEFAULT_EMULATE_DTMF_DURATION ? duration : AST_DEFAULT_EMULATE_DTMF_DURATION)); + return ast_senddigit_end(chan, digit, duration); } int ast_prod(struct ast_channel *chan)