static DBusMessage *sink_resume(DBusConnection *conn, DBusMessage *msg, void *data) { struct audio_device *device = data; struct sink *sink = device->sink; struct pending_request *pending; int err; if (!sink->session) return g_dbus_create_error(msg, ERROR_INTERFACE ".NotConnected", "Device not Connected"); if (sink->connect || sink->disconnect) return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", strerror(EBUSY)); if (sink->state < AVDTP_STATE_OPEN) { DBusMessage *reply = dbus_message_new_method_return(msg); if (!reply) return NULL; avdtp_unref(sink->session); sink->session = NULL; return reply; } err = avdtp_start(sink->session, sink->stream); if (err < 0) return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "%s", strerror(-err)); return NULL; }
static void send_command(void) { avdtp_state_t state = avdtp_sep_get_state(local_sep); switch (command) { case CMD_GET_CONF: avdtp_get_configuration(avdtp, avdtp_stream); break; case CMD_OPEN: if (state == AVDTP_STATE_CONFIGURED) avdtp_open(avdtp, avdtp_stream); break; case CMD_START: if (state == AVDTP_STATE_OPEN) avdtp_start(avdtp, avdtp_stream); break; case CMD_SUSPEND: if (state == AVDTP_STATE_STREAMING) avdtp_suspend(avdtp , avdtp_stream); break; case CMD_CLOSE: if (state == AVDTP_STATE_STREAMING) avdtp_close(avdtp, avdtp_stream, FALSE); break; case CMD_ABORT: avdtp_abort(avdtp , avdtp_stream); break; case CMD_DELAY: avdtp_delay_report(avdtp , avdtp_stream , 250); break; default: break; } }
static void bt_stream_resume(const void *buf, uint16_t len) { const struct audio_cmd_resume_stream *cmd = buf; struct a2dp_setup *setup; int err; DBG(""); setup = find_setup(cmd->id); if (!setup) { error("Unable to find stream for endpoint %u", cmd->id); goto failed; } if (setup->state != HAL_AUDIO_STARTED) { err = avdtp_start(setup->dev->session, setup->stream); if (err < 0) { error("avdtp_start: %s", strerror(-err)); goto failed; } } ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM, AUDIO_STATUS_SUCCESS); return; failed: ipc_send_rsp(audio_ipc, AUDIO_SERVICE_ID, AUDIO_OP_RESUME_STREAM, AUDIO_STATUS_FAILED); }
static void stream_state_changed(struct avdtp_stream *stream, avdtp_state_t old_state, avdtp_state_t new_state, struct avdtp_error *err, void *user_data) { struct a2dp_sep *sep = user_data; if (new_state == AVDTP_STATE_OPEN) { struct a2dp_setup *setup; int err; setup = find_setup_by_stream(stream); if (!setup || !setup->start) return; setup->start = FALSE; err = avdtp_start(setup->session, stream); if (err < 0 && err != -EINPROGRESS) { error("avdtp_start: %s (%d)", strerror(-err), -err); finalize_setup_errno(setup, err, finalize_resume, NULL); return; } sep->starting = TRUE; return; } if (new_state != AVDTP_STATE_IDLE) return; if (sep->suspend_timer) { g_source_remove(sep->suspend_timer); sep->suspend_timer = 0; } if (sep->session) { avdtp_unref(sep->session); sep->session = NULL; } sep->stream = NULL; if (sep->endpoint && sep->endpoint->clear_configuration) sep->endpoint->clear_configuration(sep, sep->user_data); }
static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, struct avdtp_error *err, void *user_data) { struct a2dp_sep *a2dp_sep = user_data; struct a2dp_setup *setup; gboolean start; if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) DBG("Sink %p: Suspend_Cfm", sep); else DBG("Source %p: Suspend_Cfm", sep); a2dp_sep->suspending = FALSE; setup = find_setup_by_session(session); if (!setup) return; start = setup->start; setup->start = FALSE; if (err) { setup->stream = NULL; setup->err = err; finalize_suspend(setup); } else finalize_suspend_errno(setup, 0); if (!start) return; if (err) { setup->err = err; finalize_suspend(setup); } else if (avdtp_start(session, a2dp_sep->stream) < 0) { struct avdtp_error start_err; error("avdtp_start failed"); avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO); setup->err = err; finalize_suspend(setup); } }