static guint resume_a2dp(struct media_transport *transport, struct media_owner *owner) { struct a2dp_transport *a2dp = transport->data; struct media_endpoint *endpoint = transport->endpoint; struct a2dp_sep *sep = media_endpoint_get_sep(endpoint); guint id; if (a2dp->session == NULL) { a2dp->session = avdtp_get(transport->device); if (a2dp->session == NULL) return 0; } if (state_in_use(transport->state)) return a2dp_resume(a2dp->session, sep, a2dp_resume_complete, owner); if (a2dp_sep_lock(sep, a2dp->session) == FALSE) return 0; id = a2dp_resume(a2dp->session, sep, a2dp_resume_complete, owner); if (id == 0) { a2dp_sep_unlock(sep, a2dp->session); return 0; } if (transport->state == TRANSPORT_STATE_IDLE) transport_set_state(transport, TRANSPORT_STATE_REQUESTING); return id; }
static guint suspend_a2dp(struct media_transport *transport, struct media_owner *owner) { struct a2dp_transport *a2dp = transport->data; struct media_endpoint *endpoint = transport->endpoint; struct a2dp_sep *sep = media_endpoint_get_sep(endpoint); if (!owner) { a2dp_sep_unlock(sep, a2dp->session); transport->in_use = FALSE; return 0; } return a2dp_suspend(a2dp->session, sep, a2dp_suspend_complete, owner); }
static void a2dp_resume_complete(struct avdtp *session, struct avdtp_error *err, void *user_data) { struct media_owner *owner = user_data; struct media_request *req = owner->pending; struct media_transport *transport = owner->transport; struct a2dp_sep *sep = media_endpoint_get_sep(transport->endpoint); struct avdtp_stream *stream; int fd; uint16_t imtu, omtu; gboolean ret; req->id = 0; if (err) goto fail; stream = a2dp_sep_get_stream(sep); if (stream == NULL) goto fail; ret = avdtp_stream_get_transport(stream, &fd, &imtu, &omtu, NULL); if (ret == FALSE) goto fail; media_transport_set_fd(transport, fd, imtu, omtu); if (g_strstr_len(owner->accesstype, -1, "r") == NULL) imtu = 0; if (g_strstr_len(owner->accesstype, -1, "w") == NULL) omtu = 0; ret = g_dbus_send_reply(transport->conn, req->msg, DBUS_TYPE_UNIX_FD, &fd, DBUS_TYPE_UINT16, &imtu, DBUS_TYPE_UINT16, &omtu, DBUS_TYPE_INVALID); if (ret == FALSE) goto fail; media_owner_remove(owner); return; fail: media_transport_remove(transport, owner); }
static guint suspend_a2dp(struct media_transport *transport, struct media_owner *owner) { struct a2dp_transport *a2dp = transport->data; struct media_endpoint *endpoint = transport->endpoint; struct a2dp_sep *sep = media_endpoint_get_sep(endpoint); if (owner != NULL) return a2dp_suspend(a2dp->session, sep, a2dp_suspend_complete, owner); transport_set_state(transport, TRANSPORT_STATE_IDLE); a2dp_sep_unlock(sep, a2dp->session); return 0; }
static void a2dp_suspend_complete(struct avdtp *session, struct avdtp_error *err, void *user_data) { struct media_owner *owner = user_data; struct media_transport *transport = owner->transport; struct a2dp_sep *sep = media_endpoint_get_sep(transport->endpoint); /* Release always succeeds */ if (owner->pending) { owner->pending->id = 0; media_request_reply(owner->pending, transport->conn, 0); media_owner_remove(owner); } a2dp_sep_unlock(sep, transport->session); transport->in_use = FALSE; media_transport_remove(transport, owner); }
void media_transport_update_device_volume(struct btd_device *dev, uint8_t volume) { GSList *l; if (dev == NULL) return; for (l = transports; l; l = l->next) { struct media_transport *transport = l->data; if (transport->device != dev) continue; /* Volume is A2DP only */ if (media_endpoint_get_sep(transport->endpoint)) media_transport_update_volume(transport, volume); } }
static void a2dp_suspend_complete(struct avdtp *session, struct avdtp_error *err, void *user_data) { struct media_owner *owner = user_data; struct media_transport *transport = owner->transport; struct a2dp_transport *a2dp = transport->data; struct a2dp_sep *sep = media_endpoint_get_sep(transport->endpoint); /* Release always succeeds */ if (owner->pending) { owner->pending->id = 0; media_request_reply(owner->pending, 0); media_owner_remove(owner); } a2dp_sep_unlock(sep, a2dp->session); transport_set_state(transport, TRANSPORT_STATE_IDLE); media_transport_remove_owner(transport); }
uint8_t media_transport_get_device_volume(struct btd_device *dev) { GSList *l; if (dev == NULL) return 128; for (l = transports; l; l = l->next) { struct media_transport *transport = l->data; if (transport->device != dev) continue; /* Volume is A2DP only */ if (media_endpoint_get_sep(transport->endpoint)) return media_transport_get_volume(transport); } return 0; }
static guint resume_a2dp(struct media_transport *transport, struct media_owner *owner) { struct a2dp_transport *a2dp = transport->data; struct media_endpoint *endpoint = transport->endpoint; struct audio_device *device = transport->device; struct a2dp_sep *sep = media_endpoint_get_sep(endpoint); if (a2dp->session == NULL) { a2dp->session = avdtp_get(&device->src, &device->dst); if (a2dp->session == NULL) return 0; } if (transport->in_use == TRUE) goto done; transport->in_use = a2dp_sep_lock(sep, a2dp->session); if (transport->in_use == FALSE) return 0; done: return a2dp_resume(a2dp->session, sep, a2dp_resume_complete, owner); }