* [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect
@ 2012-11-21 12:10 Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 2/6] audio: Split A2DP into two btd_profile Luiz Augusto von Dentz
` (5 more replies)
0 siblings, 6 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2012-11-21 12:10 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
We should with higher priority first.
---
src/device.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/device.c b/src/device.c
index 0053098..fd29a7f 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1299,7 +1299,7 @@ static gint profile_prio_cmp(gconstpointer a, gconstpointer b)
{
const struct btd_profile *p1 = a, *p2 = b;
- return p1->priority - p2->priority;
+ return p2->priority - p1->priority;
}
static DBusMessage *connect_profiles(struct btd_device *dev, DBusMessage *msg,
--
1.7.11.7
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 2/6] audio: Split A2DP into two btd_profile
2012-11-21 12:10 [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Luiz Augusto von Dentz
@ 2012-11-21 12:10 ` Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 3/6] source: Add profile .connect and .disconnect Luiz Augusto von Dentz
` (4 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2012-11-21 12:10 UTC (permalink / raw)
To: linux-bluetooth
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Merging the three audio profiles (AVDTP, A2DP sink and A2DP source)
into one was convenient in the past was doesn't fit very well the new
btd_profile approach. The split is also more consistent with other
existing profiles.
---
profiles/audio/a2dp.c | 80 +++++++++++++++++++++++------------------------
profiles/audio/a2dp.h | 3 +-
profiles/audio/manager.c | 81 +++++++++++++++++++++++++++++++-----------------
3 files changed, 92 insertions(+), 72 deletions(-)
diff --git a/profiles/audio/a2dp.c b/profiles/audio/a2dp.c
index 50c0f43..177f653 100644
--- a/profiles/audio/a2dp.c
+++ b/profiles/audio/a2dp.c
@@ -1166,63 +1166,59 @@ static struct a2dp_server *find_server(GSList *list, const bdaddr_t *src)
return NULL;
}
-int a2dp_register(const bdaddr_t *src, GKeyFile *config)
+static struct a2dp_server *a2dp_server_register(const bdaddr_t *src,
+ GKeyFile *config)
{
- gboolean source = TRUE, sink = FALSE;
- char *str;
- GError *err = NULL;
struct a2dp_server *server;
+ int av_err;
- if (!config)
- goto proceed;
+ server = g_new0(struct a2dp_server, 1);
- str = g_key_file_get_string(config, "General", "Enable", &err);
-
- if (err) {
- DBG("audio.conf: %s", err->message);
- g_clear_error(&err);
- } else {
- if (strstr(str, "Sink"))
- source = TRUE;
- if (strstr(str, "Source"))
- sink = TRUE;
- g_free(str);
+ av_err = avdtp_init(src, config);
+ if (av_err < 0) {
+ DBG("AVDTP not registered");
+ g_free(server);
+ return NULL;
}
- str = g_key_file_get_string(config, "General", "Disable", &err);
+ bacpy(&server->src, src);
+ servers = g_slist_append(servers, server);
- if (err) {
- DBG("audio.conf: %s", err->message);
- g_clear_error(&err);
- } else {
- if (strstr(str, "Sink"))
- source = FALSE;
- if (strstr(str, "Source"))
- sink = FALSE;
- g_free(str);
- }
+ return server;
+}
-proceed:
+int a2dp_source_register(const bdaddr_t *src, GKeyFile *config)
+{
+ struct a2dp_server *server;
server = find_server(servers, src);
- if (!server) {
- int av_err;
+ if (server != NULL)
+ goto done;
- server = g_new0(struct a2dp_server, 1);
+ server = a2dp_server_register(src, config);
+ if (server == NULL)
+ return -EPROTONOSUPPORT;
- av_err = avdtp_init(src, config);
- if (av_err < 0) {
- g_free(server);
- return av_err;
- }
+done:
+ server->source_enabled = TRUE;
- bacpy(&server->src, src);
- servers = g_slist_append(servers, server);
- }
+ return 0;
+}
- server->source_enabled = source;
+int a2dp_sink_register(const bdaddr_t *src, GKeyFile *config)
+{
+ struct a2dp_server *server;
- server->sink_enabled = sink;
+ server = find_server(servers, src);
+ if (server != NULL)
+ goto done;
+
+ server = a2dp_server_register(src, config);
+ if (server == NULL)
+ return -EPROTONOSUPPORT;
+
+done:
+ server->sink_enabled = TRUE;
return 0;
}
diff --git a/profiles/audio/a2dp.h b/profiles/audio/a2dp.h
index 736bc66..ded1060 100644
--- a/profiles/audio/a2dp.h
+++ b/profiles/audio/a2dp.h
@@ -64,7 +64,8 @@ typedef void (*a2dp_stream_cb_t) (struct avdtp *session,
struct avdtp_error *err,
void *user_data);
-int a2dp_register(const bdaddr_t *src, GKeyFile *config);
+int a2dp_source_register(const bdaddr_t *src, GKeyFile *config);
+int a2dp_sink_register(const bdaddr_t *src, GKeyFile *config);
void a2dp_unregister(const bdaddr_t *src);
struct a2dp_sep *a2dp_add_sep(const bdaddr_t *src, uint8_t type,
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index e453e26..2f36efd 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -122,7 +122,7 @@ static void audio_remove(struct btd_profile *p, struct btd_device *device)
audio_device_unregister(dev);
}
-static int a2dp_probe(struct btd_profile *p, struct btd_device *device,
+static int a2dp_source_probe(struct btd_profile *p, struct btd_device *device,
GSList *uuids)
{
struct audio_device *audio_dev;
@@ -133,13 +133,23 @@ static int a2dp_probe(struct btd_profile *p, struct btd_device *device,
return -1;
}
- if (g_slist_find_custom(uuids, A2DP_SINK_UUID, bt_uuid_strcmp) &&
- audio_dev->sink == NULL)
- audio_dev->sink = sink_init(audio_dev);
+ audio_dev->source = source_init(audio_dev);
- if (g_slist_find_custom(uuids, A2DP_SOURCE_UUID, bt_uuid_strcmp) &&
- audio_dev->source == NULL)
- audio_dev->source = source_init(audio_dev);
+ return 0;
+}
+
+static int a2dp_sink_probe(struct btd_profile *p, struct btd_device *device,
+ GSList *uuids)
+{
+ struct audio_device *audio_dev;
+
+ audio_dev = get_audio_dev(device);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ audio_dev->sink = sink_init(audio_dev);
return 0;
}
@@ -213,12 +223,11 @@ static struct audio_adapter *audio_adapter_get(struct btd_adapter *adapter)
return adp;
}
-static int a2dp_server_probe(struct btd_profile *p,
+static int a2dp_source_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
struct audio_adapter *adp;
const gchar *path = adapter_get_path(adapter);
- int err;
DBG("path %s", path);
@@ -226,14 +235,12 @@ static int a2dp_server_probe(struct btd_profile *p,
if (!adp)
return -EINVAL;
- err = a2dp_register(adapter_get_address(adapter), config);
- if (err < 0)
- audio_adapter_unref(adp);
+ audio_adapter_unref(adp); /* Referenced by a2dp server */
- return err;
+ return a2dp_source_register(adapter_get_address(adapter), config);
}
-static void a2dp_server_remove(struct btd_profile *p,
+static int a2dp_sink_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
struct audio_adapter *adp;
@@ -241,12 +248,13 @@ static void a2dp_server_remove(struct btd_profile *p,
DBG("path %s", path);
- adp = find_adapter(adapters, adapter);
+ adp = audio_adapter_get(adapter);
if (!adp)
- return;
+ return -EINVAL;
- a2dp_unregister(adapter_get_address(adapter));
- audio_adapter_unref(adp);
+ audio_adapter_unref(adp); /* Referenced by a2dp server */
+
+ return a2dp_sink_register(adapter_get_address(adapter), config);
}
static int avrcp_server_probe(struct btd_profile *p,
@@ -319,17 +327,26 @@ static void media_server_remove(struct btd_adapter *adapter)
audio_adapter_unref(adp);
}
-static struct btd_profile a2dp_profile = {
- .name = "audio-a2dp",
+static struct btd_profile a2dp_source_profile = {
+ .name = "audio-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,
- .remote_uuids = BTD_UUIDS(A2DP_SOURCE_UUID, A2DP_SINK_UUID,
- ADVANCED_AUDIO_UUID),
- .device_probe = a2dp_probe,
+ .remote_uuids = BTD_UUIDS(A2DP_SOURCE_UUID),
+ .device_probe = a2dp_source_probe,
.device_remove = audio_remove,
- .adapter_probe = a2dp_server_probe,
- .adapter_remove = a2dp_server_remove,
+ .adapter_probe = a2dp_source_server_probe,
+};
+
+static struct btd_profile a2dp_sink_profile = {
+ .name = "audio-sink",
+ .priority = BTD_PROFILE_PRIORITY_MEDIUM,
+
+ .remote_uuids = BTD_UUIDS(A2DP_SINK_UUID),
+ .device_probe = a2dp_sink_probe,
+ .device_remove = audio_remove,
+
+ .adapter_probe = a2dp_sink_server_probe,
};
static struct btd_profile avrcp_profile = {
@@ -402,8 +419,11 @@ int audio_manager_init(GKeyFile *conf)
max_connected_headsets = i;
proceed:
- if (enabled.source || enabled.sink)
- btd_profile_register(&a2dp_profile);
+ if (enabled.source)
+ btd_profile_register(&a2dp_source_profile);
+
+ if (enabled.sink)
+ btd_profile_register(&a2dp_sink_profile);
if (enabled.control)
btd_profile_register(&avrcp_profile);
@@ -420,8 +440,11 @@ void audio_manager_exit(void)
config = NULL;
}
- if (enabled.source || enabled.sink)
- btd_profile_unregister(&a2dp_profile);
+ if (enabled.source)
+ btd_profile_unregister(&a2dp_source_profile);
+
+ if (enabled.sink)
+ btd_profile_unregister(&a2dp_sink_profile);
if (enabled.control)
btd_profile_unregister(&avrcp_profile);
--
1.7.11.7
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 3/6] source: Add profile .connect and .disconnect
2012-11-21 12:10 [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 2/6] audio: Split A2DP into two btd_profile Luiz Augusto von Dentz
@ 2012-11-21 12:10 ` Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 4/6] sink: " Luiz Augusto von Dentz
` (3 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2012-11-21 12:10 UTC (permalink / raw)
To: linux-bluetooth
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Add the connection and disconnection hooks to the a2dp_source
btd_profile.
---
profiles/audio/manager.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 90 insertions(+)
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 2f36efd..eaae018 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -74,6 +74,12 @@ struct audio_adapter {
gint ref;
};
+struct profile_req {
+ struct btd_device *device;
+ struct btd_profile *profile;
+ btd_profile_cb cb;
+};
+
static gboolean auto_connect = TRUE;
static int max_connected_headsets = 1;
static GKeyFile *config = NULL;
@@ -176,6 +182,86 @@ static int avrcp_probe(struct btd_profile *p, struct btd_device *device,
return 0;
}
+static struct profile_req *new_profile_request(struct btd_device *dev,
+ struct btd_profile *profile,
+ btd_profile_cb cb)
+{
+ struct profile_req *req;
+
+ req = g_new0(struct profile_req, 1);
+ req->device = dev;
+ req->profile = profile;
+ req->cb = cb;
+
+ return req;
+}
+
+static void profile_cb(struct audio_device *dev, int err, void *data)
+{
+ struct profile_req *req = data;
+
+ if (req->cb)
+ req->cb(req->profile, req->device, err);
+
+ g_free(req);
+}
+
+static int a2dp_source_connect(struct btd_device *dev,
+ struct btd_profile *profile,
+ btd_profile_cb cb)
+{
+ const gchar *path = device_get_path(dev);
+ struct audio_device *audio_dev;
+ struct profile_req *req;
+ int err;
+
+ DBG("path %s", path);
+
+ audio_dev = get_audio_dev(dev);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ req = new_profile_request(dev, profile, cb);
+
+ err = source_connect(audio_dev, profile_cb, req);
+ if (err < 0) {
+ g_free(req);
+ return err;
+ }
+
+ return 0;
+}
+
+static int a2dp_source_disconnect(struct btd_device *dev,
+ struct btd_profile *profile,
+ btd_profile_cb cb)
+{
+ const gchar *path = device_get_path(dev);
+ struct audio_device *audio_dev;
+ struct profile_req *req;
+ int err;
+
+ DBG("path %s", path);
+
+ audio_dev = get_audio_dev(dev);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ req = new_profile_request(dev, profile, cb);
+
+ err = source_disconnect(audio_dev, FALSE, profile_cb, req);
+ if (err < 0) {
+ g_free(req);
+ return err;
+ }
+
+ return 0;
+}
+
static struct audio_adapter *audio_adapter_ref(struct audio_adapter *adp)
{
adp->ref++;
@@ -335,6 +421,10 @@ static struct btd_profile a2dp_source_profile = {
.device_probe = a2dp_source_probe,
.device_remove = audio_remove,
+ .auto_connect = true,
+ .connect = a2dp_source_connect,
+ .disconnect = a2dp_source_disconnect,
+
.adapter_probe = a2dp_source_server_probe,
};
--
1.7.11.7
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 4/6] sink: Add profile .connect and .disconnect
2012-11-21 12:10 [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 2/6] audio: Split A2DP into two btd_profile Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 3/6] source: Add profile .connect and .disconnect Luiz Augusto von Dentz
@ 2012-11-21 12:10 ` Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 5/6] control: Expose internal connection API Luiz Augusto von Dentz
` (2 subsequent siblings)
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2012-11-21 12:10 UTC (permalink / raw)
To: linux-bluetooth
From: Mikel Astiz <mikel.astiz@bmw-carit.de>
Add the connection and disconnection hooks to the a2dp_sink btd_profile.
---
profiles/audio/manager.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index eaae018..dad46a9 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -262,6 +262,62 @@ static int a2dp_source_disconnect(struct btd_device *dev,
return 0;
}
+static int a2dp_sink_connect(struct btd_device *dev,
+ struct btd_profile *profile,
+ btd_profile_cb cb)
+{
+ const gchar *path = device_get_path(dev);
+ struct audio_device *audio_dev;
+ struct profile_req *req;
+ int err;
+
+ DBG("path %s", path);
+
+ audio_dev = get_audio_dev(dev);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ req = new_profile_request(dev, profile, cb);
+
+ err = sink_connect(audio_dev, profile_cb, req);
+ if (err < 0) {
+ g_free(req);
+ return err;
+ }
+
+ return 0;
+}
+
+static int a2dp_sink_disconnect(struct btd_device *dev,
+ struct btd_profile *profile,
+ btd_profile_cb cb)
+{
+ const gchar *path = device_get_path(dev);
+ struct audio_device *audio_dev;
+ struct profile_req *req;
+ int err;
+
+ DBG("path %s", path);
+
+ audio_dev = get_audio_dev(dev);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ req = new_profile_request(dev, profile, cb);
+
+ err = sink_disconnect(audio_dev, FALSE, profile_cb, req);
+ if (err < 0) {
+ g_free(req);
+ return err;
+ }
+
+ return 0;
+}
+
static struct audio_adapter *audio_adapter_ref(struct audio_adapter *adp)
{
adp->ref++;
@@ -436,6 +492,10 @@ static struct btd_profile a2dp_sink_profile = {
.device_probe = a2dp_sink_probe,
.device_remove = audio_remove,
+ .auto_connect = true,
+ .connect = a2dp_sink_connect,
+ .disconnect = a2dp_sink_disconnect,
+
.adapter_probe = a2dp_sink_server_probe,
};
--
1.7.11.7
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 5/6] control: Expose internal connection API
2012-11-21 12:10 [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Luiz Augusto von Dentz
` (2 preceding siblings ...)
2012-11-21 12:10 ` [PATCH BlueZ 4/6] sink: " Luiz Augusto von Dentz
@ 2012-11-21 12:10 ` Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 6/6] control: Add profile .connect and .disconnect Luiz Augusto von Dentz
2012-11-21 12:37 ` [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Johan Hedberg
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2012-11-21 12:10 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Separate the D-Bus code from the internal connection handling code,
exposing an internal API in case some internal codepath/plugin is
interested in using it.
---
profiles/audio/control.c | 118 ++++++++++++++++++++++++++++++++++++-----------
profiles/audio/control.h | 4 ++
2 files changed, 96 insertions(+), 26 deletions(-)
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index 1620128..b2bfb0a 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -61,12 +61,28 @@
static unsigned int avctp_id = 0;
+struct pending_request {
+ audio_device_cb cb;
+ void *data;
+ unsigned int id;
+};
+
struct control {
struct avctp *session;
gboolean target;
- DBusMessage *connect;
+ struct pending_request *connect;
};
+static void pending_request_free(struct audio_device *dev,
+ struct pending_request *pending,
+ int err)
+{
+ if (pending->cb)
+ pending->cb(dev, err, pending->data);
+
+ g_free(pending);
+}
+
static void state_changed(struct audio_device *dev, avctp_state_t old_state,
avctp_state_t new_state, void *user_data)
{
@@ -79,11 +95,7 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
control->session = NULL;
if (control->connect) {
- DBusMessage *reply = btd_error_failed(control->connect,
- "Unable to connect");
-
- g_dbus_send_message(btd_get_dbus_connection(), reply);
- dbus_message_unref(control->connect);
+ pending_request_free(dev, control->connect, -EIO);
control->connect = NULL;
}
@@ -105,9 +117,7 @@ static void state_changed(struct audio_device *dev, avctp_state_t old_state,
break;
case AVCTP_STATE_CONNECTED:
if (control->connect) {
- g_dbus_send_reply(conn, control->connect,
- DBUS_TYPE_INVALID);
- dbus_message_unref(control->connect);
+ pending_request_free(dev, control->connect, 0);
control->connect = NULL;
}
@@ -143,41 +153,97 @@ static DBusMessage *control_is_connected(DBusConnection *conn,
return reply;
}
-static DBusMessage *control_connect(DBusConnection *conn, DBusMessage *msg,
- void *data)
+int control_connect(struct audio_device *dev, audio_device_cb cb, void *data)
{
- struct audio_device *device = data;
- struct control *control = device->control;
+ struct control *control = dev->control;
+ struct pending_request *pending;
if (control->session)
- return btd_error_already_connected(msg);
+ return -EALREADY;
if (!control->target)
- return btd_error_not_supported(msg);
+ return -ENOTSUP;
if (control->connect)
- return btd_error_in_progress(msg);
+ return -EINPROGRESS;
- control->session = avctp_connect(&device->src, &device->dst);
+ control->session = avctp_connect(&dev->src, &dev->dst);
if (!control->session)
- return btd_error_failed(msg, "Unable to connect");
+ return -EIO;
- control->connect = dbus_message_ref(msg);
+ pending = g_new0(struct pending_request, 1);
+ pending->cb = cb;
+ pending->data = data;
+ control->connect = pending;
- return NULL;
+ return 0;
}
-static DBusMessage *control_disconnect(DBusConnection *conn, DBusMessage *msg,
+static void generic_cb(struct audio_device *dev, int err, void *data)
+{
+ DBusMessage *msg = data;
+ DBusMessage *reply;
+
+ if (err < 0) {
+ reply = btd_error_failed(msg, strerror(-err));
+ g_dbus_send_message(btd_get_dbus_connection(), reply);
+ dbus_message_unref(msg);
+ return;
+ }
+
+ g_dbus_send_reply(btd_get_dbus_connection(), msg, DBUS_TYPE_INVALID);
+
+ dbus_message_unref(msg);
+}
+
+static DBusMessage *connect_control(DBusConnection *conn, DBusMessage *msg,
void *data)
{
struct audio_device *device = data;
- struct control *control = device->control;
+ int err;
+
+ err = control_connect(device, generic_cb, msg);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+
+ dbus_message_ref(msg);
+
+ return NULL;
+}
+
+int control_disconnect(struct audio_device *dev, audio_device_cb cb,
+ void *data)
+{
+ struct control *control = dev->control;
if (!control->session)
- return btd_error_not_connected(msg);
+ return -ENOTCONN;
+
+ /* cancel pending connect */
+ if (control->connect) {
+ pending_request_free(dev, control->connect, -ECANCELED);
+ control->connect = NULL;
+ }
avctp_disconnect(control->session);
+ if (cb)
+ cb(dev, 0, data);
+
+ return 0;
+
+}
+
+static DBusMessage *disconnect_control(DBusConnection *conn, DBusMessage *msg,
+ void *data)
+{
+ struct audio_device *device = data;
+ int err;
+
+ err = control_disconnect(device, NULL, NULL);
+ if (err < 0)
+ return btd_error_failed(msg, strerror(-err));
+
return dbus_message_new_method_return(msg);
}
@@ -259,8 +325,8 @@ static const GDBusMethodTable control_methods[] = {
{ GDBUS_DEPRECATED_METHOD("IsConnected",
NULL, GDBUS_ARGS({ "connected", "b" }),
control_is_connected) },
- { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, control_connect) },
- { GDBUS_METHOD("Disconnect", NULL, NULL, control_disconnect) },
+ { GDBUS_ASYNC_METHOD("Connect", NULL, NULL, connect_control) },
+ { GDBUS_METHOD("Disconnect", NULL, NULL, disconnect_control) },
{ GDBUS_METHOD("Play", NULL, NULL, control_play) },
{ GDBUS_METHOD("Pause", NULL, NULL, control_pause) },
{ GDBUS_METHOD("Stop", NULL, NULL, control_stop) },
@@ -294,7 +360,7 @@ static void path_unregister(void *data)
avctp_disconnect(control->session);
if (control->connect)
- dbus_message_unref(control->connect);
+ pending_request_free(dev, control->connect, -ECANCELED);
g_free(control);
dev->control = NULL;
diff --git a/profiles/audio/control.h b/profiles/audio/control.h
index 5f4f728..800a151 100644
--- a/profiles/audio/control.h
+++ b/profiles/audio/control.h
@@ -28,3 +28,7 @@ struct control *control_init(struct audio_device *dev, GSList *uuids);
void control_update(struct control *control, GSList *uuids);
void control_unregister(struct audio_device *dev);
gboolean control_is_active(struct audio_device *dev);
+
+int control_connect(struct audio_device *dev, audio_device_cb cb, void *data);
+int control_disconnect(struct audio_device *dev, audio_device_cb cb,
+ void *data);
--
1.7.11.7
^ permalink raw reply related [flat|nested] 7+ messages in thread
* [PATCH BlueZ 6/6] control: Add profile .connect and .disconnect
2012-11-21 12:10 [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Luiz Augusto von Dentz
` (3 preceding siblings ...)
2012-11-21 12:10 ` [PATCH BlueZ 5/6] control: Expose internal connection API Luiz Augusto von Dentz
@ 2012-11-21 12:10 ` Luiz Augusto von Dentz
2012-11-21 12:37 ` [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Johan Hedberg
5 siblings, 0 replies; 7+ messages in thread
From: Luiz Augusto von Dentz @ 2012-11-21 12:10 UTC (permalink / raw)
To: linux-bluetooth
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Add the connection and disconnection hooks to the avrcp btd_profile.
---
profiles/audio/manager.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index dad46a9..714489a 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -318,6 +318,62 @@ static int a2dp_sink_disconnect(struct btd_device *dev,
return 0;
}
+static int avrcp_control_connect(struct btd_device *dev,
+ struct btd_profile *profile,
+ btd_profile_cb cb)
+{
+ const gchar *path = device_get_path(dev);
+ struct audio_device *audio_dev;
+ struct profile_req *req;
+ int err;
+
+ DBG("path %s", path);
+
+ audio_dev = get_audio_dev(dev);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ req = new_profile_request(dev, profile, cb);
+
+ err = control_connect(audio_dev, profile_cb, req);
+ if (err < 0) {
+ g_free(req);
+ return err;
+ }
+
+ return 0;
+}
+
+static int avrcp_control_disconnect(struct btd_device *dev,
+ struct btd_profile *profile,
+ btd_profile_cb cb)
+{
+ const gchar *path = device_get_path(dev);
+ struct audio_device *audio_dev;
+ struct profile_req *req;
+ int err;
+
+ DBG("path %s", path);
+
+ audio_dev = get_audio_dev(dev);
+ if (!audio_dev) {
+ DBG("unable to get a device object");
+ return -1;
+ }
+
+ req = new_profile_request(dev, profile, cb);
+
+ err = control_disconnect(audio_dev, profile_cb, req);
+ if (err < 0) {
+ g_free(req);
+ return err;
+ }
+
+ return 0;
+}
+
static struct audio_adapter *audio_adapter_ref(struct audio_adapter *adp)
{
adp->ref++;
@@ -506,6 +562,10 @@ static struct btd_profile avrcp_profile = {
.device_probe = avrcp_probe,
.device_remove = audio_remove,
+ .auto_connect = true,
+ .connect = avrcp_control_connect,
+ .disconnect = avrcp_control_disconnect,
+
.adapter_probe = avrcp_server_probe,
.adapter_remove = avrcp_server_remove,
};
--
1.7.11.7
^ permalink raw reply related [flat|nested] 7+ messages in thread
* Re: [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect
2012-11-21 12:10 [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Luiz Augusto von Dentz
` (4 preceding siblings ...)
2012-11-21 12:10 ` [PATCH BlueZ 6/6] control: Add profile .connect and .disconnect Luiz Augusto von Dentz
@ 2012-11-21 12:37 ` Johan Hedberg
5 siblings, 0 replies; 7+ messages in thread
From: Johan Hedberg @ 2012-11-21 12:37 UTC (permalink / raw)
To: Luiz Augusto von Dentz; +Cc: linux-bluetooth
Hi Luiz,
On Wed, Nov 21, 2012, Luiz Augusto von Dentz wrote:
> We should with higher priority first.
> ---
> src/device.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
All patches in this set have been applied. Thanks.
Johan
^ permalink raw reply [flat|nested] 7+ messages in thread
end of thread, other threads:[~2012-11-21 12:37 UTC | newest]
Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-11-21 12:10 [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 2/6] audio: Split A2DP into two btd_profile Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 3/6] source: Add profile .connect and .disconnect Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 4/6] sink: " Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 5/6] control: Expose internal connection API Luiz Augusto von Dentz
2012-11-21 12:10 ` [PATCH BlueZ 6/6] control: Add profile .connect and .disconnect Luiz Augusto von Dentz
2012-11-21 12:37 ` [PATCH BlueZ 1/6] core: Fix connection order of Device.Connect Johan Hedberg
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).