diff options
author | George Joseph <gjoseph@digium.com> | 2017-11-15 11:10:16 -0700 |
---|---|---|
committer | George Joseph <gjoseph@digium.com> | 2017-11-15 13:03:19 -0700 |
commit | 7e874eae7a7b4ceb8185c931e3da26df05d78d6c (patch) | |
tree | f7f7b46ba494b9932d291eb865209ede86b9edbc /apps | |
parent | e25ec49b629e516882faf70dfafb687f39d58cf0 (diff) |
app_record: Don't set RECORD_STATUS chan var until file is closed
We've been calling pbx_builtin_setvar_helper to set the
RECORD_STATUS variable before actually closing the recorded file.
If a client is watching VarSet events and tries to do something with
the file when a RECORD_STATUS event is seen, they might attempt to
do so while the file it's still open.
We now delay calling pbx_builtin_setvar_helper until after we close
the file.
ASTERISK-27423
Change-Id: I7fe9de99953e46b4bafa2b38cf151fe8f6488254
Diffstat (limited to 'apps')
-rw-r--r-- | apps/app_record.c | 56 |
1 files changed, 39 insertions, 17 deletions
diff --git a/apps/app_record.c b/apps/app_record.c index 104daa51e..d1cdeabce 100644 --- a/apps/app_record.c +++ b/apps/app_record.c @@ -139,6 +139,12 @@ enum { OPTION_NO_TRUNCATE = (1 << 9), }; +enum dtmf_response { + RESPONSE_NO_MATCH = 0, + RESPONSE_OPERATOR, + RESPONSE_DTMF, +}; + AST_APP_OPTIONS(app_opts,{ AST_APP_OPTION('a', OPTION_APPEND), AST_APP_OPTION('k', OPTION_KEEP), @@ -162,24 +168,22 @@ AST_APP_OPTIONS(app_opts,{ * \param dtmf_integer the integer value of the DTMF key received * \param terminator key currently set to be pressed for normal termination * - * \retval 0 do not exit - * \retval -1 do exit + * \returns One of enum dtmf_response */ -static int record_dtmf_response(struct ast_channel *chan, struct ast_flags *flags, int dtmf_integer, int terminator) +static enum dtmf_response record_dtmf_response(struct ast_channel *chan, + struct ast_flags *flags, int dtmf_integer, int terminator) { if ((dtmf_integer == OPERATOR_KEY) && (ast_test_flag(flags, OPTION_OPERATOR_EXIT))) { - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "OPERATOR"); - return -1; + return RESPONSE_OPERATOR; } if ((dtmf_integer == terminator) || (ast_test_flag(flags, OPTION_ANY_TERMINATE))) { - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "DTMF"); - return -1; + return RESPONSE_DTMF; } - return 0; + return RESPONSE_NO_MATCH; } static int create_destination_directory(const char *path) @@ -248,6 +252,7 @@ static int record_exec(struct ast_channel *chan, const char *data) ); int ms; struct timeval start; + const char *status_response = "ERROR"; /* The next few lines of code parse out the filename and header from the input string */ if (ast_strlen_zero(data)) { /* no data implies no filename or anything is present */ @@ -345,7 +350,7 @@ static int record_exec(struct ast_channel *chan, const char *data) if (res) { ast_log(LOG_WARNING, "Could not answer channel '%s'\n", ast_channel_name(chan)); - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR"); + status_response = "ERROR"; goto out; } @@ -381,7 +386,7 @@ static int record_exec(struct ast_channel *chan, const char *data) if (create_destination_directory(tmp)) { ast_log(LOG_WARNING, "Could not create directory for file %s\n", args.filename); - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR"); + status_response = "ERROR"; goto out; } @@ -390,7 +395,7 @@ static int record_exec(struct ast_channel *chan, const char *data) if (!s) { ast_log(LOG_WARNING, "Could not create file %s\n", args.filename); - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR"); + status_response = "ERROR"; goto out; } @@ -425,7 +430,7 @@ static int record_exec(struct ast_channel *chan, const char *data) if (res) { ast_log(LOG_WARNING, "Problem writing frame\n"); ast_frfree(f); - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR"); + status_response = "ERROR"; break; } @@ -441,7 +446,7 @@ static int record_exec(struct ast_channel *chan, const char *data) /* Ended happily with silence */ ast_frfree(f); gotsilence = 1; - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "SILENCE"); + status_response = "SILENCE"; break; } } @@ -450,12 +455,26 @@ static int record_exec(struct ast_channel *chan, const char *data) if (res) { ast_log(LOG_WARNING, "Problem writing frame\n"); - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "ERROR"); + status_response = "ERROR"; ast_frfree(f); break; } } else if (f->frametype == AST_FRAME_DTMF) { - if (record_dtmf_response(chan, &flags, f->subclass.integer, terminator)) { + enum dtmf_response rc = + record_dtmf_response(chan, &flags, f->subclass.integer, terminator); + switch(rc) { + case RESPONSE_NO_MATCH: + break; + case RESPONSE_OPERATOR: + status_response = "OPERATOR"; + ast_debug(1, "Got OPERATOR\n"); + break; + case RESPONSE_DTMF: + status_response = "DTMF"; + ast_debug(1, "Got DTMF\n"); + break; + } + if (rc != RESPONSE_NO_MATCH) { ast_frfree(f); break; } @@ -465,13 +484,13 @@ static int record_exec(struct ast_channel *chan, const char *data) if (maxduration > 0 && !ms) { gottimeout = 1; - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "TIMEOUT"); + status_response = "TIMEOUT"; } if (!f) { ast_debug(1, "Got hangup\n"); res = -1; - pbx_builtin_setvar_helper(chan, "RECORD_STATUS", "HANGUP"); + status_response = "HANGUP"; if (!ast_test_flag(&flags, OPTION_KEEP)) { ast_filedelete(args.filename, NULL); } @@ -506,6 +525,9 @@ out: if (sildet) { ast_dsp_free(sildet); } + + pbx_builtin_setvar_helper(chan, "RECORD_STATUS", status_response); + return res; } |