static gboolean headset_connect_timeout(gpointer user_data) { struct audio_device *dev = user_data; struct dev_priv *priv = dev->priv; dev->priv->headset_timer = 0; if (dev->headset == NULL) return FALSE; if (headset_config_stream(dev, FALSE, NULL, NULL) == 0) { if (priv->state != AUDIO_STATE_CONNECTED && (priv->sink_state == SINK_STATE_CONNECTED || priv->sink_state == SINK_STATE_PLAYING)) device_set_state(dev, AUDIO_STATE_CONNECTED); } return FALSE; }
static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg, void *data) { struct audio_device *dev = data; struct dev_priv *priv = dev->priv; if (priv->state == AUDIO_STATE_CONNECTING) return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", "Connect in Progress"); else if (priv->state == AUDIO_STATE_CONNECTED) return g_dbus_create_error(msg, ERROR_INTERFACE ".AlreadyConnected", "Already Connected"); dev->auto_connect = TRUE; if (dev->headset) headset_config_stream(dev, FALSE, NULL, NULL); if (priv->state != AUDIO_STATE_CONNECTING && dev->sink) { struct avdtp *session = avdtp_get(&dev->src, &dev->dst); if (!session) return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed", "Failed to get AVDTP session"); sink_setup_stream(dev->sink, session); avdtp_unref(session); } /* The previous calls should cause a call to the state callback to * indicate AUDIO_STATE_CONNECTING */ if (priv->state != AUDIO_STATE_CONNECTING) return g_dbus_create_error(msg, ERROR_INTERFACE ".ConnectFailed", "Headset connect failed"); priv->conn_req = dbus_message_ref(msg); return NULL; }
static void start_config(struct audio_device *dev, struct unix_client *client) { struct a2dp_data *a2dp; struct headset_data *hs; unsigned int id; switch (client->type) { case TYPE_SINK: case TYPE_SOURCE: a2dp = &client->d.a2dp; if (!a2dp->session) a2dp->session = avdtp_get(&dev->src, &dev->dst); if (!a2dp->session) { error("Unable to get a session"); goto failed; } if (!a2dp->sep) { error("seid %d not opened", client->seid); goto failed; } id = a2dp_config(a2dp->session, a2dp->sep, a2dp_config_complete, client->caps, client); client->cancel = a2dp_cancel; break; case TYPE_HEADSET: hs = &client->d.hs; if (!hs->locked) { error("seid %d not opened", client->seid); goto failed; } id = headset_config_stream(dev, TRUE, headset_setup_complete, client); client->cancel = headset_cancel_stream; break; case TYPE_GATEWAY: if (gateway_config_stream(dev, gateway_setup_complete, client) >= 0) { client->cancel = gateway_cancel_stream; id = 1; } else id = 0; break; default: error("No known services for device"); goto failed; } if (id == 0) { error("config failed"); goto failed; } client->req_id = id; return; failed: unix_ipc_error(client, BT_SET_CONFIGURATION, EIO); }
static void start_config(struct audio_device *dev, struct unix_client *client) { struct a2dp_data *a2dp; struct headset_data *hs; struct avdtp_remote_sep *rsep; struct avdtp_service_capability *media_scms_t; struct avdtp_content_protection_capability scms_t_cap = {0x02, 0x00}; unsigned int id; switch (client->type) { case TYPE_SINK: case TYPE_SOURCE: a2dp = &client->d.a2dp; if (!a2dp->session) a2dp->session = avdtp_get(&dev->src, &dev->dst); if (!a2dp->session) { error("Unable to get a session"); goto failed; } if (!a2dp->sep) { error("seid %d not opened", client->seid); goto failed; } rsep = avdtp_get_remote_sep(a2dp->session, client->seid); media_scms_t = avdtp_get_remote_sep_protection(rsep); if (media_scms_t && (memcmp(media_scms_t->data, &scms_t_cap, sizeof(scms_t_cap)) == 0)) { media_scms_t = avdtp_service_cap_new(AVDTP_CONTENT_PROTECTION, &scms_t_cap, 2); client->caps = g_slist_append(client->caps, media_scms_t); } id = a2dp_config(a2dp->session, a2dp->sep, a2dp_config_complete, client->caps, client); client->cancel = a2dp_cancel; break; case TYPE_HEADSET: hs = &client->d.hs; if (!hs->locked) { error("seid %d not opened", client->seid); goto failed; } id = headset_config_stream(dev, TRUE, headset_setup_complete, client); client->cancel = headset_cancel_stream; break; case TYPE_GATEWAY: if (gateway_config_stream(dev, gateway_setup_complete, client) >= 0) { client->cancel = gateway_cancel_stream; id = 1; } else id = 0; break; default: error("No known services for device"); goto failed; } if (id == 0) { error("config failed"); goto failed; } client->req_id = id; g_slist_free(client->caps); client->caps = NULL; return; failed: if (client->caps) { g_slist_free(client->caps); client->caps = NULL; } unix_ipc_error(client, BT_SET_CONFIGURATION, EIO); }