summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--res/ari/ari_model_validators.c25
-rw-r--r--res/ari/ari_model_validators.h2
-rw-r--r--res/res_stasis_playback.c28
-rw-r--r--res/res_stasis_recording.c58
-rw-r--r--rest-api/api-docs/events.json5
-rw-r--r--rest-api/api-docs/recordings.json5
6 files changed, 89 insertions, 34 deletions
diff --git a/res/ari/ari_model_validators.c b/res/ari/ari_model_validators.c
index 9634a473c..9ea2f94cd 100644
--- a/res/ari/ari_model_validators.c
+++ b/res/ari/ari_model_validators.c
@@ -996,6 +996,15 @@ int ast_ari_validate_live_recording(struct ast_json *json)
int has_state = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
+ if (strcmp("cause", ast_json_object_iter_key(iter)) == 0) {
+ int prop_is_valid;
+ prop_is_valid = ast_ari_validate_string(
+ ast_json_object_iter_value(iter));
+ if (!prop_is_valid) {
+ ast_log(LOG_ERROR, "ARI LiveRecording field cause failed validation\n");
+ res = 0;
+ }
+ } else
if (strcmp("format", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_format = 1;
@@ -3292,20 +3301,9 @@ int ast_ari_validate_recording_failed(struct ast_json *json)
{
int res = 1;
struct ast_json_iter *iter;
- int has_cause = 0;
int has_recording = 0;
for (iter = ast_json_object_iter(json); iter; iter = ast_json_object_iter_next(json, iter)) {
- if (strcmp("cause", ast_json_object_iter_key(iter)) == 0) {
- int prop_is_valid;
- has_cause = 1;
- prop_is_valid = ast_ari_validate_string(
- ast_json_object_iter_value(iter));
- if (!prop_is_valid) {
- ast_log(LOG_ERROR, "ARI RecordingFailed field cause failed validation\n");
- res = 0;
- }
- } else
if (strcmp("recording", ast_json_object_iter_key(iter)) == 0) {
int prop_is_valid;
has_recording = 1;
@@ -3324,11 +3322,6 @@ int ast_ari_validate_recording_failed(struct ast_json *json)
}
}
- if (!has_cause) {
- ast_log(LOG_ERROR, "ARI RecordingFailed missing required field cause\n");
- res = 0;
- }
-
if (!has_recording) {
ast_log(LOG_ERROR, "ARI RecordingFailed missing required field recording\n");
res = 0;
diff --git a/res/ari/ari_model_validators.h b/res/ari/ari_model_validators.h
index 8724b642a..a1e5b099e 100644
--- a/res/ari/ari_model_validators.h
+++ b/res/ari/ari_model_validators.h
@@ -1032,6 +1032,7 @@ ari_validator ast_ari_validate_application_fn(void);
* - id: string (required)
* - technology: string (required)
* LiveRecording
+ * - cause: string
* - format: string (required)
* - name: string (required)
* - state: string (required)
@@ -1167,7 +1168,6 @@ ari_validator ast_ari_validate_application_fn(void);
* - timestamp: Date
* - playback: Playback (required)
* RecordingFailed
- * - cause: string (required)
* - recording: LiveRecording (required)
* RecordingFinished
* - recording: LiveRecording (required)
diff --git a/res/res_stasis_playback.c b/res/res_stasis_playback.c
index f112e8b25..f78ccf0ba 100644
--- a/res/res_stasis_playback.c
+++ b/res/res_stasis_playback.c
@@ -57,8 +57,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
#define SOUND_URI_SCHEME "sound:"
#define RECORDING_URI_SCHEME "recording:"
-STASIS_MESSAGE_TYPE_DEFN(stasis_app_playback_snapshot_type);
-
/*! Container of all current playbacks */
static struct ao2_container *playbacks;
@@ -87,6 +85,32 @@ struct stasis_app_playback {
enum stasis_app_playback_state state;
};
+static struct ast_json *playback_to_json(struct stasis_message *message,
+ const struct stasis_message_sanitizer *sanitize)
+{
+ struct ast_channel_blob *channel_blob = stasis_message_data(message);
+ struct ast_json *blob = channel_blob->blob;
+ const char *state =
+ ast_json_string_get(ast_json_object_get(blob, "state"));
+ const char *type;
+
+ if (!strcmp(state, "playing")) {
+ type = "PlaybackStarted";
+ } else if (!strcmp(state, "done")) {
+ type = "PlaybackFinished";
+ } else {
+ return NULL;
+ }
+
+ return ast_json_pack("{s: s, s: O}",
+ "type", type,
+ "playback", blob);
+}
+
+STASIS_MESSAGE_TYPE_DEFN(stasis_app_playback_snapshot_type,
+ .to_json = playback_to_json,
+);
+
static void playback_dtor(void *obj)
{
struct stasis_app_playback *playback = obj;
diff --git a/res/res_stasis_recording.c b/res/res_stasis_recording.c
index bd2177a76..ecf0cfa49 100644
--- a/res/res_stasis_recording.c
+++ b/res/res_stasis_recording.c
@@ -49,8 +49,6 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
/*! Recording check is unimplemented. le sigh */
#define RECORDING_CHECK 0
-STASIS_MESSAGE_TYPE_DEFN(stasis_app_recording_snapshot_type);
-
/*! Container of all current recordings */
static struct ao2_container *recordings;
@@ -61,13 +59,40 @@ struct stasis_app_recording {
char *absolute_name;
/*! Control object for the channel we're recording */
struct stasis_app_control *control;
-
/*! Current state of the recording. */
enum stasis_app_recording_state state;
/*! Indicates whether the recording is currently muted */
int muted:1;
};
+static struct ast_json *recording_to_json(struct stasis_message *message,
+ const struct stasis_message_sanitizer *sanitize)
+{
+ struct ast_channel_blob *channel_blob = stasis_message_data(message);
+ struct ast_json *blob = channel_blob->blob;
+ const char *state =
+ ast_json_string_get(ast_json_object_get(blob, "state"));
+ const char *type;
+
+ if (!strcmp(state, "recording")) {
+ type = "RecordingStarted";
+ } else if (!strcmp(state, "done") || !strcasecmp(state, "canceled")) {
+ type = "RecordingFinished";
+ } else if (!strcmp(state, "failed")) {
+ type = "RecordingFailed";
+ } else {
+ return NULL;
+ }
+
+ return ast_json_pack("{s: s, s: O}",
+ "type", type,
+ "recording", blob);
+}
+
+STASIS_MESSAGE_TYPE_DEFN(stasis_app_recording_snapshot_type,
+ .to_json = recording_to_json,
+);
+
static int recording_hash(const void *obj, int flags)
{
const struct stasis_app_recording *recording = obj;
@@ -183,7 +208,7 @@ enum ast_record_if_exists stasis_app_recording_if_exists_parse(
return -1;
}
-static void recording_publish(struct stasis_app_recording *recording)
+static void recording_publish(struct stasis_app_recording *recording, const char *cause)
{
RAII_VAR(struct ast_json *, json, NULL, ast_json_unref);
RAII_VAR(struct ast_channel_snapshot *, snapshot, NULL, ao2_cleanup);
@@ -196,6 +221,19 @@ static void recording_publish(struct stasis_app_recording *recording)
return;
}
+ if (!ast_strlen_zero(cause)) {
+ struct ast_json *failure_cause = ast_json_string_create(cause);
+
+ if (!failure_cause) {
+ return;
+ }
+
+ if (ast_json_object_set(json, "cause", failure_cause)) {
+ ast_json_unref(failure_cause);
+ return;
+ }
+ }
+
message = ast_channel_blob_create_from_cache(
stasis_app_control_get_channel_id(recording->control),
stasis_app_recording_snapshot_type(), json);
@@ -206,11 +244,11 @@ static void recording_publish(struct stasis_app_recording *recording)
stasis_app_control_publish(recording->control, message);
}
-static void recording_fail(struct stasis_app_recording *recording)
+static void recording_fail(struct stasis_app_recording *recording, const char *cause)
{
SCOPED_AO2LOCK(lock, recording);
recording->state = STASIS_APP_RECORDING_STATE_FAILED;
- recording_publish(recording);
+ recording_publish(recording, cause);
}
static void recording_cleanup(struct stasis_app_recording *recording)
@@ -233,7 +271,7 @@ static void *record_file(struct stasis_app_control *control,
if (stasis_app_get_bridge(control)) {
ast_log(LOG_ERROR, "Cannot record channel while in bridge\n");
- recording_fail(recording);
+ recording_fail(recording, "Cannot record channel while in bridge");
return NULL;
}
@@ -255,13 +293,13 @@ static void *record_file(struct stasis_app_control *control,
if (res != 0) {
ast_debug(3, "%s: Failed to answer\n",
ast_channel_uniqueid(chan));
- recording_fail(recording);
+ recording_fail(recording, "Failed to answer channel");
return NULL;
}
ao2_lock(recording);
recording->state = STASIS_APP_RECORDING_STATE_RECORDING;
- recording_publish(recording);
+ recording_publish(recording, NULL);
ao2_unlock(recording);
ast_play_and_record_full(chan,
@@ -284,7 +322,7 @@ static void *record_file(struct stasis_app_control *control,
ao2_lock(recording);
recording->state = STASIS_APP_RECORDING_STATE_COMPLETE;
- recording_publish(recording);
+ recording_publish(recording, NULL);
ao2_unlock(recording);
return NULL;
diff --git a/rest-api/api-docs/events.json b/rest-api/api-docs/events.json
index 9f82d19f5..e30a193c1 100644
--- a/rest-api/api-docs/events.json
+++ b/rest-api/api-docs/events.json
@@ -153,11 +153,6 @@
"type": "LiveRecording",
"description": "Recording control object",
"required": true
- },
- "cause": {
- "type": "string",
- "description": "Cause for the recording failure",
- "required": true
}
}
},
diff --git a/rest-api/api-docs/recordings.json b/rest-api/api-docs/recordings.json
index 590a1b84d..8e25da582 100644
--- a/rest-api/api-docs/recordings.json
+++ b/rest-api/api-docs/recordings.json
@@ -307,6 +307,11 @@
]
}
},
+ "cause": {
+ "required": false,
+ "type": "string",
+ "description": "Cause for recording failure if failed"
+ },
"state": {
"required": true,
"type": "string"