diff options
-rw-r--r-- | CHANGES | 19 | ||||
-rw-r--r-- | include/asterisk/app.h | 8 | ||||
-rw-r--r-- | main/app.c | 137 | ||||
-rw-r--r-- | res/ari/resource_bridges.h | 2 | ||||
-rw-r--r-- | res/ari/resource_channels.h | 2 | ||||
-rw-r--r-- | res/res_stasis_playback.c | 5 | ||||
-rw-r--r-- | rest-api/api-docs/bridges.json | 2 | ||||
-rw-r--r-- | rest-api/api-docs/channels.json | 2 |
8 files changed, 172 insertions, 5 deletions
@@ -12,6 +12,23 @@ --- Functionality changes from Asterisk 12 to Asterisk 13 -------------------- ------------------------------------------------------------------------------ +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 12.2.0 to Asterisk 12.3.0 ------------ +------------------------------------------------------------------------------ + +ARI +------------------ + * A new Playback URI 'tone' has been added. Tones are specified either as + an indication name (e.g. 'tone:busy') from indications.conf or as a tone + pattern (e.g. 'tone:240/250,0/250'). Tones differ from normal playback + URIs in that they must be stopped manually and will continue to occupy + a channel's ARI control queue until they are stopped. They also can not + be rewound or fastforwarded. + +------------------------------------------------------------------------------ +--- Functionality changes from Asterisk 12.1.0 to Asterisk 12.2.0 ------------ +------------------------------------------------------------------------------ + Applications -------------------------- * Record application now has an option 'o' which allows 0 to act as an exit @@ -143,7 +160,7 @@ AMI used to set the UniqueId on creation. The other id is assigned to the second channel when dialing LOCAL, or defaults to appending ;2 if only the single Id is given. - + * The Mixmonitor action now has a "Command" header that can be used to indicate a post-process command to run once recording finishes. diff --git a/include/asterisk/app.h b/include/asterisk/app.h index 70cf75270..65d74dcd1 100644 --- a/include/asterisk/app.h +++ b/include/asterisk/app.h @@ -880,6 +880,14 @@ int ast_control_streamfile_lang(struct ast_channel *chan, const char *file, const char *restart, int skipms, const char *lang, long *offsetms); /*! + * \brief Controls playback of a tone + * + * \retval 0 on success + * \retval Non-zero on failure + */ +int ast_control_tone(struct ast_channel *chan, const char *tone); + +/*! * \brief Stream a file with fast forward, pause, reverse, restart. * \param chan * \param file filename diff --git a/main/app.c b/main/app.c index b6c988258..f7bb0048c 100644 --- a/main/app.c +++ b/main/app.c @@ -1070,6 +1070,143 @@ int ast_control_streamfile_lang(struct ast_channel *chan, const char *file, return control_streamfile(chan, file, fwd, rev, stop, suspend, restart, skipms, offsetms, lang, NULL); } +enum control_tone_frame_response_result { + CONTROL_TONE_RESPONSE_FAILED = -1, + CONTROL_TONE_RESPONSE_NORMAL = 0, + CONTROL_TONE_RESPONSE_FINISHED = 1, +}; + +static enum control_tone_frame_response_result control_tone_frame_response(struct ast_channel *chan, struct ast_frame *fr, struct ast_tone_zone_sound *ts, const char *tone, int *paused) +{ + switch (fr->subclass.integer) { + case AST_CONTROL_STREAM_STOP: + ast_playtones_stop(chan); + return CONTROL_TONE_RESPONSE_FINISHED; + case AST_CONTROL_STREAM_SUSPEND: + if (*paused) { + *paused = 0; + if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) { + return CONTROL_TONE_RESPONSE_FAILED; + } + } else { + *paused = 1; + ast_playtones_stop(chan); + } + return CONTROL_TONE_RESPONSE_NORMAL; + case AST_CONTROL_STREAM_RESTART: + ast_playtones_stop(chan); + if (ast_playtones_start(chan, 0, ts ? ts->data : tone, 0)) { + return CONTROL_TONE_RESPONSE_FAILED; + } + return CONTROL_TONE_RESPONSE_NORMAL; + case AST_CONTROL_STREAM_REVERSE: + ast_log(LOG_NOTICE, "Media control operation 'reverse' not supported for media type 'tone'\n"); + return CONTROL_TONE_RESPONSE_NORMAL; + case AST_CONTROL_STREAM_FORWARD: + ast_log(LOG_NOTICE, "Media control operation 'forward' not supported for media type 'tone'\n"); + return CONTROL_TONE_RESPONSE_NORMAL; + case AST_CONTROL_HANGUP: + case AST_CONTROL_BUSY: + case AST_CONTROL_CONGESTION: + return CONTROL_TONE_RESPONSE_FINISHED; + } + + return CONTROL_TONE_RESPONSE_NORMAL; +} + +static int parse_tone_uri(char *tone_parser, + const char **tone_indication, + const char **tone_zone) +{ + *tone_indication = strsep(&tone_parser, ";"); + + if (ast_strlen_zero(tone_parser)) { + /* Only the indication is included */ + return 0; + } + + if (!(strncmp(tone_parser, "tonezone=", 9))) { + *tone_zone = tone_parser + 9; + } else { + ast_log(LOG_ERROR, "Unexpected Tone URI component: %s\n", tone_parser); + return -1; + } + + return 0; +} + +int ast_control_tone(struct ast_channel *chan, const char *tone) +{ + struct ast_tone_zone *zone = NULL; + struct ast_tone_zone_sound *ts; + int paused = 0; + int res; + + const char *tone_indication = NULL; + const char *tone_zone = NULL; + char *tone_uri_parser; + + if (ast_strlen_zero(tone)) { + return -1; + } + + tone_uri_parser = ast_strdupa(tone); + + if (parse_tone_uri(tone_uri_parser, &tone_indication, &tone_zone)) { + return -1; + } + + if (tone_zone) { + zone = ast_get_indication_zone(tone_zone); + } + + ts = ast_get_indication_tone(zone ? zone : ast_channel_zone(chan), tone_indication); + + if (ast_playtones_start(chan, 0, ts ? ts->data : tone_indication, 0)) { + return -1; + } + + for (;;) { + struct ast_frame *fr; + int res; + + if (ast_waitfor(chan, -1) < 0) { + res = -1; + break; + } + + fr = ast_read_noaudio(chan); + + if (!fr) { + res = -1; + break; + } + + if (fr->frametype != AST_FRAME_CONTROL) { + continue; + } + + res = control_tone_frame_response(chan, fr, ts, tone_indication, &paused); + if (res == CONTROL_TONE_RESPONSE_FINISHED) { + res = 0; + break; + } else if (res == CONTROL_TONE_RESPONSE_FAILED) { + res = -1; + break; + } + } + + if (ts) { + ast_tone_zone_sound_unref(ts); + } + + if (zone) { + ast_tone_zone_unref(zone); + } + + return res; +} + int ast_play_and_wait(struct ast_channel *chan, const char *fn) { int d = 0; diff --git a/res/ari/resource_bridges.h b/res/ari/resource_bridges.h index 5dca82781..404760c91 100644 --- a/res/ari/resource_bridges.h +++ b/res/ari/resource_bridges.h @@ -268,7 +268,7 @@ int ast_ari_bridges_play_parse_body( /*! * \brief Start playback of media on a bridge. * - * The media URI may be any of a number of URI's. Currently sound: and recording: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.) + * The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.) * * \param headers HTTP headers * \param args Swagger parameters diff --git a/res/ari/resource_channels.h b/res/ari/resource_channels.h index cf48cee75..bc50c3da4 100644 --- a/res/ari/resource_channels.h +++ b/res/ari/resource_channels.h @@ -460,7 +460,7 @@ int ast_ari_channels_play_parse_body( /*! * \brief Start playback of media. * - * The media URI may be any of a number of URI's. Currently sound: and recording: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.) + * The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.) * * \param headers HTTP headers * \param args Swagger parameters diff --git a/res/res_stasis_playback.c b/res/res_stasis_playback.c index 79c2bab9c..960f2e334 100644 --- a/res/res_stasis_playback.c +++ b/res/res_stasis_playback.c @@ -48,6 +48,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #include "asterisk/stringfields.h" #include "asterisk/uuid.h" #include "asterisk/say.h" +#include "asterisk/indications.h" /*! Number of hash buckets for playback container. Keep it prime! */ #define PLAYBACK_BUCKETS 127 @@ -60,6 +61,7 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$") #define NUMBER_URI_SCHEME "number:" #define DIGITS_URI_SCHEME "digits:" #define CHARACTERS_URI_SCHEME "characters:" +#define TONE_URI_SCHEME "tone:" /*! Container of all current playbacks */ static struct ao2_container *playbacks; @@ -323,6 +325,9 @@ static void play_on_channel(struct stasis_app_playback *playback, } else if (ast_begins_with(playback->media, CHARACTERS_URI_SCHEME)) { res = ast_say_character_str(chan, playback->media + strlen(CHARACTERS_URI_SCHEME), stop, playback->language, AST_SAY_CASE_NONE); + } else if (ast_begins_with(playback->media, TONE_URI_SCHEME)) { + playback->controllable = 1; + res = ast_control_tone(chan, playback->media + strlen(TONE_URI_SCHEME)); } else { /* Play URL */ ast_log(LOG_ERROR, "Attempted to play URI '%s' on channel '%s' but scheme is unsupported", diff --git a/rest-api/api-docs/bridges.json b/rest-api/api-docs/bridges.json index 56a7a941e..4d2c77cea 100644 --- a/rest-api/api-docs/bridges.json +++ b/rest-api/api-docs/bridges.json @@ -314,7 +314,7 @@ { "httpMethod": "POST", "summary": "Start playback of media on a bridge.", - "notes": "The media URI may be any of a number of URI's. Currently sound: and recording: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)", + "notes": "The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)", "nickname": "play", "responseClass": "Playback", "parameters": [ diff --git a/rest-api/api-docs/channels.json b/rest-api/api-docs/channels.json index d940f4383..cc7feb6a9 100644 --- a/rest-api/api-docs/channels.json +++ b/rest-api/api-docs/channels.json @@ -808,7 +808,7 @@ { "httpMethod": "POST", "summary": "Start playback of media.", - "notes": "The media URI may be any of a number of URI's. Currently sound: and recording: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)", + "notes": "The media URI may be any of a number of URI's. Currently sound:, recording:, number:, digits:, characters:, and tone: URI's are supported. This operation creates a playback resource that can be used to control the playback of media (pause, rewind, fast forward, etc.)", "nickname": "play", "responseClass": "Playback", "parameters": [ |