2013-03-01 13:59:06

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 0/7] One remote UUID per btd_profile

From: Mikel Astiz <[email protected]>

Still not a lot of excitement after v1 but the patchset is required (or very convenient) for a later discussion which several people have shown interest in: the introduction of btd_service (or similar concept, to be discussed).

Claudio pointed out several issues affecting patch v1 3/7, which have been improved in this v2, including:
- Fix premature release of resources in cleanup_monitor().
- Fix boolean literal in monitor_unregister_linkloss (which should be FALSE).

Luiz also triggered an interesting point affecting patch v1 2/7 but I considered it unrelated to this patchset, stricly speaking, and has been therefore left aside.

Looking forward to your feedback.

>From original cover-letter:

Disclaimer: this RFC is WIP and hasn't been tested, specially because I don't have the necessary hardware for it.

The goal is to have one remote_uuid per btd_profile. There are only a few exceptions to this rule, and this patchset tries to fix three of them. This basically means splitting one btd_profile per role.

Mikel Astiz (7):
avrcp: Refactor server registration
audio: Split AVRCP into two btd_profile
proximity: Split internal monitor registration API
proximity: Split monitor into three btd_profile
gatt: List only GATT_UUID as remote UUID
health: Split health into two btd_profile
profile: Limit to one remote UUID per profile

profiles/audio/avrcp.c | 114 +++++++++++++-----
profiles/audio/avrcp.h | 6 +-
profiles/audio/manager.c | 75 ++++++++----
profiles/cyclingspeed/cyclingspeed.c | 2 +-
profiles/deviceinfo/deviceinfo.c | 2 +-
profiles/gatt/gas.c | 2 +-
profiles/health/hdp_manager.c | 20 +++-
profiles/heartrate/heartrate.c | 2 +-
profiles/input/hog.c | 2 +-
profiles/input/manager.c | 2 +-
profiles/network/manager.c | 6 +-
profiles/proximity/manager.c | 100 ++++++++++++----
profiles/proximity/monitor.c | 220 ++++++++++++++++++++++++++++-------
profiles/proximity/monitor.h | 17 ++-
profiles/scanparam/scan.c | 2 +-
profiles/thermometer/thermometer.c | 2 +-
src/device.c | 49 +++-----
src/profile.c | 25 ++--
src/profile.h | 4 +-
19 files changed, 466 insertions(+), 186 deletions(-)

--
1.8.1



2013-03-11 00:16:31

by Johan Hedberg

[permalink] [raw]
Subject: Re: [RFC v2 0/7] One remote UUID per btd_profile

Hi Mikel,

On Thu, Mar 07, 2013, Mikel Astiz wrote:
> On Fri, Mar 1, 2013 at 2:59 PM, Mikel Astiz <[email protected]> wrote:
> > From: Mikel Astiz <[email protected]>
> >
> > Still not a lot of excitement after v1 but the patchset is required (or very convenient) for a later discussion which several people have shown interest in: the introduction of btd_service (or similar concept, to be discussed).
> >
> > Claudio pointed out several issues affecting patch v1 3/7, which have been improved in this v2, including:
> > - Fix premature release of resources in cleanup_monitor().
> > - Fix boolean literal in monitor_unregister_linkloss (which should be FALSE).
> >
> > Luiz also triggered an interesting point affecting patch v1 2/7 but I considered it unrelated to this patchset, stricly speaking, and has been therefore left aside.
> >
> > Looking forward to your feedback.
> >
> > From original cover-letter:
> >
> > Disclaimer: this RFC is WIP and hasn't been tested, specially because I don't have the necessary hardware for it.
> >
> > The goal is to have one remote_uuid per btd_profile. There are only a few exceptions to this rule, and this patchset tries to fix three of them. This basically means splitting one btd_profile per role.
> >
> > Mikel Astiz (7):
> > avrcp: Refactor server registration
> > audio: Split AVRCP into two btd_profile
> > proximity: Split internal monitor registration API
> > proximity: Split monitor into three btd_profile
> > gatt: List only GATT_UUID as remote UUID
> > health: Split health into two btd_profile
> > profile: Limit to one remote UUID per profile
> >
> > profiles/audio/avrcp.c | 114 +++++++++++++-----
> > profiles/audio/avrcp.h | 6 +-
> > profiles/audio/manager.c | 75 ++++++++----
> > profiles/cyclingspeed/cyclingspeed.c | 2 +-
> > profiles/deviceinfo/deviceinfo.c | 2 +-
> > profiles/gatt/gas.c | 2 +-
> > profiles/health/hdp_manager.c | 20 +++-
> > profiles/heartrate/heartrate.c | 2 +-
> > profiles/input/hog.c | 2 +-
> > profiles/input/manager.c | 2 +-
> > profiles/network/manager.c | 6 +-
> > profiles/proximity/manager.c | 100 ++++++++++++----
> > profiles/proximity/monitor.c | 220 ++++++++++++++++++++++++++++-------
> > profiles/proximity/monitor.h | 17 ++-
> > profiles/scanparam/scan.c | 2 +-
> > profiles/thermometer/thermometer.c | 2 +-
> > src/device.c | 49 +++-----
> > src/profile.c | 25 ++--
> > src/profile.h | 4 +-
> > 19 files changed, 466 insertions(+), 186 deletions(-)
> >
> > --
> > 1.8.1
> >
>
> Ping.

This patch set has been hanging around the list long enough. After a
basic review which didn't show any obvious issues I went a head and did
a rebase against latest git and pushed it upstream. Let's hope any
issues caused by it get caught before we do the next release.

Johan

2013-03-07 17:28:14

by Mikel Astiz

[permalink] [raw]
Subject: Re: [RFC v2 0/7] One remote UUID per btd_profile

Hi,

On Fri, Mar 1, 2013 at 2:59 PM, Mikel Astiz <[email protected]> wrote:
> From: Mikel Astiz <[email protected]>
>
> Still not a lot of excitement after v1 but the patchset is required (or very convenient) for a later discussion which several people have shown interest in: the introduction of btd_service (or similar concept, to be discussed).
>
> Claudio pointed out several issues affecting patch v1 3/7, which have been improved in this v2, including:
> - Fix premature release of resources in cleanup_monitor().
> - Fix boolean literal in monitor_unregister_linkloss (which should be FALSE).
>
> Luiz also triggered an interesting point affecting patch v1 2/7 but I considered it unrelated to this patchset, stricly speaking, and has been therefore left aside.
>
> Looking forward to your feedback.
>
> From original cover-letter:
>
> Disclaimer: this RFC is WIP and hasn't been tested, specially because I don't have the necessary hardware for it.
>
> The goal is to have one remote_uuid per btd_profile. There are only a few exceptions to this rule, and this patchset tries to fix three of them. This basically means splitting one btd_profile per role.
>
> Mikel Astiz (7):
> avrcp: Refactor server registration
> audio: Split AVRCP into two btd_profile
> proximity: Split internal monitor registration API
> proximity: Split monitor into three btd_profile
> gatt: List only GATT_UUID as remote UUID
> health: Split health into two btd_profile
> profile: Limit to one remote UUID per profile
>
> profiles/audio/avrcp.c | 114 +++++++++++++-----
> profiles/audio/avrcp.h | 6 +-
> profiles/audio/manager.c | 75 ++++++++----
> profiles/cyclingspeed/cyclingspeed.c | 2 +-
> profiles/deviceinfo/deviceinfo.c | 2 +-
> profiles/gatt/gas.c | 2 +-
> profiles/health/hdp_manager.c | 20 +++-
> profiles/heartrate/heartrate.c | 2 +-
> profiles/input/hog.c | 2 +-
> profiles/input/manager.c | 2 +-
> profiles/network/manager.c | 6 +-
> profiles/proximity/manager.c | 100 ++++++++++++----
> profiles/proximity/monitor.c | 220 ++++++++++++++++++++++++++++-------
> profiles/proximity/monitor.h | 17 ++-
> profiles/scanparam/scan.c | 2 +-
> profiles/thermometer/thermometer.c | 2 +-
> src/device.c | 49 +++-----
> src/profile.c | 25 ++--
> src/profile.h | 4 +-
> 19 files changed, 466 insertions(+), 186 deletions(-)
>
> --
> 1.8.1
>

