void ast_ari_bridges_set_video_source(struct ast_variable *headers, struct ast_ari_bridges_set_video_source_args *args, struct ast_ari_response *response) { struct ast_bridge *bridge; struct stasis_app_control *control; bridge = find_bridge(response, args->bridge_id); if (!bridge) { return; } control = find_channel_control(response, args->channel_id); if (!control) { ao2_ref(bridge, -1); return; } if (stasis_app_get_bridge(control) != bridge) { ast_ari_response_error(response, 422, "Unprocessable Entity", "Channel not in this bridge"); ao2_ref(bridge, -1); ao2_ref(control, -1); return; } stasis_app_send_command(control, bridge_set_video_source_cb, ao2_bump(bridge), __ao2_cleanup); ao2_ref(bridge, -1); ao2_ref(control, -1); ast_ari_response_no_content(response); }
void ast_ari_channels_hangup(struct ast_variable *headers, struct ast_ari_channels_hangup_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_channel *, chan, NULL, ao2_cleanup); int cause; chan = ast_channel_get_by_name(args->channel_id); if (chan == NULL) { ast_ari_response_error( response, 404, "Not Found", "Channel not found"); return; } if (ast_strlen_zero(args->reason) || !strcmp(args->reason, "normal")) { cause = AST_CAUSE_NORMAL; } else if (!strcmp(args->reason, "busy")) { cause = AST_CAUSE_BUSY; } else if (!strcmp(args->reason, "congestion")) { cause = AST_CAUSE_CONGESTION; } else { ast_ari_response_error( response, 400, "Invalid Reason", "Invalid reason for hangup provided"); return; } ast_channel_hangupcause_set(chan, cause); ast_softhangup(chan, AST_SOFTHANGUP_EXPLICIT); ast_ari_response_no_content(response); }
static void control_recording(const char *name, enum stasis_app_recording_media_operation operation, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_recording *, recording, NULL, ao2_cleanup); enum stasis_app_recording_oper_results res; recording = stasis_app_recording_find_by_name(name); if (recording == NULL) { ast_ari_response_error(response, 404, "Not Found", "Recording not found"); return; } res = stasis_app_recording_operation(recording, operation); switch (res) { case STASIS_APP_RECORDING_OPER_OK: ast_ari_response_no_content(response); return; case STASIS_APP_RECORDING_OPER_FAILED: ast_ari_response_error(response, 500, "Internal Server Error", "Recording operation failed"); return; case STASIS_APP_RECORDING_OPER_NOT_RECORDING: ast_ari_response_error(response, 409, "Conflict", "Recording not in session"); } }
void ast_ari_asterisk_add_log(struct ast_variable *headers, struct ast_ari_asterisk_add_log_args *args, struct ast_ari_response *response) { int res; ast_assert(response != NULL); res = ast_logger_create_channel(args->log_channel_name, args->configuration); if (res == AST_LOGGER_DECLINE) { ast_ari_response_error(response, 400, "Bad Request", "Configuration levels are required"); return; } else if (res == AST_LOGGER_FAILURE) { ast_ari_response_error(response, 409, "Conflict", "Log channel already exists"); return; } else if (res == AST_LOGGER_ALLOC_ERROR) { ast_ari_response_error(response, 500, "Internal Server Error", "Allocation failed"); return; } ast_ari_response_no_content(response); }
void ast_ari_playbacks_stop(struct ast_variable *headers, struct ast_ari_playbacks_stop_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup); enum stasis_playback_oper_results res; playback = stasis_app_playback_find_by_id(args->playback_id); if (playback == NULL) { ast_ari_response_error(response, 404, "Not Found", "Playback not found"); return; } res = stasis_app_playback_operation(playback, STASIS_PLAYBACK_STOP); switch (res) { case STASIS_PLAYBACK_OPER_OK: ast_ari_response_no_content(response); return; case STASIS_PLAYBACK_OPER_FAILED: ast_ari_response_error(response, 500, "Internal Server Error", "Could not stop playback"); return; case STASIS_PLAYBACK_OPER_NOT_PLAYING: /* Stop operation should be valid even when not playing */ ast_assert(0); ast_ari_response_error(response, 500, "Internal Server Error", "Could not stop playback"); return; } }
void ast_ari_asterisk_unload_module(struct ast_variable *headers, struct ast_ari_asterisk_unload_module_args *args, struct ast_ari_response *response) { int unload_result; enum ast_module_unload_mode unload_mode = AST_FORCE_SOFT; ast_assert(response != NULL); if (!ast_module_check(args->module_name)) { ast_ari_response_error( response, 404, "Not Found", "Module not found in running modules"); return; } unload_result = ast_unload_resource(args->module_name, unload_mode); if (unload_result != 0) { ast_ari_response_error( response, 409, "Conflict", "Module could not be unloaded"); return; } ast_ari_response_no_content(response); }
void ast_ari_channels_redirect(struct ast_variable *headers, struct ast_ari_channels_redirect_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); RAII_VAR(struct ast_channel_snapshot *, chan_snapshot, NULL, ao2_cleanup); char *tech; char *resource; int tech_len; control = find_control(response, args->channel_id); if (!control) { return; } if (ast_strlen_zero(args->endpoint)) { ast_ari_response_error(response, 400, "Not Found", "Required parameter 'endpoint' not provided."); return; } tech = ast_strdupa(args->endpoint); if (!(resource = strchr(tech, '/')) || !(tech_len = resource - tech)) { ast_ari_response_error(response, 422, "Unprocessable Entity", "Endpoint parameter '%s' does not contain tech/resource", args->endpoint); return; } *resource++ = '\0'; if (ast_strlen_zero(resource)) { ast_ari_response_error(response, 422, "Unprocessable Entity", "No resource provided in endpoint parameter '%s'", args->endpoint); return; } chan_snapshot = ast_channel_snapshot_get_latest(args->channel_id); if (!chan_snapshot) { ast_ari_response_error(response, 500, "Internal Server Error", "Unable to find channel snapshot for '%s'", args->channel_id); return; } if (strncasecmp(chan_snapshot->type, tech, tech_len)) { ast_ari_response_error(response, 422, "Unprocessable Entity", "Endpoint technology '%s' does not match channel technology '%s'", tech, chan_snapshot->type); return; } if (stasis_app_control_redirect(control, resource)) { ast_ari_response_error(response, 500, "Internal Server Error", "Failed to redirect channel"); return; } ast_ari_response_no_content(response); }
void ast_ari_events_user_event(struct ast_variable *headers, struct ast_ari_events_user_event_args *args, struct ast_ari_response *response) { enum stasis_app_user_event_res res; struct ast_json *json_variables = NULL; if (args->variables) { ast_ari_events_user_event_parse_body(args->variables, args); json_variables = ast_json_object_get(args->variables, "variables"); } if (ast_strlen_zero(args->application)) { ast_ari_response_error(response, 400, "Bad Request", "Missing parameter application"); return; } res = stasis_app_user_event(args->application, args->event_name, args->source, args->source_count, json_variables); switch (res) { case STASIS_APP_USER_OK: ast_ari_response_no_content(response); break; case STASIS_APP_USER_APP_NOT_FOUND: ast_ari_response_error(response, 404, "Not Found", "Application not found"); break; case STASIS_APP_USER_EVENT_SOURCE_NOT_FOUND: ast_ari_response_error(response, 422, "Unprocessable Entity", "Event source was not found"); break; case STASIS_APP_USER_EVENT_SOURCE_BAD_SCHEME: ast_ari_response_error(response, 400, "Bad Request", "Invalid event source URI scheme"); break; case STASIS_APP_USER_USEREVENT_INVALID: ast_ari_response_error(response, 400, "Bad Request", "Invalid userevnet data"); break; case STASIS_APP_USER_INTERNAL_ERROR: default: ast_ari_response_error(response, 500, "Internal Server Error", "Error processing request"); } }
void ast_ari_mailboxes_update(struct ast_variable *headers, struct ast_ari_mailboxes_update_args *args, struct ast_ari_response *response) { if (stasis_app_mailbox_update(args->mailbox_name, args->old_messages, args->new_messages)) { ast_ari_response_error(response, 500, "Internal Server Error", "Error updating mailbox"); return; } ast_ari_response_no_content(response); }
void ast_ari_playbacks_control(struct ast_variable *headers, struct ast_ari_playbacks_control_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_playback *, playback, NULL, ao2_cleanup); enum stasis_app_playback_media_operation oper; enum stasis_playback_oper_results res; if (!args->operation) { ast_ari_response_error(response, 400, "Bad Request", "Missing operation"); return; } if (strcmp(args->operation, "unpause") == 0) { oper = STASIS_PLAYBACK_UNPAUSE; } else if (strcmp(args->operation, "pause") == 0) { oper = STASIS_PLAYBACK_PAUSE; } else if (strcmp(args->operation, "restart") == 0) { oper = STASIS_PLAYBACK_RESTART; } else if (strcmp(args->operation, "reverse") == 0) { oper = STASIS_PLAYBACK_REVERSE; } else if (strcmp(args->operation, "forward") == 0) { oper = STASIS_PLAYBACK_FORWARD; } else { ast_ari_response_error(response, 400, "Bad Request", "Invalid operation %s", args->operation); return; } playback = stasis_app_playback_find_by_id(args->playback_id); if (playback == NULL) { ast_ari_response_error(response, 404, "Not Found", "Playback not found"); return; } res = stasis_app_playback_operation(playback, oper); switch (res) { case STASIS_PLAYBACK_OPER_OK: ast_ari_response_no_content(response); return; case STASIS_PLAYBACK_OPER_FAILED: ast_ari_response_error(response, 500, "Internal Server Error", "Could not %s playback", args->operation); return; case STASIS_PLAYBACK_OPER_NOT_PLAYING: ast_ari_response_error(response, 409, "Conflict", "Can only %s while media is playing", args->operation); return; } }
void ast_ari_bridges_destroy(struct ast_variable *headers, struct ast_ari_bridges_destroy_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup); if (!bridge) { return; } stasis_app_bridge_destroy(args->bridge_id); ast_ari_response_no_content(response); }
void ast_ari_asterisk_reload_module(struct ast_variable *headers, struct ast_ari_asterisk_reload_module_args *args, struct ast_ari_response *response) { enum ast_module_reload_result reload_result; ast_assert(response != NULL); if (!ast_module_check(args->module_name)) { ast_ari_response_error( response, 404, "Not Found", "Module not found in running modules"); return; } reload_result = ast_module_reload(args->module_name); if (reload_result == AST_MODULE_RELOAD_NOT_FOUND) { ast_ari_response_error( response, 404, "Not Found", "Module could not be found"); return; } else if (reload_result == AST_MODULE_RELOAD_ERROR) { ast_ari_response_error( response, 409, "Conflict", "An unknown error occurred while reloading the module"); return; } else if (reload_result == AST_MODULE_RELOAD_IN_PROGRESS) { ast_ari_response_error( response, 409, "Conflict", "Another reload is currently in progress"); return; } else if (reload_result == AST_MODULE_RELOAD_UNINITIALIZED) { ast_ari_response_error( response, 409, "Conflict", "Module has not been initialized"); return; } else if (reload_result == AST_MODULE_RELOAD_NOT_IMPLEMENTED) { ast_ari_response_error( response, 409, "Conflict", "Module does not support reloading"); return; } else if (reload_result == AST_MODULE_RELOAD_QUEUED) { ast_ari_response_accepted(response); return; } ast_ari_response_no_content(response); }
void ast_ari_channels_stop_silence(struct ast_variable *headers, struct ast_ari_channels_stop_silence_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); control = find_control(response, args->channel_id); if (control == NULL) { /* Response filled in by find_control */ return; } stasis_app_control_silence_stop(control); ast_ari_response_no_content(response); }
void ast_ari_channels_ring_stop(struct ast_variable *headers, struct ast_ari_channels_ring_stop_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); control = find_control(response, args->channel_id); if (control == NULL) { return; } stasis_app_control_ring_stop(control); ast_ari_response_no_content(response); }
void ast_ari_set_global_var(struct ast_variable *headers, struct ast_set_global_var_args *args, struct ast_ari_response *response) { ast_assert(response != NULL); if (ast_strlen_zero(args->variable)) { ast_ari_response_error( response, 400, "Bad Request", "Variable name is required"); return; } pbx_builtin_setvar_helper(NULL, args->variable, args->value); ast_ari_response_no_content(response); }
void ast_ari_bridges_clear_video_source(struct ast_variable *headers, struct ast_ari_bridges_clear_video_source_args *args, struct ast_ari_response *response) { struct ast_bridge *bridge; bridge = find_bridge(response, args->bridge_id); if (!bridge) { return; } ast_bridge_lock(bridge); ast_bridge_set_talker_src_video_mode(bridge); ast_bridge_unlock(bridge); ao2_ref(bridge, -1); ast_ari_response_no_content(response); }
void ast_ari_mailboxes_delete(struct ast_variable *headers, struct ast_ari_mailboxes_delete_args *args, struct ast_ari_response *response) { switch (stasis_app_mailbox_delete(args->mailbox_name)) { case STASIS_MAILBOX_MISSING: ast_ari_response_error(response, 404, "Not Found", "Mailbox does not exist"); return; case STASIS_MAILBOX_ERROR: ast_ari_response_error(response, 500, "INternal Server Error", "Failed to delete the mailbox"); return; case STASIS_MAILBOX_OK: ast_ari_response_no_content(response); } }
void ast_ari_asterisk_delete_object(struct ast_variable *headers, struct ast_ari_asterisk_delete_object_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_sorcery *, sorcery, NULL, ast_sorcery_unref); RAII_VAR(struct ast_sorcery_object_type *, object_type, NULL, ao2_cleanup); RAII_VAR(void *, sorcery_obj, NULL, ao2_cleanup); sorcery = ast_sorcery_retrieve_by_module_name(args->config_class); if (!sorcery) { ast_ari_response_error( response, 404, "Not Found", "configClass '%s' not found", args->config_class); return; } object_type = ast_sorcery_get_object_type(sorcery, args->object_type); if (!object_type) { ast_ari_response_error( response, 404, "Not Found", "objectType '%s' not found", args->object_type); return; } sorcery_obj = ast_sorcery_retrieve_by_id(sorcery, args->object_type, args->id); if (!sorcery_obj) { ast_ari_response_error( response, 404, "Not Found", "Object with id '%s' not found", args->id); return; } if (ast_sorcery_delete(sorcery, sorcery_obj)) { ast_ari_response_error( response, 403, "Forbidden", "Could not delete object with id '%s'", args->id); return; } ast_ari_response_no_content(response); }
void ast_ari_bridges_add_channel(struct ast_variable *headers, struct ast_ari_bridges_add_channel_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup); RAII_VAR(struct control_list *, list, NULL, ao2_cleanup); size_t i; int has_error = 0; if (!bridge) { /* Response filled in by find_bridge() */ return; } list = control_list_create(response, args->channel_count, args->channel); if (!list) { /* Response filled in by control_list_create() */ return; } for (i = 0; i < list->count; ++i) { stasis_app_control_clear_roles(list->controls[i]); if (!ast_strlen_zero(args->role)) { if (stasis_app_control_add_role(list->controls[i], args->role)) { ast_ari_response_alloc_failed(response); return; } } } for (i = 0; i < list->count; ++i) { if ((has_error = check_add_remove_channel(response, list->controls[i], stasis_app_control_add_channel_to_bridge( list->controls[i], bridge)))) { break; } } if (!has_error) { ast_ari_response_no_content(response); } }
void ast_ari_bridges_stop_moh(struct ast_variable *headers, struct ast_ari_bridges_stop_moh_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup); if (!bridge) { /* the response is provided by find_bridge() */ return; } if (stasis_app_bridge_moh_stop(bridge)) { ast_ari_response_error( response, 409, "Conflict", "Bridge isn't playing music"); return; } ast_ari_response_no_content(response); }
void ast_ari_channels_answer(struct ast_variable *headers, struct ast_ari_channels_answer_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); control = find_control(response, args->channel_id); if (control == NULL) { return; } if (stasis_app_control_answer(control) != 0) { ast_ari_response_error( response, 500, "Internal Server Error", "Failed to answer channel"); return; } ast_ari_response_no_content(response); }
void ast_ari_channels_continue_in_dialplan( struct ast_variable *headers, struct ast_ari_channels_continue_in_dialplan_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); ast_assert(response != NULL); control = find_control(response, args->channel_id); if (control == NULL) { return; } if (stasis_app_control_continue(control, args->context, args->extension, args->priority)) { ast_ari_response_alloc_failed(response); return; } ast_ari_response_no_content(response); }
void ast_ari_recordings_delete_stored(struct ast_variable *headers, struct ast_ari_recordings_delete_stored_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_stored_recording *, recording, NULL, ao2_cleanup); int res; 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; } res = stasis_app_stored_recording_delete(recording); if (res != 0) { switch (errno) { case EACCES: case EPERM: ast_ari_response_error(response, 500, "Internal Server Error", "Delete failed"); break; default: ast_log(LOG_WARNING, "Unexpected error deleting recording %s: %s\n", args->recording_name, strerror(errno)); ast_ari_response_error(response, 500, "Internal Server Error", "Delete failed"); break; } return; } ast_ari_response_no_content(response); }
void ast_ari_bridges_remove_channel(struct ast_variable *headers, struct ast_ari_bridges_remove_channel_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup); RAII_VAR(struct control_list *, list, NULL, ao2_cleanup); size_t i; if (!bridge) { /* Response filled in by find_bridge() */ return; } list = control_list_create(response, args->channel_count, args->channel); if (!list) { /* Response filled in by control_list_create() */ return; } /* Make sure all of the channels are in this bridge */ for (i = 0; i < list->count; ++i) { if (stasis_app_get_bridge(list->controls[i]) != bridge) { ast_log(LOG_WARNING, "Channel %s not in bridge %s\n", args->channel[i], args->bridge_id); ast_ari_response_error(response, 422, "Unprocessable Entity", "Channel not in this bridge"); return; } } /* Now actually remove it */ for (i = 0; i < list->count; ++i) { stasis_app_control_remove_channel_from_bridge(list->controls[i], bridge); } ast_ari_response_no_content(response); }
void ast_ari_channels_send_dtmf(struct ast_variable *headers, struct ast_ari_channels_send_dtmf_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); control = find_control(response, args->channel_id); if (control == NULL) { return; } if (ast_strlen_zero(args->dtmf)) { ast_ari_response_error( response, 400, "Bad Request", "DTMF is required"); return; } stasis_app_control_dtmf(control, args->dtmf, args->before, args->between, args->duration, args->after); ast_ari_response_no_content(response); }
void ast_ari_asterisk_delete_log(struct ast_variable *headers, struct ast_ari_asterisk_delete_log_args *args, struct ast_ari_response *response) { int res; ast_assert(response != NULL); res = ast_logger_remove_channel(args->log_channel_name); if (res == AST_LOGGER_FAILURE) { ast_ari_response_error(response, 404, "Not Found", "Log channel does not exist"); return; } else if (res == AST_LOGGER_ALLOC_ERROR) { ast_ari_response_error(response, 500, "Internal Server Error", "Allocation failed"); return; } ast_ari_response_no_content(response); }
void ast_ari_device_states_update(struct ast_variable *headers, struct ast_ari_device_states_update_args *args, struct ast_ari_response *response) { switch (stasis_app_device_state_update( args->device_name, args->device_state)) { case STASIS_DEVICE_STATE_NOT_CONTROLLED: ast_ari_response_error(response, 409, "Conflict", "Uncontrolled device specified"); return; case STASIS_DEVICE_STATE_MISSING: ast_ari_response_error(response, 404, "Not Found", "Device name is missing"); return; case STASIS_DEVICE_STATE_UNKNOWN: ast_ari_response_error(response, 500, "Internal Server Error", "Unknown device"); return; case STASIS_DEVICE_STATE_OK: case STASIS_DEVICE_STATE_SUBSCRIBERS: /* shouldn't be returned for update */ ast_ari_response_no_content(response); } }
void ast_ari_device_states_delete(struct ast_variable *headers, struct ast_ari_device_states_delete_args *args, struct ast_ari_response *response) { switch (stasis_app_device_state_delete(args->device_name)) { case STASIS_DEVICE_STATE_NOT_CONTROLLED: ast_ari_response_error(response, 409, "Conflict", "Uncontrolled device specified"); return; case STASIS_DEVICE_STATE_MISSING: ast_ari_response_error(response, 404, "Not Found", "Device name is missing"); return; case STASIS_DEVICE_STATE_SUBSCRIBERS: ast_ari_response_error(response, 500, "Internal Server Error", "Cannot delete device with subscribers"); return; case STASIS_DEVICE_STATE_OK: case STASIS_DEVICE_STATE_UNKNOWN: ast_ari_response_no_content(response); } }
void ast_ari_channels_unmute(struct ast_variable *headers, struct ast_ari_channels_unmute_args *args, struct ast_ari_response *response) { RAII_VAR(struct stasis_app_control *, control, NULL, ao2_cleanup); unsigned int direction = 0; enum ast_frame_type frametype = AST_FRAME_VOICE; control = find_control(response, args->channel_id); if (control == NULL) { return; } if (ast_strlen_zero(args->direction)) { ast_ari_response_error( response, 400, "Bad Request", "Direction is required"); return; } if (!strcmp(args->direction, "in")) { direction = AST_MUTE_DIRECTION_READ; } else if (!strcmp(args->direction, "out")) { direction = AST_MUTE_DIRECTION_WRITE; } else if (!strcmp(args->direction, "both")) { direction = AST_MUTE_DIRECTION_READ | AST_MUTE_DIRECTION_WRITE; } else { ast_ari_response_error( response, 400, "Bad Request", "Invalid direction specified"); return; } stasis_app_control_unmute(control, direction, frametype); ast_ari_response_no_content(response); }
void ast_ari_bridges_start_moh(struct ast_variable *headers, struct ast_ari_bridges_start_moh_args *args, struct ast_ari_response *response) { RAII_VAR(struct ast_bridge *, bridge, find_bridge(response, args->bridge_id), ao2_cleanup); struct ast_channel *moh_channel; const char *moh_class = args->moh_class; if (!bridge) { /* The response is provided by find_bridge() */ return; } moh_channel = stasis_app_bridge_moh_channel(bridge); if (!moh_channel) { ast_ari_response_alloc_failed(response); return; } ast_moh_start(moh_channel, moh_class, NULL); ast_ari_response_no_content(response); }