struct ast_json *stasis_app_event_filter_to_json(struct stasis_app *app, struct ast_json *json) { if (!app || !json) { return json; } ast_json_object_set(json, "events_allowed", app->events_allowed ? ast_json_ref(app->events_allowed) : ast_json_array_create()); ast_json_object_set(json, "events_disallowed", app->events_disallowed ? ast_json_ref(app->events_disallowed) : ast_json_array_create()); return json; }
struct ast_json *app_to_json(const struct stasis_app *app) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ast_json *channels; struct ast_json *bridges; struct ast_json *endpoints; struct ao2_iterator i; void *obj; json = ast_json_pack("{s: s, s: [], s: [], s: []}", "name", app->name, "channel_ids", "bridge_ids", "endpoint_ids"); channels = ast_json_object_get(json, "channel_ids"); bridges = ast_json_object_get(json, "bridge_ids"); endpoints = ast_json_object_get(json, "endpoint_ids"); i = ao2_iterator_init(app->forwards, 0); while ((obj = ao2_iterator_next(&i))) { RAII_VAR(struct app_forwards *, forwards, obj, ao2_cleanup); RAII_VAR(struct ast_json *, id, NULL, ast_json_unref); int append_res = -1; id = ast_json_string_create(forwards->id); switch (forwards->forward_type) { case FORWARD_CHANNEL: append_res = ast_json_array_append(channels, ast_json_ref(id)); break; case FORWARD_BRIDGE: append_res = ast_json_array_append(bridges, ast_json_ref(id)); break; case FORWARD_ENDPOINT: append_res = ast_json_array_append(endpoints, ast_json_ref(id)); break; } if (append_res != 0) { ast_log(LOG_ERROR, "Error building response\n"); ao2_iterator_destroy(&i); return NULL; } } ao2_iterator_destroy(&i); return ast_json_ref(json); }
/*! \internal \brief convert multi object blob to ari json */ static struct ast_json *multi_user_event_to_json( struct stasis_message *message, const struct stasis_message_sanitizer *sanitize) { RAII_VAR(struct ast_json *, out, NULL, ast_json_unref); struct ast_multi_object_blob *multi = stasis_message_data(message); struct ast_json *blob = multi->blob; const struct timeval *tv = stasis_message_timestamp(message); enum stasis_user_multi_object_snapshot_type type; int i; out = ast_json_object_create(); if (!out) { return NULL; } ast_json_object_set(out, "type", ast_json_string_create("ChannelUserevent")); ast_json_object_set(out, "timestamp", ast_json_timeval(*tv, NULL)); ast_json_object_set(out, "eventname", ast_json_ref(ast_json_object_get(blob, "eventname"))); ast_json_object_set(out, "userevent", ast_json_ref(blob)); /* eventname gets duplicated, that's ok */ for (type = 0; type < STASIS_UMOS_MAX; ++type) { for (i = 0; i < AST_VECTOR_SIZE(&multi->snapshots[type]); ++i) { struct ast_json *json_object = NULL; char *name = NULL; void *snapshot = AST_VECTOR_GET(&multi->snapshots[type], i); switch (type) { case STASIS_UMOS_CHANNEL: json_object = ast_channel_snapshot_to_json(snapshot, sanitize); name = "channel"; break; case STASIS_UMOS_BRIDGE: json_object = ast_bridge_snapshot_to_json(snapshot, sanitize); name = "bridge"; break; case STASIS_UMOS_ENDPOINT: json_object = ast_endpoint_snapshot_to_json(snapshot, sanitize); name = "endpoint"; break; } if (json_object) { ast_json_object_set(out, name, json_object); } } } return ast_json_ref(out); }
struct ast_json *ast_channel_snapshot_to_json( const struct ast_channel_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize) { RAII_VAR(struct ast_json *, json_chan, NULL, ast_json_unref); if (snapshot == NULL || (sanitize && sanitize->channel_snapshot && sanitize->channel_snapshot(snapshot))) { return NULL; } json_chan = ast_json_pack( /* Broken up into groups of three for readability */ "{ s: s, s: s, s: s," " s: o, s: o, s: s," " s: o, s: o }", /* First line */ "id", snapshot->uniqueid, "name", snapshot->name, "state", ast_state2str(snapshot->state), /* Second line */ "caller", ast_json_name_number( snapshot->caller_name, snapshot->caller_number), "connected", ast_json_name_number( snapshot->connected_name, snapshot->connected_number), "accountcode", snapshot->accountcode, /* Third line */ "dialplan", ast_json_dialplan_cep( snapshot->context, snapshot->exten, snapshot->priority), "creationtime", ast_json_timeval(snapshot->creationtime, NULL)); return ast_json_ref(json_chan); }
void ast_ari_get_stored_recording(struct ast_variable *headers, struct ast_get_stored_recording_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_stored_recording *, recording, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); recording = stasis_app_stored_recording_find_by_name( args->recording_name); if (recording == NULL) { ast_ari_response_error(response, 404, "Not Found", "Recording not found"); return; } json = stasis_app_stored_recording_to_json(recording); if (json == NULL) { ast_ari_response_error(response, 500, "Internal Server Error", "Error building response"); return; } ast_ari_response_ok(response, ast_json_ref(json)); }
static struct stasis_message *create_channel_blob_message(struct ast_channel_snapshot *snapshot, struct stasis_message_type *type, struct ast_json *blob) { struct stasis_message *msg; struct ast_channel_blob *obj; obj = ao2_alloc(sizeof(*obj), channel_blob_dtor); if (!obj) { return NULL; } if (snapshot) { obj->snapshot = snapshot; ao2_ref(obj->snapshot, +1); } if (!blob) { blob = ast_json_null(); } obj->blob = ast_json_ref(blob); msg = stasis_message_create(type, obj); ao2_cleanup(obj); return msg; }
void ast_ari_response_ok(struct ast_ari_response *response, struct ast_json *message) { response->message = ast_json_ref(message); response->response_code = 200; response->response_text = "OK"; }
void ast_ari_asterisk_get_global_var(struct ast_variable *headers, struct ast_ari_asterisk_get_global_var_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); RAII_VAR(struct ast_str *, tmp, NULL, ast_free); const char *value; ast_assert(response != NULL); if (ast_strlen_zero(args->variable)) { ast_ari_response_error( response, 400, "Bad Request", "Variable name is required"); return; } tmp = ast_str_create(32); if (!tmp) { ast_ari_response_alloc_failed(response); return; } value = ast_str_retrieve_variable(&tmp, 0, NULL, NULL, args->variable); if (!(json = ast_json_pack("{s: s}", "value", S_OR(value, "")))) { ast_ari_response_alloc_failed(response); return; } ast_ari_response_ok(response, ast_json_ref(json)); }
struct ast_json *ast_json_party_id(struct ast_party_id *party) { RAII_VAR(struct ast_json *, json_party_id, NULL, ast_json_unref); int pres; /* Combined party presentation */ pres = ast_party_id_presentation(party); json_party_id = ast_json_pack("{s: i, s: s}", "presentation", pres, "presentation_txt", ast_describe_caller_presentation(pres)); if (!json_party_id) { return NULL; } /* Party number */ if (party->number.valid && ast_json_object_set(json_party_id, "number", json_party_number(&party->number))) { return NULL; } /* Party name */ if (party->name.valid && ast_json_object_set(json_party_id, "name", json_party_name(&party->name))) { return NULL; } /* Party subaddress */ if (party->subaddress.valid && ast_json_object_set(json_party_id, "subaddress", json_party_subaddress(&party->subaddress))) { return NULL; } return ast_json_ref(json_party_id); }
struct stasis_message *ast_endpoint_blob_create(struct ast_endpoint *endpoint, struct stasis_message_type *type, struct ast_json *blob) { RAII_VAR(struct ast_endpoint_blob *, obj, NULL, ao2_cleanup); RAII_VAR(struct stasis_message *, msg, NULL, ao2_cleanup); if (!type) { return NULL; } if (!blob) { blob = ast_json_null(); } if (!(obj = ao2_alloc(sizeof(*obj), endpoint_blob_dtor))) { return NULL; } if (endpoint) { if (!(obj->snapshot = ast_endpoint_snapshot_create(endpoint))) { return NULL; } } obj->blob = ast_json_ref(blob); if (!(msg = stasis_message_create(type, obj))) { return NULL; } ao2_ref(msg, +1); return msg; }
int ast_json_object_update_missing(struct ast_json *object, struct ast_json *other) { #if JANSSON_VERSION_HEX >= 0x020300 return json_object_update_missing((json_t *)object, (json_t *)other); #else struct ast_json_iter *iter = ast_json_object_iter(other); int ret = 0; if (object == NULL || other == NULL) { return -1; } while (iter != NULL && ret == 0) { const char *key = ast_json_object_iter_key(iter); if (ast_json_object_get(object, key) == NULL) { struct ast_json *value = ast_json_object_iter_value(iter); if (!value || ast_json_object_set(object, key, ast_json_ref(value))) { ret = -1; } } iter = ast_json_object_iter_next(other, iter); } return ret; #endif }
struct ast_json *stasis_app_recording_to_json( const struct stasis_app_recording *recording) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); if (recording == NULL) { return NULL; } json = ast_json_pack("{s: s, s: s, s: s, s: s}", "name", recording->options->name, "format", recording->options->format, "state", state_to_string(recording->state), "target_uri", recording->options->target); if (json && recording->duration.total > -1) { ast_json_object_set(json, "duration", ast_json_integer_create(recording->duration.total)); } if (json && recording->duration.energy_only > -1) { ast_json_object_set(json, "talking_duration", ast_json_integer_create(recording->duration.energy_only)); ast_json_object_set(json, "silence_duration", ast_json_integer_create(recording->duration.total - recording->duration.energy_only)); } return ast_json_ref(json); }
void ast_ari_response_created(struct ast_ari_response *response, const char *url, struct ast_json *message) { response->message = ast_json_ref(message); response->response_code = 201; response->response_text = "Created"; ast_str_append(&response->headers, 0, "Location: %s\r\n", url); }
void ast_ari_websocket_events_event_websocket_established(struct ast_ari_websocket_session *ws_session, struct ast_variable *headers, struct ast_ari_events_event_websocket_args *args) { RAII_VAR(struct event_session *, session, NULL, session_cleanup); struct ast_json *msg; int res; size_t i; int (* register_handler)(const char *, stasis_app_cb handler, void *data); ast_debug(3, "/events WebSocket connection\n"); session = session_create(ws_session); if (!session) { ast_ari_websocket_session_write(ws_session, ast_ari_oom_json()); return; } if (args->subscribe_all) { register_handler = &stasis_app_register_all; } else { register_handler = &stasis_app_register; } res = 0; for (i = 0; i < args->app_count; ++i) { if (ast_strlen_zero(args->app[i])) { continue; } res |= session_register_app(session, args->app[i], register_handler); } if (ao2_container_count(session->websocket_apps) == 0) { RAII_VAR(struct ast_json *, msg, NULL, ast_json_unref); msg = ast_json_pack("{s: s, s: [s]}", "type", "MissingParams", "params", "app"); if (!msg) { msg = ast_json_ref(ast_ari_oom_json()); } ast_ari_websocket_session_write(session->ws_session, msg); return; } if (res != 0) { ast_ari_websocket_session_write(ws_session, ast_ari_oom_json()); return; } /* We don't process any input, but we'll consume it waiting for EOF */ while ((msg = ast_ari_websocket_session_read(ws_session))) { ast_json_unref(msg); } }
void ast_ari_channels_list(struct ast_variable *headers, struct ast_ari_channels_list_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup); RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ao2_iterator i; void *obj; struct stasis_message_sanitizer *sanitize = stasis_app_get_sanitizer(); cache = ast_channel_cache(); if (!cache) { ast_ari_response_error( response, 500, "Internal Server Error", "Message bus not initialized"); return; } ao2_ref(cache, +1); snapshots = stasis_cache_dump(cache, ast_channel_snapshot_type()); if (!snapshots) { ast_ari_response_alloc_failed(response); return; } json = ast_json_array_create(); if (!json) { ast_ari_response_alloc_failed(response); return; } for (i = ao2_iterator_init(snapshots, 0); (obj = ao2_iterator_next(&i)); ao2_cleanup(obj)) { RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup); struct ast_channel_snapshot *snapshot = stasis_message_data(msg); int r; if (sanitize && sanitize->channel_snapshot && sanitize->channel_snapshot(snapshot)) { continue; } r = ast_json_array_append( json, ast_channel_snapshot_to_json(snapshot, NULL)); if (r != 0) { ast_ari_response_alloc_failed(response); ao2_cleanup(obj); ao2_iterator_destroy(&i); return; } } ao2_iterator_destroy(&i); ast_ari_response_ok(response, ast_json_ref(json)); }
struct ast_json *ast_ari_websocket_session_read( struct ast_ari_websocket_session *session) { RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); if (ast_websocket_fd(session->ws_session) < 0) { return NULL; } while (!message) { int res; char *payload; uint64_t payload_len; enum ast_websocket_opcode opcode; int fragmented; res = ast_wait_for_input( ast_websocket_fd(session->ws_session), -1); if (res <= 0) { ast_log(LOG_WARNING, "WebSocket poll error: %s\n", strerror(errno)); return NULL; } res = ast_websocket_read(session->ws_session, &payload, &payload_len, &opcode, &fragmented); if (res != 0) { ast_log(LOG_WARNING, "WebSocket read error: %s\n", strerror(errno)); return NULL; } switch (opcode) { case AST_WEBSOCKET_OPCODE_CLOSE: ast_debug(1, "WebSocket closed\n"); return NULL; case AST_WEBSOCKET_OPCODE_TEXT: message = ast_json_load_buf(payload, payload_len, NULL); if (message == NULL) { ast_log(LOG_WARNING, "WebSocket input failed to parse\n"); } break; default: /* Ignore all other message types */ break; } } return ast_json_ref(message); }
struct ast_json_payload *ast_json_payload_create(struct ast_json *json) { struct ast_json_payload *payload; if (!(payload = ao2_alloc(sizeof(*payload), json_payload_destructor))) { return NULL; } ast_json_ref(json); payload->json = json; return payload; }
void ast_ari_response_error(struct ast_ari_response *response, int response_code, const char *response_text, const char *message_fmt, ...) { RAII_VAR(struct ast_json *, message, NULL, ast_json_unref); va_list ap; va_start(ap, message_fmt); message = ast_json_vstringf(message_fmt, ap); response->message = ast_json_pack("{s: o}", "message", ast_json_ref(message)); response->response_code = response_code; response->response_text = response_text; }
struct ast_json *stasis_app_recording_to_json( const struct stasis_app_recording *recording) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); if (recording == NULL) { return NULL; } json = ast_json_pack("{s: s, s: s, s: s}", "name", recording->options->name, "format", recording->options->format, "state", state_to_string(recording->state)); return ast_json_ref(json); }
static int app_event_filter_set(struct stasis_app *app, struct ast_json **member, struct ast_json *filter, const char *filter_type) { if (filter && ast_json_typeof(filter) == AST_JSON_OBJECT) { if (!ast_json_object_size(filter)) { /* If no filters are specified then reset this filter type */ filter = NULL; } else { /* Otherwise try to get the filter array for this type */ filter = ast_json_object_get(filter, filter_type); if (!filter) { /* A filter type exists, but not this one, so don't update */ return 0; } } } /* At this point the filter object should be an array */ if (filter && ast_json_typeof(filter) != AST_JSON_ARRAY) { ast_log(LOG_ERROR, "Invalid json type event filter - app: %s, filter: %s\n", app->name, filter_type); return -1; } if (filter) { /* Confirm that at least the type names are specified */ struct ast_json *obj; int i; for (i = 0; i < ast_json_array_size(filter) && (obj = ast_json_array_get(filter, i)); ++i) { if (ast_strlen_zero(ast_json_object_string_get(obj, "type"))) { ast_log(LOG_ERROR, "Filter event must have a type - app: %s, " "filter: %s\n", app->name, filter_type); return -1; } } } ao2_lock(app); ast_json_unref(*member); *member = filter ? ast_json_ref(filter) : NULL; ao2_unlock(app); return 0; }
void ast_ari_bridges_list(struct ast_variable *headers, struct ast_ari_bridges_list_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_cache *, cache, NULL, ao2_cleanup); RAII_VAR(struct ao2_container *, snapshots, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ao2_iterator i; void *obj; cache = ast_bridge_cache(); if (!cache) { ast_ari_response_error( response, 500, "Internal Server Error", "Message bus not initialized"); return; } ao2_ref(cache, +1); snapshots = stasis_cache_dump(cache, ast_bridge_snapshot_type()); if (!snapshots) { ast_ari_response_alloc_failed(response); return; } json = ast_json_array_create(); if (!json) { ast_ari_response_alloc_failed(response); return; } i = ao2_iterator_init(snapshots, 0); while ((obj = ao2_iterator_next(&i))) { RAII_VAR(struct stasis_message *, msg, obj, ao2_cleanup); struct ast_bridge_snapshot *snapshot = stasis_message_data(msg); struct ast_json *json_bridge = ast_bridge_snapshot_to_json(snapshot, stasis_app_get_sanitizer()); if (!json_bridge || ast_json_array_append(json, json_bridge)) { ao2_iterator_destroy(&i); ast_ari_response_alloc_failed(response); return; } } ao2_iterator_destroy(&i); ast_ari_response_ok(response, ast_json_ref(json)); }
static void return_sorcery_object(struct ast_sorcery *sorcery, void *sorcery_obj, struct ast_ari_response *response) { RAII_VAR(struct ast_json *, return_set, NULL, ast_json_unref); struct ast_variable *change_set; struct ast_variable *it_change_set; return_set = ast_json_array_create(); if (!return_set) { ast_ari_response_alloc_failed(response); return; } /* Note that we can't use the sorcery JSON change set directly, * as it will hand us back an Object (with fields), and we need * a more generic representation of whatever the API call asked * for, i.e., a list of tuples. */ change_set = ast_sorcery_objectset_create(sorcery, sorcery_obj); if (!change_set) { ast_ari_response_alloc_failed(response); return; } for (it_change_set = change_set; it_change_set; it_change_set = it_change_set->next) { struct ast_json *tuple; tuple = ast_json_pack("{s: s, s: s}", "attribute", it_change_set->name, "value", it_change_set->value); if (!tuple) { ast_variables_destroy(change_set); ast_ari_response_alloc_failed(response); return; } if (ast_json_array_append(return_set, tuple)) { ast_json_unref(tuple); ast_variables_destroy(change_set); ast_ari_response_alloc_failed(response); return; } } ast_variables_destroy(change_set); ast_ari_response_ok(response, ast_json_ref(return_set)); }
struct ast_json *ast_endpoint_snapshot_to_json( const struct ast_endpoint_snapshot *snapshot, const struct stasis_message_sanitizer *sanitize) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ast_json *channel_array; int i; json = ast_json_pack("{s: s, s: s, s: s, s: []}", "technology", snapshot->tech, "resource", snapshot->resource, "state", ast_endpoint_state_to_string(snapshot->state), "channel_ids"); if (json == NULL) { return NULL; } if (snapshot->max_channels != -1) { int res = ast_json_object_set(json, "max_channels", ast_json_integer_create(snapshot->max_channels)); if (res != 0) { return NULL; } } channel_array = ast_json_object_get(json, "channel_ids"); ast_assert(channel_array != NULL); for (i = 0; i < snapshot->num_channels; ++i) { int res; if (sanitize && sanitize->channel_id && sanitize->channel_id(snapshot->channel_ids[i])) { continue; } res = ast_json_array_append(channel_array, ast_json_string_create(snapshot->channel_ids[i])); if (res != 0) { return NULL; } } return ast_json_ref(json); }
static struct ast_json *channel_blob_to_json( struct stasis_message *message, const char *type, const struct stasis_message_sanitizer *sanitize) { RAII_VAR(struct ast_json *, out, NULL, ast_json_unref); struct ast_channel_blob *channel_blob = stasis_message_data(message); struct ast_json *blob = channel_blob->blob; struct ast_channel_snapshot *snapshot = channel_blob->snapshot; const struct timeval *tv = stasis_message_timestamp(message); int res = 0; if (blob == NULL || ast_json_is_null(blob)) { out = ast_json_object_create(); } else { /* blobs are immutable, so shallow copies are fine */ out = ast_json_copy(blob); } if (!out) { return NULL; } res |= ast_json_object_set(out, "type", ast_json_string_create(type)); res |= ast_json_object_set(out, "timestamp", ast_json_timeval(*tv, NULL)); /* For global channel messages, the snapshot is optional */ if (snapshot) { struct ast_json *json_channel = ast_channel_snapshot_to_json(snapshot, sanitize); if (!json_channel) { return NULL; } res |= ast_json_object_set(out, "channel", json_channel); } if (res != 0) { return NULL; } return ast_json_ref(out); }
static int message_received_handler(const char *endpoint_id, struct ast_json *json_msg, void *pvt) { struct ast_endpoint_snapshot *snapshot; struct ast_json *json_endpoint; struct ast_json *message; struct stasis_app *app = pvt; char *tech; char *resource; tech = ast_strdupa(endpoint_id); resource = strchr(tech, '/'); if (resource) { resource[0] = '\0'; resource++; } if (ast_strlen_zero(tech) || ast_strlen_zero(resource)) { return -1; } snapshot = ast_endpoint_latest_snapshot(tech, resource); if (!snapshot) { return -1; } json_endpoint = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer()); ao2_ref(snapshot, -1); if (!json_endpoint) { return -1; } message = ast_json_pack("{s: s, s: o, s: o, s: o}", "type", "TextMessageReceived", "timestamp", ast_json_timeval(ast_tvnow(), NULL), "endpoint", json_endpoint, "message", ast_json_ref(json_msg)); if (message) { app_send(app, message); ast_json_unref(message); } return 0; }
struct ast_json* create_dial_plan_info(struct ast_json* j_plan) { struct ast_json* j_res; if(j_plan == NULL) { ast_log(LOG_WARNING, "Wrong input parameter.\n"); return NULL; } j_res = ast_json_pack("{s:I, s:s}", "dial_timeout", ast_json_integer_get(ast_json_object_get(j_plan, "dial_timeout")), "plan_variables", ast_json_string_get(ast_json_object_get(j_plan, "variables"))? : "" ); if(ast_json_string_get(ast_json_object_get(j_plan, "caller_id")) != NULL) { ast_json_object_set(j_res, "callerid", ast_json_ref(ast_json_object_get(j_plan, "caller_id"))); } return j_res; }
void ast_ari_endpoints_get(struct ast_variable *headers, struct ast_ari_endpoints_get_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); RAII_VAR(struct ast_endpoint_snapshot *, snapshot, NULL, ao2_cleanup); snapshot = ast_endpoint_latest_snapshot(args->tech, args->resource); if (!snapshot) { ast_ari_response_error(response, 404, "Not Found", "Endpoint not found"); return; } json = ast_endpoint_snapshot_to_json(snapshot, stasis_app_get_sanitizer()); if (!json) { ast_ari_response_alloc_failed(response); return; } ast_ari_response_ok(response, ast_json_ref(json)); }
void ast_ari_recordings_list_stored(struct ast_variable *headers, struct ast_ari_recordings_list_stored_args *args, struct ast_ari_response *response) { RAII_VAR(struct ao2_container *, recordings, NULL, ao2_cleanup); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); struct ao2_iterator i; void *obj; recordings = stasis_app_stored_recording_find_all(); if (!recordings) { ast_ari_response_alloc_failed(response); return; } json = ast_json_array_create(); if (!json) { ast_ari_response_alloc_failed(response); return; } i = ao2_iterator_init(recordings, 0); while ((obj = ao2_iterator_next(&i))) { RAII_VAR(struct stasis_app_stored_recording *, recording, obj, ao2_cleanup); int r = ast_json_array_append( json, stasis_app_stored_recording_to_json(recording)); if (r != 0) { ast_ari_response_alloc_failed(response); ao2_iterator_destroy(&i); return; } } ao2_iterator_destroy(&i); ast_ari_response_ok(response, ast_json_ref(json)); }
/*! * \brief Performs common setup for a bridge playback operation * with both new controls and when existing controls are found. * * \param args_media media string split from arguments * \param args_lang language string split from arguments * \param args_offset_ms milliseconds offset split from arguments * \param args_playback_id string to use for playback split from * arguments (null valid) * \param response ARI response being built * \param bridge Bridge the playback is being peformed on * \param found_channel The channel that was found controlling playback * * \retval PLAY_FOUND_SUCCESS The operation was successful * \retval PLAY_FOUND_FAILURE The operation failed (terminal failure) * \retval PLAY_FOUND_CHANNEL_UNAVAILABLE The operation failed because * the channel requested to playback with is breaking down. */ static enum play_found_result ari_bridges_play_found(const char *args_media, const char *args_lang, int args_offset_ms, int args_skipms, const char *args_playback_id, struct ast_ari_response *response, struct ast_bridge *bridge, struct ast_channel *found_channel) { RAII_VAR(struct ast_channel *, play_channel, found_channel, ao2_cleanup); RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); RAII_VAR(char *, playback_url, NULL, ast_free); RAII_VAR(struct ast_json *, json, NULL, ast_json_unref); control = stasis_app_control_find_by_channel(play_channel); if (!control) { ast_ari_response_error( response, 500, "Internal Error", "Failed to get control snapshot"); return PLAY_FOUND_FAILURE; } ao2_lock(control); if (stasis_app_control_is_done(control)) { /* We failed to queue the action. Bailout and return that we aren't terminal. */ ao2_unlock(control); return PLAY_FOUND_CHANNEL_UNAVAILABLE; } if (ari_bridges_play_helper(args_media, args_lang, args_offset_ms, args_skipms, args_playback_id, response, bridge, control, &json, &playback_url)) { ao2_unlock(control); return PLAY_FOUND_FAILURE; } ao2_unlock(control); ast_ari_response_created(response, playback_url, ast_json_ref(json)); return PLAY_FOUND_SUCCESS; }
struct ast_multi_channel_blob *ast_multi_channel_blob_create(struct ast_json *blob) { RAII_VAR(struct ast_multi_channel_blob *, obj, ao2_alloc(sizeof(*obj), multi_channel_blob_dtor), ao2_cleanup); ast_assert(blob != NULL); if (!obj) { return NULL; } obj->channel_snapshots = ao2_container_alloc(NUM_MULTI_CHANNEL_BLOB_BUCKETS, channel_role_hash_cb, channel_role_single_cmp_cb); if (!obj->channel_snapshots) { return NULL; } obj->blob = ast_json_ref(blob); ao2_ref(obj, +1); return obj; }