From: Mikel Astiz <[email protected]>
I promote this to PATCH instead of RFC considering that Johan's feedback to RFC v2 was farily positive.
The patchset has now been reworked with the aim to make the review easier, while some of the patches are still quite big and unavoidably sparse. The non-trivial changes have been split to separate patchset and the ones not stricly related to btd_service have been moved to the front (first 10 patches).
Besides that, v3 includes:
- btd_service ownership by btd_device, as suggested by Johan. This means the btd_service instance holds a weak reference to btd_device (no reference counting).
- All btd_profile callback handling moved now to service.c, improving the API in service.h (with "active" functions such as btd_service_connect() etc. instead of the former state-propagation functions).
Cheers,
Mikel
Mikel Astiz (27):
device: Fix returned error code
control: Simplify UUID handling during probe
input: Simplify code since UUID is known
profile: Remove UUID list from probe function
network: Fail if multiple profile instances
input: Fix ignored profile shutdown
input: Move timeout setting to device.c
input: Remove unused UUID field
input: Bypass manager during probe/remove
network: Bypass manager during probe/remove
core: Add btd_service to represent device services
device: Use btd_service to represent profiles
core: Add probe API to btd_service
core: Add connect/disconnect API to btd_service
core: Add a state enum to btd_service
device: Replace connected_profiles with btd_service
device: Find services instead of profiles
device: Replace pending profile list with services
profile: Use btd_service for probing profiles
network: Add trivial helper function
core: Add user_data to btd_service
network: Hold a reference to btd_service
audio: Hold a reference to btd_service
control: Bypass manager for connect state changes
input: Hold a reference to btd_service
service: Add callbacks to track state changes
profile: Use btd_service for connect/disconnect
Makefile.am | 1 +
Makefile.plugins | 4 +-
profiles/audio/avrcp.c | 16 +-
profiles/audio/control.c | 48 ++++-
profiles/audio/control.h | 12 +-
profiles/audio/manager.c | 88 +++------
profiles/audio/manager.h | 9 -
profiles/audio/sink.c | 24 +--
profiles/audio/sink.h | 4 +-
profiles/audio/source.c | 25 +--
profiles/audio/source.h | 5 +-
profiles/cyclingspeed/cyclingspeed.c | 9 +-
profiles/deviceinfo/deviceinfo.c | 11 +-
profiles/gatt/gas.c | 10 +-
profiles/health/hdp_manager.c | 10 +-
profiles/heartrate/heartrate.c | 10 +-
profiles/input/device.c | 87 +++++----
profiles/input/device.h | 13 +-
profiles/input/hog.c | 8 +-
profiles/input/manager.c | 51 +-----
profiles/input/manager.h | 25 ---
profiles/network/connection.c | 75 ++++----
profiles/network/connection.h | 8 +-
profiles/network/manager.c | 123 ++-----------
profiles/network/manager.h | 25 ---
profiles/proximity/manager.c | 28 +--
profiles/proximity/reporter.c | 8 +-
profiles/proximity/reporter.h | 5 +-
profiles/sap/manager.c | 1 +
profiles/scanparam/scan.c | 9 +-
profiles/thermometer/thermometer.c | 11 +-
src/device.c | 244 +++++++++++++------------
src/device.h | 7 -
src/profile.c | 40 +++--
src/profile.h | 14 +-
src/service.c | 338 +++++++++++++++++++++++++++++++++++
src/service.h | 68 +++++++
37 files changed, 875 insertions(+), 599 deletions(-)
delete mode 100644 profiles/input/manager.h
delete mode 100644 profiles/network/manager.h
create mode 100644 src/service.c
create mode 100644 src/service.h
--
1.8.1.4
Hi Anderson,
On Fri, Apr 26, 2013 at 1:48 PM, Anderson Lizardo
<[email protected]> wrote:
> Hi Mikel,
>
> On Fri, Apr 26, 2013 at 2:17 AM, Mikel Astiz <[email protected]> wrote:
>> +static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
>> +{
>> + GSList *l;
>> +
>> + for (l = list; l != NULL; l = g_slist_next(l)) {
>> + struct btd_service *service = l->data;
>> +
>> + if (btd_service_get_profile(service) == p)
>> + return l;
>
> Why you don't return service directly here? It should avoid the caller
> having to do "service = l->data;".
The patch has already been applied, but please go ahead with the
review since there's been a lot of code being changed, and testing was
fairly limited due to lack of hardware.
The purpose of this was to be able to delete the node more efficiently
in case that's the intention of the caller, but it's certainly of
little use considering that it's a singly-linked list.
Feel free to submit a patch to simplify this, or otherwise I'll
consider this for a later cleanup patchset.
>
> Another option: you could try using g_slist_find_custom() on the
> callers and turn this into a comparison callback for it.
Johan preferred this approach over find_custom() in a very similar
scenario, so I changed this one as well for consistency.
Cheers,
Mikel
Hi Mikel,
On Fri, Apr 26, 2013 at 2:17 AM, Mikel Astiz <[email protected]> wrote:
> +static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
> +{
> + GSList *l;
> +
> + for (l = list; l != NULL; l = g_slist_next(l)) {
> + struct btd_service *service = l->data;
> +
> + if (btd_service_get_profile(service) == p)
> + return l;
Why you don't return service directly here? It should avoid the caller
having to do "service = l->data;".
Another option: you could try using g_slist_find_custom() on the
callers and turn this into a comparison callback for it.
> + }
> +
> + return NULL;
> +}
Best Regards,
--
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil
From: Mikel Astiz <[email protected]>
Change the btd_profile connect/disconnect callbacks to receive a
btd_service pointer. This should make it possible to handle multiple
instances of the same profile in a specific device.
The patch strongly influences how the profiles should interact with the
core. The state transitions, previously reported using the device.h API
(device_profile_connected() and device_profile_disconnected()), have
now been replaced by the btd_service API.
The transitions will then be propagated to device.c by means of the
conventional state-changed callback mechanism.
---
Makefile.plugins | 4 +--
profiles/audio/control.c | 20 +++--------
profiles/audio/manager.c | 44 +++++++-----------------
profiles/audio/manager.h | 5 ---
profiles/audio/sink.c | 18 +++++-----
profiles/audio/source.c | 18 +++++-----
profiles/input/device.c | 21 +++++-------
profiles/input/device.h | 5 ++-
profiles/input/manager.c | 11 ------
profiles/input/manager.h | 25 --------------
profiles/network/connection.c | 39 ++++++---------------
profiles/network/connection.h | 4 +--
profiles/network/manager.c | 79 ++++---------------------------------------
profiles/network/manager.h | 25 --------------
src/device.c | 32 +++++++++++-------
src/device.h | 7 ----
src/profile.c | 29 ++++++++++------
src/profile.h | 6 ++--
src/service.c | 4 +--
19 files changed, 107 insertions(+), 289 deletions(-)
delete mode 100644 profiles/input/manager.h
delete mode 100644 profiles/network/manager.h
diff --git a/Makefile.plugins b/Makefile.plugins
index f497782..44e6eca 100644
--- a/Makefile.plugins
+++ b/Makefile.plugins
@@ -41,14 +41,14 @@ builtin_sources += profiles/audio/main.c \
profiles/audio/a2dp-codecs.h
builtin_modules += network
-builtin_sources += profiles/network/manager.h profiles/network/manager.c \
+builtin_sources += profiles/network/manager.c \
profiles/network/common.h profiles/network/common.c \
profiles/network/server.h profiles/network/server.c \
profiles/network/connection.h \
profiles/network/connection.c
builtin_modules += input
-builtin_sources += profiles/input/manager.h profiles/input/manager.c \
+builtin_sources += profiles/input/manager.c \
profiles/input/server.h profiles/input/server.c \
profiles/input/device.h profiles/input/device.c
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index bb3f812..cdba385 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -70,34 +70,22 @@ struct control {
void control_target_connected(struct control *control, int err)
{
- struct btd_device *device = btd_service_get_device(control->target);
- struct btd_profile *profile = btd_service_get_profile(control->target);
-
- device_profile_connected(device, profile, err);
+ btd_service_connecting_complete(control->target, err);
}
void control_target_disconnected(struct control *control, int err)
{
- struct btd_device *device = btd_service_get_device(control->target);
- struct btd_profile *profile = btd_service_get_profile(control->target);
-
- device_profile_disconnected(device, profile, err);
+ btd_service_disconnecting_complete(control->target, err);
}
void control_remote_connected(struct control *control, int err)
{
- struct btd_device *device = btd_service_get_device(control->remote);
- struct btd_profile *profile = btd_service_get_profile(control->remote);
-
- device_profile_connected(device, profile, err);
+ btd_service_connecting_complete(control->remote, err);
}
void control_remote_disconnected(struct control *control, int err)
{
- struct btd_device *device = btd_service_get_device(control->remote);
- struct btd_profile *profile = btd_service_get_profile(control->remote);
-
- device_profile_disconnected(device, profile, err);
+ btd_service_disconnecting_complete(control->remote, err);
}
static void state_changed(struct audio_device *dev, avctp_state_t old_state,
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 901f94f..15226e4 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -157,9 +157,9 @@ static int avrcp_probe(struct btd_service *service)
return 0;
}
-static int a2dp_source_connect(struct btd_device *dev,
- struct btd_profile *profile)
+static int a2dp_source_connect(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
struct audio_device *audio_dev;
@@ -174,9 +174,9 @@ static int a2dp_source_connect(struct btd_device *dev,
return source_connect(audio_dev);
}
-static int a2dp_source_disconnect(struct btd_device *dev,
- struct btd_profile *profile)
+static int a2dp_source_disconnect(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
struct audio_device *audio_dev;
@@ -191,9 +191,9 @@ static int a2dp_source_disconnect(struct btd_device *dev,
return source_disconnect(audio_dev, FALSE);
}
-static int a2dp_sink_connect(struct btd_device *dev,
- struct btd_profile *profile)
+static int a2dp_sink_connect(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
struct audio_device *audio_dev;
@@ -208,9 +208,9 @@ static int a2dp_sink_connect(struct btd_device *dev,
return sink_connect(audio_dev);
}
-static int a2dp_sink_disconnect(struct btd_device *dev,
- struct btd_profile *profile)
+static int a2dp_sink_disconnect(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
struct audio_device *audio_dev;
@@ -225,9 +225,9 @@ static int a2dp_sink_disconnect(struct btd_device *dev,
return sink_disconnect(audio_dev, FALSE);
}
-static int avrcp_target_connect(struct btd_device *dev,
- struct btd_profile *profile)
+static int avrcp_target_connect(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
struct audio_device *audio_dev;
@@ -242,9 +242,9 @@ static int avrcp_target_connect(struct btd_device *dev,
return control_connect(audio_dev);
}
-static int avrcp_target_disconnect(struct btd_device *dev,
- struct btd_profile *profile)
+static int avrcp_target_disconnect(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
const char *path = device_get_path(dev);
struct audio_device *audio_dev;
@@ -401,26 +401,6 @@ static struct btd_adapter_driver media_driver = {
.remove = media_server_remove,
};
-void audio_sink_connected(struct btd_device *dev, int err)
-{
- device_profile_connected(dev, &a2dp_sink_profile, err);
-}
-
-void audio_sink_disconnected(struct btd_device *dev, int err)
-{
- device_profile_disconnected(dev, &a2dp_sink_profile, err);
-}
-
-void audio_source_connected(struct btd_device *dev, int err)
-{
- device_profile_connected(dev, &a2dp_source_profile, err);
-}
-
-void audio_source_disconnected(struct btd_device *dev, int err)
-{
- device_profile_disconnected(dev, &a2dp_source_profile, err);
-}
-
int audio_manager_init(GKeyFile *conf)
{
if (conf)
diff --git a/profiles/audio/manager.h b/profiles/audio/manager.h
index 2567e46..b8d8ef7 100644
--- a/profiles/audio/manager.h
+++ b/profiles/audio/manager.h
@@ -29,11 +29,6 @@ struct enabled_interfaces {
gboolean media_player;
};
-void audio_sink_connected(struct btd_device *dev, int err);
-void audio_sink_disconnected(struct btd_device *dev, int err);
-void audio_source_connected(struct btd_device *dev, int err);
-void audio_source_disconnected(struct btd_device *dev, int err);
-
int audio_manager_init(GKeyFile *config);
void audio_manager_exit(void);
diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index 9f1a2d9..3969417 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -149,7 +149,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
switch (new_state) {
case AVDTP_STATE_IDLE:
- audio_sink_disconnected(dev->btd_dev, 0);
+ btd_service_disconnecting_complete(sink->service, 0);
if (sink->disconnect_id > 0) {
a2dp_cancel(dev, sink->disconnect_id);
@@ -194,7 +194,7 @@ static gboolean stream_setup_retry(gpointer user_data)
err = -EIO;
}
- audio_sink_connected(sink->dev->btd_dev, err);
+ btd_service_connecting_complete(sink->service, err);
if (sink->connect_id > 0) {
a2dp_cancel(sink->dev, sink->connect_id);
@@ -214,7 +214,7 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
if (stream) {
DBG("Stream successfully created");
- audio_sink_connected(sink->dev->btd_dev, 0);
+ btd_service_connecting_complete(sink->service, 0);
return;
}
@@ -228,7 +228,7 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
sink);
} else {
DBG("Stream setup failed : %s", avdtp_strerror(err));
- audio_sink_connected(sink->dev->btd_dev, -EIO);
+ btd_service_connecting_complete(sink->service, -EIO);
}
}
@@ -248,7 +248,7 @@ static void select_complete(struct avdtp *session, struct a2dp_sep *sep,
return;
failed:
- audio_sink_connected(sink->dev->btd_dev, -EIO);
+ btd_service_connecting_complete(sink->service, -EIO);
avdtp_unref(sink->session);
sink->session = NULL;
@@ -286,7 +286,7 @@ static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp
return;
failed:
- audio_sink_connected(sink->dev->btd_dev, -EIO);
+ btd_service_connecting_complete(sink->service, -EIO);
avdtp_unref(sink->session);
sink->session = NULL;
}
@@ -348,13 +348,13 @@ static void sink_free(struct audio_device *dev)
avdtp_unref(sink->session);
if (sink->connect_id > 0) {
- audio_sink_connected(dev->btd_dev, -ECANCELED);
+ btd_service_connecting_complete(sink->service, -ECANCELED);
a2dp_cancel(dev, sink->connect_id);
sink->connect_id = 0;
}
if (sink->disconnect_id > 0) {
- audio_sink_disconnected(dev->btd_dev, -ECANCELED);
+ btd_service_disconnecting_complete(sink->service, -ECANCELED);
a2dp_cancel(dev, sink->disconnect_id);
sink->disconnect_id = 0;
}
@@ -434,7 +434,7 @@ int sink_disconnect(struct audio_device *dev, gboolean shutdown)
if (sink->connect_id > 0) {
a2dp_cancel(dev, sink->connect_id);
sink->connect_id = 0;
- audio_sink_connected(dev->btd_dev, -ECANCELED);
+ btd_service_connecting_complete(sink->service, -ECANCELED);
avdtp_unref(sink->session);
sink->session = NULL;
diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 20fd412..226c372 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -150,7 +150,7 @@ static void stream_state_changed(struct avdtp_stream *stream,
switch (new_state) {
case AVDTP_STATE_IDLE:
- audio_source_disconnected(dev->btd_dev, 0);
+ btd_service_disconnecting_complete(source->service, 0);
if (source->disconnect_id > 0) {
a2dp_cancel(dev, source->disconnect_id);
@@ -195,7 +195,7 @@ static gboolean stream_setup_retry(gpointer user_data)
err = -EIO;
}
- audio_source_connected(source->dev->btd_dev, err);
+ btd_service_connecting_complete(source->service, err);
if (source->connect_id > 0) {
a2dp_cancel(source->dev, source->connect_id);
@@ -215,7 +215,7 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
if (stream) {
DBG("Stream successfully created");
- audio_source_connected(source->dev->btd_dev, 0);
+ btd_service_connecting_complete(source->service, 0);
return;
}
@@ -229,7 +229,7 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
source);
} else {
DBG("Stream setup failed : %s", avdtp_strerror(err));
- audio_source_connected(source->dev->btd_dev, -EIO);
+ btd_service_connecting_complete(source->service, -EIO);
}
}
@@ -252,7 +252,7 @@ static void select_complete(struct avdtp *session, struct a2dp_sep *sep,
return;
failed:
- audio_source_connected(source->dev->btd_dev, -EIO);
+ btd_service_connecting_complete(source->service, -EIO);
avdtp_unref(source->session);
source->session = NULL;
@@ -290,7 +290,7 @@ static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp
return;
failed:
- audio_source_connected(source->dev->btd_dev, -EIO);
+ btd_service_connecting_complete(source->service, -EIO);
avdtp_unref(source->session);
source->session = NULL;
}
@@ -352,13 +352,13 @@ static void source_free(struct audio_device *dev)
avdtp_unref(source->session);
if (source->connect_id > 0) {
- audio_source_connected(dev->btd_dev, -ECANCELED);
+ btd_service_connecting_complete(source->service, -ECANCELED);
a2dp_cancel(dev, source->connect_id);
source->connect_id = 0;
}
if (source->disconnect_id > 0) {
- audio_source_disconnected(dev->btd_dev, -ECANCELED);
+ btd_service_disconnecting_complete(source->service, -ECANCELED);
a2dp_cancel(dev, source->disconnect_id);
source->disconnect_id = 0;
}
@@ -431,7 +431,7 @@ int source_disconnect(struct audio_device *dev, gboolean shutdown)
if (source->connect_id > 0) {
a2dp_cancel(dev, source->connect_id);
source->connect_id = 0;
- audio_source_connected(dev->btd_dev, -ECANCELED);
+ btd_service_connecting_complete(source->service, -ECANCELED);
avdtp_unref(source->session);
source->session = NULL;
diff --git a/profiles/input/device.c b/profiles/input/device.c
index adbd114..b2d5f58 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -48,7 +48,6 @@
#include "../src/storage.h"
#include "../src/dbus-common.h"
-#include "manager.h"
#include "device.h"
#include "error.h"
#include <btio/btio.h>
@@ -563,7 +562,7 @@ static int input_device_connected(struct input_device *idev)
idev->dc_id = device_add_disconnect_watch(idev->device, disconnect_cb,
idev, NULL);
- input_manager_device_connected(idev->device, 0);
+ btd_service_connecting_complete(idev->service, 0);
return 0;
}
@@ -590,7 +589,7 @@ static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err,
return;
failed:
- input_manager_device_connected(idev->device, err);
+ btd_service_connecting_complete(idev->service, err);
/* So we guarantee the interrupt channel is closed before the
* control channel (if we only do unref GLib will close it only
@@ -642,7 +641,7 @@ static void control_connect_cb(GIOChannel *chan, GError *conn_err,
return;
failed:
- input_manager_device_connected(idev->device, -EIO);
+ btd_service_connecting_complete(idev->service, -EIO);
g_io_channel_unref(idev->ctrl_io);
idev->ctrl_io = NULL;
}
@@ -729,13 +728,11 @@ static void input_device_enter_reconnect_mode(struct input_device *idev)
}
-int input_device_connect(struct btd_device *dev, struct btd_profile *profile)
+int input_device_connect(struct btd_service *service)
{
struct input_device *idev;
- idev = find_device_by_path(devices, device_get_path(dev));
- if (!idev)
- return -ENOENT;
+ idev = btd_service_get_user_data(service);
if (idev->ctrl_io)
return -EBUSY;
@@ -746,20 +743,18 @@ int input_device_connect(struct btd_device *dev, struct btd_profile *profile)
return dev_connect(idev);
}
-int input_device_disconnect(struct btd_device *dev, struct btd_profile *profile)
+int input_device_disconnect(struct btd_service *service)
{
struct input_device *idev;
int err;
- idev = find_device_by_path(devices, device_get_path(dev));
- if (!idev)
- return -ENOENT;
+ idev = btd_service_get_user_data(service);
err = connection_disconnect(idev, 0);
if (err < 0)
return err;
- device_profile_disconnected(dev, profile, 0);
+ btd_service_disconnecting_complete(service, 0);
return 0;
}
diff --git a/profiles/input/device.h b/profiles/input/device.h
index fd7f847..39c642d 100644
--- a/profiles/input/device.h
+++ b/profiles/input/device.h
@@ -36,6 +36,5 @@ int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
GIOChannel *io);
int input_device_close_channels(const bdaddr_t *src, const bdaddr_t *dst);
-int input_device_connect(struct btd_device *dev, struct btd_profile *profile);
-int input_device_disconnect(struct btd_device *dev,
- struct btd_profile *profile);
+int input_device_connect(struct btd_service *service);
+int input_device_disconnect(struct btd_service *service);
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index dc771a6..689ccdd 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -43,7 +43,6 @@
#include "device.h"
#include "server.h"
-#include "manager.h"
static int hid_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
@@ -72,16 +71,6 @@ static struct btd_profile input_profile = {
.adapter_remove = hid_server_remove,
};
-void input_manager_device_connected(struct btd_device *dev, int err)
-{
- device_profile_connected(dev, &input_profile, err);
-}
-
-void input_manager_device_disconnected(struct btd_device *dev, int err)
-{
- device_profile_disconnected(dev, &input_profile, err);
-}
-
static GKeyFile *load_config_file(const char *file)
{
GKeyFile *keyfile;
diff --git a/profiles/input/manager.h b/profiles/input/manager.h
deleted file mode 100644
index 3a05094..0000000
--- a/profiles/input/manager.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-void input_manager_device_connected(struct btd_device *dev, int err);
-void input_manager_device_disconnected(struct btd_device *dev, int err);
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 8fbde14..2d6c363 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -48,7 +48,6 @@
#include "error.h"
#include "common.h"
-#include "manager.h"
#include "connection.h"
#define NETWORK_PEER_INTERFACE "org.bluez.Network1"
@@ -144,7 +143,7 @@ static gboolean bnep_watchdog_cb(GIOChannel *chan, GIOCondition cond,
device_remove_disconnect_watch(nc->peer->device, nc->dc_id);
nc->dc_id = 0;
- network_disconnected(nc->peer->device, nc->id, 0);
+ btd_service_disconnecting_complete(nc->service, 0);
info("%s disconnected", nc->dev);
@@ -181,7 +180,7 @@ static void cancel_connection(struct network_conn *nc, int err)
nc->timeout_source = 0;
}
- network_connected(nc->peer->device, nc->id, err);
+ btd_service_connecting_complete(nc->service, err);
if (nc->connect)
local_connect_cb(nc, err);
@@ -289,7 +288,7 @@ static gboolean bnep_setup_cb(GIOChannel *chan, GIOCondition cond,
bnep_if_up(nc->dev);
- network_connected(nc->peer->device, nc->id, 0);
+ btd_service_connecting_complete(nc->service, 0);
if (nc->connect)
local_connect_cb(nc, 0);
@@ -430,7 +429,7 @@ static DBusMessage *local_connect(DBusConnection *conn,
if (nc && nc->connect)
return btd_error_busy(msg);
- err = connection_connect(peer->device, id);
+ err = connection_connect(nc->service);
if (err < 0)
return btd_error_failed(msg, strerror(-err));
@@ -444,24 +443,17 @@ static DBusMessage *local_connect(DBusConnection *conn,
}
/* Connect and initiate BNEP session */
-int connection_connect(struct btd_device *device, uint16_t id)
+int connection_connect(struct btd_service *service)
{
- struct network_peer *peer;
- struct network_conn *nc;
+ struct network_conn *nc = btd_service_get_user_data(service);
+ struct network_peer *peer = nc->peer;
+ uint16_t id = get_service_id(service);
GError *err = NULL;
const bdaddr_t *src;
const bdaddr_t *dst;
DBG("id %u", id);
- peer = find_peer(peers, device);
- if (!peer)
- return -ENOENT;
-
- nc = find_connection(peer->connections, id);
- if (!nc)
- return -ENOTSUP;
-
if (nc->state != DISCONNECTED)
return -EALREADY;
@@ -485,18 +477,9 @@ int connection_connect(struct btd_device *device, uint16_t id)
return 0;
}
-int connection_disconnect(struct btd_device *device, uint16_t id)
+int connection_disconnect(struct btd_service *service)
{
- struct network_peer *peer;
- struct network_conn *nc;
-
- peer = find_peer(peers, device);
- if (!peer)
- return -ENOENT;
-
- nc = find_connection(peer->connections, id);
- if (!nc)
- return -ENOTSUP;
+ struct network_conn *nc = btd_service_get_user_data(service);
if (nc->state == DISCONNECTED)
return 0;
@@ -519,7 +502,7 @@ static DBusMessage *local_disconnect(DBusConnection *conn,
if (nc->state == DISCONNECTED)
continue;
- err = connection_disconnect(peer->device, nc->id);
+ err = connection_disconnect(nc->service);
if (err < 0)
return btd_error_failed(msg, strerror(-err));
diff --git a/profiles/network/connection.h b/profiles/network/connection.h
index 1e7eedb..4a8b43b 100644
--- a/profiles/network/connection.h
+++ b/profiles/network/connection.h
@@ -23,5 +23,5 @@
int connection_register(struct btd_service *service);
void connection_unregister(struct btd_service *service);
-int connection_connect(struct btd_device *device, uint16_t id);
-int connection_disconnect(struct btd_device *device, uint16_t id);
+int connection_connect(struct btd_service *service);
+int connection_disconnect(struct btd_service *service);
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index f37954a..03b1b3d 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -42,7 +42,6 @@
#include "device.h"
#include "profile.h"
#include "service.h"
-#include "manager.h"
#include "common.h"
#include "connection.h"
#include "server.h"
@@ -75,16 +74,6 @@ done:
conf_security ? "true" : "false");
}
-static int panu_connect(struct btd_device *dev, struct btd_profile *profile)
-{
- return connection_connect(dev, BNEP_SVC_PANU);
-}
-
-static int panu_disconnect(struct btd_device *dev, struct btd_profile *profile)
-{
- return connection_disconnect(dev, BNEP_SVC_PANU);
-}
-
static int panu_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
const char *path = adapter_get_path(adapter);
@@ -104,16 +93,6 @@ static void panu_server_remove(struct btd_profile *p,
server_unregister(adapter, BNEP_SVC_PANU);
}
-static int gn_connect(struct btd_device *dev, struct btd_profile *profile)
-{
- return connection_connect(dev, BNEP_SVC_GN);
-}
-
-static int gn_disconnect(struct btd_device *dev, struct btd_profile *profile)
-{
- return connection_disconnect(dev, BNEP_SVC_GN);
-}
-
static int gn_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
const char *path = adapter_get_path(adapter);
@@ -133,16 +112,6 @@ static void gn_server_remove(struct btd_profile *p,
server_unregister(adapter, BNEP_SVC_GN);
}
-static int nap_connect(struct btd_device *dev, struct btd_profile *profile)
-{
- return connection_connect(dev, BNEP_SVC_NAP);
-}
-
-static int nap_disconnect(struct btd_device *dev, struct btd_profile *profile)
-{
- return connection_disconnect(dev, BNEP_SVC_NAP);
-}
-
static int nap_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
const char *path = adapter_get_path(adapter);
@@ -168,8 +137,8 @@ static struct btd_profile panu_profile = {
.remote_uuid = PANU_UUID,
.device_probe = connection_register,
.device_remove = connection_unregister,
- .connect = panu_connect,
- .disconnect = panu_disconnect,
+ .connect = connection_connect,
+ .disconnect = connection_disconnect,
.adapter_probe = panu_server_probe,
.adapter_remove = panu_server_remove,
};
@@ -180,8 +149,8 @@ static struct btd_profile gn_profile = {
.remote_uuid = GN_UUID,
.device_probe = connection_register,
.device_remove = connection_unregister,
- .connect = gn_connect,
- .disconnect = gn_disconnect,
+ .connect = connection_connect,
+ .disconnect = connection_disconnect,
.adapter_probe = gn_server_probe,
.adapter_remove = gn_server_remove,
};
@@ -192,48 +161,12 @@ static struct btd_profile nap_profile = {
.remote_uuid = NAP_UUID,
.device_probe = connection_register,
.device_remove = connection_unregister,
- .connect = nap_connect,
- .disconnect = nap_disconnect,
+ .connect = connection_connect,
+ .disconnect = connection_disconnect,
.adapter_probe = nap_server_probe,
.adapter_remove = nap_server_remove,
};
-void network_connected(struct btd_device *dev, int id, int err)
-{
- switch (id) {
- case BNEP_SVC_PANU:
- device_profile_connected(dev, &panu_profile, err);
- break;
- case BNEP_SVC_GN:
- device_profile_connected(dev, &gn_profile, err);
- break;
- case BNEP_SVC_NAP:
- device_profile_connected(dev, &nap_profile, err);
- break;
- default:
- error("Invalid id %d passed to network_connected", id);
- break;
- }
-}
-
-void network_disconnected(struct btd_device *dev, int id, int err)
-{
- switch (id) {
- case BNEP_SVC_PANU:
- device_profile_disconnected(dev, &panu_profile, err);
- break;
- case BNEP_SVC_GN:
- device_profile_disconnected(dev, &gn_profile, err);
- break;
- case BNEP_SVC_NAP:
- device_profile_disconnected(dev, &gn_profile, err);
- break;
- default:
- error("Invalid id %d passed to network_disconnected", id);
- break;
- }
-}
-
static int network_init(void)
{
read_config(CONFIGDIR "/network.conf");
diff --git a/profiles/network/manager.h b/profiles/network/manager.h
deleted file mode 100644
index 8a8c065..0000000
--- a/profiles/network/manager.h
+++ /dev/null
@@ -1,25 +0,0 @@
-/*
- *
- * BlueZ - Bluetooth protocol stack for Linux
- *
- * Copyright (C) 2004-2010 Marcel Holtmann <[email protected]>
- *
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
- *
- */
-
-void network_connected(struct btd_device *dev, int id, int err);
-void network_disconnected(struct btd_device *dev, int id, int err);
diff --git a/src/device.c b/src/device.c
index 91fcd89..332e61c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -73,6 +73,7 @@
#define DISCOVERY_TIMER 1
static DBusConnection *dbus_conn = NULL;
+guint service_state_cb_id;
struct btd_disconnect_data {
guint id;
@@ -1092,7 +1093,7 @@ static int connect_next(struct btd_device *dev)
return err;
}
-void device_profile_connected(struct btd_device *dev,
+static void device_profile_connected(struct btd_device *dev,
struct btd_profile *profile, int err)
{
struct btd_service *pending;
@@ -1108,10 +1109,6 @@ void device_profile_connected(struct btd_device *dev,
if (l != NULL)
dev->pending = g_slist_delete_link(dev->pending, l);
- l = find_service_with_profile(dev->services, profile);
- if (l != NULL)
- btd_service_connecting_complete(l->data, err);
-
/* Only continue connecting the next profile if it matches the first
* pending, otherwise it will trigger another connect to the same
* profile
@@ -1312,15 +1309,9 @@ static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
return reply;
}
-void device_profile_disconnected(struct btd_device *dev,
+static void device_profile_disconnected(struct btd_device *dev,
struct btd_profile *profile, int err)
{
- GSList *l;
-
- l = find_service_with_profile(dev->services, profile);
- if (l != NULL)
- btd_service_disconnecting_complete(l->data, err);
-
if (!dev->disconnect)
return;
@@ -4307,11 +4298,28 @@ void btd_device_set_pnpid(struct btd_device *device, uint16_t source,
store_device_info(device);
}
+static void service_state_changed(struct btd_service *service,
+ btd_service_state_t old_state,
+ btd_service_state_t new_state,
+ int err, void *user_data)
+{
+ struct btd_profile *profile = btd_service_get_profile(service);
+ struct btd_device *device = btd_service_get_device(service);
+
+ if (old_state == BTD_SERVICE_STATE_CONNECTING)
+ device_profile_connected(device, profile, err);
+ else if (old_state == BTD_SERVICE_STATE_DISCONNECTING)
+ device_profile_disconnected(device, profile, err);
+}
+
void btd_device_init(void)
{
dbus_conn = btd_get_dbus_connection();
+ service_state_cb_id = btd_service_add_state_cb(
+ service_state_changed, NULL);
}
void btd_device_cleanup(void)
{
+ btd_service_remove_state_cb(service_state_cb_id);
}
diff --git a/src/device.h b/src/device.h
index d072015..f467fa6 100644
--- a/src/device.h
+++ b/src/device.h
@@ -120,12 +120,5 @@ unsigned int device_wait_for_svc_complete(struct btd_device *dev,
bool device_remove_svc_complete_callback(struct btd_device *dev,
unsigned int id);
-struct btd_profile;
-
-void device_profile_connected(struct btd_device *dev,
- struct btd_profile *profile, int err);
-void device_profile_disconnected(struct btd_device *dev,
- struct btd_profile *profile, int err);
-
void btd_device_init(void);
void btd_device_cleanup(void);
diff --git a/src/profile.c b/src/profile.c
index b2c5ebf..0500983 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -591,6 +591,7 @@ struct ext_io {
guint io_id;
struct btd_adapter *adapter;
struct btd_device *device;
+ struct btd_service *service;
bool resolving;
bool connected;
@@ -722,6 +723,9 @@ static void ext_io_destroy(gpointer p)
if (ext_io->device)
btd_device_unref(ext_io->device);
+ if (ext_io->service)
+ btd_service_unref(ext_io->service);
+
g_free(ext_io);
}
@@ -746,7 +750,7 @@ static gboolean ext_io_disconnected(GIOChannel *io, GIOCondition cond,
DBG("%s disconnected from %s", ext->name, addr);
drop:
- device_profile_disconnected(conn->device, &ext->p, 0);
+ btd_service_disconnecting_complete(conn->service, 0);
ext->conns = g_slist_remove(ext->conns, conn);
ext_io_destroy(conn);
return FALSE;
@@ -768,7 +772,7 @@ static void new_conn_reply(DBusPendingCall *call, void *user_data)
conn->pending = NULL;
if (!dbus_error_is_set(&err)) {
- device_profile_connected(conn->device, &ext->p, 0);
+ btd_service_connecting_complete(conn->service, 0);
conn->connected = true;
return;
}
@@ -776,7 +780,7 @@ static void new_conn_reply(DBusPendingCall *call, void *user_data)
error("%s replied with an error: %s, %s", ext->name,
err.name, err.message);
- device_profile_connected(conn->device, &ext->p, -ECONNREFUSED);
+ btd_service_connecting_complete(conn->service, -ECONNREFUSED);
if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY))
ext_cancel(ext);
@@ -803,14 +807,14 @@ static void disconn_reply(DBusPendingCall *call, void *user_data)
conn->pending = NULL;
if (!dbus_error_is_set(&err)) {
- device_profile_disconnected(conn->device, &ext->p, 0);
+ btd_service_disconnecting_complete(conn->service, 0);
goto disconnect;
}
error("%s replied with an error: %s, %s", ext->name,
err.name, err.message);
- device_profile_disconnected(conn->device, &ext->p, -ECONNREFUSED);
+ btd_service_disconnecting_complete(conn->service, -ECONNREFUSED);
if (dbus_error_has_name(&err, DBUS_ERROR_NO_REPLY))
ext_cancel(ext);
@@ -986,8 +990,7 @@ static void ext_connect(GIOChannel *io, GError *err, gpointer user_data)
return;
drop:
- device_profile_connected(conn->device, &ext->p,
- err ? -err->code : -EIO);
+ btd_service_connecting_complete(conn->service, err ? -err->code : -EIO);
if (io_err)
g_error_free(io_err);
ext->conns = g_slist_remove(ext->conns, conn);
@@ -1569,7 +1572,7 @@ static void record_cb(sdp_list_t *recs, int err, gpointer user_data)
return;
failed:
- device_profile_connected(conn->device, &ext->p, err);
+ btd_service_connecting_complete(conn->service, err);
ext->conns = g_slist_remove(ext->conns, conn);
ext_io_destroy(conn);
}
@@ -1591,8 +1594,10 @@ static int resolve_service(struct ext_io *conn, const bdaddr_t *src,
return err;
}
-static int ext_connect_dev(struct btd_device *dev, struct btd_profile *profile)
+static int ext_connect_dev(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
+ struct btd_profile *profile = btd_service_get_profile(service);
struct btd_adapter *adapter;
struct ext_io *conn;
struct ext_profile *ext;
@@ -1626,6 +1631,7 @@ static int ext_connect_dev(struct btd_device *dev, struct btd_profile *profile)
conn->adapter = btd_adapter_ref(adapter);
conn->device = btd_device_ref(dev);
+ conn->service = btd_service_ref(service);
ext->conns = g_slist_append(ext->conns, conn);
@@ -1668,9 +1674,10 @@ static int send_disconn_req(struct ext_profile *ext, struct ext_io *conn)
return 0;
}
-static int ext_disconnect_dev(struct btd_device *dev,
- struct btd_profile *profile)
+static int ext_disconnect_dev(struct btd_service *service)
{
+ struct btd_device *dev = btd_service_get_device(service);
+ struct btd_profile *profile = btd_service_get_profile(service);
struct ext_profile *ext;
struct ext_io *conn;
int err;
diff --git a/src/profile.h b/src/profile.h
index 8daa358..9aec27e 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -39,10 +39,8 @@ struct btd_profile {
int (*device_probe) (struct btd_service *service);
void (*device_remove) (struct btd_service *service);
- int (*connect) (struct btd_device *device,
- struct btd_profile *profile);
- int (*disconnect) (struct btd_device *device,
- struct btd_profile *profile);
+ int (*connect) (struct btd_service *service);
+ int (*disconnect) (struct btd_service *service);
int (*adapter_probe) (struct btd_profile *p,
struct btd_adapter *adapter);
diff --git a/src/service.c b/src/service.c
index d74fc98..96f3d79 100644
--- a/src/service.c
+++ b/src/service.c
@@ -197,7 +197,7 @@ int btd_service_connect(struct btd_service *service)
change_state(service, BTD_SERVICE_STATE_CONNECTING, 0);
- err = profile->connect(service->device, service->profile);
+ err = profile->connect(service);
if (err == 0)
return 0;
@@ -232,7 +232,7 @@ int btd_service_disconnect(struct btd_service *service)
change_state(service, BTD_SERVICE_STATE_DISCONNECTING, 0);
- err = profile->disconnect(service->device, service->profile);
+ err = profile->disconnect(service);
if (err == 0)
return 0;
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Extend the btd_service API to support state observers.
---
src/service.c | 48 ++++++++++++++++++++++++++++++++++++++++++++++++
src/service.h | 8 ++++++++
2 files changed, 56 insertions(+)
diff --git a/src/service.c b/src/service.c
index e03a412..d74fc98 100644
--- a/src/service.c
+++ b/src/service.c
@@ -54,6 +54,14 @@ struct btd_service {
btd_service_state_t state;
};
+struct service_state_callback {
+ btd_service_state_cb cb;
+ void *user_data;
+ guint id;
+};
+
+static GSList *state_callbacks;
+
static const char *state2str(btd_service_state_t state)
{
switch (state) {
@@ -77,6 +85,7 @@ static void change_state(struct btd_service *service, btd_service_state_t state,
{
btd_service_state_t old = service->state;
char addr[18];
+ GSList *l;
if (state == old)
return;
@@ -90,6 +99,12 @@ static void change_state(struct btd_service *service, btd_service_state_t state,
DBG("%p: device %s profile %s state changed: %s -> %s (%d)", service,
addr, service->profile->name,
state2str(old), state2str(state), err);
+
+ for (l = state_callbacks; l != NULL; l = g_slist_next(l)) {
+ struct service_state_callback *cb = l->data;
+
+ cb->cb(service, old, state, err, cb->user_data);
+ }
}
struct btd_service *btd_service_ref(struct btd_service *service)
@@ -256,6 +271,39 @@ btd_service_state_t btd_service_get_state(const struct btd_service *service)
return service->state;
}
+guint btd_service_add_state_cb(btd_service_state_cb cb, void *user_data)
+{
+ struct service_state_callback *state_cb;
+ static guint id = 0;
+
+ state_cb = g_new0(struct service_state_callback, 1);
+ state_cb->cb = cb;
+ state_cb->user_data = user_data;
+ state_cb->id = ++id;
+
+ state_callbacks = g_slist_append(state_callbacks, state_cb);
+
+ return state_cb->id;
+}
+
+gboolean btd_service_remove_state_cb(guint id)
+{
+ GSList *l;
+
+ for (l = state_callbacks; l != NULL; l = g_slist_next(l)) {
+ struct service_state_callback *cb = l->data;
+
+ if (cb && cb->id == id) {
+ state_callbacks = g_slist_remove_link(state_callbacks,
+ l);
+ g_free(cb);
+ return TRUE;
+ }
+ }
+
+ return FALSE;
+}
+
void btd_service_connecting_complete(struct btd_service *service, int err)
{
if (service->state != BTD_SERVICE_STATE_DISCONNECTED &&
diff --git a/src/service.h b/src/service.h
index a89b524..718a465 100644
--- a/src/service.h
+++ b/src/service.h
@@ -33,6 +33,11 @@ struct btd_service;
struct btd_device;
struct btd_profile;
+typedef void (*btd_service_state_cb) (struct btd_service *service,
+ btd_service_state_t old_state,
+ btd_service_state_t new_state,
+ int err, void *user_data);
+
struct btd_service *btd_service_ref(struct btd_service *service);
void btd_service_unref(struct btd_service *service);
@@ -52,6 +57,9 @@ struct btd_device *btd_service_get_device(const struct btd_service *service);
struct btd_profile *btd_service_get_profile(const struct btd_service *service);
btd_service_state_t btd_service_get_state(const struct btd_service *service);
+guint btd_service_add_state_cb(btd_service_state_cb cb, void *user_data);
+gboolean btd_service_remove_state_cb(guint id);
+
/* Functions used by profile implementation */
void btd_service_connecting_complete(struct btd_service *service, int err);
void btd_service_disconnecting_complete(struct btd_service *service, int err);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Profile implementations are allowed to hold a reference to probed
services and make use of the service's userdata pointer, so update the
input profiles accordingly.
---
profiles/input/device.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index c9a3612..adbd114 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -65,6 +65,7 @@ enum reconnect_mode_t {
};
struct input_device {
+ struct btd_service *service;
struct btd_device *device;
char *path;
bdaddr_t src;
@@ -115,6 +116,7 @@ static void input_device_free(struct input_device *idev)
if (idev->dc_id)
device_remove_disconnect_watch(idev->device, idev->dc_id);
+ btd_service_unref(idev->service);
btd_device_unref(idev->device);
g_free(idev->name);
g_free(idev->path);
@@ -775,6 +777,7 @@ static struct input_device *input_device_new(struct btd_service *service)
idev = g_new0(struct input_device, 1);
bacpy(&idev->src, adapter_get_address(adapter));
bacpy(&idev->dst, device_get_address(device));
+ idev->service = btd_service_ref(service);
idev->device = btd_device_ref(device);
idev->path = g_strdup(path);
idev->handle = rec->handle;
@@ -887,6 +890,8 @@ int input_device_register(struct btd_service *service)
return -EINVAL;
}
+ btd_service_set_user_data(service, idev);
+
devices = g_slist_append(devices, idev);
return 0;
@@ -911,14 +916,10 @@ void input_device_unregister(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
const char *path = device_get_path(device);
- struct input_device *idev;
+ struct input_device *idev = btd_service_get_user_data(service);
DBG("%s", path);
- idev = find_device_by_path(devices, path);
- if (idev == NULL)
- return;
-
g_dbus_unregister_interface(btd_get_dbus_connection(),
idev->path, INPUT_INTERFACE);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Move the code to propagate the AVRCP->core state changes from manager.c
to control.c.
---
profiles/audio/avrcp.c | 16 ++++++++--------
profiles/audio/control.c | 32 ++++++++++++++++++++++++++++++++
profiles/audio/control.h | 5 +++++
profiles/audio/manager.c | 20 --------------------
profiles/audio/manager.h | 4 ----
5 files changed, 45 insertions(+), 32 deletions(-)
diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 512b018..b7de051 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -2668,7 +2668,7 @@ static void session_tg_init_control(struct avrcp *session)
avrcp_register_notification(session,
AVRCP_EVENT_VOLUME_CHANGED);
- audio_controller_connected(session->dev->btd_dev, 0);
+ control_remote_connected(session->dev->control, 0);
}
static void session_ct_init_browsing(struct avrcp *session)
@@ -2694,7 +2694,7 @@ static void session_ct_init_control(struct avrcp *session)
if (session->version >= 0x0104)
session->supported_events = (1 << AVRCP_EVENT_VOLUME_CHANGED);
- audio_target_connected(session->dev->btd_dev, 0);
+ control_target_connected(session->dev->control, 0);
player = create_ct_player(session, 0);
if (player == NULL)
@@ -2731,9 +2731,9 @@ static void session_tg_destroy(struct avrcp *session)
player->sessions = g_slist_remove(player->sessions, session);
if (session->control_id == 0)
- audio_controller_connected(session->dev->btd_dev, -EIO);
-
- audio_controller_disconnected(session->dev->btd_dev, 0);
+ control_remote_connected(session->dev->control, -EIO);
+ else
+ control_remote_disconnected(session->dev->control, 0);
session_destroy(session);
}
@@ -2745,9 +2745,9 @@ static void session_ct_destroy(struct avrcp *session)
g_slist_free_full(session->players, player_destroy);
if (session->control_id == 0)
- audio_target_connected(session->dev->btd_dev, -EIO);
-
- audio_target_disconnected(session->dev->btd_dev, 0);
+ control_target_connected(session->dev->control, -EIO);
+ else
+ control_target_disconnected(session->dev->control, 0);
session_destroy(session);
}
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index 10cd1de..bb3f812 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -68,6 +68,38 @@ struct control {
unsigned int avctp_id;
};
+void control_target_connected(struct control *control, int err)
+{
+ struct btd_device *device = btd_service_get_device(control->target);
+ struct btd_profile *profile = btd_service_get_profile(control->target);
+
+ device_profile_connected(device, profile, err);
+}
+
+void control_target_disconnected(struct control *control, int err)
+{
+ struct btd_device *device = btd_service_get_device(control->target);
+ struct btd_profile *profile = btd_service_get_profile(control->target);
+
+ device_profile_disconnected(device, profile, err);
+}
+
+void control_remote_connected(struct control *control, int err)
+{
+ struct btd_device *device = btd_service_get_device(control->remote);
+ struct btd_profile *profile = btd_service_get_profile(control->remote);
+
+ device_profile_connected(device, profile, err);
+}
+
+void control_remote_disconnected(struct control *control, int err)
+{
+ struct btd_device *device = btd_service_get_device(control->remote);
+ struct btd_profile *profile = btd_service_get_profile(control->remote);
+
+ device_profile_disconnected(device, profile, err);
+}
+
static void state_changed(struct audio_device *dev, avctp_state_t old_state,
avctp_state_t new_state)
{
diff --git a/profiles/audio/control.h b/profiles/audio/control.h
index 0176b54..0a0f208 100644
--- a/profiles/audio/control.h
+++ b/profiles/audio/control.h
@@ -34,3 +34,8 @@ gboolean control_is_active(struct audio_device *dev);
int control_connect(struct audio_device *dev);
int control_disconnect(struct audio_device *dev);
+
+void control_target_connected(struct control *control, int err);
+void control_target_disconnected(struct control *control, int err);
+void control_remote_connected(struct control *control, int err);
+void control_remote_disconnected(struct control *control, int err);
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index e886e12..901f94f 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -421,26 +421,6 @@ void audio_source_disconnected(struct btd_device *dev, int err)
device_profile_disconnected(dev, &a2dp_source_profile, err);
}
-void audio_target_connected(struct btd_device *dev, int err)
-{
- device_profile_connected(dev, &avrcp_target_profile, err);
-}
-
-void audio_target_disconnected(struct btd_device *dev, int err)
-{
- device_profile_disconnected(dev, &avrcp_target_profile, err);
-}
-
-void audio_controller_connected(struct btd_device *dev, int err)
-{
- device_profile_connected(dev, &avrcp_remote_profile, err);
-}
-
-void audio_controller_disconnected(struct btd_device *dev, int err)
-{
- device_profile_disconnected(dev, &avrcp_remote_profile, err);
-}
-
int audio_manager_init(GKeyFile *conf)
{
if (conf)
diff --git a/profiles/audio/manager.h b/profiles/audio/manager.h
index 9b5af5f..2567e46 100644
--- a/profiles/audio/manager.h
+++ b/profiles/audio/manager.h
@@ -33,10 +33,6 @@ void audio_sink_connected(struct btd_device *dev, int err);
void audio_sink_disconnected(struct btd_device *dev, int err);
void audio_source_connected(struct btd_device *dev, int err);
void audio_source_disconnected(struct btd_device *dev, int err);
-void audio_target_connected(struct btd_device *dev, int err);
-void audio_target_disconnected(struct btd_device *dev, int err);
-void audio_controller_connected(struct btd_device *dev, int err);
-void audio_controller_disconnected(struct btd_device *dev, int err);
int audio_manager_init(GKeyFile *config);
void audio_manager_exit(void);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Profile implementations are allowed to hold a reference to probed
services, so update the audio profiles accordingly.
---
profiles/audio/control.c | 28 ++++++++++++++++++++++------
profiles/audio/control.h | 7 +++++--
profiles/audio/manager.c | 9 ++++-----
profiles/audio/sink.c | 6 +++++-
profiles/audio/sink.h | 4 +++-
profiles/audio/source.c | 7 ++++++-
profiles/audio/source.h | 5 ++++-
7 files changed, 49 insertions(+), 17 deletions(-)
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index fd5ff92..10cd1de 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -48,6 +48,8 @@
#include "lib/uuid.h"
#include "../src/adapter.h"
#include "../src/device.h"
+#include "../src/profile.h"
+#include "../src/service.h"
#include "log.h"
#include "error.h"
@@ -61,7 +63,8 @@
struct control {
struct avctp *session;
- gboolean target;
+ struct btd_service *target;
+ struct btd_service *remote;
unsigned int avctp_id;
};
@@ -242,6 +245,12 @@ static void path_unregister(void *data)
avctp_remove_state_cb(control->avctp_id);
+ if (control->target)
+ btd_service_unref(control->target);
+
+ if (control->remote)
+ btd_service_unref(control->remote);
+
g_free(control);
dev->control = NULL;
}
@@ -253,13 +262,20 @@ void control_unregister(struct audio_device *dev)
AUDIO_CONTROL_INTERFACE);
}
-void control_update(struct control *control, const char *uuid)
+void control_update(struct control *control, struct btd_service *service)
{
- if (bt_uuid_strcmp(uuid, AVRCP_TARGET_UUID) == 0)
- control->target = TRUE;
+ struct btd_profile *p = btd_service_get_profile(service);
+ const char *uuid = p->remote_uuid;
+
+ if (!control->target && bt_uuid_strcmp(uuid, AVRCP_TARGET_UUID) == 0)
+ control->target = btd_service_ref(service);
+ else if (!control->remote &&
+ bt_uuid_strcmp(uuid, AVRCP_REMOTE_UUID) == 0)
+ control->remote = btd_service_ref(service);
}
-struct control *control_init(struct audio_device *dev, const char *uuid)
+struct control *control_init(struct audio_device *dev,
+ struct btd_service *service)
{
struct control *control;
@@ -276,7 +292,7 @@ struct control *control_init(struct audio_device *dev, const char *uuid)
control = g_new0(struct control, 1);
- control_update(control, uuid);
+ control_update(control, service);
control->avctp_id = avctp_add_state_cb(dev, state_changed);
diff --git a/profiles/audio/control.h b/profiles/audio/control.h
index 82ad0d2..0176b54 100644
--- a/profiles/audio/control.h
+++ b/profiles/audio/control.h
@@ -24,8 +24,11 @@
#define AUDIO_CONTROL_INTERFACE "org.bluez.MediaControl1"
-struct control *control_init(struct audio_device *dev, const char *uuid);
-void control_update(struct control *control, const char *uuid);
+struct btd_service;
+
+struct control *control_init(struct audio_device *dev,
+ struct btd_service *service);
+void control_update(struct control *control, struct btd_service *service);
void control_unregister(struct audio_device *dev);
gboolean control_is_active(struct audio_device *dev);
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index ff4590e..e886e12 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -114,7 +114,7 @@ static int a2dp_source_probe(struct btd_service *service)
return -1;
}
- audio_dev->source = source_init(audio_dev);
+ audio_dev->source = source_init(audio_dev, service);
return 0;
}
@@ -130,7 +130,7 @@ static int a2dp_sink_probe(struct btd_service *service)
return -1;
}
- audio_dev->sink = sink_init(audio_dev);
+ audio_dev->sink = sink_init(audio_dev, service);
return 0;
}
@@ -138,7 +138,6 @@ static int a2dp_sink_probe(struct btd_service *service)
static int avrcp_probe(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
- struct btd_profile *p = btd_service_get_profile(service);
struct audio_device *audio_dev;
audio_dev = get_audio_dev(device);
@@ -148,9 +147,9 @@ static int avrcp_probe(struct btd_service *service)
}
if (audio_dev->control)
- control_update(audio_dev->control, p->remote_uuid);
+ control_update(audio_dev->control, service);
else
- audio_dev->control = control_init(audio_dev, p->remote_uuid);
+ audio_dev->control = control_init(audio_dev, service);
if (audio_dev->sink && sink_is_active(audio_dev))
avrcp_connect(audio_dev);
diff --git a/profiles/audio/sink.c b/profiles/audio/sink.c
index f023307..9f1a2d9 100644
--- a/profiles/audio/sink.c
+++ b/profiles/audio/sink.c
@@ -41,6 +41,7 @@
#include "../src/adapter.h"
#include "../src/device.h"
+#include "../src/service.h"
#include "device.h"
#include "avdtp.h"
@@ -55,6 +56,7 @@
struct sink {
struct audio_device *dev;
+ struct btd_service *service;
struct avdtp *session;
struct avdtp_stream *stream;
unsigned int cb_id;
@@ -361,6 +363,7 @@ static void sink_free(struct audio_device *dev)
g_source_remove(sink->retry_id);
avdtp_remove_state_cb(sink->avdtp_callback_id);
+ btd_service_unref(sink->service);
g_free(sink);
dev->sink = NULL;
@@ -372,7 +375,7 @@ void sink_unregister(struct audio_device *dev)
sink_free(dev);
}
-struct sink *sink_init(struct audio_device *dev)
+struct sink *sink_init(struct audio_device *dev, struct btd_service *service)
{
struct sink *sink;
@@ -381,6 +384,7 @@ struct sink *sink_init(struct audio_device *dev)
sink = g_new0(struct sink, 1);
sink->dev = dev;
+ sink->service = btd_service_ref(service);
sink->avdtp_callback_id = avdtp_add_state_cb(dev, avdtp_state_callback);
diff --git a/profiles/audio/sink.h b/profiles/audio/sink.h
index 7ec7610..1a80756 100644
--- a/profiles/audio/sink.h
+++ b/profiles/audio/sink.h
@@ -34,11 +34,13 @@ typedef void (*sink_state_cb) (struct audio_device *dev,
sink_state_t new_state,
void *user_data);
+struct btd_service;
+
unsigned int sink_add_state_cb(struct audio_device *dev, sink_state_cb cb,
void *user_data);
gboolean sink_remove_state_cb(unsigned int id);
-struct sink *sink_init(struct audio_device *dev);
+struct sink *sink_init(struct audio_device *dev, struct btd_service *service);
void sink_unregister(struct audio_device *dev);
gboolean sink_is_active(struct audio_device *dev);
int sink_connect(struct audio_device *dev);
diff --git a/profiles/audio/source.c b/profiles/audio/source.c
index 5d9e237..20fd412 100644
--- a/profiles/audio/source.c
+++ b/profiles/audio/source.c
@@ -42,6 +42,7 @@
#include "../src/adapter.h"
#include "../src/device.h"
+#include "../src/service.h"
#include "device.h"
#include "avdtp.h"
@@ -56,6 +57,7 @@
struct source {
struct audio_device *dev;
+ struct btd_service *service;
struct avdtp *session;
struct avdtp_stream *stream;
unsigned int cb_id;
@@ -365,6 +367,7 @@ static void source_free(struct audio_device *dev)
g_source_remove(source->retry_id);
avdtp_remove_state_cb(source->avdtp_callback_id);
+ btd_service_unref(source->service);
g_free(source);
dev->source = NULL;
@@ -377,7 +380,8 @@ void source_unregister(struct audio_device *dev)
source_free(dev);
}
-struct source *source_init(struct audio_device *dev)
+struct source *source_init(struct audio_device *dev,
+ struct btd_service *service)
{
struct source *source;
@@ -386,6 +390,7 @@ struct source *source_init(struct audio_device *dev)
source = g_new0(struct source, 1);
source->dev = dev;
+ source->service = btd_service_ref(service);
source->avdtp_callback_id = avdtp_add_state_cb(dev,
avdtp_state_callback);
diff --git a/profiles/audio/source.h b/profiles/audio/source.h
index 317db9a..8bd20a7 100644
--- a/profiles/audio/source.h
+++ b/profiles/audio/source.h
@@ -35,11 +35,14 @@ typedef void (*source_state_cb) (struct audio_device *dev,
source_state_t new_state,
void *user_data);
+struct btd_service;
+
unsigned int source_add_state_cb(struct audio_device *dev, source_state_cb cb,
void *user_data);
gboolean source_remove_state_cb(unsigned int id);
-struct source *source_init(struct audio_device *dev);
+struct source *source_init(struct audio_device *dev,
+ struct btd_service *service);
void source_unregister(struct audio_device *dev);
int source_connect(struct audio_device *dev);
gboolean source_new_stream(struct audio_device *dev, struct avdtp *session,
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Profile implementations are allowed to hold a reference to probed
services and make use of the service's userdata pointer, so update the
network profiles accordingly.
---
profiles/network/connection.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 16ee318..8fbde14 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -67,6 +67,7 @@ struct network_peer {
};
struct network_conn {
+ struct btd_service *service;
char dev[16]; /* Interface name */
uint16_t id; /* Role: Service Class Identifier */
conn_state state;
@@ -606,6 +607,7 @@ static void connection_free(void *data)
if (nc->connect)
dbus_message_unref(nc->connect);
+ btd_service_unref(nc->service);
g_free(nc);
}
@@ -649,15 +651,12 @@ static const GDBusPropertyTable connection_properties[] = {
void connection_unregister(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
- struct network_peer *peer;
+ struct network_conn *conn = btd_service_get_user_data(service);
+ struct network_peer *peer = conn->peer;
uint16_t id = get_service_id(service);
DBG("%s id %u", device_get_path(device), id);
- peer = find_peer(peers, device);
- if (!peer)
- return;
-
g_slist_free_full(peer->connections, connection_free);
peer->connections = NULL;
@@ -721,9 +720,12 @@ int connection_register(struct btd_service *service)
nc->id = id;
memset(nc->dev, 0, sizeof(nc->dev));
strcpy(nc->dev, "bnep%d");
+ nc->service = btd_service_ref(service);
nc->state = DISCONNECTED;
nc->peer = peer;
+ btd_service_set_user_data(service, nc);
+
DBG("id %u registered", id);
peer->connections = g_slist_append(peer->connections, nc);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Change the profile probe mechanism in order to pass the btd_service
instance representing the remote service. This object is bound to a
btd_profile and a btd_device, thus replacing the previous parameters.
The probe callback is allowed to hold a reference to the btd_service
by means of btd_service_ref(), which should be unreferenced during
removal.
Keeping such a reference of the btd_service allows supporting multiple
instances of the same UUID, since the reference can serve as a handle
during the interactions between the profile implementation and the core.
---
profiles/audio/manager.c | 14 ++++++++++----
profiles/cyclingspeed/cyclingspeed.c | 8 +++++---
profiles/deviceinfo/deviceinfo.c | 10 ++++++----
profiles/gatt/gas.c | 9 ++++++---
profiles/health/hdp_manager.c | 9 +++++++--
profiles/heartrate/heartrate.c | 10 ++++++----
profiles/input/device.c | 14 +++++++++-----
profiles/input/device.h | 4 ++--
profiles/input/hog.c | 7 +++++--
profiles/input/manager.c | 1 +
profiles/network/connection.c | 9 +++++++--
profiles/network/connection.h | 4 ++--
profiles/network/manager.c | 1 +
profiles/proximity/manager.c | 28 ++++++++++++++++------------
profiles/proximity/reporter.c | 7 +++++--
profiles/proximity/reporter.h | 4 ++--
profiles/sap/manager.c | 1 +
profiles/scanparam/scan.c | 8 ++++++--
profiles/thermometer/thermometer.c | 10 ++++++----
src/profile.c | 8 ++++++--
src/profile.h | 7 ++++---
src/service.c | 4 ++--
22 files changed, 115 insertions(+), 62 deletions(-)
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index f9c0ca6..ff4590e 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -53,6 +53,7 @@
#include "../src/adapter.h"
#include "../src/device.h"
#include "../src/profile.h"
+#include "../src/service.h"
#include "log.h"
#include "device.h"
@@ -89,8 +90,9 @@ static struct audio_device *manager_find_device(struct btd_device *device)
return NULL;
}
-static void audio_remove(struct btd_profile *p, struct btd_device *device)
+static void audio_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct audio_device *dev;
dev = manager_find_device(device);
@@ -101,8 +103,9 @@ static void audio_remove(struct btd_profile *p, struct btd_device *device)
audio_device_unregister(dev);
}
-static int a2dp_source_probe(struct btd_profile *p, struct btd_device *device)
+static int a2dp_source_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct audio_device *audio_dev;
audio_dev = get_audio_dev(device);
@@ -116,8 +119,9 @@ static int a2dp_source_probe(struct btd_profile *p, struct btd_device *device)
return 0;
}
-static int a2dp_sink_probe(struct btd_profile *p, struct btd_device *device)
+static int a2dp_sink_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct audio_device *audio_dev;
audio_dev = get_audio_dev(device);
@@ -131,8 +135,10 @@ static int a2dp_sink_probe(struct btd_profile *p, struct btd_device *device)
return 0;
}
-static int avrcp_probe(struct btd_profile *p, struct btd_device *device)
+static int avrcp_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+ struct btd_profile *p = btd_service_get_profile(service);
struct audio_device *audio_dev;
audio_dev = get_audio_dev(device);
diff --git a/profiles/cyclingspeed/cyclingspeed.c b/profiles/cyclingspeed/cyclingspeed.c
index 744bd4b..6080f09 100644
--- a/profiles/cyclingspeed/cyclingspeed.c
+++ b/profiles/cyclingspeed/cyclingspeed.c
@@ -34,6 +34,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "dbus-common.h"
#include "error.h"
#include "attrib/gattrib.h"
@@ -1180,8 +1181,9 @@ static const GDBusMethodTable cyclingspeed_device_methods[] = {
{ }
};
-static int csc_device_probe(struct btd_profile *p, struct btd_device *device)
+static int csc_device_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct btd_adapter *adapter;
struct csc_adapter *cadapter;
struct csc *csc;
@@ -1226,9 +1228,9 @@ static int csc_device_probe(struct btd_profile *p, struct btd_device *device)
return 0;
}
-static void csc_device_remove(struct btd_profile *p,
- struct btd_device *device)
+static void csc_device_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct btd_adapter *adapter;
struct csc_adapter *cadapter;
struct csc *csc;
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index 08f53b3..fc8babd 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -34,6 +34,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "attrib/gattrib.h"
#include "attio.h"
#include "attrib/att.h"
@@ -198,9 +199,9 @@ static void deviceinfo_unregister(struct btd_device *device)
deviceinfo_free(d);
}
-static int deviceinfo_driver_probe(struct btd_profile *p,
- struct btd_device *device)
+static int deviceinfo_driver_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *prim;
prim = btd_device_get_primary(device, DEVICE_INFORMATION_UUID);
@@ -210,9 +211,10 @@ static int deviceinfo_driver_probe(struct btd_profile *p,
return deviceinfo_register(device, prim);
}
-static void deviceinfo_driver_remove(struct btd_profile *p,
- struct btd_device *device)
+static void deviceinfo_driver_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
deviceinfo_unregister(device);
}
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 4c7af4b..33a680f 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -39,6 +39,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "attrib/att.h"
#include "attrib/gattrib.h"
#include "attio.h"
@@ -407,8 +408,9 @@ static void gas_unregister(struct btd_device *device)
gas_free(gas);
}
-static int gatt_driver_probe(struct btd_profile *p, struct btd_device *device)
+static int gatt_driver_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *gap, *gatt;
gap = btd_device_get_primary(device, GAP_UUID);
@@ -422,9 +424,10 @@ static int gatt_driver_probe(struct btd_profile *p, struct btd_device *device)
return gas_register(device, &gap->range, &gatt->range);
}
-static void gatt_driver_remove(struct btd_profile *p,
- struct btd_device *device)
+static void gatt_driver_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
gas_unregister(device);
}
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index 3777fd4..1bb6007 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -34,6 +34,7 @@
#include <adapter.h>
#include <device.h>
#include <profile.h>
+#include <service.h>
#include <glib-helper.h>
#include <log.h>
@@ -54,13 +55,17 @@ static void hdp_adapter_remove(struct btd_profile *p,
hdp_adapter_unregister(adapter);
}
-static int hdp_driver_probe(struct btd_profile *p, struct btd_device *device)
+static int hdp_driver_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
return hdp_device_register(device);
}
-static void hdp_driver_remove(struct btd_profile *p, struct btd_device *device)
+static void hdp_driver_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
hdp_device_unregister(device);
}
diff --git a/profiles/heartrate/heartrate.c b/profiles/heartrate/heartrate.c
index 18a9448..3a2d419 100644
--- a/profiles/heartrate/heartrate.c
+++ b/profiles/heartrate/heartrate.c
@@ -35,6 +35,7 @@
#include "dbus-common.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "error.h"
#include "attrib/gattrib.h"
#include "attrib/att.h"
@@ -841,9 +842,9 @@ static void heartrate_adapter_remove(struct btd_profile *p,
heartrate_adapter_unregister(adapter);
}
-static int heartrate_device_probe(struct btd_profile *p,
- struct btd_device *device)
+static int heartrate_device_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *prim;
prim = btd_device_get_primary(device, HEART_RATE_UUID);
@@ -853,9 +854,10 @@ static int heartrate_device_probe(struct btd_profile *p,
return heartrate_device_register(device, prim);
}
-static void heartrate_device_remove(struct btd_profile *p,
- struct btd_device *device)
+static void heartrate_device_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
heartrate_device_unregister(device);
}
diff --git a/profiles/input/device.c b/profiles/input/device.c
index b6f9028..c9a3612 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -44,6 +44,7 @@
#include "../src/adapter.h"
#include "../src/device.h"
#include "../src/profile.h"
+#include "../src/service.h"
#include "../src/storage.h"
#include "../src/dbus-common.h"
@@ -761,9 +762,10 @@ int input_device_disconnect(struct btd_device *dev, struct btd_profile *profile)
return 0;
}
-static struct input_device *input_device_new(struct btd_device *device,
- struct btd_profile *p)
+static struct input_device *input_device_new(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+ struct btd_profile *p = btd_service_get_profile(service);
const char *path = device_get_path(device);
const sdp_record_t *rec = btd_device_get_record(device, p->remote_uuid);
struct btd_adapter *adapter = device_get_adapter(device);
@@ -859,8 +861,9 @@ static const GDBusPropertyTable input_properties[] = {
{ }
};
-int input_device_register(struct btd_profile *p, struct btd_device *device)
+int input_device_register(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
const char *path = device_get_path(device);
struct input_device *idev;
@@ -870,7 +873,7 @@ int input_device_register(struct btd_profile *p, struct btd_device *device)
if (idev)
return -EEXIST;
- idev = input_device_new(device, p);
+ idev = input_device_new(service);
if (!idev)
return -EINVAL;
@@ -904,8 +907,9 @@ static struct input_device *find_device(const bdaddr_t *src,
return NULL;
}
-void input_device_unregister(struct btd_profile *p, struct btd_device *device)
+void input_device_unregister(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
const char *path = device_get_path(device);
struct input_device *idev;
diff --git a/profiles/input/device.h b/profiles/input/device.h
index 1c237fc..fd7f847 100644
--- a/profiles/input/device.h
+++ b/profiles/input/device.h
@@ -29,8 +29,8 @@ struct input_conn;
void input_set_idle_timeout(int timeout);
-int input_device_register(struct btd_profile *p, struct btd_device *device);
-void input_device_unregister(struct btd_profile *p, struct btd_device *device);
+int input_device_register(struct btd_service *service);
+void input_device_unregister(struct btd_service *service);
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
GIOChannel *io);
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index eec0eee..c092875 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -46,6 +46,7 @@
#include "src/adapter.h"
#include "src/device.h"
#include "src/profile.h"
+#include "src/service.h"
#include "plugin.h"
#include "suspend.h"
@@ -820,8 +821,9 @@ static void resume_callback(void)
g_slist_foreach(devices, set_suspend, GINT_TO_POINTER(suspend));
}
-static int hog_probe(struct btd_profile *p, struct btd_device *device)
+static int hog_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
const char *path = device_get_path(device);
GSList *primaries, *l;
@@ -860,8 +862,9 @@ static void remove_device(gpointer a, gpointer b)
hog_unregister_device(hogdev);
}
-static void hog_remove(struct btd_profile *p, struct btd_device *device)
+static void hog_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
const char *path = device_get_path(device);
DBG("path %s", path);
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 51cd4cf..dc771a6 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -39,6 +39,7 @@
#include "../src/adapter.h"
#include "../src/device.h"
#include "../src/profile.h"
+#include "../src/service.h"
#include "device.h"
#include "server.h"
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 84359c0..cc7c5ce 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -44,6 +44,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "error.h"
#include "common.h"
@@ -640,8 +641,10 @@ static const GDBusPropertyTable connection_properties[] = {
{ }
};
-void connection_unregister(struct btd_profile *p, struct btd_device *device)
+void connection_unregister(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+ struct btd_profile *p = btd_service_get_profile(service);
struct network_peer *peer;
uint16_t id = bnep_service_id(p->remote_uuid);
@@ -686,8 +689,10 @@ static struct network_peer *create_peer(struct btd_device *device)
return peer;
}
-int connection_register(struct btd_profile *p, struct btd_device *device)
+int connection_register(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+ struct btd_profile *p = btd_service_get_profile(service);
struct network_peer *peer;
struct network_conn *nc;
uint16_t id = bnep_service_id(p->remote_uuid);
diff --git a/profiles/network/connection.h b/profiles/network/connection.h
index 5daead0..1e7eedb 100644
--- a/profiles/network/connection.h
+++ b/profiles/network/connection.h
@@ -21,7 +21,7 @@
*
*/
-int connection_register(struct btd_profile *p, struct btd_device *device);
-void connection_unregister(struct btd_profile *p, struct btd_device *device);
+int connection_register(struct btd_service *service);
+void connection_unregister(struct btd_service *service);
int connection_connect(struct btd_device *device, uint16_t id);
int connection_disconnect(struct btd_device *device, uint16_t id);
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index df79351..f37954a 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -41,6 +41,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "manager.h"
#include "common.h"
#include "connection.h"
diff --git a/profiles/proximity/manager.c b/profiles/proximity/manager.c
index f24428b..7dab23f 100644
--- a/profiles/proximity/manager.c
+++ b/profiles/proximity/manager.c
@@ -35,6 +35,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "attrib/att.h"
#include "attrib/gattrib.h"
#include "attrib/gatt.h"
@@ -48,9 +49,9 @@ static struct enabled enabled = {
.findme = TRUE,
};
-static int monitor_linkloss_probe(struct btd_profile *p,
- struct btd_device *device)
+static int monitor_linkloss_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *linkloss;
linkloss = btd_device_get_primary(device, LINK_LOSS_UUID);
@@ -60,9 +61,9 @@ static int monitor_linkloss_probe(struct btd_profile *p,
return monitor_register_linkloss(device, &enabled, linkloss);
}
-static int monitor_immediate_probe(struct btd_profile *p,
- struct btd_device *device)
+static int monitor_immediate_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *immediate;
immediate = btd_device_get_primary(device, IMMEDIATE_ALERT_UUID);
@@ -72,9 +73,9 @@ static int monitor_immediate_probe(struct btd_profile *p,
return monitor_register_immediate(device, &enabled, immediate);
}
-static int monitor_txpower_probe(struct btd_profile *p,
- struct btd_device *device)
+static int monitor_txpower_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *txpower;
txpower = btd_device_get_primary(device, TX_POWER_UUID);
@@ -84,21 +85,24 @@ static int monitor_txpower_probe(struct btd_profile *p,
return monitor_register_txpower(device, &enabled, txpower);
}
-static void monitor_linkloss_remove(struct btd_profile *p,
- struct btd_device *device)
+static void monitor_linkloss_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
monitor_unregister_linkloss(device);
}
-static void monitor_immediate_remove(struct btd_profile *p,
- struct btd_device *device)
+static void monitor_immediate_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
monitor_unregister_immediate(device);
}
-static void monitor_txpower_remove(struct btd_profile *p,
- struct btd_device *device)
+static void monitor_txpower_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
monitor_unregister_txpower(device);
}
diff --git a/profiles/proximity/reporter.c b/profiles/proximity/reporter.c
index 66f52fe..dbb593a 100644
--- a/profiles/proximity/reporter.c
+++ b/profiles/proximity/reporter.c
@@ -42,6 +42,7 @@
#include "error.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "hcid.h"
#include "attrib/gattrib.h"
#include "attrib/att.h"
@@ -203,8 +204,9 @@ static void register_reporter_device(struct btd_device *device,
radapter->devices = g_slist_prepend(radapter->devices, device);
}
-int reporter_device_probe(struct btd_profile *p, struct btd_device *device)
+int reporter_device_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct reporter_adapter *radapter;
struct btd_adapter *adapter = device_get_adapter(device);
@@ -217,8 +219,9 @@ int reporter_device_probe(struct btd_profile *p, struct btd_device *device)
return 0;
}
-void reporter_device_remove(struct btd_profile *p, struct btd_device *device)
+void reporter_device_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct reporter_adapter *radapter;
struct btd_adapter *adapter = device_get_adapter(device);
diff --git a/profiles/proximity/reporter.h b/profiles/proximity/reporter.h
index b02ae9c..a8e1aac 100644
--- a/profiles/proximity/reporter.h
+++ b/profiles/proximity/reporter.h
@@ -36,8 +36,8 @@ enum {
HIGH_ALERT = 0x02,
};
-void reporter_device_remove(struct btd_profile *p, struct btd_device *device);
-int reporter_device_probe(struct btd_profile *p, struct btd_device *device);
+void reporter_device_remove(struct btd_service *service);
+int reporter_device_probe(struct btd_service *service);
int reporter_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter);
void reporter_adapter_remove(struct btd_profile *p,
diff --git a/profiles/sap/manager.c b/profiles/sap/manager.c
index fddd7aa..24b73e7 100644
--- a/profiles/sap/manager.c
+++ b/profiles/sap/manager.c
@@ -28,6 +28,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "manager.h"
#include "server.h"
diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index deb0653..dbbb4ea 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -37,6 +37,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "attrib/att.h"
#include "attrib/gattrib.h"
#include "attrib/gatt.h"
@@ -266,8 +267,9 @@ static void scan_unregister(struct btd_device *device)
g_free(scan);
}
-static int scan_param_probe(struct btd_profile *p, struct btd_device *device)
+static int scan_param_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *prim;
DBG("Probing Scan Parameters");
@@ -279,8 +281,10 @@ static int scan_param_probe(struct btd_profile *p, struct btd_device *device)
return scan_register(device, prim);
}
-static void scan_param_remove(struct btd_profile *p, struct btd_device *device)
+static void scan_param_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
scan_unregister(device);
}
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index ae8ccb2..3757b25 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -35,6 +35,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "error.h"
#include "log.h"
#include "attrib/gattrib.h"
@@ -1280,9 +1281,9 @@ static void thermometer_adapter_unregister(struct btd_adapter *adapter)
THERMOMETER_MANAGER_INTERFACE);
}
-static int thermometer_device_probe(struct btd_profile *p,
- struct btd_device *device)
+static int thermometer_device_probe(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
struct gatt_primary *tattr;
tattr = btd_device_get_primary(device, HEALTH_THERMOMETER_UUID);
@@ -1292,9 +1293,10 @@ static int thermometer_device_probe(struct btd_profile *p,
return thermometer_register(device, tattr);
}
-static void thermometer_device_remove(struct btd_profile *p,
- struct btd_device *device)
+static void thermometer_device_remove(struct btd_service *service)
{
+ struct btd_device *device = btd_service_get_device(service);
+
thermometer_unregister(device);
}
diff --git a/src/profile.c b/src/profile.c
index 7bd7970..b2c5ebf 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -50,6 +50,7 @@
#include "adapter.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#define DUN_DEFAULT_CHANNEL 1
#define SPP_DEFAULT_CHANNEL 3
@@ -1397,8 +1398,9 @@ static void ext_adapter_remove(struct btd_profile *p,
}
}
-static int ext_device_probe(struct btd_profile *p, struct btd_device *dev)
+static int ext_device_probe(struct btd_service *service)
{
+ struct btd_profile *p = btd_service_get_profile(service);
struct ext_profile *ext;
ext = find_ext(p);
@@ -1425,8 +1427,10 @@ static struct ext_io *find_connection(struct ext_profile *ext,
return NULL;
}
-static void ext_device_remove(struct btd_profile *p, struct btd_device *dev)
+static void ext_device_remove(struct btd_service *service)
{
+ struct btd_profile *p = btd_service_get_profile(service);
+ struct btd_device *dev = btd_service_get_device(service);
struct ext_profile *ext;
struct ext_io *conn;
diff --git a/src/profile.h b/src/profile.h
index 5622f23..8daa358 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -25,6 +25,8 @@
#define BTD_PROFILE_PRIORITY_MEDIUM 1
#define BTD_PROFILE_PRIORITY_HIGH 2
+struct btd_service;
+
struct btd_profile {
const char *name;
int priority;
@@ -34,9 +36,8 @@ struct btd_profile {
bool auto_connect;
- int (*device_probe) (struct btd_profile *p, struct btd_device *device);
- void (*device_remove) (struct btd_profile *p,
- struct btd_device *device);
+ int (*device_probe) (struct btd_service *service);
+ void (*device_remove) (struct btd_service *service);
int (*connect) (struct btd_device *device,
struct btd_profile *profile);
diff --git a/src/service.c b/src/service.c
index 298d600..a10138d 100644
--- a/src/service.c
+++ b/src/service.c
@@ -138,7 +138,7 @@ int service_probe(struct btd_service *service)
assert(service->state == BTD_SERVICE_STATE_UNAVAILABLE);
- err = service->profile->device_probe(service->profile, service->device);
+ err = service->profile->device_probe(service);
if (err == 0) {
change_state(service, BTD_SERVICE_STATE_DISCONNECTED, 0);
return 0;
@@ -153,7 +153,7 @@ int service_probe(struct btd_service *service)
void service_shutdown(struct btd_service *service)
{
change_state(service, BTD_SERVICE_STATE_UNAVAILABLE, 0);
- service->profile->device_remove(service->profile, service->device);
+ service->profile->device_remove(service);
service->device = NULL;
service->profile = NULL;
}
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Profile implementations can benefit from a user_data associated to a
service, which will typically be set during probe.
---
src/service.c | 12 ++++++++++++
src/service.h | 2 ++
2 files changed, 14 insertions(+)
diff --git a/src/service.c b/src/service.c
index a10138d..e03a412 100644
--- a/src/service.c
+++ b/src/service.c
@@ -50,6 +50,7 @@ struct btd_service {
gint ref;
struct btd_device *device;
struct btd_profile *profile;
+ void *user_data;
btd_service_state_t state;
};
@@ -239,6 +240,17 @@ struct btd_profile *btd_service_get_profile(const struct btd_service *service)
return service->profile;
}
+void btd_service_set_user_data(struct btd_service *service, void *user_data)
+{
+ assert(service->state == BTD_SERVICE_STATE_UNAVAILABLE);
+ service->user_data = user_data;
+}
+
+void *btd_service_get_user_data(const struct btd_service *service)
+{
+ return service->user_data;
+}
+
btd_service_state_t btd_service_get_state(const struct btd_service *service)
{
return service->state;
diff --git a/src/service.h b/src/service.h
index 8fb1ed5..a89b524 100644
--- a/src/service.h
+++ b/src/service.h
@@ -55,3 +55,5 @@ btd_service_state_t btd_service_get_state(const struct btd_service *service);
/* Functions used by profile implementation */
void btd_service_connecting_complete(struct btd_service *service, int err);
void btd_service_disconnecting_complete(struct btd_service *service, int err);
+void btd_service_set_user_data(struct btd_service *service, void *user_data);
+void *btd_service_get_user_data(const struct btd_service *service);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Simplify the code and make it more readable by adding a trivial helper
function.
---
profiles/network/connection.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index cc7c5ce..16ee318 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -85,6 +85,11 @@ struct __service_16 {
static GSList *peers = NULL;
+static uint16_t get_service_id(struct btd_service *service)
+{
+ return bnep_service_id(btd_service_get_profile(service)->remote_uuid);
+}
+
static struct network_peer *find_peer(GSList *list, struct btd_device *device)
{
for (; list; list = list->next) {
@@ -644,9 +649,8 @@ static const GDBusPropertyTable connection_properties[] = {
void connection_unregister(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
- struct btd_profile *p = btd_service_get_profile(service);
struct network_peer *peer;
- uint16_t id = bnep_service_id(p->remote_uuid);
+ uint16_t id = get_service_id(service);
DBG("%s id %u", device_get_path(device), id);
@@ -692,10 +696,9 @@ static struct network_peer *create_peer(struct btd_device *device)
int connection_register(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
- struct btd_profile *p = btd_service_get_profile(service);
struct network_peer *peer;
struct network_conn *nc;
- uint16_t id = bnep_service_id(p->remote_uuid);
+ uint16_t id = get_service_id(service);
DBG("%s id %u", device_get_path(device), id);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Use btd_service pointers to represent the list of services pending for
connection.
This list doesn't reference count the btd_service instances, since the
pending services should be a subset of the available services, and thus
they should already be referenced by device->services. This means
special care must be taken to make sure any removed service is also
removed from the pending list, as addressed in remove_service().
---
src/device.c | 38 ++++++++++++++++++--------------------
1 file changed, 18 insertions(+), 20 deletions(-)
diff --git a/src/device.c b/src/device.c
index a5301df..91fcd89 100644
--- a/src/device.c
+++ b/src/device.c
@@ -170,7 +170,7 @@ struct btd_device {
GSList *uuids;
GSList *primaries; /* List of primary services */
GSList *services; /* List of btd_service */
- GSList *pending; /* Pending profiles */
+ GSList *pending; /* Pending services */
GSList *watches; /* List of disconnect_data */
gboolean temporary;
guint disconn_timer;
@@ -906,8 +906,10 @@ static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
static void remove_service(gpointer data)
{
struct btd_service *service = data;
+ struct btd_device *device = btd_service_get_device(service);
service_shutdown(service);
+ device->pending = g_slist_remove(device->pending, service);
btd_service_unref(service);
}
@@ -1075,22 +1077,16 @@ static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
static int connect_next(struct btd_device *dev)
{
- struct btd_profile *profile;
struct btd_service *service;
int err = -ENOENT;
while (dev->pending) {
- GSList *l;
-
- profile = dev->pending->data;
-
- l = find_service_with_profile(dev->services, profile);
- service = l->data;
+ service = dev->pending->data;
if (btd_service_connect(service) == 0)
return 0;
- dev->pending = g_slist_remove(dev->pending, profile);
+ dev->pending = g_slist_delete_link(dev->pending, dev->pending);
}
return err;
@@ -1099,7 +1095,7 @@ static int connect_next(struct btd_device *dev)
void device_profile_connected(struct btd_device *dev,
struct btd_profile *profile, int err)
{
- struct btd_profile *pending;
+ struct btd_service *pending;
GSList *l;
DBG("%s %s (%d)", profile->name, strerror(-err), -err);
@@ -1108,7 +1104,9 @@ void device_profile_connected(struct btd_device *dev,
return;
pending = dev->pending->data;
- dev->pending = g_slist_remove(dev->pending, profile);
+ l = find_service_with_profile(dev->pending, profile);
+ if (l != NULL)
+ dev->pending = g_slist_delete_link(dev->pending, l);
l = find_service_with_profile(dev->services, profile);
if (l != NULL)
@@ -1118,7 +1116,7 @@ void device_profile_connected(struct btd_device *dev,
* pending, otherwise it will trigger another connect to the same
* profile
*/
- if (profile != pending)
+ if (profile != btd_service_get_profile(pending))
return;
if (connect_next(dev) == 0)
@@ -1196,9 +1194,10 @@ static struct btd_service *find_connectable_service(struct btd_device *dev,
return NULL;
}
-static gint profile_prio_cmp(gconstpointer a, gconstpointer b)
+static gint service_prio_cmp(gconstpointer a, gconstpointer b)
{
- const struct btd_profile *p1 = a, *p2 = b;
+ struct btd_profile *p1 = btd_service_get_profile(a);
+ struct btd_profile *p2 = btd_service_get_profile(b);
return p2->priority - p1->priority;
}
@@ -1231,8 +1230,7 @@ static DBusMessage *connect_profiles(struct btd_device *dev, DBusMessage *msg,
if (!service)
return btd_error_invalid_args(msg);
- p = btd_service_get_profile(service);
- dev->pending = g_slist_prepend(dev->pending, p);
+ dev->pending = g_slist_prepend(dev->pending, service);
goto start_connect;
}
@@ -1244,15 +1242,15 @@ static DBusMessage *connect_profiles(struct btd_device *dev, DBusMessage *msg,
if (!p->auto_connect)
continue;
- if (g_slist_find(dev->pending, p))
+ if (g_slist_find(dev->pending, service))
continue;
if (btd_service_get_state(service) !=
BTD_SERVICE_STATE_DISCONNECTED)
continue;
- dev->pending = g_slist_insert_sorted(dev->pending, p,
- profile_prio_cmp);
+ dev->pending = g_slist_insert_sorted(dev->pending, service,
+ service_prio_cmp);
}
if (!dev->pending)
@@ -2400,7 +2398,7 @@ void device_probe_profile(gpointer a, gpointer b)
if (!profile->auto_connect || !device->general_connect)
return;
- device->pending = g_slist_append(device->pending, profile);
+ device->pending = g_slist_append(device->pending, service);
if (g_slist_length(device->pending) == 1)
connect_next(device);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
The service state can provide enough information not to maintain such
a connected_profiles list. Therefore, avoid duplicated information and
remove the list.
---
src/device.c | 62 ++++++++++++++++++++++++++++++++----------------------------
1 file changed, 33 insertions(+), 29 deletions(-)
diff --git a/src/device.c b/src/device.c
index abdd3af..2e91499 100644
--- a/src/device.c
+++ b/src/device.c
@@ -187,7 +187,6 @@ struct btd_device {
guint attachid; /* Attrib server attach */
gboolean connected;
- GSList *connected_profiles;
sdp_list_t *tmp_records;
@@ -233,6 +232,21 @@ static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
return NULL;
}
+static GSList *find_service_with_state(GSList *list,
+ btd_service_state_t state)
+{
+ GSList *l;
+
+ for (l = list; l != NULL; l = g_slist_next(l)) {
+ struct btd_service *service = l->data;
+
+ if (btd_service_get_state(service) == state)
+ return l;
+ }
+
+ return NULL;
+}
+
static gboolean store_device_info_cb(gpointer user_data)
{
struct btd_device *device = user_data;
@@ -986,16 +1000,9 @@ static void bonding_request_cancel(struct bonding_req *bonding)
adapter_cancel_bonding(adapter, &device->bdaddr, device->bdaddr_type);
}
-static void dev_disconn_profile(gpointer a, gpointer b)
+static void dev_disconn_service(gpointer a, gpointer b)
{
- struct btd_profile *profile = a;
- struct btd_device *dev = b;
- struct btd_service *service;
- GSList *l;
-
- l = find_service_with_profile(dev->services, profile);
- service = l->data;
- btd_service_disconnect(service);
+ btd_service_disconnect(a);
}
void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
@@ -1021,10 +1028,7 @@ void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
if (device->disconn_timer)
return;
- g_slist_foreach(device->connected_profiles, dev_disconn_profile,
- device);
- g_slist_free(device->connected_profiles);
- device->connected_profiles = NULL;
+ g_slist_foreach(device->services, dev_disconn_service, NULL);
g_slist_free(device->pending);
device->pending = NULL;
@@ -1096,6 +1100,7 @@ void device_profile_connected(struct btd_device *dev,
struct btd_profile *profile, int err)
{
struct btd_profile *pending;
+ GSList *l;
DBG("%s %s (%d)", profile->name, strerror(-err), -err);
@@ -1105,10 +1110,9 @@ void device_profile_connected(struct btd_device *dev,
pending = dev->pending->data;
dev->pending = g_slist_remove(dev->pending, profile);
- if (!err)
- dev->connected_profiles =
- g_slist_append(dev->connected_profiles,
- profile);
+ l = find_service_with_profile(dev->services, profile);
+ if (l != NULL)
+ btd_service_connecting_complete(l->data, err);
/* Only continue connecting the next profile if it matches the first
* pending, otherwise it will trigger another connect to the same
@@ -1129,7 +1133,9 @@ void device_profile_connected(struct btd_device *dev,
DBG("returning response to %s", dbus_message_get_sender(dev->connect));
- if (err && dev->connected_profiles == NULL)
+ l = find_service_with_state(dev->services, BTD_SERVICE_STATE_CONNECTED);
+
+ if (err && l == NULL)
g_dbus_send_message(dbus_conn,
btd_error_failed(dev->connect, strerror(-err)));
else
@@ -1240,7 +1246,8 @@ static DBusMessage *connect_profiles(struct btd_device *dev, DBusMessage *msg,
if (g_slist_find(dev->pending, p))
continue;
- if (g_slist_find(dev->connected_profiles, p))
+ if (btd_service_get_state(service) !=
+ BTD_SERVICE_STATE_DISCONNECTED)
continue;
dev->pending = g_slist_insert_sorted(dev->pending, p,
@@ -1309,8 +1316,11 @@ static DBusMessage *connect_profile(DBusConnection *conn, DBusMessage *msg,
void device_profile_disconnected(struct btd_device *dev,
struct btd_profile *profile, int err)
{
- dev->connected_profiles = g_slist_remove(dev->connected_profiles,
- profile);
+ GSList *l;
+
+ l = find_service_with_profile(dev->services, profile);
+ if (l != NULL)
+ btd_service_disconnecting_complete(l->data, err);
if (!dev->disconnect)
return;
@@ -2257,10 +2267,7 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
if (device->browse)
browse_request_cancel(device->browse);
- g_slist_foreach(device->connected_profiles, dev_disconn_profile,
- device);
- g_slist_free(device->connected_profiles);
- device->connected_profiles = NULL;
+ g_slist_foreach(device->services, dev_disconn_service, NULL);
g_slist_free(device->pending);
device->pending = NULL;
@@ -2414,9 +2421,6 @@ void device_remove_profile(gpointer a, gpointer b)
if (l == NULL)
return;
- device->connected_profiles = g_slist_remove(device->connected_profiles,
- profile);
-
service = l->data;
device->services = g_slist_delete_link(device->services, l);
remove_service(service);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Trivially replace the former find_connectable_profile() with
find_connectable_service().
---
src/device.c | 18 +++++++-----------
1 file changed, 7 insertions(+), 11 deletions(-)
diff --git a/src/device.c b/src/device.c
index 2e91499..a5301df 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1177,7 +1177,7 @@ static int device_resolve_svc(struct btd_device *dev, DBusMessage *msg)
return device_browse_primary(dev, msg, FALSE);
}
-static struct btd_profile *find_connectable_profile(struct btd_device *dev,
+static struct btd_service *find_connectable_service(struct btd_device *dev,
const char *uuid)
{
GSList *l;
@@ -1190,7 +1190,7 @@ static struct btd_profile *find_connectable_profile(struct btd_device *dev,
continue;
if (strcasecmp(uuid, p->remote_uuid) == 0)
- return p;
+ return service;
}
return NULL;
@@ -1227,10 +1227,11 @@ static DBusMessage *connect_profiles(struct btd_device *dev, DBusMessage *msg,
}
if (uuid) {
- p = find_connectable_profile(dev, uuid);
- if (!p)
+ service = find_connectable_service(dev, uuid);
+ if (!service)
return btd_error_invalid_args(msg);
+ p = btd_service_get_profile(service);
dev->pending = g_slist_prepend(dev->pending, p);
goto start_connect;
@@ -1341,9 +1342,7 @@ static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
struct btd_device *dev = user_data;
- struct btd_profile *p;
struct btd_service *service;
- GSList *l;
const char *pattern;
char *uuid;
int err;
@@ -1356,15 +1355,12 @@ static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
if (uuid == NULL)
return btd_error_invalid_args(msg);
- p = find_connectable_profile(dev, uuid);
+ service = find_connectable_service(dev, uuid);
g_free(uuid);
- if (!p)
+ if (!service)
return btd_error_invalid_args(msg);
- l = find_service_with_profile(dev->services, p);
- service = l->data;
-
err = btd_service_disconnect(service);
if (err == 0) {
dev->disconnect = dbus_message_ref(msg);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Add a state to btd_service in order to distinguish which operations are
allowed in a certain point in time.
---
src/service.c | 107 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
src/service.h | 13 +++++++
2 files changed, 119 insertions(+), 1 deletion(-)
diff --git a/src/service.c b/src/service.c
index 378dd2d..298d600 100644
--- a/src/service.c
+++ b/src/service.c
@@ -50,8 +50,47 @@ struct btd_service {
gint ref;
struct btd_device *device;
struct btd_profile *profile;
+ btd_service_state_t state;
};
+static const char *state2str(btd_service_state_t state)
+{
+ switch (state) {
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ return "unavailable";
+ case BTD_SERVICE_STATE_DISCONNECTED:
+ return "disconnected";
+ case BTD_SERVICE_STATE_CONNECTING:
+ return "connecting";
+ case BTD_SERVICE_STATE_CONNECTED:
+ return "connected";
+ case BTD_SERVICE_STATE_DISCONNECTING:
+ return "disconnecting";
+ }
+
+ return NULL;
+}
+
+static void change_state(struct btd_service *service, btd_service_state_t state,
+ int err)
+{
+ btd_service_state_t old = service->state;
+ char addr[18];
+
+ if (state == old)
+ return;
+
+ assert(service->device != NULL);
+ assert(service->profile != NULL);
+
+ service->state = state;
+
+ ba2str(device_get_address(service->device), addr);
+ DBG("%p: device %s profile %s state changed: %s -> %s (%d)", service,
+ addr, service->profile->name,
+ state2str(old), state2str(state), err);
+}
+
struct btd_service *btd_service_ref(struct btd_service *service)
{
service->ref++;
@@ -87,6 +126,7 @@ struct btd_service *service_create(struct btd_device *device,
service->ref = 1;
service->device = device; /* Weak ref */
service->profile = profile;
+ service->state = BTD_SERVICE_STATE_UNAVAILABLE;
return service;
}
@@ -96,9 +136,13 @@ int service_probe(struct btd_service *service)
char addr[18];
int err;
+ assert(service->state == BTD_SERVICE_STATE_UNAVAILABLE);
+
err = service->profile->device_probe(service->profile, service->device);
- if (err == 0)
+ if (err == 0) {
+ change_state(service, BTD_SERVICE_STATE_DISCONNECTED, 0);
return 0;
+ }
ba2str(device_get_address(service->device), addr);
error("%s profile probe failed for %s", service->profile->name, addr);
@@ -108,6 +152,7 @@ int service_probe(struct btd_service *service)
void service_shutdown(struct btd_service *service)
{
+ change_state(service, BTD_SERVICE_STATE_UNAVAILABLE, 0);
service->profile->device_remove(service->profile, service->device);
service->device = NULL;
service->profile = NULL;
@@ -122,6 +167,20 @@ int btd_service_connect(struct btd_service *service)
if (!profile->connect)
return -ENOTSUP;
+ switch (service->state) {
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ return -EINVAL;
+ case BTD_SERVICE_STATE_DISCONNECTED:
+ break;
+ case BTD_SERVICE_STATE_CONNECTING:
+ case BTD_SERVICE_STATE_CONNECTED:
+ return -EALREADY;
+ case BTD_SERVICE_STATE_DISCONNECTING:
+ return -EBUSY;
+ }
+
+ change_state(service, BTD_SERVICE_STATE_CONNECTING, 0);
+
err = profile->connect(service->device, service->profile);
if (err == 0)
return 0;
@@ -130,6 +189,8 @@ int btd_service_connect(struct btd_service *service)
error("%s profile connect failed for %s: %s", profile->name, addr,
strerror(-err));
+ btd_service_connecting_complete(service, err);
+
return err;
}
@@ -142,6 +203,19 @@ int btd_service_disconnect(struct btd_service *service)
if (!profile->disconnect)
return -ENOTSUP;
+ switch (service->state) {
+ case BTD_SERVICE_STATE_UNAVAILABLE:
+ return -EINVAL;
+ case BTD_SERVICE_STATE_DISCONNECTED:
+ case BTD_SERVICE_STATE_DISCONNECTING:
+ return -EALREADY;
+ case BTD_SERVICE_STATE_CONNECTING:
+ case BTD_SERVICE_STATE_CONNECTED:
+ break;
+ }
+
+ change_state(service, BTD_SERVICE_STATE_DISCONNECTING, 0);
+
err = profile->disconnect(service->device, service->profile);
if (err == 0)
return 0;
@@ -150,6 +224,8 @@ int btd_service_disconnect(struct btd_service *service)
error("%s profile disconnect failed for %s: %s", profile->name, addr,
strerror(-err));
+ btd_service_disconnecting_complete(service, err);
+
return err;
}
@@ -162,3 +238,32 @@ struct btd_profile *btd_service_get_profile(const struct btd_service *service)
{
return service->profile;
}
+
+btd_service_state_t btd_service_get_state(const struct btd_service *service)
+{
+ return service->state;
+}
+
+void btd_service_connecting_complete(struct btd_service *service, int err)
+{
+ if (service->state != BTD_SERVICE_STATE_DISCONNECTED &&
+ service->state != BTD_SERVICE_STATE_CONNECTING)
+ return;
+
+ if (err == 0)
+ change_state(service, BTD_SERVICE_STATE_CONNECTED, 0);
+ else
+ change_state(service, BTD_SERVICE_STATE_DISCONNECTED, err);
+}
+
+void btd_service_disconnecting_complete(struct btd_service *service, int err)
+{
+ if (service->state != BTD_SERVICE_STATE_CONNECTED &&
+ service->state != BTD_SERVICE_STATE_DISCONNECTING)
+ return;
+
+ if (err == 0)
+ change_state(service, BTD_SERVICE_STATE_DISCONNECTED, 0);
+ else /* If disconnect fails, we assume it remains connected */
+ change_state(service, BTD_SERVICE_STATE_CONNECTED, err);
+}
diff --git a/src/service.h b/src/service.h
index f242f2f..8fb1ed5 100644
--- a/src/service.h
+++ b/src/service.h
@@ -21,6 +21,14 @@
*
*/
+typedef enum {
+ BTD_SERVICE_STATE_UNAVAILABLE, /* Not probed */
+ BTD_SERVICE_STATE_DISCONNECTED,
+ BTD_SERVICE_STATE_CONNECTING,
+ BTD_SERVICE_STATE_CONNECTED,
+ BTD_SERVICE_STATE_DISCONNECTING,
+} btd_service_state_t;
+
struct btd_service;
struct btd_device;
struct btd_profile;
@@ -42,3 +50,8 @@ int btd_service_disconnect(struct btd_service *service);
/* Public member access */
struct btd_device *btd_service_get_device(const struct btd_service *service);
struct btd_profile *btd_service_get_profile(const struct btd_service *service);
+btd_service_state_t btd_service_get_state(const struct btd_service *service);
+
+/* Functions used by profile implementation */
+void btd_service_connecting_complete(struct btd_service *service, int err);
+void btd_service_disconnecting_complete(struct btd_service *service, int err);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Make use of the btd_profile connect/disconnect callbacks directly within
service.c instead of doing it inside device.c.
---
src/device.c | 39 ++++++++++++++++++++++++---------------
src/service.c | 40 ++++++++++++++++++++++++++++++++++++++++
src/service.h | 4 ++++
3 files changed, 68 insertions(+), 15 deletions(-)
diff --git a/src/device.c b/src/device.c
index 0ae921e..abdd3af 100644
--- a/src/device.c
+++ b/src/device.c
@@ -990,11 +990,12 @@ static void dev_disconn_profile(gpointer a, gpointer b)
{
struct btd_profile *profile = a;
struct btd_device *dev = b;
+ struct btd_service *service;
+ GSList *l;
- if (!profile->disconnect)
- return;
-
- profile->disconnect(dev, profile);
+ l = find_service_with_profile(dev->services, profile);
+ service = l->data;
+ btd_service_disconnect(service);
}
void device_request_disconnect(struct btd_device *device, DBusMessage *msg)
@@ -1071,17 +1072,20 @@ static DBusMessage *disconnect(DBusConnection *conn, DBusMessage *msg,
static int connect_next(struct btd_device *dev)
{
struct btd_profile *profile;
+ struct btd_service *service;
int err = -ENOENT;
while (dev->pending) {
+ GSList *l;
+
profile = dev->pending->data;
- err = profile->connect(dev, profile);
- if (err == 0)
+ l = find_service_with_profile(dev->services, profile);
+ service = l->data;
+
+ if (btd_service_connect(service) == 0)
return 0;
- error("Failed to connect %s: %s", profile->name,
- strerror(-err));
dev->pending = g_slist_remove(dev->pending, profile);
}
@@ -1328,6 +1332,8 @@ static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
{
struct btd_device *dev = user_data;
struct btd_profile *p;
+ struct btd_service *service;
+ GSList *l;
const char *pattern;
char *uuid;
int err;
@@ -1346,16 +1352,19 @@ static DBusMessage *disconnect_profile(DBusConnection *conn, DBusMessage *msg,
if (!p)
return btd_error_invalid_args(msg);
- if (!p->disconnect)
- return btd_error_not_supported(msg);
+ l = find_service_with_profile(dev->services, p);
+ service = l->data;
- err = p->disconnect(dev, p);
- if (err < 0)
- return btd_error_failed(msg, strerror(-err));
+ err = btd_service_disconnect(service);
+ if (err == 0) {
+ dev->disconnect = dbus_message_ref(msg);
+ return NULL;
+ }
- dev->disconnect = dbus_message_ref(msg);
+ if (err == -ENOTSUP)
+ return btd_error_not_supported(msg);
- return NULL;
+ return btd_error_failed(msg, strerror(-err));
}
static void device_svc_resolved(struct btd_device *dev, int err)
diff --git a/src/service.c b/src/service.c
index 39a58d9..378dd2d 100644
--- a/src/service.c
+++ b/src/service.c
@@ -113,6 +113,46 @@ void service_shutdown(struct btd_service *service)
service->profile = NULL;
}
+int btd_service_connect(struct btd_service *service)
+{
+ struct btd_profile *profile = service->profile;
+ char addr[18];
+ int err;
+
+ if (!profile->connect)
+ return -ENOTSUP;
+
+ err = profile->connect(service->device, service->profile);
+ if (err == 0)
+ return 0;
+
+ ba2str(device_get_address(service->device), addr);
+ error("%s profile connect failed for %s: %s", profile->name, addr,
+ strerror(-err));
+
+ return err;
+}
+
+int btd_service_disconnect(struct btd_service *service)
+{
+ struct btd_profile *profile = service->profile;
+ char addr[18];
+ int err;
+
+ if (!profile->disconnect)
+ return -ENOTSUP;
+
+ err = profile->disconnect(service->device, service->profile);
+ if (err == 0)
+ return 0;
+
+ ba2str(device_get_address(service->device), addr);
+ error("%s profile disconnect failed for %s: %s", profile->name, addr,
+ strerror(-err));
+
+ return err;
+}
+
struct btd_device *btd_service_get_device(const struct btd_service *service)
{
return service->device;
diff --git a/src/service.h b/src/service.h
index 4a69571..f242f2f 100644
--- a/src/service.h
+++ b/src/service.h
@@ -35,6 +35,10 @@ struct btd_service *service_create(struct btd_device *device,
int service_probe(struct btd_service *service);
void service_shutdown(struct btd_service *service);
+/* Connection control API */
+int btd_service_connect(struct btd_service *service);
+int btd_service_disconnect(struct btd_service *service);
+
/* Public member access */
struct btd_device *btd_service_get_device(const struct btd_service *service);
struct btd_profile *btd_service_get_profile(const struct btd_service *service);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Make use of the btd_profile callbacks directly within service.c instead
of doing it inside device.c.
---
src/device.c | 17 +++--------------
src/service.c | 22 ++++++++++++++++++++++
src/service.h | 3 +++
3 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/src/device.c b/src/device.c
index 81a06fd..0ae921e 100644
--- a/src/device.c
+++ b/src/device.c
@@ -892,10 +892,8 @@ static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
static void remove_service(gpointer data)
{
struct btd_service *service = data;
- struct btd_profile *profile = btd_service_get_profile(service);
- struct btd_device *device = btd_service_get_device(service);
- profile->device_remove(profile, device);
+ service_shutdown(service);
btd_service_unref(service);
}
@@ -2349,7 +2347,6 @@ static void dev_probe(struct btd_profile *p, void *user_data)
{
struct probe_data *d = user_data;
struct btd_service *service;
- int err;
if (p->device_probe == NULL)
return;
@@ -2359,9 +2356,7 @@ static void dev_probe(struct btd_profile *p, void *user_data)
service = service_create(d->dev, p);
- err = p->device_probe(p, d->dev);
- if (err < 0) {
- error("%s profile probe failed for %s", p->name, d->addr);
+ if (service_probe(service) < 0) {
btd_service_unref(service);
return;
}
@@ -2374,8 +2369,6 @@ void device_probe_profile(gpointer a, gpointer b)
struct btd_device *device = a;
struct btd_profile *profile = b;
struct btd_service *service;
- char addr[18];
- int err;
if (profile->device_probe == NULL)
return;
@@ -2383,13 +2376,9 @@ void device_probe_profile(gpointer a, gpointer b)
if (!device_match_profile(device, profile, device->uuids))
return;
- ba2str(&device->bdaddr, addr);
-
service = service_create(device, profile);
- err = profile->device_probe(profile, device);
- if (err < 0) {
- error("%s profile probe failed for %s", profile->name, addr);
+ if (service_probe(service) < 0) {
btd_service_unref(service);
return;
}
diff --git a/src/service.c b/src/service.c
index 4b69cba..39a58d9 100644
--- a/src/service.c
+++ b/src/service.c
@@ -91,6 +91,28 @@ struct btd_service *service_create(struct btd_device *device,
return service;
}
+int service_probe(struct btd_service *service)
+{
+ char addr[18];
+ int err;
+
+ err = service->profile->device_probe(service->profile, service->device);
+ if (err == 0)
+ return 0;
+
+ ba2str(device_get_address(service->device), addr);
+ error("%s profile probe failed for %s", service->profile->name, addr);
+
+ return err;
+}
+
+void service_shutdown(struct btd_service *service)
+{
+ service->profile->device_remove(service->profile, service->device);
+ service->device = NULL;
+ service->profile = NULL;
+}
+
struct btd_device *btd_service_get_device(const struct btd_service *service)
{
return service->device;
diff --git a/src/service.h b/src/service.h
index 4f83387..4a69571 100644
--- a/src/service.h
+++ b/src/service.h
@@ -32,6 +32,9 @@ void btd_service_unref(struct btd_service *service);
struct btd_service *service_create(struct btd_device *device,
struct btd_profile *profile);
+int service_probe(struct btd_service *service);
+void service_shutdown(struct btd_service *service);
+
/* Public member access */
struct btd_device *btd_service_get_device(const struct btd_service *service);
struct btd_profile *btd_service_get_profile(const struct btd_service *service);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Maintain a list of btd_service pointers instead of btd_profile pointers,
for services that have been probed for this device.
This list will not only reference count the btd_service instances but
also "own" them, in the sense of destroying them (make them completely
unavailable) when the service is removed from the list. This is needed
because the btd_service does not reference count the btd_device
instance.
---
src/device.c | 77 ++++++++++++++++++++++++++++++++++++++++++------------------
1 file changed, 54 insertions(+), 23 deletions(-)
diff --git a/src/device.c b/src/device.c
index 01afd49..81a06fd 100644
--- a/src/device.c
+++ b/src/device.c
@@ -56,6 +56,7 @@
#include "attio.h"
#include "device.h"
#include "profile.h"
+#include "service.h"
#include "dbus-common.h"
#include "error.h"
#include "glib-helper.h"
@@ -168,7 +169,7 @@ struct btd_device {
struct btd_adapter *adapter;
GSList *uuids;
GSList *primaries; /* List of primary services */
- GSList *profiles; /* Probed profiles */
+ GSList *services; /* List of btd_service */
GSList *pending; /* Pending profiles */
GSList *watches; /* List of disconnect_data */
gboolean temporary;
@@ -218,6 +219,20 @@ static int device_browse_primary(struct btd_device *device, DBusMessage *msg,
static int device_browse_sdp(struct btd_device *device, DBusMessage *msg,
gboolean reverse);
+static GSList *find_service_with_profile(GSList *list, struct btd_profile *p)
+{
+ GSList *l;
+
+ for (l = list; l != NULL; l = g_slist_next(l)) {
+ struct btd_service *service = l->data;
+
+ if (btd_service_get_profile(service) == p)
+ return l;
+ }
+
+ return NULL;
+}
+
static gboolean store_device_info_cb(gpointer user_data)
{
struct btd_device *device = user_data;
@@ -874,12 +889,14 @@ static gboolean dev_property_get_adapter(const GDBusPropertyTable *property,
return TRUE;
}
-static void profile_remove(gpointer data, gpointer user_data)
+static void remove_service(gpointer data)
{
- struct btd_profile *profile = data;
- struct btd_device *device = user_data;
+ struct btd_service *service = data;
+ struct btd_profile *profile = btd_service_get_profile(service);
+ struct btd_device *device = btd_service_get_device(service);
profile->device_remove(profile, device);
+ btd_service_unref(service);
}
static gboolean do_disconnect(gpointer user_data)
@@ -904,9 +921,8 @@ int device_block(struct btd_device *device, gboolean update_only)
if (device->connected)
do_disconnect(device);
- g_slist_foreach(device->profiles, profile_remove, device);
- g_slist_free(device->profiles);
- device->profiles = NULL;
+ g_slist_free_full(device->services, remove_service);
+ device->services = NULL;
if (!update_only)
err = btd_adapter_block_address(device->adapter,
@@ -1158,8 +1174,9 @@ static struct btd_profile *find_connectable_profile(struct btd_device *dev,
{
GSList *l;
- for (l = dev->profiles; l != NULL; l = g_slist_next(l)) {
- struct btd_profile *p = l->data;
+ for (l = dev->services; l != NULL; l = g_slist_next(l)) {
+ struct btd_service *service = l->data;
+ struct btd_profile *p = btd_service_get_profile(service);
if (!p->connect || !p->remote_uuid)
continue;
@@ -1181,6 +1198,7 @@ static gint profile_prio_cmp(gconstpointer a, gconstpointer b)
static DBusMessage *connect_profiles(struct btd_device *dev, DBusMessage *msg,
const char *uuid)
{
+ struct btd_service *service;
struct btd_profile *p;
GSList *l;
int err;
@@ -1210,8 +1228,9 @@ static DBusMessage *connect_profiles(struct btd_device *dev, DBusMessage *msg,
goto start_connect;
}
- for (l = dev->profiles; l != NULL; l = g_slist_next(l)) {
- p = l->data;
+ for (l = dev->services; l != NULL; l = g_slist_next(l)) {
+ service = l->data;
+ p = btd_service_get_profile(service);
if (!p->auto_connect)
continue;
@@ -2253,9 +2272,8 @@ void device_remove(struct btd_device *device, gboolean remove_stored)
if (remove_stored)
device_remove_stored(device);
- g_slist_foreach(device->profiles, profile_remove, device);
- g_slist_free(device->profiles);
- device->profiles = NULL;
+ g_slist_free_full(device->services, remove_service);
+ device->services = NULL;
btd_device_unref(device);
}
@@ -2330,6 +2348,7 @@ struct probe_data {
static void dev_probe(struct btd_profile *p, void *user_data)
{
struct probe_data *d = user_data;
+ struct btd_service *service;
int err;
if (p->device_probe == NULL)
@@ -2338,19 +2357,23 @@ static void dev_probe(struct btd_profile *p, void *user_data)
if (!device_match_profile(d->dev, p, d->uuids))
return;
+ service = service_create(d->dev, p);
+
err = p->device_probe(p, d->dev);
if (err < 0) {
error("%s profile probe failed for %s", p->name, d->addr);
+ btd_service_unref(service);
return;
}
- d->dev->profiles = g_slist_append(d->dev->profiles, p);
+ d->dev->services = g_slist_append(d->dev->services, service);
}
void device_probe_profile(gpointer a, gpointer b)
{
struct btd_device *device = a;
struct btd_profile *profile = b;
+ struct btd_service *service;
char addr[18];
int err;
@@ -2362,13 +2385,16 @@ void device_probe_profile(gpointer a, gpointer b)
ba2str(&device->bdaddr, addr);
+ service = service_create(device, profile);
+
err = profile->device_probe(profile, device);
if (err < 0) {
error("%s profile probe failed for %s", profile->name, addr);
+ btd_service_unref(service);
return;
}
- device->profiles = g_slist_append(device->profiles, profile);
+ device->services = g_slist_append(device->services, service);
if (!profile->auto_connect || !device->general_connect)
return;
@@ -2383,15 +2409,19 @@ void device_remove_profile(gpointer a, gpointer b)
{
struct btd_device *device = a;
struct btd_profile *profile = b;
+ struct btd_service *service;
+ GSList *l;
- if (!g_slist_find(device->profiles, profile))
+ l = find_service_with_profile(device->services, profile);
+ if (l == NULL)
return;
device->connected_profiles = g_slist_remove(device->connected_profiles,
profile);
- device->profiles = g_slist_remove(device->profiles, profile);
- profile->device_remove(profile, device);
+ service = l->data;
+ device->services = g_slist_delete_link(device->services, l);
+ remove_service(service);
}
void device_probe_profiles(struct btd_device *device, GSList *uuids)
@@ -2440,15 +2470,16 @@ static void device_remove_profiles(struct btd_device *device, GSList *uuids)
device->uuids = NULL;
store_device_info(device);
- for (l = device->profiles; l != NULL; l = next) {
- struct btd_profile *profile = l->data;
+ for (l = device->services; l != NULL; l = next) {
+ struct btd_service *service = l->data;
+ struct btd_profile *profile = btd_service_get_profile(service);
next = l->next;
if (device_match_profile(device, profile, device->uuids))
continue;
- profile->device_remove(profile, device);
- device->profiles = g_slist_remove(device->profiles, profile);
+ device->services = g_slist_delete_link(device->services, l);
+ remove_service(service);
}
}
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Add a new object to centralize all data corresponding to a service
provided by a remote device, coupling a pair of btd_profile and
btd_device pointers.
---
Makefile.am | 1 +
src/service.c | 102 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/service.h | 37 +++++++++++++++++++++
3 files changed, 140 insertions(+)
create mode 100644 src/service.c
create mode 100644 src/service.h
diff --git a/Makefile.am b/Makefile.am
index 1d0dd13..da87a21 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -142,6 +142,7 @@ src_bluetoothd_SOURCES = $(gdbus_sources) $(builtin_sources) \
src/error.h src/error.c \
src/adapter.h src/adapter.c \
src/profile.h src/profile.c \
+ src/service.h src/service.c \
src/device.h src/device.c src/attio.h \
src/dbus-common.c src/dbus-common.h \
src/eir.h src/eir.c \
diff --git a/src/service.c b/src/service.c
new file mode 100644
index 0000000..4b69cba
--- /dev/null
+++ b/src/service.c
@@ -0,0 +1,102 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012-2013 BMW Car IT GmbH. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <assert.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <stdbool.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+
+#include <bluetooth/bluetooth.h>
+
+#include <glib.h>
+
+#include "log.h"
+
+#include "adapter.h"
+#include "device.h"
+#include "profile.h"
+#include "service.h"
+
+struct btd_service {
+ gint ref;
+ struct btd_device *device;
+ struct btd_profile *profile;
+};
+
+struct btd_service *btd_service_ref(struct btd_service *service)
+{
+ service->ref++;
+
+ DBG("%p: ref=%d", service, service->ref);
+
+ return service;
+}
+
+void btd_service_unref(struct btd_service *service)
+{
+ service->ref--;
+
+ DBG("%p: ref=%d", service, service->ref);
+
+ if (service->ref > 0)
+ return;
+
+ g_free(service);
+}
+
+struct btd_service *service_create(struct btd_device *device,
+ struct btd_profile *profile)
+{
+ struct btd_service *service;
+
+ service = g_try_new0(struct btd_service, 1);
+ if (!service) {
+ error("service_create: failed to alloc memory");
+ return NULL;
+ }
+
+ service->ref = 1;
+ service->device = device; /* Weak ref */
+ service->profile = profile;
+
+ return service;
+}
+
+struct btd_device *btd_service_get_device(const struct btd_service *service)
+{
+ return service->device;
+}
+
+struct btd_profile *btd_service_get_profile(const struct btd_service *service)
+{
+ return service->profile;
+}
diff --git a/src/service.h b/src/service.h
new file mode 100644
index 0000000..4f83387
--- /dev/null
+++ b/src/service.h
@@ -0,0 +1,37 @@
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2012-2013 BMW Car IT GmbH. All rights reserved.
+ *
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ */
+
+struct btd_service;
+struct btd_device;
+struct btd_profile;
+
+struct btd_service *btd_service_ref(struct btd_service *service);
+void btd_service_unref(struct btd_service *service);
+
+/* Service management functions used by the core */
+struct btd_service *service_create(struct btd_device *device,
+ struct btd_profile *profile);
+
+/* Public member access */
+struct btd_device *btd_service_get_device(const struct btd_service *service);
+struct btd_profile *btd_service_get_profile(const struct btd_service *service);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Use the internal device API to provide the btd_profile callback
functions, without boilerplate code in manager.c.
---
profiles/network/connection.c | 11 ++++++++---
profiles/network/connection.h | 4 ++--
profiles/network/manager.c | 40 ++++++----------------------------------
3 files changed, 16 insertions(+), 39 deletions(-)
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 3ccd211..84359c0 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -43,6 +43,7 @@
#include "dbus-common.h"
#include "adapter.h"
#include "device.h"
+#include "profile.h"
#include "error.h"
#include "common.h"
@@ -639,9 +640,12 @@ static const GDBusPropertyTable connection_properties[] = {
{ }
};
-void connection_unregister(struct btd_device *device)
+void connection_unregister(struct btd_profile *p, struct btd_device *device)
{
struct network_peer *peer;
+ uint16_t id = bnep_service_id(p->remote_uuid);
+
+ DBG("%s id %u", device_get_path(device), id);
peer = find_peer(peers, device);
if (!peer)
@@ -682,12 +686,13 @@ static struct network_peer *create_peer(struct btd_device *device)
return peer;
}
-int connection_register(struct btd_device *device, uint16_t id)
+int connection_register(struct btd_profile *p, struct btd_device *device)
{
struct network_peer *peer;
struct network_conn *nc;
+ uint16_t id = bnep_service_id(p->remote_uuid);
- DBG("id %u", id);
+ DBG("%s id %u", device_get_path(device), id);
peer = find_peer(peers, device);
if (!peer) {
diff --git a/profiles/network/connection.h b/profiles/network/connection.h
index 32356f9..5daead0 100644
--- a/profiles/network/connection.h
+++ b/profiles/network/connection.h
@@ -21,7 +21,7 @@
*
*/
-int connection_register(struct btd_device *device, uint16_t id);
-void connection_unregister(struct btd_device *device);
+int connection_register(struct btd_profile *p, struct btd_device *device);
+void connection_unregister(struct btd_profile *p, struct btd_device *device);
int connection_connect(struct btd_device *device, uint16_t id);
int connection_disconnect(struct btd_device *device, uint16_t id);
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 4aa6a2b..df79351 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -74,20 +74,6 @@ done:
conf_security ? "true" : "false");
}
-static int panu_probe(struct btd_profile *p, struct btd_device *device)
-{
- DBG("path %s", device_get_path(device));
-
- return connection_register(device, BNEP_SVC_PANU);
-}
-
-static void network_remove(struct btd_profile *p, struct btd_device *device)
-{
- DBG("path %s", device_get_path(device));
-
- connection_unregister(device);
-}
-
static int panu_connect(struct btd_device *dev, struct btd_profile *profile)
{
return connection_connect(dev, BNEP_SVC_PANU);
@@ -117,13 +103,6 @@ static void panu_server_remove(struct btd_profile *p,
server_unregister(adapter, BNEP_SVC_PANU);
}
-static int gn_probe(struct btd_profile *p, struct btd_device *device)
-{
- DBG("path %s", device_get_path(device));
-
- return connection_register(device, BNEP_SVC_GN);
-}
-
static int gn_connect(struct btd_device *dev, struct btd_profile *profile)
{
return connection_connect(dev, BNEP_SVC_GN);
@@ -153,13 +132,6 @@ static void gn_server_remove(struct btd_profile *p,
server_unregister(adapter, BNEP_SVC_GN);
}
-static int nap_probe(struct btd_profile *p, struct btd_device *device)
-{
- DBG("path %s", device_get_path(device));
-
- return connection_register(device, BNEP_SVC_NAP);
-}
-
static int nap_connect(struct btd_device *dev, struct btd_profile *profile)
{
return connection_connect(dev, BNEP_SVC_NAP);
@@ -193,8 +165,8 @@ static struct btd_profile panu_profile = {
.name = "network-panu",
.local_uuid = NAP_UUID,
.remote_uuid = PANU_UUID,
- .device_probe = panu_probe,
- .device_remove = network_remove,
+ .device_probe = connection_register,
+ .device_remove = connection_unregister,
.connect = panu_connect,
.disconnect = panu_disconnect,
.adapter_probe = panu_server_probe,
@@ -205,8 +177,8 @@ static struct btd_profile gn_profile = {
.name = "network-gn",
.local_uuid = PANU_UUID,
.remote_uuid = GN_UUID,
- .device_probe = gn_probe,
- .device_remove = network_remove,
+ .device_probe = connection_register,
+ .device_remove = connection_unregister,
.connect = gn_connect,
.disconnect = gn_disconnect,
.adapter_probe = gn_server_probe,
@@ -217,8 +189,8 @@ static struct btd_profile nap_profile = {
.name = "network-nap",
.local_uuid = PANU_UUID,
.remote_uuid = NAP_UUID,
- .device_probe = nap_probe,
- .device_remove = network_remove,
+ .device_probe = connection_register,
+ .device_remove = connection_unregister,
.connect = nap_connect,
.disconnect = nap_disconnect,
.adapter_probe = nap_server_probe,
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Use the internal device API to provide the btd_profile callback
functions, without boilerplate code in manager.c.
---
profiles/input/device.c | 29 ++++++++++++++++-------------
profiles/input/device.h | 5 ++---
profiles/input/manager.c | 31 ++-----------------------------
3 files changed, 20 insertions(+), 45 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index 0688a02..b6f9028 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -92,6 +92,9 @@ void input_set_idle_timeout(int timeout)
}
static void input_device_enter_reconnect_mode(struct input_device *idev);
+static bool is_device_sdp_disable(const sdp_record_t *rec);
+static void extract_hid_props(struct input_device *idev,
+ const sdp_record_t *rec);
static const char *reconnect_mode_to_string(const enum reconnect_mode_t mode);
static struct input_device *find_device_by_path(GSList *list, const char *path)
@@ -759,9 +762,10 @@ int input_device_disconnect(struct btd_device *dev, struct btd_profile *profile)
}
static struct input_device *input_device_new(struct btd_device *device,
- const char *path, const uint32_t handle,
- bool disable_sdp)
+ struct btd_profile *p)
{
+ const char *path = device_get_path(device);
+ const sdp_record_t *rec = btd_device_get_record(device, p->remote_uuid);
struct btd_adapter *adapter = device_get_adapter(device);
struct input_device *idev;
char name[HCI_MAX_NAME_LENGTH + 1];
@@ -771,13 +775,16 @@ static struct input_device *input_device_new(struct btd_device *device,
bacpy(&idev->dst, device_get_address(device));
idev->device = btd_device_ref(device);
idev->path = g_strdup(path);
- idev->handle = handle;
- idev->disable_sdp = disable_sdp;
+ idev->handle = rec->handle;
+ idev->disable_sdp = is_device_sdp_disable(rec);
device_get_name(device, name, HCI_MAX_NAME_LENGTH);
if (strlen(name) > 0)
idev->name = g_strdup(name);
+ /* Initialize device properties */
+ extract_hid_props(idev, rec);
+
return idev;
}
@@ -852,10 +859,9 @@ static const GDBusPropertyTable input_properties[] = {
{ }
};
-int input_device_register(struct btd_device *device,
- const char *path, const char *uuid,
- const sdp_record_t *rec)
+int input_device_register(struct btd_profile *p, struct btd_device *device)
{
+ const char *path = device_get_path(device);
struct input_device *idev;
DBG("%s", path);
@@ -864,14 +870,10 @@ int input_device_register(struct btd_device *device,
if (idev)
return -EEXIST;
- idev = input_device_new(device, path, rec->handle,
- is_device_sdp_disable(rec));
+ idev = input_device_new(device, p);
if (!idev)
return -EINVAL;
- /* Initialize device properties */
- extract_hid_props(idev, rec);
-
if (g_dbus_register_interface(btd_get_dbus_connection(),
idev->path, INPUT_INTERFACE,
NULL, NULL,
@@ -902,8 +904,9 @@ static struct input_device *find_device(const bdaddr_t *src,
return NULL;
}
-void input_device_unregister(const char *path, const char *uuid)
+void input_device_unregister(struct btd_profile *p, struct btd_device *device)
{
+ const char *path = device_get_path(device);
struct input_device *idev;
DBG("%s", path);
diff --git a/profiles/input/device.h b/profiles/input/device.h
index 798b4b0..1c237fc 100644
--- a/profiles/input/device.h
+++ b/profiles/input/device.h
@@ -29,9 +29,8 @@ struct input_conn;
void input_set_idle_timeout(int timeout);
-int input_device_register(struct btd_device *device, const char *path,
- const char *uuid, const sdp_record_t *rec);
-void input_device_unregister(const char *path, const char *uuid);
+int input_device_register(struct btd_profile *p, struct btd_device *device);
+void input_device_unregister(struct btd_profile *p, struct btd_device *device);
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
GIOChannel *io);
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index cdcabfe..51cd4cf 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -44,33 +44,6 @@
#include "server.h"
#include "manager.h"
-static void input_remove(struct btd_device *device, const char *uuid)
-{
- const char *path = device_get_path(device);
-
- DBG("path %s", path);
-
- input_device_unregister(path, uuid);
-}
-
-static int hid_device_probe(struct btd_profile *p, struct btd_device *device)
-{
- const char *path = device_get_path(device);
- const sdp_record_t *rec = btd_device_get_record(device, HID_UUID);
-
- DBG("path %s", path);
-
- if (!rec)
- return -1;
-
- return input_device_register(device, path, HID_UUID, rec);
-}
-
-static void hid_device_remove(struct btd_profile *p, struct btd_device *device)
-{
- input_remove(device, HID_UUID);
-}
-
static int hid_server_probe(struct btd_profile *p, struct btd_adapter *adapter)
{
return server_start(adapter_get_address(adapter));
@@ -91,8 +64,8 @@ static struct btd_profile input_profile = {
.connect = input_device_connect,
.disconnect = input_device_disconnect,
- .device_probe = hid_device_probe,
- .device_remove = hid_device_remove,
+ .device_probe = input_device_register,
+ .device_remove = input_device_unregister,
.adapter_probe = hid_server_probe,
.adapter_remove = hid_server_remove,
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Unprobing the profile should never fail which means neither should
input_device_unregister(). This requires shutting everything down
regardless of possible pending connection requests.
---
profiles/input/device.c | 11 ++---------
profiles/input/device.h | 2 +-
2 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index 4af95d8..161d8af 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -903,7 +903,7 @@ static struct input_device *find_device(const bdaddr_t *src,
return NULL;
}
-int input_device_unregister(const char *path, const char *uuid)
+void input_device_unregister(const char *path, const char *uuid)
{
struct input_device *idev;
@@ -911,20 +911,13 @@ int input_device_unregister(const char *path, const char *uuid)
idev = find_device_by_path(devices, path);
if (idev == NULL)
- return -EINVAL;
-
- if (idev->ctrl_io) {
- /* Pending connection running */
- return -EBUSY;
- }
+ return;
g_dbus_unregister_interface(btd_get_dbus_connection(),
idev->path, INPUT_INTERFACE);
devices = g_slist_remove(devices, idev);
input_device_free(idev);
-
- return 0;
}
static int input_device_connadd(struct input_device *idev)
diff --git a/profiles/input/device.h b/profiles/input/device.h
index aabc79c..db69053 100644
--- a/profiles/input/device.h
+++ b/profiles/input/device.h
@@ -30,7 +30,7 @@ struct input_conn;
int input_device_register(struct btd_device *device, const char *path,
const char *uuid, const sdp_record_t *rec,
int timeout);
-int input_device_unregister(const char *path, const char *uuid);
+void input_device_unregister(const char *path, const char *uuid);
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
GIOChannel *io);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Trivially remove the field because it's actually not being used.
---
profiles/input/device.c | 5 -----
1 file changed, 5 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index d191967..0688a02 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -66,7 +66,6 @@ enum reconnect_mode_t {
struct input_device {
struct btd_device *device;
char *path;
- char *uuid;
bdaddr_t src;
bdaddr_t dst;
uint32_t handle;
@@ -139,8 +138,6 @@ static void input_device_free(struct input_device *idev)
if (idev->reconnect_timer > 0)
g_source_remove(idev->reconnect_timer);
- g_free(idev->uuid);
-
g_free(idev);
}
@@ -885,8 +882,6 @@ int input_device_register(struct btd_device *device,
return -EINVAL;
}
- idev->uuid = g_strdup(uuid);
-
devices = g_slist_append(devices, idev);
return 0;
--
1.8.1.4
From: Mikel Astiz <[email protected]>
The timeout setting is global across devices and it's actually only used
inside device.c. Therefore, simplify the code by just passing it once.
---
profiles/input/device.c | 12 ++++++++----
profiles/input/device.h | 5 +++--
profiles/input/manager.c | 9 +++++----
3 files changed, 16 insertions(+), 10 deletions(-)
diff --git a/profiles/input/device.c b/profiles/input/device.c
index 161d8af..d191967 100644
--- a/profiles/input/device.c
+++ b/profiles/input/device.c
@@ -75,7 +75,6 @@ struct input_device {
guint ctrl_watch;
guint intr_watch;
guint sec_watch;
- int timeout;
struct hidp_connadd_req *req;
guint dc_id;
bool disable_sdp;
@@ -86,6 +85,12 @@ struct input_device {
};
static GSList *devices = NULL;
+static int idle_timeout = 0;
+
+void input_set_idle_timeout(int timeout)
+{
+ idle_timeout = timeout;
+}
static void input_device_enter_reconnect_mode(struct input_device *idev);
static const char *reconnect_mode_to_string(const enum reconnect_mode_t mode);
@@ -392,7 +397,7 @@ static int hidp_add_connection(struct input_device *idev)
req->ctrl_sock = g_io_channel_unix_get_fd(idev->ctrl_io);
req->intr_sock = g_io_channel_unix_get_fd(idev->intr_io);
req->flags = 0;
- req->idle_to = idev->timeout;
+ req->idle_to = idle_timeout;
ba2str(&idev->src, src_addr);
ba2str(&idev->dst, dst_addr);
@@ -852,7 +857,7 @@ static const GDBusPropertyTable input_properties[] = {
int input_device_register(struct btd_device *device,
const char *path, const char *uuid,
- const sdp_record_t *rec, int timeout)
+ const sdp_record_t *rec)
{
struct input_device *idev;
@@ -880,7 +885,6 @@ int input_device_register(struct btd_device *device,
return -EINVAL;
}
- idev->timeout = timeout;
idev->uuid = g_strdup(uuid);
devices = g_slist_append(devices, idev);
diff --git a/profiles/input/device.h b/profiles/input/device.h
index db69053..798b4b0 100644
--- a/profiles/input/device.h
+++ b/profiles/input/device.h
@@ -27,9 +27,10 @@
struct input_device;
struct input_conn;
+void input_set_idle_timeout(int timeout);
+
int input_device_register(struct btd_device *device, const char *path,
- const char *uuid, const sdp_record_t *rec,
- int timeout);
+ const char *uuid, const sdp_record_t *rec);
void input_device_unregister(const char *path, const char *uuid);
int input_device_set_channel(const bdaddr_t *src, const bdaddr_t *dst, int psm,
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index d3d4cf3..cdcabfe 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -44,8 +44,6 @@
#include "server.h"
#include "manager.h"
-static int idle_timeout = 0;
-
static void input_remove(struct btd_device *device, const char *uuid)
{
const char *path = device_get_path(device);
@@ -65,8 +63,7 @@ static int hid_device_probe(struct btd_profile *p, struct btd_device *device)
if (!rec)
return -1;
- return input_device_register(device, path, HID_UUID, rec,
- idle_timeout * 60);
+ return input_device_register(device, path, HID_UUID, rec);
}
static void hid_device_remove(struct btd_profile *p, struct btd_device *device)
@@ -136,12 +133,16 @@ static int input_init(void)
config = load_config_file(CONFIGDIR "/input.conf");
if (config) {
+ int idle_timeout;
+
idle_timeout = g_key_file_get_integer(config, "General",
"IdleTimeout", &err);
if (err) {
DBG("input.conf: %s", err->message);
g_error_free(err);
}
+
+ input_set_idle_timeout(idle_timeout * 60);
}
btd_profile_register(&input_profile);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Each instance of btd_profile is associated to one single remote UUID
and therefore the list provided by the callback is redundant and can be
removed.
---
profiles/audio/manager.c | 9 +++------
profiles/cyclingspeed/cyclingspeed.c | 3 +--
profiles/deviceinfo/deviceinfo.c | 3 +--
profiles/gatt/gas.c | 3 +--
profiles/health/hdp_manager.c | 3 +--
profiles/heartrate/heartrate.c | 2 +-
profiles/input/hog.c | 3 +--
profiles/input/manager.c | 3 +--
profiles/network/manager.c | 9 +++------
profiles/proximity/manager.c | 6 +++---
profiles/proximity/reporter.c | 3 +--
profiles/proximity/reporter.h | 3 +--
profiles/scanparam/scan.c | 3 +--
profiles/thermometer/thermometer.c | 3 +--
src/device.c | 14 ++------------
src/profile.c | 5 ++---
src/profile.h | 3 +--
17 files changed, 25 insertions(+), 53 deletions(-)
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 8131a3e..f9c0ca6 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -101,8 +101,7 @@ static void audio_remove(struct btd_profile *p, struct btd_device *device)
audio_device_unregister(dev);
}
-static int a2dp_source_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int a2dp_source_probe(struct btd_profile *p, struct btd_device *device)
{
struct audio_device *audio_dev;
@@ -117,8 +116,7 @@ static int a2dp_source_probe(struct btd_profile *p, struct btd_device *device,
return 0;
}
-static int a2dp_sink_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int a2dp_sink_probe(struct btd_profile *p, struct btd_device *device)
{
struct audio_device *audio_dev;
@@ -133,8 +131,7 @@ static int a2dp_sink_probe(struct btd_profile *p, struct btd_device *device,
return 0;
}
-static int avrcp_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int avrcp_probe(struct btd_profile *p, struct btd_device *device)
{
struct audio_device *audio_dev;
diff --git a/profiles/cyclingspeed/cyclingspeed.c b/profiles/cyclingspeed/cyclingspeed.c
index 125007e..744bd4b 100644
--- a/profiles/cyclingspeed/cyclingspeed.c
+++ b/profiles/cyclingspeed/cyclingspeed.c
@@ -1180,8 +1180,7 @@ static const GDBusMethodTable cyclingspeed_device_methods[] = {
{ }
};
-static int csc_device_probe(struct btd_profile *p,
- struct btd_device *device, GSList *uuids)
+static int csc_device_probe(struct btd_profile *p, struct btd_device *device)
{
struct btd_adapter *adapter;
struct csc_adapter *cadapter;
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index 471241b..08f53b3 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -199,8 +199,7 @@ static void deviceinfo_unregister(struct btd_device *device)
}
static int deviceinfo_driver_probe(struct btd_profile *p,
- struct btd_device *device,
- GSList *uuids)
+ struct btd_device *device)
{
struct gatt_primary *prim;
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index bc8dbb5..4c7af4b 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -407,8 +407,7 @@ static void gas_unregister(struct btd_device *device)
gas_free(gas);
}
-static int gatt_driver_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int gatt_driver_probe(struct btd_profile *p, struct btd_device *device)
{
struct gatt_primary *gap, *gatt;
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index 5428724..3777fd4 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -54,8 +54,7 @@ static void hdp_adapter_remove(struct btd_profile *p,
hdp_adapter_unregister(adapter);
}
-static int hdp_driver_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int hdp_driver_probe(struct btd_profile *p, struct btd_device *device)
{
return hdp_device_register(device);
}
diff --git a/profiles/heartrate/heartrate.c b/profiles/heartrate/heartrate.c
index 0520f5c..18a9448 100644
--- a/profiles/heartrate/heartrate.c
+++ b/profiles/heartrate/heartrate.c
@@ -842,7 +842,7 @@ static void heartrate_adapter_remove(struct btd_profile *p,
}
static int heartrate_device_probe(struct btd_profile *p,
- struct btd_device *device, GSList *uuids)
+ struct btd_device *device)
{
struct gatt_primary *prim;
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index eadc860..eec0eee 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -820,8 +820,7 @@ static void resume_callback(void)
g_slist_foreach(devices, set_suspend, GINT_TO_POINTER(suspend));
}
-static int hog_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int hog_probe(struct btd_profile *p, struct btd_device *device)
{
const char *path = device_get_path(device);
GSList *primaries, *l;
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 8bbf768..d3d4cf3 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -55,8 +55,7 @@ static void input_remove(struct btd_device *device, const char *uuid)
input_device_unregister(path, uuid);
}
-static int hid_device_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int hid_device_probe(struct btd_profile *p, struct btd_device *device)
{
const char *path = device_get_path(device);
const sdp_record_t *rec = btd_device_get_record(device, HID_UUID);
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index 53bb652..4aa6a2b 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -74,8 +74,7 @@ done:
conf_security ? "true" : "false");
}
-static int panu_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int panu_probe(struct btd_profile *p, struct btd_device *device)
{
DBG("path %s", device_get_path(device));
@@ -118,8 +117,7 @@ static void panu_server_remove(struct btd_profile *p,
server_unregister(adapter, BNEP_SVC_PANU);
}
-static int gn_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int gn_probe(struct btd_profile *p, struct btd_device *device)
{
DBG("path %s", device_get_path(device));
@@ -155,8 +153,7 @@ static void gn_server_remove(struct btd_profile *p,
server_unregister(adapter, BNEP_SVC_GN);
}
-static int nap_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int nap_probe(struct btd_profile *p, struct btd_device *device)
{
DBG("path %s", device_get_path(device));
diff --git a/profiles/proximity/manager.c b/profiles/proximity/manager.c
index 81bfc3b..f24428b 100644
--- a/profiles/proximity/manager.c
+++ b/profiles/proximity/manager.c
@@ -49,7 +49,7 @@ static struct enabled enabled = {
};
static int monitor_linkloss_probe(struct btd_profile *p,
- struct btd_device *device, GSList *uuids)
+ struct btd_device *device)
{
struct gatt_primary *linkloss;
@@ -61,7 +61,7 @@ static int monitor_linkloss_probe(struct btd_profile *p,
}
static int monitor_immediate_probe(struct btd_profile *p,
- struct btd_device *device, GSList *uuids)
+ struct btd_device *device)
{
struct gatt_primary *immediate;
@@ -73,7 +73,7 @@ static int monitor_immediate_probe(struct btd_profile *p,
}
static int monitor_txpower_probe(struct btd_profile *p,
- struct btd_device *device, GSList *uuids)
+ struct btd_device *device)
{
struct gatt_primary *txpower;
diff --git a/profiles/proximity/reporter.c b/profiles/proximity/reporter.c
index 31c33ef..66f52fe 100644
--- a/profiles/proximity/reporter.c
+++ b/profiles/proximity/reporter.c
@@ -203,8 +203,7 @@ static void register_reporter_device(struct btd_device *device,
radapter->devices = g_slist_prepend(radapter->devices, device);
}
-int reporter_device_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+int reporter_device_probe(struct btd_profile *p, struct btd_device *device)
{
struct reporter_adapter *radapter;
struct btd_adapter *adapter = device_get_adapter(device);
diff --git a/profiles/proximity/reporter.h b/profiles/proximity/reporter.h
index 6a7066d..b02ae9c 100644
--- a/profiles/proximity/reporter.h
+++ b/profiles/proximity/reporter.h
@@ -37,8 +37,7 @@ enum {
};
void reporter_device_remove(struct btd_profile *p, struct btd_device *device);
-int reporter_device_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids);
+int reporter_device_probe(struct btd_profile *p, struct btd_device *device);
int reporter_adapter_probe(struct btd_profile *p, struct btd_adapter *adapter);
void reporter_adapter_remove(struct btd_profile *p,
diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index abbd129..deb0653 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -266,8 +266,7 @@ static void scan_unregister(struct btd_device *device)
g_free(scan);
}
-static int scan_param_probe(struct btd_profile *p, struct btd_device *device,
- GSList *uuids)
+static int scan_param_probe(struct btd_profile *p, struct btd_device *device)
{
struct gatt_primary *prim;
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 8550500..ae8ccb2 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -1281,8 +1281,7 @@ static void thermometer_adapter_unregister(struct btd_adapter *adapter)
}
static int thermometer_device_probe(struct btd_profile *p,
- struct btd_device *device,
- GSList *uuids)
+ struct btd_device *device)
{
struct gatt_primary *tattr;
diff --git a/src/device.c b/src/device.c
index 18beed9..01afd49 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2330,7 +2330,6 @@ struct probe_data {
static void dev_probe(struct btd_profile *p, void *user_data)
{
struct probe_data *d = user_data;
- GSList *probe_uuids;
int err;
if (p->device_probe == NULL)
@@ -2339,24 +2338,19 @@ static void dev_probe(struct btd_profile *p, void *user_data)
if (!device_match_profile(d->dev, p, d->uuids))
return;
- probe_uuids = g_slist_append(NULL, (char *) p->remote_uuid);
-
- err = p->device_probe(p, d->dev, probe_uuids);
+ err = p->device_probe(p, d->dev);
if (err < 0) {
error("%s profile probe failed for %s", p->name, d->addr);
- g_slist_free(probe_uuids);
return;
}
d->dev->profiles = g_slist_append(d->dev->profiles, p);
- g_slist_free(probe_uuids);
}
void device_probe_profile(gpointer a, gpointer b)
{
struct btd_device *device = a;
struct btd_profile *profile = b;
- GSList *probe_uuids;
char addr[18];
int err;
@@ -2366,19 +2360,15 @@ void device_probe_profile(gpointer a, gpointer b)
if (!device_match_profile(device, profile, device->uuids))
return;
- probe_uuids = g_slist_append(NULL, (char *) profile->remote_uuid);
-
ba2str(&device->bdaddr, addr);
- err = profile->device_probe(profile, device, probe_uuids);
+ err = profile->device_probe(profile, device);
if (err < 0) {
error("%s profile probe failed for %s", profile->name, addr);
- g_slist_free(probe_uuids);
return;
}
device->profiles = g_slist_append(device->profiles, profile);
- g_slist_free(probe_uuids);
if (!profile->auto_connect || !device->general_connect)
return;
diff --git a/src/profile.c b/src/profile.c
index 55e72dd..7bd7970 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -1397,8 +1397,7 @@ static void ext_adapter_remove(struct btd_profile *p,
}
}
-static int ext_device_probe(struct btd_profile *p, struct btd_device *dev,
- GSList *uuids)
+static int ext_device_probe(struct btd_profile *p, struct btd_device *dev)
{
struct ext_profile *ext;
@@ -1406,7 +1405,7 @@ static int ext_device_probe(struct btd_profile *p, struct btd_device *dev,
if (!ext)
return -ENOENT;
- DBG("%s probed with %u UUIDs", ext->name, g_slist_length(uuids));
+ DBG("%s probed with UUID %s", ext->name, p->remote_uuid);
return 0;
}
diff --git a/src/profile.h b/src/profile.h
index 5d78b37..5622f23 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -34,8 +34,7 @@ struct btd_profile {
bool auto_connect;
- int (*device_probe) (struct btd_profile *p, struct btd_device *device,
- GSList *uuids);
+ int (*device_probe) (struct btd_profile *p, struct btd_device *device);
void (*device_remove) (struct btd_profile *p,
struct btd_device *device);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
Considerable parts codebase are assuming that there is one single
instance of each UUID and therefore return an error during probe instead
of silently ignoring duplicated entries.
---
profiles/network/connection.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/profiles/network/connection.c b/profiles/network/connection.c
index 3a913cf..3ccd211 100644
--- a/profiles/network/connection.c
+++ b/profiles/network/connection.c
@@ -698,8 +698,11 @@ int connection_register(struct btd_device *device, uint16_t id)
}
nc = find_connection(peer->connections, id);
- if (nc)
- return 0;
+ if (nc) {
+ error("Device %s has multiple connection instances of %d",
+ device_get_path(device), id);
+ return -1;
+ }
nc = g_new0(struct network_conn, 1);
nc->id = id;
--
1.8.1.4
From: Mikel Astiz <[email protected]>
There is actually one single UUID which can be received during probe, so
simplify the code accordingly.
---
profiles/audio/control.c | 8 ++++----
profiles/audio/control.h | 4 ++--
profiles/audio/manager.c | 4 ++--
3 files changed, 8 insertions(+), 8 deletions(-)
diff --git a/profiles/audio/control.c b/profiles/audio/control.c
index 6086bde..fd5ff92 100644
--- a/profiles/audio/control.c
+++ b/profiles/audio/control.c
@@ -253,13 +253,13 @@ void control_unregister(struct audio_device *dev)
AUDIO_CONTROL_INTERFACE);
}
-void control_update(struct control *control, GSList *uuids)
+void control_update(struct control *control, const char *uuid)
{
- if (g_slist_find_custom(uuids, AVRCP_TARGET_UUID, bt_uuid_strcmp))
+ if (bt_uuid_strcmp(uuid, AVRCP_TARGET_UUID) == 0)
control->target = TRUE;
}
-struct control *control_init(struct audio_device *dev, GSList *uuids)
+struct control *control_init(struct audio_device *dev, const char *uuid)
{
struct control *control;
@@ -276,7 +276,7 @@ struct control *control_init(struct audio_device *dev, GSList *uuids)
control = g_new0(struct control, 1);
- control_update(control, uuids);
+ control_update(control, uuid);
control->avctp_id = avctp_add_state_cb(dev, state_changed);
diff --git a/profiles/audio/control.h b/profiles/audio/control.h
index de0259e..82ad0d2 100644
--- a/profiles/audio/control.h
+++ b/profiles/audio/control.h
@@ -24,8 +24,8 @@
#define AUDIO_CONTROL_INTERFACE "org.bluez.MediaControl1"
-struct control *control_init(struct audio_device *dev, GSList *uuids);
-void control_update(struct control *control, GSList *uuids);
+struct control *control_init(struct audio_device *dev, const char *uuid);
+void control_update(struct control *control, const char *uuid);
void control_unregister(struct audio_device *dev);
gboolean control_is_active(struct audio_device *dev);
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 4517815..8131a3e 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -145,9 +145,9 @@ static int avrcp_probe(struct btd_profile *p, struct btd_device *device,
}
if (audio_dev->control)
- control_update(audio_dev->control, uuids);
+ control_update(audio_dev->control, p->remote_uuid);
else
- audio_dev->control = control_init(audio_dev, uuids);
+ audio_dev->control = control_init(audio_dev, p->remote_uuid);
if (audio_dev->sink && sink_is_active(audio_dev))
avrcp_connect(audio_dev);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
The second 'err' shadows the main local variable which is being used to
as return value of the function. Otherwise -ENOENT was always returned
in case of error.
---
src/device.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/src/device.c b/src/device.c
index 5f67610..18beed9 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1060,8 +1060,6 @@ static int connect_next(struct btd_device *dev)
int err = -ENOENT;
while (dev->pending) {
- int err;
-
profile = dev->pending->data;
err = profile->connect(dev, profile);
--
1.8.1.4
From: Mikel Astiz <[email protected]>
The UUID in this code path is fixed so trivially use it instead of
using the provided probe parameter.
---
profiles/input/manager.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index d30ba67..8bbf768 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -59,7 +59,7 @@ static int hid_device_probe(struct btd_profile *p, struct btd_device *device,
GSList *uuids)
{
const char *path = device_get_path(device);
- const sdp_record_t *rec = btd_device_get_record(device, uuids->data);
+ const sdp_record_t *rec = btd_device_get_record(device, HID_UUID);
DBG("path %s", path);
--
1.8.1.4