Ping.

Cheers,
Mikel

2013-03-01 13:59:13

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 7/7] profile: Limit to one remote UUID per profile

From: Mikel Astiz <[email protected]>

The code can be considerably simplified by constraining struct
btd_profile to one single remote UUID.
---
profiles/audio/manager.c | 8 +++---
profiles/cyclingspeed/cyclingspeed.c | 2 +-
profiles/deviceinfo/deviceinfo.c | 2 +-
profiles/gatt/gas.c | 2 +-
profiles/health/hdp_manager.c | 4 +--
profiles/heartrate/heartrate.c | 2 +-
profiles/input/hog.c | 2 +-
profiles/input/manager.c | 2 +-
profiles/network/manager.c | 6 ++---
profiles/proximity/manager.c | 8 +++---
profiles/scanparam/scan.c | 2 +-
profiles/thermometer/thermometer.c | 2 +-
src/device.c | 49 +++++++++++++-----------------------
src/profile.c | 25 ++++++++----------
src/profile.h | 4 +--
15 files changed, 49 insertions(+), 71 deletions(-)

diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 3023249..5799e77 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -345,7 +345,7 @@ static struct btd_profile a2dp_source_profile = {
.name = "audio-source",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,

- .remote_uuids = BTD_UUIDS(A2DP_SOURCE_UUID),
+ .remote_uuid = A2DP_SOURCE_UUID,
.device_probe = a2dp_source_probe,
.device_remove = audio_remove,

@@ -361,7 +361,7 @@ static struct btd_profile a2dp_sink_profile = {
.name = "audio-sink",
.priority = BTD_PROFILE_PRIORITY_MEDIUM,

- .remote_uuids = BTD_UUIDS(A2DP_SINK_UUID),
+ .remote_uuid = A2DP_SINK_UUID,
.device_probe = a2dp_sink_probe,
.device_remove = audio_remove,

@@ -376,7 +376,7 @@ static struct btd_profile a2dp_sink_profile = {
static struct btd_profile avrcp_target_profile = {
.name = "audio-avrcp-target",

- .remote_uuids = BTD_UUIDS(AVRCP_TARGET_UUID),
+ .remote_uuid = AVRCP_TARGET_UUID,
.device_probe = avrcp_probe,
.device_remove = audio_remove,

@@ -391,7 +391,7 @@ static struct btd_profile avrcp_target_profile = {
static struct btd_profile avrcp_remote_profile = {
.name = "audio-avrcp-control",

- .remote_uuids = BTD_UUIDS(AVRCP_REMOTE_UUID),
+ .remote_uuid = AVRCP_REMOTE_UUID,
.device_probe = avrcp_probe,
.device_remove = audio_remove,

diff --git a/profiles/cyclingspeed/cyclingspeed.c b/profiles/cyclingspeed/cyclingspeed.c
index fc72791..125007e 100644
--- a/profiles/cyclingspeed/cyclingspeed.c
+++ b/profiles/cyclingspeed/cyclingspeed.c
@@ -1256,7 +1256,7 @@ static void csc_device_remove(struct btd_profile *p,

static struct btd_profile cscp_profile = {
.name = "Cycling Speed and Cadence GATT Driver",
- .remote_uuids = BTD_UUIDS(CYCLING_SC_UUID),
+ .remote_uuid = CYCLING_SC_UUID,

.adapter_probe = csc_adapter_probe,
.adapter_remove = csc_adapter_remove,
diff --git a/profiles/deviceinfo/deviceinfo.c b/profiles/deviceinfo/deviceinfo.c
index fb423fa..471241b 100644
--- a/profiles/deviceinfo/deviceinfo.c
+++ b/profiles/deviceinfo/deviceinfo.c
@@ -219,7 +219,7 @@ static void deviceinfo_driver_remove(struct btd_profile *p,

static struct btd_profile deviceinfo_profile = {
.name = "deviceinfo",
- .remote_uuids = BTD_UUIDS(DEVICE_INFORMATION_UUID),
+ .remote_uuid = DEVICE_INFORMATION_UUID,
.device_probe = deviceinfo_driver_probe,
.device_remove = deviceinfo_driver_remove
};
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 6a8571c..bc8dbb5 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -431,7 +431,7 @@ static void gatt_driver_remove(struct btd_profile *p,

static struct btd_profile gatt_profile = {
.name = "gap-gatt-profile",
- .remote_uuids = BTD_UUIDS(GATT_UUID),
+ .remote_uuid = GATT_UUID,
.device_probe = gatt_driver_probe,
.device_remove = gatt_driver_remove
};
diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index 9df5b2b..5428724 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -67,7 +67,7 @@ static void hdp_driver_remove(struct btd_profile *p, struct btd_device *device)

static struct btd_profile hdp_source_profile = {
.name = "hdp-source",
- .remote_uuids = BTD_UUIDS(HDP_SOURCE_UUID),
+ .remote_uuid = HDP_SOURCE_UUID,

.device_probe = hdp_driver_probe,
.device_remove = hdp_driver_remove,
@@ -78,7 +78,7 @@ static struct btd_profile hdp_source_profile = {

static struct btd_profile hdp_sink_profile = {
.name = "hdp-sink",
- .remote_uuids = BTD_UUIDS(HDP_SINK_UUID),
+ .remote_uuid = HDP_SINK_UUID,

.device_probe = hdp_driver_probe,
.device_remove = hdp_driver_remove,
diff --git a/profiles/heartrate/heartrate.c b/profiles/heartrate/heartrate.c
index 5c56d3f..0520f5c 100644
--- a/profiles/heartrate/heartrate.c
+++ b/profiles/heartrate/heartrate.c
@@ -861,7 +861,7 @@ static void heartrate_device_remove(struct btd_profile *p,

static struct btd_profile hrp_profile = {
.name = "Heart Rate GATT Driver",
- .remote_uuids = BTD_UUIDS(HEART_RATE_UUID),
+ .remote_uuid = HEART_RATE_UUID,

.device_probe = heartrate_device_probe,
.device_remove = heartrate_device_remove,
diff --git a/profiles/input/hog.c b/profiles/input/hog.c
index a5269d9..eadc860 100644
--- a/profiles/input/hog.c
+++ b/profiles/input/hog.c
@@ -872,7 +872,7 @@ static void hog_remove(struct btd_profile *p, struct btd_device *device)

static struct btd_profile hog_profile = {
.name = "input-hog",
- .remote_uuids = BTD_UUIDS(HOG_UUID),
+ .remote_uuid = HOG_UUID,
.device_probe = hog_probe,
.device_remove = hog_remove,
};
diff --git a/profiles/input/manager.c b/profiles/input/manager.c
index 6ed12ee..d30ba67 100644
--- a/profiles/input/manager.c
+++ b/profiles/input/manager.c
@@ -89,7 +89,7 @@ static void hid_server_remove(struct btd_profile *p,
static struct btd_profile input_profile = {
.name = "input-hid",
.local_uuid = HID_UUID,
- .remote_uuids = BTD_UUIDS(HID_UUID),
+ .remote_uuid = HID_UUID,

.auto_connect = true,
.connect = input_device_connect,
diff --git a/profiles/network/manager.c b/profiles/network/manager.c
index bc553c4..53bb652 100644
--- a/profiles/network/manager.c
+++ b/profiles/network/manager.c
@@ -195,7 +195,7 @@ static void nap_server_remove(struct btd_profile *p,
static struct btd_profile panu_profile = {
.name = "network-panu",
.local_uuid = NAP_UUID,
- .remote_uuids = BTD_UUIDS(PANU_UUID),
+ .remote_uuid = PANU_UUID,
.device_probe = panu_probe,
.device_remove = network_remove,
.connect = panu_connect,
@@ -207,7 +207,7 @@ static struct btd_profile panu_profile = {
static struct btd_profile gn_profile = {
.name = "network-gn",
.local_uuid = PANU_UUID,
- .remote_uuids = BTD_UUIDS(GN_UUID),
+ .remote_uuid = GN_UUID,
.device_probe = gn_probe,
.device_remove = network_remove,
.connect = gn_connect,
@@ -219,7 +219,7 @@ static struct btd_profile gn_profile = {
static struct btd_profile nap_profile = {
.name = "network-nap",
.local_uuid = PANU_UUID,
- .remote_uuids = BTD_UUIDS(NAP_UUID),
+ .remote_uuid = NAP_UUID,
.device_probe = nap_probe,
.device_remove = network_remove,
.connect = nap_connect,
diff --git a/profiles/proximity/manager.c b/profiles/proximity/manager.c
index 7579be5..81bfc3b 100644
--- a/profiles/proximity/manager.c
+++ b/profiles/proximity/manager.c
@@ -104,28 +104,28 @@ static void monitor_txpower_remove(struct btd_profile *p,

static struct btd_profile pxp_monitor_linkloss_profile = {
.name = "proximity-linkloss",
- .remote_uuids = BTD_UUIDS(LINK_LOSS_UUID),
+ .remote_uuid = LINK_LOSS_UUID,
.device_probe = monitor_linkloss_probe,
.device_remove = monitor_linkloss_remove,
};

static struct btd_profile pxp_monitor_immediate_profile = {
.name = "proximity-immediate",
- .remote_uuids = BTD_UUIDS(IMMEDIATE_ALERT_UUID),
+ .remote_uuid = IMMEDIATE_ALERT_UUID,
.device_probe = monitor_immediate_probe,
.device_remove = monitor_immediate_remove,
};

static struct btd_profile pxp_monitor_txpower_profile = {
.name = "proximity-txpower",
- .remote_uuids = BTD_UUIDS(TX_POWER_UUID),
+ .remote_uuid = TX_POWER_UUID,
.device_probe = monitor_txpower_probe,
.device_remove = monitor_txpower_remove,
};

static struct btd_profile pxp_reporter_profile = {
.name = "Proximity Reporter GATT Driver",
- .remote_uuids = BTD_UUIDS(GATT_UUID),
+ .remote_uuid = GATT_UUID,
.device_probe = reporter_device_probe,
.device_remove = reporter_device_remove,

diff --git a/profiles/scanparam/scan.c b/profiles/scanparam/scan.c
index 268bdc8..abbd129 100644
--- a/profiles/scanparam/scan.c
+++ b/profiles/scanparam/scan.c
@@ -287,7 +287,7 @@ static void scan_param_remove(struct btd_profile *p, struct btd_device *device)

static struct btd_profile scan_profile = {
.name = "Scan Parameters Client Driver",
- .remote_uuids = BTD_UUIDS(SCAN_PARAMETERS_UUID),
+ .remote_uuid = SCAN_PARAMETERS_UUID,
.device_probe = scan_param_probe,
.device_remove = scan_param_remove,
};
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 1b299e7..8550500 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -1313,7 +1313,7 @@ static void thermometer_adapter_remove(struct btd_profile *p,

static struct btd_profile thermometer_profile = {
.name = "Health Thermometer GATT driver",
- .remote_uuids = BTD_UUIDS(HEALTH_THERMOMETER_UUID),
+ .remote_uuid = HEALTH_THERMOMETER_UUID,
.device_probe = thermometer_device_probe,
.device_remove = thermometer_device_remove,
.adapter_probe = thermometer_adapter_probe,
diff --git a/src/device.c b/src/device.c
index 4320234..3cd7f10 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1158,15 +1158,12 @@ static struct btd_profile *find_connectable_profile(struct btd_device *dev,

for (l = dev->profiles; l != NULL; l = g_slist_next(l)) {
struct btd_profile *p = l->data;
- int i;

- if (!p->connect || !p->remote_uuids)
+ if (!p->connect || !p->remote_uuid)
continue;

- for (i = 0; p->remote_uuids[i] != NULL; i++) {
- if (strcasecmp(uuid, p->remote_uuids[i]) == 0)
- return p;
- }
+ if (strcasecmp(uuid, p->remote_uuid) == 0)
+ return p;
}

return NULL;
@@ -2302,27 +2299,18 @@ GSList *device_get_uuids(struct btd_device *device)
return device->uuids;
}

-static GSList *device_match_profile(struct btd_device *device,
+static bool device_match_profile(struct btd_device *device,
struct btd_profile *profile,
GSList *uuids)
{
- const char **uuid;
- GSList *match_uuids = NULL;
-
- for (uuid = profile->remote_uuids; *uuid; uuid++) {
- GSList *match;
-
- /* skip duplicated uuids */
- if (g_slist_find_custom(match_uuids, *uuid, bt_uuid_strcmp))
- continue;
+ if (profile->remote_uuid == NULL)
+ return false;

- /* match profile uuid */
- match = g_slist_find_custom(uuids, *uuid, bt_uuid_strcmp);
- if (match)
- match_uuids = g_slist_append(match_uuids, match->data);
- }
+ if (g_slist_find_custom(uuids, profile->remote_uuid,
+ bt_uuid_strcmp) == NULL)
+ return false;

- return match_uuids;
+ return true;
}

struct probe_data {
@@ -2340,10 +2328,11 @@ static void dev_probe(struct btd_profile *p, void *user_data)
if (p->device_probe == NULL)
return;

- probe_uuids = device_match_profile(d->dev, p, d->uuids);
- if (!probe_uuids)
+ 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);
if (err < 0) {
error("%s profile probe failed for %s", p->name, d->addr);
@@ -2366,10 +2355,11 @@ void device_probe_profile(gpointer a, gpointer b)
if (profile->device_probe == NULL)
return;

- probe_uuids = device_match_profile(device, profile, device->uuids);
- if (!probe_uuids)
+ 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);
@@ -2454,15 +2444,10 @@ static void device_remove_profiles(struct btd_device *device, GSList *uuids)

for (l = device->profiles; l != NULL; l = next) {
struct btd_profile *profile = l->data;
- GSList *probe_uuids;

next = l->next;
- probe_uuids = device_match_profile(device, profile,
- device->uuids);
- if (probe_uuids != NULL) {
- g_slist_free(probe_uuids);
+ if (device_match_profile(device, profile, device->uuids))
continue;
- }

profile->device_remove(profile, device);
device->profiles = g_slist_remove(device->profiles, profile);
diff --git a/src/profile.c b/src/profile.c
index 656506a..29f9ee6 100644
--- a/src/profile.c
+++ b/src/profile.c
@@ -519,7 +519,7 @@ struct ext_profile {
char *(*get_record)(struct ext_profile *ext, struct ext_io *l2cap,
struct ext_io *rfcomm);

- char **remote_uuids;
+ char *remote_uuid;

guint id;

@@ -851,7 +851,7 @@ static bool send_new_connection(struct ext_profile *ext, struct ext_io *conn)
DBusMessage *msg;
DBusMessageIter iter, dict;
struct prop_append_data data = { &dict, conn };
- const char *remote_uuid = ext->remote_uuids[0];
+ const char *remote_uuid = ext->remote_uuid;
const sdp_record_t *rec;
const char *path;
int fd;
@@ -1540,7 +1540,7 @@ static int resolve_service(struct ext_io *conn, const bdaddr_t *src,
uuid_t uuid;
int err;

- bt_string2uuid(&uuid, ext->remote_uuids[0]);
+ bt_string2uuid(&uuid, ext->remote_uuid);
sdp_uuid128_to_uuid(&uuid);

err = bt_search_service(src, dst, &uuid, record_cb, conn, NULL);
@@ -1910,8 +1910,7 @@ static void ext_set_defaults(struct ext_profile *ext)
ext->authorize = true;
ext->enable_client = true;
ext->enable_server = true;
-
- ext->remote_uuids = g_new0(char *, 2);
+ ext->remote_uuid = NULL;

for (i = 0; i < G_N_ELEMENTS(defaults); i++) {
struct default_settings *settings = &defaults[i];
@@ -1925,7 +1924,7 @@ static void ext_set_defaults(struct ext_profile *ext)
else
remote_uuid = ext->uuid;

- ext->remote_uuids[0] = g_strdup(remote_uuid);
+ ext->remote_uuid = g_strdup(remote_uuid);

if (settings->channel)
ext->local_chan = settings->channel;
@@ -2122,21 +2121,18 @@ static struct ext_profile *create_ext(const char *owner, const char *path,
if (!ext->name)
ext->name = g_strdup_printf("%s%s/%s", owner, path, uuid);

- if (!ext->remote_uuids[0]) {
+ if (!ext->remote_uuid) {
if (ext->service)
- ext->remote_uuids[0] = g_strdup(ext->service);
+ ext->remote_uuid = g_strdup(ext->service);
else
- ext->remote_uuids[0] = g_strdup(ext->uuid);
+ ext->remote_uuid = g_strdup(ext->uuid);
}

p = &ext->p;

p->name = ext->name;
p->local_uuid = ext->service ? ext->service : ext->uuid;
-
- /* Typecast can't really be avoided here:
- * http://c-faq.com/ansi/constmismatch.html */
- p->remote_uuids = (const char **) ext->remote_uuids;
+ p->remote_uuid = ext->remote_uuid;

if (ext->enable_server || ext->record || ext->get_record) {
p->adapter_probe = ext_adapter_probe;
@@ -2172,8 +2168,7 @@ static void remove_ext(struct ext_profile *ext)
g_slist_free_full(ext->servers, ext_io_destroy);
g_slist_free_full(ext->conns, ext_io_destroy);

- g_strfreev(ext->remote_uuids);
-
+ g_free(ext->remote_uuid);
g_free(ext->name);
g_free(ext->owner);
g_free(ext->uuid);
diff --git a/src/profile.h b/src/profile.h
index d858925..5d78b37 100644
--- a/src/profile.h
+++ b/src/profile.h
@@ -21,8 +21,6 @@
*
*/

-#define BTD_UUIDS(args...) ((const char *[]) { args, NULL } )
-
#define BTD_PROFILE_PRIORITY_LOW 0
#define BTD_PROFILE_PRIORITY_MEDIUM 1
#define BTD_PROFILE_PRIORITY_HIGH 2
@@ -32,7 +30,7 @@ struct btd_profile {
int priority;

const char *local_uuid;
- const char **remote_uuids;
+ const char *remote_uuid;

bool auto_connect;

--
1.8.1


2013-03-01 13:59:11

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 5/7] gatt: List only GATT_UUID as remote UUID

From: Mikel Astiz <[email protected]>

The probe function checks if both UUIDs are present, so there is no
need to list both in btd_profile.
---
profiles/gatt/gas.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 9360201..6a8571c 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -431,7 +431,7 @@ static void gatt_driver_remove(struct btd_profile *p,

static struct btd_profile gatt_profile = {
.name = "gap-gatt-profile",
- .remote_uuids = BTD_UUIDS(GAP_UUID, GATT_UUID),
+ .remote_uuids = BTD_UUIDS(GATT_UUID),
.device_probe = gatt_driver_probe,
.device_remove = gatt_driver_remove
};
--
1.8.1


2013-03-01 13:59:12

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 6/7] health: Split health into two btd_profile

From: Mikel Astiz <[email protected]>

Register a separate btd_profile for each health device role.
---
profiles/health/hdp_manager.c | 20 +++++++++++++++-----
1 file changed, 15 insertions(+), 5 deletions(-)

diff --git a/profiles/health/hdp_manager.c b/profiles/health/hdp_manager.c
index 87e70cd..9df5b2b 100644
--- a/profiles/health/hdp_manager.c
+++ b/profiles/health/hdp_manager.c
@@ -65,9 +65,9 @@ static void hdp_driver_remove(struct btd_profile *p, struct btd_device *device)
hdp_device_unregister(device);
}

-static struct btd_profile hdp_profile = {
- .name = "hdp-profile",
- .remote_uuids = BTD_UUIDS(HDP_UUID, HDP_SOURCE_UUID, HDP_SINK_UUID),
+static struct btd_profile hdp_source_profile = {
+ .name = "hdp-source",
+ .remote_uuids = BTD_UUIDS(HDP_SOURCE_UUID),

.device_probe = hdp_driver_probe,
.device_remove = hdp_driver_remove,
@@ -76,19 +76,29 @@ static struct btd_profile hdp_profile = {
.adapter_remove = hdp_adapter_remove,
};

+static struct btd_profile hdp_sink_profile = {
+ .name = "hdp-sink",
+ .remote_uuids = BTD_UUIDS(HDP_SINK_UUID),
+
+ .device_probe = hdp_driver_probe,
+ .device_remove = hdp_driver_remove,
+};
+
int hdp_manager_init(void)
{
if (hdp_manager_start() < 0)
return -1;

- btd_profile_register(&hdp_profile);
+ btd_profile_register(&hdp_source_profile);
+ btd_profile_register(&hdp_sink_profile);

return 0;
}

void hdp_manager_exit(void)
{
- btd_profile_unregister(&hdp_profile);
+ btd_profile_unregister(&hdp_sink_profile);
+ btd_profile_unregister(&hdp_source_profile);

hdp_manager_stop();
}
--
1.8.1


2013-03-01 13:59:10

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 4/7] proximity: Split monitor into three btd_profile

From: Mikel Astiz <[email protected]>

Split into three btd_profile such that each of them handles one single
UUID.
---
profiles/proximity/manager.c | 104 +++++++++++++++++++++++++++++++------------
1 file changed, 76 insertions(+), 28 deletions(-)

diff --git a/profiles/proximity/manager.c b/profiles/proximity/manager.c
index 3182596..7579be5 100644
--- a/profiles/proximity/manager.c
+++ b/profiles/proximity/manager.c
@@ -48,42 +48,79 @@ static struct enabled enabled = {
.findme = TRUE,
};

-static int monitor_device_probe(struct btd_profile *p,
+static int monitor_linkloss_probe(struct btd_profile *p,
struct btd_device *device, GSList *uuids)
{
- struct gatt_primary *linkloss, *txpower, *immediate;
- int err = 0;
+ struct gatt_primary *linkloss;

- immediate = btd_device_get_primary(device, IMMEDIATE_ALERT_UUID);
- txpower = btd_device_get_primary(device, TX_POWER_UUID);
linkloss = btd_device_get_primary(device, LINK_LOSS_UUID);
+ if (linkloss == NULL)
+ return -1;
+
+ return monitor_register_linkloss(device, &enabled, linkloss);
+}
+
+static int monitor_immediate_probe(struct btd_profile *p,
+ struct btd_device *device, GSList *uuids)
+{
+ struct gatt_primary *immediate;
+
+ immediate = btd_device_get_primary(device, IMMEDIATE_ALERT_UUID);
+ if (immediate == NULL)
+ return -1;

- if (linkloss)
- err = monitor_register_linkloss(device, &enabled, linkloss);
+ return monitor_register_immediate(device, &enabled, immediate);
+}

- if (err >= 0 && immediate)
- err = monitor_register_immediate(device, &enabled, immediate);
+static int monitor_txpower_probe(struct btd_profile *p,
+ struct btd_device *device, GSList *uuids)
+{
+ struct gatt_primary *txpower;

- if (err >= 0 && txpower)
- err = monitor_register_txpower(device, &enabled, txpower);
+ txpower = btd_device_get_primary(device, TX_POWER_UUID);
+ if (txpower == NULL)
+ return -1;

- return err;
+ return monitor_register_txpower(device, &enabled, txpower);
}

-static void monitor_device_remove(struct btd_profile *p,
+static void monitor_linkloss_remove(struct btd_profile *p,
struct btd_device *device)
{
- monitor_unregister_txpower(device);
- monitor_unregister_immediate(device);
monitor_unregister_linkloss(device);
}

-static struct btd_profile pxp_monitor_profile = {
- .name = "Proximity Monitor GATT Driver",
- .remote_uuids = BTD_UUIDS(IMMEDIATE_ALERT_UUID,
- LINK_LOSS_UUID, TX_POWER_UUID),
- .device_probe = monitor_device_probe,
- .device_remove = monitor_device_remove,
+static void monitor_immediate_remove(struct btd_profile *p,
+ struct btd_device *device)
+{
+ monitor_unregister_immediate(device);
+}
+
+static void monitor_txpower_remove(struct btd_profile *p,
+ struct btd_device *device)
+{
+ monitor_unregister_txpower(device);
+}
+
+static struct btd_profile pxp_monitor_linkloss_profile = {
+ .name = "proximity-linkloss",
+ .remote_uuids = BTD_UUIDS(LINK_LOSS_UUID),
+ .device_probe = monitor_linkloss_probe,
+ .device_remove = monitor_linkloss_remove,
+};
+
+static struct btd_profile pxp_monitor_immediate_profile = {
+ .name = "proximity-immediate",
+ .remote_uuids = BTD_UUIDS(IMMEDIATE_ALERT_UUID),
+ .device_probe = monitor_immediate_probe,
+ .device_remove = monitor_immediate_remove,
+};
+
+static struct btd_profile pxp_monitor_txpower_profile = {
+ .name = "proximity-txpower",
+ .remote_uuids = BTD_UUIDS(TX_POWER_UUID),
+ .device_probe = monitor_txpower_probe,
+ .device_remove = monitor_txpower_remove,
};

static struct btd_profile pxp_reporter_profile = {
@@ -122,19 +159,30 @@ int proximity_manager_init(GKeyFile *config)
{
load_config_file(config);

- if (btd_profile_register(&pxp_monitor_profile) < 0)
- return -1;
+ if (btd_profile_register(&pxp_monitor_linkloss_profile) < 0)
+ goto fail;

- if (btd_profile_register(&pxp_reporter_profile) < 0) {
- btd_profile_unregister(&pxp_monitor_profile);
- return -1;
- }
+ if (btd_profile_register(&pxp_monitor_immediate_profile) < 0)
+ goto fail;
+
+ if (btd_profile_register(&pxp_monitor_txpower_profile) < 0)
+ goto fail;
+
+ if (btd_profile_register(&pxp_reporter_profile) < 0)
+ goto fail;

return 0;
+
+fail:
+ proximity_manager_exit();
+
+ return -1;
}

void proximity_manager_exit(void)
{
- btd_profile_unregister(&pxp_monitor_profile);
btd_profile_unregister(&pxp_reporter_profile);
+ btd_profile_unregister(&pxp_monitor_txpower_profile);
+ btd_profile_unregister(&pxp_monitor_immediate_profile);
+ btd_profile_unregister(&pxp_monitor_linkloss_profile);
}
--
1.8.1


2013-03-01 13:59:09

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 3/7] proximity: Split internal monitor registration API

From: Mikel Astiz <[email protected]>

Split the monitor registration API into three independent registrations
each of them taking one specific GATT primary.
---
profiles/proximity/manager.c | 16 +++-
profiles/proximity/monitor.c | 220 ++++++++++++++++++++++++++++++++++---------
profiles/proximity/monitor.h | 17 +++-
3 files changed, 204 insertions(+), 49 deletions(-)

diff --git a/profiles/proximity/manager.c b/profiles/proximity/manager.c
index b405f15..3182596 100644
--- a/profiles/proximity/manager.c
+++ b/profiles/proximity/manager.c
@@ -52,18 +52,30 @@ static int monitor_device_probe(struct btd_profile *p,
struct btd_device *device, GSList *uuids)
{
struct gatt_primary *linkloss, *txpower, *immediate;
+ int err = 0;

immediate = btd_device_get_primary(device, IMMEDIATE_ALERT_UUID);
txpower = btd_device_get_primary(device, TX_POWER_UUID);
linkloss = btd_device_get_primary(device, LINK_LOSS_UUID);

- return monitor_register(device, linkloss, txpower, immediate, &enabled);
+ if (linkloss)
+ err = monitor_register_linkloss(device, &enabled, linkloss);
+
+ if (err >= 0 && immediate)
+ err = monitor_register_immediate(device, &enabled, immediate);
+
+ if (err >= 0 && txpower)
+ err = monitor_register_txpower(device, &enabled, txpower);
+
+ return err;
}

static void monitor_device_remove(struct btd_profile *p,
struct btd_device *device)
{
- monitor_unregister(device);
+ monitor_unregister_txpower(device);
+ monitor_unregister_immediate(device);
+ monitor_unregister_linkloss(device);
}

static struct btd_profile pxp_monitor_profile = {
diff --git a/profiles/proximity/monitor.c b/profiles/proximity/monitor.c
index 597f161..48f877d 100644
--- a/profiles/proximity/monitor.c
+++ b/profiles/proximity/monitor.c
@@ -34,6 +34,7 @@
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
+#include <glib.h>

#include <bluetooth/bluetooth.h>

@@ -83,6 +84,22 @@ struct monitor {
guint attioid;
};

+static GSList *monitors = NULL;
+
+static struct monitor *find_monitor(struct btd_device *device)
+{
+ GSList *l;
+
+ for (l = monitors; l; l = l->next) {
+ struct monitor *monitor = l->data;
+
+ if (monitor->device == device)
+ return monitor;
+ }
+
+ return NULL;
+}
+
static void write_proximity_config(struct btd_device *device, const char *alert,
const char *level)
{
@@ -580,33 +597,25 @@ static void monitor_destroy(gpointer user_data)
{
struct monitor *monitor = user_data;

- if (monitor->immediateto)
- g_source_remove(monitor->immediateto);
-
- if (monitor->attioid)
- btd_device_remove_attio_callback(monitor->device,
- monitor->attioid);
- if (monitor->attrib)
- g_attrib_unref(monitor->attrib);
-
btd_device_unref(monitor->device);
- g_free(monitor->linkloss);
- g_free(monitor->immediate);
- g_free(monitor->txpower);
g_free(monitor->linklosslevel);
g_free(monitor->immediatelevel);
g_free(monitor->signallevel);
g_free(monitor);
+
+ monitors = g_slist_remove(monitors, monitor);
}

-int monitor_register(struct btd_device *device,
- struct gatt_primary *linkloss, struct gatt_primary *txpower,
- struct gatt_primary *immediate, struct enabled *enabled)
+static struct monitor *register_monitor(struct btd_device *device)
{
const char *path = device_get_path(device);
struct monitor *monitor;
char *level;

+ monitor = find_monitor(device);
+ if (monitor != NULL)
+ return monitor;
+
level = read_proximity_config(device, "LinkLossAlertLevel");

monitor = g_new0(struct monitor, 1);
@@ -615,6 +624,8 @@ int monitor_register(struct btd_device *device,
monitor->signallevel = g_strdup("unknown");
monitor->immediatelevel = g_strdup("none");

+ monitors = g_slist_append(monitors, monitor);
+
if (g_dbus_register_interface(btd_get_dbus_connection(), path,
PROXIMITY_INTERFACE,
NULL, NULL, monitor_device_properties,
@@ -622,55 +633,178 @@ int monitor_register(struct btd_device *device,
error("D-Bus failed to register %s interface",
PROXIMITY_INTERFACE);
monitor_destroy(monitor);
- return -1;
+ return NULL;
}

DBG("Registered interface %s on path %s", PROXIMITY_INTERFACE, path);

- if (linkloss && enabled->linkloss) {
- monitor->linkloss = g_new0(struct att_range, 1);
- monitor->linkloss->start = linkloss->range.start;
- monitor->linkloss->end = linkloss->range.end;
-
- monitor->enabled.linkloss = TRUE;
- }
-
- if (immediate) {
- if (txpower && enabled->pathloss) {
- monitor->txpower = g_new0(struct att_range, 1);
- monitor->txpower->start = txpower->range.start;
- monitor->txpower->end = txpower->range.end;
-
- monitor->enabled.pathloss = TRUE;
- }
-
- if (enabled->pathloss || enabled->findme) {
- monitor->immediate = g_new0(struct att_range, 1);
- monitor->immediate->start = immediate->range.start;
- monitor->immediate->end = immediate->range.end;
- }
+ return monitor;
+}

- monitor->enabled.findme = enabled->findme;
- }
+static void update_monitor(struct monitor *monitor)
+{
+ if (monitor->txpower != NULL && monitor->immediate != NULL)
+ monitor->enabled.pathloss = TRUE;
+ else
+ monitor->enabled.pathloss = FALSE;

DBG("Link Loss: %s, Path Loss: %s, FindMe: %s",
monitor->enabled.linkloss ? "TRUE" : "FALSE",
monitor->enabled.pathloss ? "TRUE" : "FALSE",
monitor->enabled.findme ? "TRUE" : "FALSE");

- if (monitor->enabled.linkloss || monitor->enabled.pathloss)
- monitor->attioid = btd_device_add_attio_callback(device,
+ if (!monitor->enabled.linkloss && !monitor->enabled.pathloss)
+ return;
+
+ if (monitor->attioid != 0)
+ return;
+
+ monitor->attioid = btd_device_add_attio_callback(monitor->device,
attio_connected_cb,
attio_disconnected_cb,
monitor);
+}
+
+int monitor_register_linkloss(struct btd_device *device,
+ struct enabled *enabled,
+ struct gatt_primary *linkloss)
+{
+ struct monitor *monitor;
+
+ if (!enabled->linkloss)
+ return 0;
+
+ monitor = register_monitor(device);
+ if (monitor == NULL)
+ return -1;
+
+ monitor->linkloss = g_new0(struct att_range, 1);
+ monitor->linkloss->start = linkloss->range.start;
+ monitor->linkloss->end = linkloss->range.end;
+ monitor->enabled.linkloss = TRUE;
+
+ update_monitor(monitor);

return 0;
}

-void monitor_unregister(struct btd_device *device)
+int monitor_register_txpower(struct btd_device *device,
+ struct enabled *enabled,
+ struct gatt_primary *txpower)
{
+ struct monitor *monitor;
+
+ if (!enabled->pathloss)
+ return 0;
+
+ monitor = register_monitor(device);
+ if (monitor == NULL)
+ return -1;
+
+ monitor->txpower = g_new0(struct att_range, 1);
+ monitor->txpower->start = txpower->range.start;
+ monitor->txpower->end = txpower->range.end;
+
+ update_monitor(monitor);
+
+ return 0;
+}
+
+int monitor_register_immediate(struct btd_device *device,
+ struct enabled *enabled,
+ struct gatt_primary *immediate)
+{
+ struct monitor *monitor;
+
+ if (!enabled->pathloss && !enabled->findme)
+ return 0;
+
+ monitor = register_monitor(device);
+ if (monitor == NULL)
+ return -1;
+
+ monitor->immediate = g_new0(struct att_range, 1);
+ monitor->immediate->start = immediate->range.start;
+ monitor->immediate->end = immediate->range.end;
+ monitor->enabled.findme = enabled->findme;
+
+ update_monitor(monitor);
+
+ return 0;
+}
+
+static void cleanup_monitor(struct monitor *monitor)
+{
+ struct btd_device *device = monitor->device;
const char *path = device_get_path(device);

+ if (monitor->immediate != NULL || monitor->txpower != NULL)
+ return;
+
+ if (monitor->immediateto != 0) {
+ g_source_remove(monitor->immediateto);
+ monitor->immediateto = 0;
+ }
+
+ if (monitor->linkloss != NULL)
+ return;
+
+ if (monitor->attioid != 0) {
+ btd_device_remove_attio_callback(device, monitor->attioid);
+ monitor->attioid = 0;
+ }
+
+ if (monitor->attrib != NULL) {
+ g_attrib_unref(monitor->attrib);
+ monitor->attrib = NULL;
+ }
+
g_dbus_unregister_interface(btd_get_dbus_connection(), path,
PROXIMITY_INTERFACE);
}
+
+void monitor_unregister_linkloss(struct btd_device *device)
+{
+ struct monitor *monitor;
+
+ monitor = find_monitor(device);
+ if (monitor == NULL)
+ return;
+
+ g_free(monitor->linkloss);
+ monitor->linkloss = NULL;
+ monitor->enabled.linkloss = FALSE;
+
+ cleanup_monitor(monitor);
+}
+
+void monitor_unregister_txpower(struct btd_device *device)
+{
+ struct monitor *monitor;
+
+ monitor = find_monitor(device);
+ if (monitor == NULL)
+ return;
+
+ g_free(monitor->txpower);
+ monitor->txpower = NULL;
+ monitor->enabled.pathloss = FALSE;
+
+ cleanup_monitor(monitor);
+}
+
+void monitor_unregister_immediate(struct btd_device *device)
+{
+ struct monitor *monitor;
+
+ monitor = find_monitor(device);
+ if (monitor == NULL)
+ return;
+
+ g_free(monitor->immediate);
+ monitor->immediate = NULL;
+ monitor->enabled.findme = FALSE;
+ monitor->enabled.pathloss = FALSE;
+
+ cleanup_monitor(monitor);
+}
diff --git a/profiles/proximity/monitor.h b/profiles/proximity/monitor.h
index 191b562..d9a40c6 100644
--- a/profiles/proximity/monitor.h
+++ b/profiles/proximity/monitor.h
@@ -28,7 +28,16 @@ struct enabled {
gboolean findme;
};

-int monitor_register(struct btd_device *device, struct gatt_primary *linkloss,
- struct gatt_primary *txpower, struct gatt_primary *immediate,
- struct enabled *enabled);
-void monitor_unregister(struct btd_device *device);
+int monitor_register_linkloss(struct btd_device *device,
+ struct enabled *enabled,
+ struct gatt_primary *linkloss);
+int monitor_register_txpower(struct btd_device *device,
+ struct enabled *enabled,
+ struct gatt_primary *txpower);
+int monitor_register_immediate(struct btd_device *device,
+ struct enabled *enabled,
+ struct gatt_primary *immediate);
+
+void monitor_unregister_linkloss(struct btd_device *device);
+void monitor_unregister_txpower(struct btd_device *device);
+void monitor_unregister_immediate(struct btd_device *device);
--
1.8.1


2013-03-01 13:59:08

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 2/7] audio: Split AVRCP into two btd_profile

From: Mikel Astiz <[email protected]>

Register a separate btd_profile for each role of AVRCP.
---
profiles/audio/avrcp.c | 80 +++++++++++++++++++++++++++++++++++++-----------
profiles/audio/avrcp.h | 6 ++--
profiles/audio/manager.c | 71 ++++++++++++++++++++++++++++++------------
3 files changed, 118 insertions(+), 39 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 836ba9b..108fe4b 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -2785,41 +2785,63 @@ static struct avrcp_server *avrcp_server_register(struct btd_adapter *adapter,
return server;
}

-int avrcp_register(struct btd_adapter *adapter, GKeyFile *config)
+int avrcp_target_register(struct btd_adapter *adapter, GKeyFile *config)
{
sdp_record_t *record;
struct avrcp_server *server;

+ server = find_server(servers, adapter);
+ if (server != NULL)
+ goto done;
+
server = avrcp_server_register(adapter, config);
if (server == NULL)
return -EPROTONOSUPPORT;

+done:
record = avrcp_tg_record();
if (!record) {
error("Unable to allocate new service record");
- avrcp_unregister(adapter);
+ avrcp_target_unregister(adapter);
return -1;
}

if (add_record_to_server(adapter_get_address(adapter), record) < 0) {
error("Unable to register AVRCP target service record");
- avrcp_unregister(adapter);
+ avrcp_target_unregister(adapter);
sdp_record_free(record);
return -1;
}
server->tg_record_id = record->handle;

+ return 0;
+}
+
+int avrcp_remote_register(struct btd_adapter *adapter, GKeyFile *config)
+{
+ sdp_record_t *record;
+ struct avrcp_server *server;
+
+ server = find_server(servers, adapter);
+ if (server != NULL)
+ goto done;
+
+ server = avrcp_server_register(adapter, config);
+ if (server == NULL)
+ return -EPROTONOSUPPORT;
+
+done:
record = avrcp_ct_record();
if (!record) {
error("Unable to allocate new service record");
- avrcp_unregister(adapter);
+ avrcp_remote_unregister(adapter);
return -1;
}

if (add_record_to_server(adapter_get_address(adapter), record) < 0) {
error("Unable to register AVRCP service record");
sdp_record_free(record);
- avrcp_unregister(adapter);
+ avrcp_remote_unregister(adapter);
return -1;
}
server->ct_record_id = record->handle;
@@ -2827,25 +2849,13 @@ int avrcp_register(struct btd_adapter *adapter, GKeyFile *config)
return 0;
}

-void avrcp_unregister(struct btd_adapter *adapter)
+static void avrcp_server_unregister(struct avrcp_server *server)
{
- struct avrcp_server *server;
-
- server = find_server(servers, adapter);
- if (!server)
- return;
-
g_slist_free_full(server->sessions, g_free);
g_slist_free_full(server->players, player_destroy);

servers = g_slist_remove(servers, server);

- if (server->ct_record_id != 0)
- remove_record_from_server(server->ct_record_id);
-
- if (server->tg_record_id != 0)
- remove_record_from_server(server->tg_record_id);
-
avctp_unregister(server->adapter);
btd_adapter_unref(server->adapter);
g_free(server);
@@ -2859,6 +2869,40 @@ void avrcp_unregister(struct btd_adapter *adapter)
}
}

+void avrcp_target_unregister(struct btd_adapter *adapter)
+{
+ struct avrcp_server *server;
+
+ server = find_server(servers, adapter);
+ if (!server)
+ return;
+
+ if (server->tg_record_id != 0) {
+ remove_record_from_server(server->tg_record_id);
+ server->tg_record_id = 0;
+ }
+
+ if (server->ct_record_id == 0)
+ avrcp_server_unregister(server);
+}
+
+void avrcp_remote_unregister(struct btd_adapter *adapter)
+{
+ struct avrcp_server *server;
+
+ server = find_server(servers, adapter);
+ if (!server)
+ return;
+
+ if (server->ct_record_id != 0) {
+ remove_record_from_server(server->ct_record_id);
+ server->ct_record_id = 0;
+ }
+
+ if (server->tg_record_id == 0)
+ avrcp_server_unregister(server);
+}
+
struct avrcp_player *avrcp_register_player(struct btd_adapter *adapter,
struct avrcp_player_cb *cb,
void *user_data,
diff --git a/profiles/audio/avrcp.h b/profiles/audio/avrcp.h
index 3799da1..1f98090 100644
--- a/profiles/audio/avrcp.h
+++ b/profiles/audio/avrcp.h
@@ -93,8 +93,10 @@ struct avrcp_player_cb {
void *user_data);
};

-int avrcp_register(struct btd_adapter *adapter, GKeyFile *config);
-void avrcp_unregister(struct btd_adapter *adapter);
+int avrcp_target_register(struct btd_adapter *adapter, GKeyFile *config);
+void avrcp_target_unregister(struct btd_adapter *adapter);
+int avrcp_remote_register(struct btd_adapter *adapter, GKeyFile *config);
+void avrcp_remote_unregister(struct btd_adapter *adapter);

gboolean avrcp_connect(struct audio_device *dev);
void avrcp_disconnect(struct audio_device *dev);
diff --git a/profiles/audio/manager.c b/profiles/audio/manager.c
index 934227e..3023249 100644
--- a/profiles/audio/manager.c
+++ b/profiles/audio/manager.c
@@ -229,7 +229,7 @@ static int a2dp_sink_disconnect(struct btd_device *dev,
return sink_disconnect(audio_dev, FALSE);
}

-static int avrcp_control_connect(struct btd_device *dev,
+static int avrcp_target_connect(struct btd_device *dev,
struct btd_profile *profile)
{
const char *path = device_get_path(dev);
@@ -246,7 +246,7 @@ static int avrcp_control_connect(struct btd_device *dev,
return control_connect(audio_dev);
}

-static int avrcp_control_disconnect(struct btd_device *dev,
+static int avrcp_target_disconnect(struct btd_device *dev,
struct btd_profile *profile)
{
const char *path = device_get_path(dev);
@@ -295,20 +295,36 @@ static void a2dp_sink_server_remove(struct btd_profile *p,
a2dp_sink_unregister(adapter);
}

-static int avrcp_server_probe(struct btd_profile *p,
+static int avrcp_target_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
DBG("path %s", adapter_get_path(adapter));

- return avrcp_register(adapter, config);
+ return avrcp_target_register(adapter, config);
}

-static void avrcp_server_remove(struct btd_profile *p,
+static int avrcp_remote_server_probe(struct btd_profile *p,
struct btd_adapter *adapter)
{
DBG("path %s", adapter_get_path(adapter));

- return avrcp_unregister(adapter);
+ return avrcp_remote_register(adapter, config);
+}
+
+static void avrcp_target_server_remove(struct btd_profile *p,
+ struct btd_adapter *adapter)
+{
+ DBG("path %s", adapter_get_path(adapter));
+
+ avrcp_target_unregister(adapter);
+}
+
+static void avrcp_remote_server_remove(struct btd_profile *p,
+ struct btd_adapter *adapter)
+{
+ DBG("path %s", adapter_get_path(adapter));
+
+ avrcp_remote_unregister(adapter);
}

static int media_server_probe(struct btd_adapter *adapter)
@@ -357,19 +373,30 @@ static struct btd_profile a2dp_sink_profile = {
.adapter_remove = a2dp_sink_server_remove,
};

-static struct btd_profile avrcp_profile = {
- .name = "audio-avrcp",
+static struct btd_profile avrcp_target_profile = {
+ .name = "audio-avrcp-target",

- .remote_uuids = BTD_UUIDS(AVRCP_TARGET_UUID, AVRCP_REMOTE_UUID),
+ .remote_uuids = BTD_UUIDS(AVRCP_TARGET_UUID),
.device_probe = avrcp_probe,
.device_remove = audio_remove,

.auto_connect = true,
- .connect = avrcp_control_connect,
- .disconnect = avrcp_control_disconnect,
+ .connect = avrcp_target_connect,
+ .disconnect = avrcp_target_disconnect,
+
+ .adapter_probe = avrcp_target_server_probe,
+ .adapter_remove = avrcp_target_server_remove,
+};
+
+static struct btd_profile avrcp_remote_profile = {
+ .name = "audio-avrcp-control",

- .adapter_probe = avrcp_server_probe,
- .adapter_remove = avrcp_server_remove,
+ .remote_uuids = BTD_UUIDS(AVRCP_REMOTE_UUID),
+ .device_probe = avrcp_probe,
+ .device_remove = audio_remove,
+
+ .adapter_probe = avrcp_remote_server_probe,
+ .adapter_remove = avrcp_remote_server_remove,
};

static struct btd_adapter_driver media_driver = {
@@ -400,12 +427,14 @@ void audio_source_disconnected(struct btd_device *dev, int err)

void audio_control_connected(struct btd_device *dev, int err)
{
- device_profile_connected(dev, &avrcp_profile, err);
+ device_profile_connected(dev, &avrcp_target_profile, err);
+ device_profile_connected(dev, &avrcp_remote_profile, err);
}

void audio_control_disconnected(struct btd_device *dev, int err)
{
- device_profile_disconnected(dev, &avrcp_profile, err);
+ device_profile_disconnected(dev, &avrcp_target_profile, err);
+ device_profile_disconnected(dev, &avrcp_remote_profile, err);
}

int audio_manager_init(GKeyFile *conf)
@@ -449,8 +478,10 @@ proceed:
if (enabled.sink)
btd_profile_register(&a2dp_sink_profile);

- if (enabled.control)
- btd_profile_register(&avrcp_profile);
+ if (enabled.control) {
+ btd_profile_register(&avrcp_remote_profile);
+ btd_profile_register(&avrcp_target_profile);
+ }

btd_register_adapter_driver(&media_driver);

@@ -470,8 +501,10 @@ void audio_manager_exit(void)
if (enabled.sink)
btd_profile_unregister(&a2dp_sink_profile);

- if (enabled.control)
- btd_profile_unregister(&avrcp_profile);
+ if (enabled.control) {
+ btd_profile_unregister(&avrcp_remote_profile);
+ btd_profile_unregister(&avrcp_target_profile);
+ }

btd_unregister_adapter_driver(&media_driver);
}
--
1.8.1


2013-03-01 13:59:07

by Mikel Astiz

[permalink] [raw]
Subject: [RFC v2 1/7] avrcp: Refactor server registration

From: Mikel Astiz <[email protected]>

Use a helper function to install the AVRCP server, just like other audio
profiles such as in a2dp.c do.
---
profiles/audio/avrcp.c | 54 ++++++++++++++++++++++++++++++--------------------
1 file changed, 32 insertions(+), 22 deletions(-)

diff --git a/profiles/audio/avrcp.c b/profiles/audio/avrcp.c
index 9be977e..836ba9b 100644
--- a/profiles/audio/avrcp.c
+++ b/profiles/audio/avrcp.c
@@ -2754,9 +2754,9 @@ void avrcp_disconnect(struct audio_device *dev)
avctp_disconnect(session);
}

-int avrcp_register(struct btd_adapter *adapter, GKeyFile *config)
+static struct avrcp_server *avrcp_server_register(struct btd_adapter *adapter,
+ GKeyFile *config)
{
- sdp_record_t *record;
gboolean tmp, master = TRUE;
GError *err = NULL;
struct avrcp_server *server;
@@ -2771,18 +2771,39 @@ int avrcp_register(struct btd_adapter *adapter, GKeyFile *config)
master = tmp;
}

+ if (avctp_register(adapter, master) < 0)
+ return NULL;
+
server = g_new0(struct avrcp_server, 1);
+ server->adapter = btd_adapter_ref(adapter);
+
+ servers = g_slist_append(servers, server);
+
+ if (!avctp_id)
+ avctp_id = avctp_add_state_cb(state_changed, NULL);
+
+ return server;
+}
+
+int avrcp_register(struct btd_adapter *adapter, GKeyFile *config)
+{
+ sdp_record_t *record;
+ struct avrcp_server *server;
+
+ server = avrcp_server_register(adapter, config);
+ if (server == NULL)
+ return -EPROTONOSUPPORT;

record = avrcp_tg_record();
if (!record) {
error("Unable to allocate new service record");
- g_free(server);
+ avrcp_unregister(adapter);
return -1;
}

if (add_record_to_server(adapter_get_address(adapter), record) < 0) {
error("Unable to register AVRCP target service record");
- g_free(server);
+ avrcp_unregister(adapter);
sdp_record_free(record);
return -1;
}
@@ -2791,32 +2812,18 @@ int avrcp_register(struct btd_adapter *adapter, GKeyFile *config)
record = avrcp_ct_record();
if (!record) {
error("Unable to allocate new service record");
- g_free(server);
+ avrcp_unregister(adapter);
return -1;
}

if (add_record_to_server(adapter_get_address(adapter), record) < 0) {
error("Unable to register AVRCP service record");
sdp_record_free(record);
- g_free(server);
+ avrcp_unregister(adapter);
return -1;
}
server->ct_record_id = record->handle;

- if (avctp_register(adapter, master) < 0) {
- remove_record_from_server(server->ct_record_id);
- remove_record_from_server(server->tg_record_id);
- g_free(server);
- return -1;
- }
-
- server->adapter = btd_adapter_ref(adapter);
-
- servers = g_slist_append(servers, server);
-
- if (!avctp_id)
- avctp_id = avctp_add_state_cb(state_changed, NULL);
-
return 0;
}

@@ -2833,8 +2840,11 @@ void avrcp_unregister(struct btd_adapter *adapter)

servers = g_slist_remove(servers, server);

- remove_record_from_server(server->ct_record_id);
- remove_record_from_server(server->tg_record_id);
+ if (server->ct_record_id != 0)
+ remove_record_from_server(server->ct_record_id);
+
+ if (server->tg_record_id != 0)
+ remove_record_from_server(server->tg_record_id);

avctp_unregister(server->adapter);
btd_adapter_unref(server->adapter);
--
1.8.1