From: Arman Uguray <armansito@chromium.org>
To: linux-bluetooth@vger.kernel.org
Cc: Arman Uguray <armansito@chromium.org>
Subject: [PATCH BlueZ v3 4/8] profiles/gap: Fix probe/accept behavior.
Date: Tue, 13 Jan 2015 19:31:03 -0800 [thread overview]
Message-ID: <1421206267-26369-5-git-send-email-armansito@chromium.org> (raw)
In-Reply-To: <1421206267-26369-1-git-send-email-armansito@chromium.org>
This patch fixes the GAP profile so that it assumes that there will be
one btd_service instance per-device rather than per-service-per-device.
---
profiles/gap/gas.c | 127 ++++++++++++++++++++++++++++++-----------------------
1 file changed, 71 insertions(+), 56 deletions(-)
diff --git a/profiles/gap/gas.c b/profiles/gap/gas.c
index 01b6ec2..7d81592 100644
--- a/profiles/gap/gas.c
+++ b/profiles/gap/gas.c
@@ -43,21 +43,25 @@
#include "src/service.h"
#include "src/log.h"
+#define GAP_UUID16 0x1800
+
/* Generic Attribute/Access Service */
struct gas {
struct btd_device *device;
struct gatt_db *db;
+ unsigned int db_id;
struct bt_gatt_client *client;
- uint16_t start_handle, end_handle;
+ struct gatt_db_attribute *attr;
};
static GSList *devices;
static void gas_free(struct gas *gas)
{
- btd_device_unref(gas->device);
+ gatt_db_unregister(gas->db, gas->db_id);
gatt_db_unref(gas->db);
bt_gatt_client_unref(gas->client);
+ btd_device_unref(gas->device);
g_free(gas);
}
@@ -183,48 +187,31 @@ static void handle_characteristic(struct gatt_db_attribute *attr,
static void handle_gap_service(struct gas *gas)
{
- struct gatt_db_attribute *attr;
-
- attr = gatt_db_get_attribute(gas->db, gas->start_handle);
- if (!attr) {
- error("Service with handle 0x%04x not found in db",
- gas->start_handle);
- return;
- }
-
- gatt_db_service_foreach_char(attr, handle_characteristic, gas);
+ gatt_db_service_foreach_char(gas->attr, handle_characteristic, gas);
}
static int gap_driver_probe(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
struct gas *gas;
- uint16_t start_handle, end_handle;
GSList *l;
char addr[18];
- if (!btd_service_get_gatt_handles(service, &start_handle, &end_handle))
- return -1;
-
ba2str(device_get_address(device), addr);
- DBG("GAP profile probe (%s): start: 0x%04x, end 0x%04x", addr,
- start_handle, end_handle);
+ DBG("GAP profile probe (%s)", addr);
- /*
- * There can't be more than one instance of the GAP service on the same
- * device.
- */
+ /* Ignore, if we were probed for this device already */
l = g_slist_find_custom(devices, device, cmp_device);
if (l) {
- error("More than one GAP service exists on device");
+ error("Profile probed twice for the same device!");
return -1;
}
gas = g_new0(struct gas, 1);
+ if (!gas)
+ return -1;
gas->device = btd_device_ref(device);
- gas->start_handle = start_handle;
- gas->end_handle = end_handle;
devices = g_slist_append(devices, gas);
return 0;
@@ -234,19 +221,11 @@ static void gap_driver_remove(struct btd_service *service)
{
struct btd_device *device = btd_service_get_device(service);
struct gas *gas;
- uint16_t start_handle, end_handle;
GSList *l;
char addr[18];
- if (!btd_service_get_gatt_handles(service, &start_handle,
- &end_handle)) {
- error("Removed service is not a GATT service");
- return;
- }
-
ba2str(device_get_address(device), addr);
- DBG("GAP profile remove (%s): start: 0x%04x, end 0x%04x", addr,
- start_handle, end_handle);
+ DBG("GAP profile remove (%s)", addr);
l = g_slist_find_custom(devices, device, cmp_device);
if (!l) {
@@ -256,14 +235,58 @@ static void gap_driver_remove(struct btd_service *service)
gas = l->data;
- if (gas->start_handle != start_handle ||
- gas->end_handle != end_handle) {
- error("Removed unknown GAP service");
+ devices = g_slist_remove(devices, gas);
+ gas_free(gas);
+}
+
+static void foreach_gap_service(struct gatt_db_attribute *attr, void *user_data)
+{
+ struct gas *gas = user_data;
+
+ if (gas->attr) {
+ error("More than one GAP service exists for this device");
return;
}
- devices = g_slist_remove(devices, gas);
- gas_free(gas);
+ gas->attr = attr;
+ handle_gap_service(gas);
+}
+
+static void service_added(struct gatt_db_attribute *attr, void *user_data)
+{
+ struct gas *gas = user_data;
+ bt_uuid_t uuid, gap_uuid;
+
+ if (!bt_gatt_client_is_ready(gas->client))
+ return;
+
+ gatt_db_attribute_get_service_uuid(attr, &uuid);
+ bt_uuid16_create(&gap_uuid, GAP_UUID16);
+
+ if (bt_uuid_cmp(&uuid, &gap_uuid))
+ return;
+
+ if (gas->attr) {
+ error("More than one GAP service added to device");
+ return;
+ }
+
+ DBG("GAP service added");
+
+ gas->attr = attr;
+ handle_gap_service(gas);
+}
+
+static void service_removed(struct gatt_db_attribute *attr, void *user_data)
+{
+ struct gas *gas = user_data;
+
+ if (gas->attr != attr)
+ return;
+
+ DBG("GAP service removed");
+
+ gas->attr = NULL;
}
static int gap_driver_accept(struct btd_service *service)
@@ -272,19 +295,12 @@ static int gap_driver_accept(struct btd_service *service)
struct gatt_db *db = btd_device_get_gatt_db(device);
struct bt_gatt_client *client = btd_device_get_gatt_client(device);
struct gas *gas;
- uint16_t start_handle, end_handle;
GSList *l;
char addr[18];
-
- if (!btd_service_get_gatt_handles(service, &start_handle,
- &end_handle)) {
- error("Service is not a GATT service");
- return -1;
- }
+ bt_uuid_t gap_uuid;
ba2str(device_get_address(device), addr);
- DBG("GAP profile accept (%s): start: 0x%04x, end 0x%04x", addr,
- start_handle, end_handle);
+ DBG("GAP profile accept (%s)", addr);
l = g_slist_find_custom(devices, device, cmp_device);
if (!l) {
@@ -294,21 +310,20 @@ static int gap_driver_accept(struct btd_service *service)
gas = l->data;
- if (gas->start_handle != start_handle ||
- gas->end_handle != end_handle) {
- error("Accepting unknown GAP service");
- return -1;
- }
-
/* Clean-up any old client/db and acquire the new ones */
+ gas->attr = NULL;
+ gatt_db_unregister(gas->db, gas->db_id);
gatt_db_unref(gas->db);
bt_gatt_client_unref(gas->client);
gas->db = gatt_db_ref(db);
gas->client = bt_gatt_client_ref(client);
+ gas->db_id = gatt_db_register(db, service_added, service_removed, gas,
+ NULL);
- /* Handle the service */
- handle_gap_service(gas);
+ /* Handle the GAP services */
+ bt_uuid16_create(&gap_uuid, GAP_UUID16);
+ gatt_db_foreach_service(db, &gap_uuid, foreach_gap_service, gas);
return 0;
}
--
2.2.0.rc0.207.ga3a616c
next prev parent reply other threads:[~2015-01-14 3:31 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2015-01-14 3:30 [PATCH BlueZ v3 0/8] Implement doc/gatt-api.txt for client Arman Uguray
2015-01-14 3:31 ` [PATCH BlueZ v3 1/8] shared/gatt-db: Add service getter by UUID Arman Uguray
2015-01-14 3:31 ` [PATCH BlueZ v3 2/8] core: device: Fix GATT profile probing Arman Uguray
2015-01-14 3:31 ` [PATCH BlueZ v3 3/8] core: device: Fix broken GATT UUID management Arman Uguray
2015-01-14 13:17 ` Luiz Augusto von Dentz
2015-01-14 19:38 ` Arman Uguray
2015-01-16 0:58 ` Arman Uguray
2015-01-16 8:53 ` Luiz Augusto von Dentz
2015-01-14 3:31 ` Arman Uguray [this message]
2015-01-14 3:31 ` [PATCH BlueZ v3 5/8] core: service: Remove GATT handle logic Arman Uguray
2015-01-14 3:31 ` [PATCH BlueZ v3 6/8] shared/gatt-db: Add "claimed" field to services Arman Uguray
2015-01-14 3:31 ` [PATCH BlueZ v3 7/8] core: gatt: Use "claimed" instead of "active" Arman Uguray
2015-01-14 3:31 ` [PATCH BlueZ v3 8/8] doc/gatt-api.txt: Update error names Arman Uguray
2015-01-16 14:21 ` [PATCH BlueZ v3 0/8] Implement doc/gatt-api.txt for client Luiz Augusto von Dentz
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1421206267-26369-5-git-send-email-armansito@chromium.org \
--to=armansito@chromium.org \
--cc=linux-bluetooth@vger.kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).