linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/9] Register primary services exported over basic rate
@ 2011-04-07 17:30 Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 2/9] Cleanup primary service registration from storage Claudio Takahasi
                   ` (8 more replies)
  0 siblings, 9 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch registers the object paths for primary services exported
through SDP. PSM, start and end handle information are available in
the Protocol Descriptor List.
---
 src/device.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 files changed, 129 insertions(+), 1 deletions(-)

diff --git a/src/device.c b/src/device.c
index d567952..32eb643 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1367,6 +1367,127 @@ static void create_device_reply(struct btd_device *device, struct browse_req *re
 	g_dbus_send_message(req->conn, reply);
 }
 
+static sdp_data_t *proto_seq_find(sdp_list_t *proto_list)
+{
+	sdp_list_t *list;
+	uuid_t proto;
+
+	sdp_uuid16_create(&proto, ATT_UUID);
+
+	for (;list = proto_list, list; list = list->next) {
+		sdp_list_t *p;
+		for (p = list->data; p; p = p->next) {
+			sdp_data_t *seq = p->data;
+			if (seq && seq->dtd == SDP_UUID16 &&
+				sdp_uuid16_cmp(&proto, &seq->val.uuid) == 0)
+				return seq->next;
+		}
+	}
+
+	return NULL;
+}
+
+static gboolean parse_proto_params(sdp_list_t *proto_list, uint16_t *psm,
+						uint16_t *start, uint16_t *end)
+{
+	sdp_data_t *seq1, *seq2;
+
+	if (psm)
+		*psm = sdp_get_proto_port(proto_list, L2CAP_UUID);
+
+	/* Getting start and end handle */
+	seq1 = proto_seq_find(proto_list);
+	if (!seq1 || seq1->dtd != SDP_UINT16)
+		return FALSE;
+
+	seq2 = seq1->next;
+	if (!seq2 || seq2->dtd != SDP_UINT16)
+		return FALSE;
+
+	if (start)
+		*start = seq1->val.uint16;
+
+	if (end)
+		*end = seq2->val.uint16;
+
+	return TRUE;
+}
+
+static gboolean parse_primary_record(const sdp_record_t *rec,
+					uuid_t *prim_uuid, uint16_t *psm,
+					uint16_t *start, uint16_t *end)
+{
+	sdp_list_t *list;
+	uuid_t uuid;
+	gboolean ret;
+
+	if (sdp_get_service_classes(rec, &list) < 0)
+		return FALSE;
+
+	memcpy(&uuid, list->data, sizeof(uuid));
+	sdp_list_free(list, free);
+
+	if (sdp_get_access_protos(rec, &list) < 0)
+		return FALSE;
+
+	ret = parse_proto_params(list, psm, start, end);
+
+	sdp_list_foreach(list, (sdp_list_func_t) sdp_list_free, NULL);
+	sdp_list_free(list, NULL);
+
+	if (ret && prim_uuid)
+		memcpy(prim_uuid, &uuid, sizeof(uuid_t));
+
+	return ret;
+}
+
+static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
+{
+	GSList *l, *prim_list = NULL;
+	char *att_uuid;
+	uuid_t proto_uuid;
+
+	sdp_uuid16_create(&proto_uuid, ATT_UUID);
+	att_uuid = bt_uuid2string(&proto_uuid);
+
+	for (l = profiles; l; l = l->next) {
+		const char *profile_uuid = l->data;
+		const sdp_record_t *rec;
+		struct att_primary *prim;
+		uint16_t start = 0, end = 0, psm = 0;
+		uuid_t prim_uuid;
+
+		rec = btd_device_get_record(device, profile_uuid);
+		if (!rec)
+			continue;
+
+		if (!record_has_uuid(rec, att_uuid))
+			continue;
+
+		if (!parse_primary_record(rec, &prim_uuid, &psm, &start, &end))
+			continue;
+
+		prim = g_new0(struct att_primary, 1);
+		prim->start = start;
+		prim->end = end;
+		sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
+
+		prim_list = g_slist_append(prim_list, prim);
+	}
+
+	g_free(att_uuid);
+
+	return prim_list;
+}
+
+static void register_primary_services(DBusConnection *conn,
+				struct btd_device *device, GSList *prim_list)
+{
+	/* TODO: PSM is hardcoded */
+	attrib_client_register(conn, device, 31, NULL, prim_list);
+	device->primaries = g_slist_concat(device->primaries, prim_list);
+}
+
 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 {
 	struct browse_req *req = user_data;
@@ -1396,9 +1517,16 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 	}
 
 	/* Probe matching drivers for services added */
-	if (req->profiles_added)
+	if (req->profiles_added) {
+		GSList *list;
+
 		device_probe_drivers(device, req->profiles_added);
 
+		list = primary_from_record(device, req->profiles_added);
+		if (list)
+			register_primary_services(req->conn, device, list);
+	}
+
 	/* Remove drivers for services removed */
 	if (req->profiles_removed)
 		device_remove_drivers(device, req->profiles_removed);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 2/9] Cleanup primary service registration from storage
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:24   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 3/9] Remove btd_device_add_service function Claudio Takahasi
                   ` (7 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/adapter.c |    9 +--------
 src/device.c  |   20 ++++++--------------
 src/device.h  |    4 ++--
 3 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index c400bfd..6caff9a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -58,8 +58,6 @@
 #include "storage.h"
 #include "attrib-server.h"
 #include "att.h"
-#include "gattrib.h"
-#include "attrib/client.h"
 
 /* Interleaved discovery window: 5.12 sec */
 #define GAP_INTER_DISCOV_WIN		5120
@@ -2193,16 +2191,11 @@ static void create_stored_device_from_primary(char *key, char *value,
 	for (l = services, uuids = NULL; l; l = l->next) {
 		struct att_primary *prim = l->data;
 		uuids = g_slist_append(uuids, prim->uuid);
-
-		device_add_primary(device, prim);
 	}
 
-	/* FIXME: Need the correct psm */
-	attrib_client_register(connection, device, -1, NULL, services);
-
 	device_probe_drivers(device, uuids);
+	device_register_services(connection, device, services, -1);
 
-	g_slist_free(services);
 	g_slist_free(uuids);
 }
 
diff --git a/src/device.c b/src/device.c
index 32eb643..b6750b6 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1480,14 +1480,6 @@ static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
 	return prim_list;
 }
 
-static void register_primary_services(DBusConnection *conn,
-				struct btd_device *device, GSList *prim_list)
-{
-	/* TODO: PSM is hardcoded */
-	attrib_client_register(conn, device, 31, NULL, prim_list);
-	device->primaries = g_slist_concat(device->primaries, prim_list);
-}
-
 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 {
 	struct browse_req *req = user_data;
@@ -1524,7 +1516,7 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 
 		list = primary_from_record(device, req->profiles_added);
 		if (list)
-			register_primary_services(req->conn, device, list);
+			device_register_services(req->conn, device, list, 31);
 	}
 
 	/* Remove drivers for services removed */
@@ -1666,13 +1658,11 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 	for (l = services; l; l = l->next) {
 		struct att_primary *prim = l->data;
 		uuids = g_slist_append(uuids, prim->uuid);
-		device_add_primary(device, prim);
 	}
 
 	device_probe_drivers(device, uuids);
 
-	/* FIXME: Need the correct psm */
-	attrib_client_register(req->conn, device, -1, req->attrib, services);
+	device_register_services(req->conn, device, services, -1);
 
 	g_slist_free(uuids);
 
@@ -2428,9 +2418,11 @@ void btd_device_add_service(struct btd_device *device, const char *path)
 	device->services = g_slist_append(device->services, g_strdup(path));
 }
 
-void device_add_primary(struct btd_device *device, struct att_primary *prim)
+void device_register_services(DBusConnection *conn, struct btd_device *device,
+						GSList *prim_list, int psm)
 {
-	device->primaries = g_slist_append(device->primaries, prim);
+	attrib_client_register(conn, device, psm, NULL, prim_list);
+	device->primaries = g_slist_concat(device->primaries, prim_list);
 }
 
 GSList *btd_device_get_primaries(struct btd_device *device)
diff --git a/src/device.h b/src/device.h
index 3ce212b..285364f 100644
--- a/src/device.h
+++ b/src/device.h
@@ -25,7 +25,6 @@
 #define DEVICE_INTERFACE	"org.bluez.Device"
 
 struct btd_device;
-struct att_primary;
 
 typedef enum {
 	AUTH_TYPE_PINCODE,
@@ -58,7 +57,8 @@ const sdp_record_t *btd_device_get_record(struct btd_device *device,
 						const char *uuid);
 GSList *btd_device_get_primaries(struct btd_device *device);
 void btd_device_add_service(struct btd_device *device, const char *path);
-void device_add_primary(struct btd_device *device, struct att_primary *prim);
+void device_register_services(DBusConnection *conn, struct btd_device *device,
+						GSList *prim_list, int psm);
 void btd_device_add_uuid(struct btd_device *device, const char *uuid);
 struct btd_adapter *device_get_adapter(struct btd_device *device);
 void device_get_address(struct btd_device *device, bdaddr_t *bdaddr);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 3/9] Remove btd_device_add_service function
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 2/9] Cleanup primary service registration from storage Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:24   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 4/9] Move the primary service storage code to a local function Claudio Takahasi
                   ` (6 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

btd_device_add_service is no longer necessary if the object paths for
the primary services can be returned during the registration.
---
 attrib/client.c |   16 ++++++++--------
 attrib/client.h |    2 +-
 src/device.c    |   11 ++---------
 src/device.h    |    1 -
 4 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 28e5704..2dd70c9 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -1020,11 +1020,11 @@ static GDBusMethodTable prim_methods[] = {
 	{ }
 };
 
-static void register_primaries(struct gatt_service *gatt, GSList *primaries)
+static GSList *register_primaries(struct gatt_service *gatt, GSList *primaries)
 {
-	GSList *l;
+	GSList *l, *paths;
 
-	for (l = primaries; l; l = l->next) {
+	for (paths = NULL, l = primaries; l; l = l->next) {
 		struct att_primary *att = l->data;
 		struct primary *prim;
 
@@ -1040,12 +1040,14 @@ static void register_primaries(struct gatt_service *gatt, GSList *primaries)
 		DBG("Registered: %s", prim->path);
 
 		gatt->primary = g_slist_append(gatt->primary, prim);
-		btd_device_add_service(gatt->dev, prim->path);
+		paths = g_slist_append(paths, g_strdup(prim->path));
 		load_characteristics(prim, gatt);
 	}
+
+	return paths;
 }
 
-int attrib_client_register(DBusConnection *connection,
+GSList *attrib_client_register(DBusConnection *connection,
 					struct btd_device *device, int psm,
 					GAttrib *attrib, GSList *primaries)
 {
@@ -1069,11 +1071,9 @@ int attrib_client_register(DBusConnection *connection,
 	if (attrib)
 		gatt->attrib = g_attrib_ref(attrib);
 
-	register_primaries(gatt, primaries);
-
 	gatt_services = g_slist_append(gatt_services, gatt);
 
-	return 0;
+	return register_primaries(gatt, primaries);
 }
 
 void attrib_client_unregister(struct btd_device *device)
diff --git a/attrib/client.h b/attrib/client.h
index b4a4ecc..b29797c 100644
--- a/attrib/client.h
+++ b/attrib/client.h
@@ -22,7 +22,7 @@
  *
  */
 
-int attrib_client_register(DBusConnection *connection,
+GSList *attrib_client_register(DBusConnection *connection,
 					struct btd_device *device, int psm,
 					GAttrib *attrib, GSList *primaries);
 void attrib_client_unregister(struct btd_device *device);
diff --git a/src/device.c b/src/device.c
index b6750b6..d1ed05a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2410,18 +2410,11 @@ void device_set_authorizing(struct btd_device *device, gboolean auth)
 	device->authorizing = auth;
 }
 
-void btd_device_add_service(struct btd_device *device, const char *path)
-{
-	if (g_slist_find_custom(device->services, path, (GCompareFunc) strcmp))
-		return;
-
-	device->services = g_slist_append(device->services, g_strdup(path));
-}
-
 void device_register_services(DBusConnection *conn, struct btd_device *device,
 						GSList *prim_list, int psm)
 {
-	attrib_client_register(conn, device, psm, NULL, prim_list);
+	device->services = attrib_client_register(conn, device, psm, NULL,
+								prim_list);
 	device->primaries = g_slist_concat(device->primaries, prim_list);
 }
 
diff --git a/src/device.h b/src/device.h
index 285364f..2432884 100644
--- a/src/device.h
+++ b/src/device.h
@@ -56,7 +56,6 @@ void device_probe_drivers(struct btd_device *device, GSList *profiles);
 const sdp_record_t *btd_device_get_record(struct btd_device *device,
 						const char *uuid);
 GSList *btd_device_get_primaries(struct btd_device *device);
-void btd_device_add_service(struct btd_device *device, const char *path);
 void device_register_services(DBusConnection *conn, struct btd_device *device,
 						GSList *prim_list, int psm);
 void btd_device_add_uuid(struct btd_device *device, const char *uuid);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 4/9] Move the primary service storage code to a local function
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 2/9] Cleanup primary service registration from storage Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 3/9] Remove btd_device_add_service function Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:25   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 5/9] Fix device type when creating from primary services storage Claudio Takahasi
                   ` (5 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/device.c |   27 ++++++++++++++++-----------
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/src/device.c b/src/device.c
index d1ed05a..eecaee0 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1636,14 +1636,26 @@ static char *primary_list_to_string(GSList *primary_list)
 	return g_string_free(services, FALSE);
 }
 
+static void store_services(struct btd_device *device)
+{
+	struct btd_adapter *adapter = device->adapter;
+	bdaddr_t dba, sba;
+	char *str = primary_list_to_string(device->services);
+
+	adapter_get_address(adapter, &sba);
+	device_get_address(device, &dba);
+
+	write_device_type(&sba, &dba, device->type);
+	write_device_services(&sba, &dba, str);
+
+	g_free(str);
+}
+
 static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 {
 	struct browse_req *req = user_data;
 	struct btd_device *device = req->device;
-	struct btd_adapter *adapter = device->adapter;
 	GSList *l, *uuids = NULL;
-	bdaddr_t dba, sba;
-	char *str;
 
 	if (status) {
 		DBusMessage *reply;
@@ -1668,14 +1680,7 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 
 	create_device_reply(device, req);
 
-	str = primary_list_to_string(services);
-
-	adapter_get_address(adapter, &sba);
-	device_get_address(device, &dba);
-
-	write_device_type(&sba, &dba, device->type);
-	write_device_services(&sba, &dba, str);
-	g_free(str);
+	store_services(device);
 
 done:
 	device->browse = NULL;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 5/9] Fix device type when creating from primary services storage
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
                   ` (2 preceding siblings ...)
  2011-04-07 17:30 ` [PATCH 4/9] Move the primary service storage code to a local function Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:25   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 6/9] Fix LE device creation from storage Claudio Takahasi
                   ` (4 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

GATT services exported through basic rate need to be created based
on the "profiles" file. For GATT over LE, "primary" file entries need
to be used to create the devices and primary services objects.
---
 src/adapter.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 6caff9a..8380a58 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2176,7 +2176,7 @@ static void create_stored_device_from_primary(char *key, char *value,
 	if (l)
 		device = l->data;
 	else {
-		device = device_create(connection, adapter, key, DEVICE_TYPE_BREDR);
+		device = device_create(connection, adapter, key, DEVICE_TYPE_LE);
 		if (!device)
 			return;
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 6/9] Fix LE device creation from storage
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
                   ` (3 preceding siblings ...)
  2011-04-07 17:30 ` [PATCH 5/9] Fix device type when creating from primary services storage Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:25   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 7/9] Fix primary services registration from storage for basic rate Claudio Takahasi
                   ` (3 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

Ignore the device if it already created. This patch adds a consistency
check to avoid registering the same service over basic rate and LE.
---
 src/adapter.c |   20 +++++++++-----------
 1 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 8380a58..9a0f688 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2171,18 +2171,16 @@ static void create_stored_device_from_primary(char *key, char *value,
 	struct btd_device *device;
 	GSList *services, *uuids, *l;
 
-	l = g_slist_find_custom(adapter->devices,
-				key, (GCompareFunc) device_address_cmp);
-	if (l)
-		device = l->data;
-	else {
-		device = device_create(connection, adapter, key, DEVICE_TYPE_LE);
-		if (!device)
-			return;
+	if (g_slist_find_custom(adapter->devices,
+			key, (GCompareFunc) device_address_cmp))
+		return;
 
-		device_set_temporary(device, FALSE);
-		adapter->devices = g_slist_append(adapter->devices, device);
-	}
+	device = device_create(connection, adapter, key, DEVICE_TYPE_LE);
+	if (!device)
+		return;
+
+	device_set_temporary(device, FALSE);
+	adapter->devices = g_slist_append(adapter->devices, device);
 
 	services = string_to_primary_list(value);
 	if (services == NULL)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 7/9] Fix primary services registration from storage for basic rate
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
                   ` (4 preceding siblings ...)
  2011-04-07 17:30 ` [PATCH 6/9] Fix LE device creation from storage Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:26   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 8/9] TODO: Remove item related to GATT service over " Claudio Takahasi
                   ` (2 subsequent siblings)
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/adapter.c |    5 ++++-
 src/device.c  |    4 ++--
 src/device.h  |    2 ++
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 9a0f688..7049ba6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2004,7 +2004,7 @@ static void create_stored_device_from_profiles(char *key, char *value,
 						void *user_data)
 {
 	struct btd_adapter *adapter = user_data;
-	GSList *uuids = bt_string2list(value);
+	GSList *list, *uuids = bt_string2list(value);
 	struct btd_device *device;
 
 	if (g_slist_find_custom(adapter->devices,
@@ -2019,6 +2019,9 @@ static void create_stored_device_from_profiles(char *key, char *value,
 	adapter->devices = g_slist_append(adapter->devices, device);
 
 	device_probe_drivers(device, uuids);
+	list = device_services_from_record(device, uuids);
+	if (list)
+		device_register_services(connection, device, list, 31);
 
 	g_slist_foreach(uuids, (GFunc) g_free, NULL);
 	g_slist_free(uuids);
diff --git a/src/device.c b/src/device.c
index eecaee0..4da6579 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1441,7 +1441,7 @@ static gboolean parse_primary_record(const sdp_record_t *rec,
 	return ret;
 }
 
-static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
+GSList *device_services_from_record(struct btd_device *device, GSList *profiles)
 {
 	GSList *l, *prim_list = NULL;
 	char *att_uuid;
@@ -1514,7 +1514,7 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 
 		device_probe_drivers(device, req->profiles_added);
 
-		list = primary_from_record(device, req->profiles_added);
+		list = device_services_from_record(device, req->profiles_added);
 		if (list)
 			device_register_services(req->conn, device, list, 31);
 	}
diff --git a/src/device.h b/src/device.h
index 2432884..370382d 100644
--- a/src/device.h
+++ b/src/device.h
@@ -58,6 +58,8 @@ const sdp_record_t *btd_device_get_record(struct btd_device *device,
 GSList *btd_device_get_primaries(struct btd_device *device);
 void device_register_services(DBusConnection *conn, struct btd_device *device,
 						GSList *prim_list, int psm);
+GSList *device_services_from_record(struct btd_device *device,
+							GSList *profiles);
 void btd_device_add_uuid(struct btd_device *device, const char *uuid);
 struct btd_adapter *device_get_adapter(struct btd_device *device);
 void device_get_address(struct btd_device *device, bdaddr_t *bdaddr);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 8/9] TODO: Remove item related to GATT service over basic rate
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
                   ` (5 preceding siblings ...)
  2011-04-07 17:30 ` [PATCH 7/9] Fix primary services registration from storage for basic rate Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:26   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:30 ` [PATCH 9/9] TODO: Add hard-coded PSM for GATT " Claudio Takahasi
  2011-04-07 17:58 ` [PATCH 1/9] Register primary services exported " Vinicius Costa Gomes
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 TODO |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/TODO b/TODO
index d52808b..461b179 100644
--- a/TODO
+++ b/TODO
@@ -114,16 +114,6 @@ Low Energy
 ATT/GATT
 ========
 
-- For BR/EDR, primary services can be registered based on the information
-  extracted from the service records. UUIDs, start and end handles information
-  are available in the record, Discover All Primary Services procedure is not
-  necessary. If a GATT service doesn't export a service record means that
-  it should not be used over BR/EDR. Don't start this task before to move the
-  attribute client code to the bluetoothd core.
-
-  Priority: Medium
-  Complexity: C1
-
 - At the moment authentication and authorization is not supported at the
   same time, read/write requirements in the attribute server needs to
   be extended. According to Bluetooth Specification a server shall check
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH 9/9] TODO: Add hard-coded PSM for GATT over basic rate
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
                   ` (6 preceding siblings ...)
  2011-04-07 17:30 ` [PATCH 8/9] TODO: Remove item related to GATT service over " Claudio Takahasi
@ 2011-04-07 17:30 ` Claudio Takahasi
  2011-04-11 18:26   ` [PATCH v2 " Claudio Takahasi
  2011-04-07 17:58 ` [PATCH 1/9] Register primary services exported " Vinicius Costa Gomes
  8 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 17:30 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 TODO |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/TODO b/TODO
index 461b179..fab3ec0 100644
--- a/TODO
+++ b/TODO
@@ -136,6 +136,11 @@ ATT/GATT
   Priority: Medium
   Complexity: C1
 
+- Fix hard-coded PSM for GATT services over basic rate.
+
+  Priority: Low
+  Complexity: C1
+
 - Refactor read_by_group() and read_by_type() in src/attrib-server.c
   (they've grown simply too big). First step could be to move out the
   long for-loops to new functions called e.g. get_groups() and get_types().
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/9] Register primary services exported over basic rate
  2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
                   ` (7 preceding siblings ...)
  2011-04-07 17:30 ` [PATCH 9/9] TODO: Add hard-coded PSM for GATT " Claudio Takahasi
@ 2011-04-07 17:58 ` Vinicius Costa Gomes
  2011-04-07 18:15   ` Claudio Takahasi
  8 siblings, 1 reply; 21+ messages in thread
From: Vinicius Costa Gomes @ 2011-04-07 17:58 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth

Hi Claudio,

On 14:30 Thu 07 Apr, Claudio Takahasi wrote:
> This patch registers the object paths for primary services exported
> through SDP. PSM, start and end handle information are available in
> the Protocol Descriptor List.
> ---
>  src/device.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>  1 files changed, 129 insertions(+), 1 deletions(-)
> 
> diff --git a/src/device.c b/src/device.c
> index d567952..32eb643 100644
> --- a/src/device.c
> +++ b/src/device.c
> @@ -1367,6 +1367,127 @@ static void create_device_reply(struct btd_device *device, struct browse_req *re
>  	g_dbus_send_message(req->conn, reply);
>  }
>  
> +static sdp_data_t *proto_seq_find(sdp_list_t *proto_list)
> +{
> +	sdp_list_t *list;
> +	uuid_t proto;
> +
> +	sdp_uuid16_create(&proto, ATT_UUID);
> +
> +	for (;list = proto_list, list; list = list->next) {

The first ";" doesn't look right.

> +		sdp_list_t *p;
> +		for (p = list->data; p; p = p->next) {
> +			sdp_data_t *seq = p->data;
> +			if (seq && seq->dtd == SDP_UUID16 &&
> +				sdp_uuid16_cmp(&proto, &seq->val.uuid) == 0)
> +				return seq->next;
> +		}
> +	}
> +
> +	return NULL;
> +}
> +
> +static gboolean parse_proto_params(sdp_list_t *proto_list, uint16_t *psm,
> +						uint16_t *start, uint16_t *end)
> +{
> +	sdp_data_t *seq1, *seq2;
> +
> +	if (psm)
> +		*psm = sdp_get_proto_port(proto_list, L2CAP_UUID);
> +
> +	/* Getting start and end handle */
> +	seq1 = proto_seq_find(proto_list);
> +	if (!seq1 || seq1->dtd != SDP_UINT16)
> +		return FALSE;
> +
> +	seq2 = seq1->next;
> +	if (!seq2 || seq2->dtd != SDP_UINT16)
> +		return FALSE;
> +
> +	if (start)
> +		*start = seq1->val.uint16;
> +
> +	if (end)
> +		*end = seq2->val.uint16;
> +
> +	return TRUE;
> +}
> +
> +static gboolean parse_primary_record(const sdp_record_t *rec,
> +					uuid_t *prim_uuid, uint16_t *psm,
> +					uint16_t *start, uint16_t *end)
> +{
> +	sdp_list_t *list;
> +	uuid_t uuid;
> +	gboolean ret;
> +
> +	if (sdp_get_service_classes(rec, &list) < 0)
> +		return FALSE;
> +
> +	memcpy(&uuid, list->data, sizeof(uuid));
> +	sdp_list_free(list, free);
> +
> +	if (sdp_get_access_protos(rec, &list) < 0)
> +		return FALSE;
> +
> +	ret = parse_proto_params(list, psm, start, end);
> +
> +	sdp_list_foreach(list, (sdp_list_func_t) sdp_list_free, NULL);
> +	sdp_list_free(list, NULL);
> +
> +	if (ret && prim_uuid)
> +		memcpy(prim_uuid, &uuid, sizeof(uuid_t));
> +
> +	return ret;
> +}
> +
> +static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
> +{
> +	GSList *l, *prim_list = NULL;
> +	char *att_uuid;
> +	uuid_t proto_uuid;
> +
> +	sdp_uuid16_create(&proto_uuid, ATT_UUID);
> +	att_uuid = bt_uuid2string(&proto_uuid);
> +
> +	for (l = profiles; l; l = l->next) {
> +		const char *profile_uuid = l->data;
> +		const sdp_record_t *rec;
> +		struct att_primary *prim;
> +		uint16_t start = 0, end = 0, psm = 0;
> +		uuid_t prim_uuid;
> +
> +		rec = btd_device_get_record(device, profile_uuid);
> +		if (!rec)
> +			continue;
> +
> +		if (!record_has_uuid(rec, att_uuid))
> +			continue;
> +
> +		if (!parse_primary_record(rec, &prim_uuid, &psm, &start, &end))
> +			continue;
> +
> +		prim = g_new0(struct att_primary, 1);
> +		prim->start = start;
> +		prim->end = end;
> +		sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
> +
> +		prim_list = g_slist_append(prim_list, prim);
> +	}
> +
> +	g_free(att_uuid);
> +
> +	return prim_list;
> +}
> +
> +static void register_primary_services(DBusConnection *conn,
> +				struct btd_device *device, GSList *prim_list)
> +{
> +	/* TODO: PSM is hardcoded */
> +	attrib_client_register(conn, device, 31, NULL, prim_list);
> +	device->primaries = g_slist_concat(device->primaries, prim_list);
> +}
> +
>  static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
>  {
>  	struct browse_req *req = user_data;
> @@ -1396,9 +1517,16 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
>  	}
>  
>  	/* Probe matching drivers for services added */
> -	if (req->profiles_added)
> +	if (req->profiles_added) {
> +		GSList *list;
> +
>  		device_probe_drivers(device, req->profiles_added);
>  
> +		list = primary_from_record(device, req->profiles_added);
> +		if (list)
> +			register_primary_services(req->conn, device, list);
> +	}
> +
>  	/* Remove drivers for services removed */
>  	if (req->profiles_removed)
>  		device_remove_drivers(device, req->profiles_removed);
> -- 
> 1.7.4.1
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html


Cheers,
-- 
Vinicius

^ permalink raw reply	[flat|nested] 21+ messages in thread

* Re: [PATCH 1/9] Register primary services exported over basic rate
  2011-04-07 17:58 ` [PATCH 1/9] Register primary services exported " Vinicius Costa Gomes
@ 2011-04-07 18:15   ` Claudio Takahasi
  2011-04-11 18:24     ` [PATCH v2 " Claudio Takahasi
  0 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-07 18:15 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth

Hi Vinicius & Johan,

I will fix this error and move the GATT SDP record functions to gatt.c

BR,
Claudio

On Thu, Apr 7, 2011 at 5:58 PM, Vinicius Costa Gomes
<vinicius.gomes@openbossa.org> wrote:
> Hi Claudio,
>
> On 14:30 Thu 07 Apr, Claudio Takahasi wrote:
>> This patch registers the object paths for primary services exported
>> through SDP. PSM, start and end handle information are available in
>> the Protocol Descriptor List.
>> ---
>>  src/device.c |  130 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
>>  1 files changed, 129 insertions(+), 1 deletions(-)
>>
>> diff --git a/src/device.c b/src/device.c
>> index d567952..32eb643 100644
>> --- a/src/device.c
>> +++ b/src/device.c
>> @@ -1367,6 +1367,127 @@ static void create_device_reply(struct btd_device *device, struct browse_req *re
>>       g_dbus_send_message(req->conn, reply);
>>  }
>>
>> +static sdp_data_t *proto_seq_find(sdp_list_t *proto_list)
>> +{
>> +     sdp_list_t *list;
>> +     uuid_t proto;
>> +
>> +     sdp_uuid16_create(&proto, ATT_UUID);
>> +
>> +     for (;list = proto_list, list; list = list->next) {
>
> The first ";" doesn't look right.
>
>> +             sdp_list_t *p;
>> +             for (p = list->data; p; p = p->next) {
>> +                     sdp_data_t *seq = p->data;
>> +                     if (seq && seq->dtd == SDP_UUID16 &&
>> +                             sdp_uuid16_cmp(&proto, &seq->val.uuid) == 0)
>> +                             return seq->next;
>> +             }
>> +     }
>> +
>> +     return NULL;
>> +}
>> +
>> +static gboolean parse_proto_params(sdp_list_t *proto_list, uint16_t *psm,
>> +                                             uint16_t *start, uint16_t *end)
>> +{
>> +     sdp_data_t *seq1, *seq2;
>> +
>> +     if (psm)
>> +             *psm = sdp_get_proto_port(proto_list, L2CAP_UUID);
>> +
>> +     /* Getting start and end handle */
>> +     seq1 = proto_seq_find(proto_list);
>> +     if (!seq1 || seq1->dtd != SDP_UINT16)
>> +             return FALSE;
>> +
>> +     seq2 = seq1->next;
>> +     if (!seq2 || seq2->dtd != SDP_UINT16)
>> +             return FALSE;
>> +
>> +     if (start)
>> +             *start = seq1->val.uint16;
>> +
>> +     if (end)
>> +             *end = seq2->val.uint16;
>> +
>> +     return TRUE;
>> +}
>> +
>> +static gboolean parse_primary_record(const sdp_record_t *rec,
>> +                                     uuid_t *prim_uuid, uint16_t *psm,
>> +                                     uint16_t *start, uint16_t *end)
>> +{
>> +     sdp_list_t *list;
>> +     uuid_t uuid;
>> +     gboolean ret;
>> +
>> +     if (sdp_get_service_classes(rec, &list) < 0)
>> +             return FALSE;
>> +
>> +     memcpy(&uuid, list->data, sizeof(uuid));
>> +     sdp_list_free(list, free);
>> +
>> +     if (sdp_get_access_protos(rec, &list) < 0)
>> +             return FALSE;
>> +
>> +     ret = parse_proto_params(list, psm, start, end);
>> +
>> +     sdp_list_foreach(list, (sdp_list_func_t) sdp_list_free, NULL);
>> +     sdp_list_free(list, NULL);
>> +
>> +     if (ret && prim_uuid)
>> +             memcpy(prim_uuid, &uuid, sizeof(uuid_t));
>> +
>> +     return ret;
>> +}
>> +
>> +static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
>> +{
>> +     GSList *l, *prim_list = NULL;
>> +     char *att_uuid;
>> +     uuid_t proto_uuid;
>> +
>> +     sdp_uuid16_create(&proto_uuid, ATT_UUID);
>> +     att_uuid = bt_uuid2string(&proto_uuid);
>> +
>> +     for (l = profiles; l; l = l->next) {
>> +             const char *profile_uuid = l->data;
>> +             const sdp_record_t *rec;
>> +             struct att_primary *prim;
>> +             uint16_t start = 0, end = 0, psm = 0;
>> +             uuid_t prim_uuid;
>> +
>> +             rec = btd_device_get_record(device, profile_uuid);
>> +             if (!rec)
>> +                     continue;
>> +
>> +             if (!record_has_uuid(rec, att_uuid))
>> +                     continue;
>> +
>> +             if (!parse_primary_record(rec, &prim_uuid, &psm, &start, &end))
>> +                     continue;
>> +
>> +             prim = g_new0(struct att_primary, 1);
>> +             prim->start = start;
>> +             prim->end = end;
>> +             sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
>> +
>> +             prim_list = g_slist_append(prim_list, prim);
>> +     }
>> +
>> +     g_free(att_uuid);
>> +
>> +     return prim_list;
>> +}
>> +
>> +static void register_primary_services(DBusConnection *conn,
>> +                             struct btd_device *device, GSList *prim_list)
>> +{
>> +     /* TODO: PSM is hardcoded */
>> +     attrib_client_register(conn, device, 31, NULL, prim_list);
>> +     device->primaries = g_slist_concat(device->primaries, prim_list);
>> +}
>> +
>>  static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
>>  {
>>       struct browse_req *req = user_data;
>> @@ -1396,9 +1517,16 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
>>       }
>>
>>       /* Probe matching drivers for services added */
>> -     if (req->profiles_added)
>> +     if (req->profiles_added) {
>> +             GSList *list;
>> +
>>               device_probe_drivers(device, req->profiles_added);
>>
>> +             list = primary_from_record(device, req->profiles_added);
>> +             if (list)
>> +                     register_primary_services(req->conn, device, list);
>> +     }
>> +
>>       /* Remove drivers for services removed */
>>       if (req->profiles_removed)
>>               device_remove_drivers(device, req->profiles_removed);
>> --
>> 1.7.4.1
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html
>
>
> Cheers,
> --
> Vinicius
>



-- 
--
Claudio Takahasi
Instituto Nokia de Tecnologia
Recife - Pernambuco - Brasil
+55 81 30879999

^ permalink raw reply	[flat|nested] 21+ messages in thread

* [PATCH v2 1/9] Register primary services exported over basic rate
  2011-04-07 18:15   ` Claudio Takahasi
@ 2011-04-11 18:24     ` Claudio Takahasi
  2011-04-14 17:13       ` Johan Hedberg
  0 siblings, 1 reply; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

This patch registers the object paths for primary services exported
through SDP. PSM, start and end handle information are available in
the Protocol Descriptor List.
---
 attrib/gatt.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 attrib/gatt.h |    6 ++++
 src/device.c  |   56 ++++++++++++++++++++++++++++++++++++++++-
 3 files changed, 139 insertions(+), 1 deletions(-)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index 0b69daf..360218b 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -23,8 +23,11 @@
  */
 
 #include <stdint.h>
+#include <stdlib.h>
 #include <glib.h>
 #include <bluetooth/uuid.h>
+#include <bluetooth/sdp.h>
+#include <bluetooth/sdp_lib.h>
 
 #include "att.h"
 #include "gattrib.h"
@@ -575,3 +578,78 @@ guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
 	return g_attrib_send(attrib, 0, ATT_OP_WRITE_CMD, buf, plen, NULL,
 							user_data, notify);
 }
+
+static sdp_data_t *proto_seq_find(sdp_list_t *proto_list)
+{
+	sdp_list_t *list;
+	uuid_t proto;
+
+	sdp_uuid16_create(&proto, ATT_UUID);
+
+	for (list = proto_list; list; list = list->next) {
+		sdp_list_t *p;
+		for (p = list->data; p; p = p->next) {
+			sdp_data_t *seq = p->data;
+			if (seq && seq->dtd == SDP_UUID16 &&
+				sdp_uuid16_cmp(&proto, &seq->val.uuid) == 0)
+				return seq->next;
+		}
+	}
+
+	return NULL;
+}
+
+static gboolean parse_proto_params(sdp_list_t *proto_list, uint16_t *psm,
+						uint16_t *start, uint16_t *end)
+{
+	sdp_data_t *seq1, *seq2;
+
+	if (psm)
+		*psm = sdp_get_proto_port(proto_list, L2CAP_UUID);
+
+	/* Getting start and end handle */
+	seq1 = proto_seq_find(proto_list);
+	if (!seq1 || seq1->dtd != SDP_UINT16)
+		return FALSE;
+
+	seq2 = seq1->next;
+	if (!seq2 || seq2->dtd != SDP_UINT16)
+		return FALSE;
+
+	if (start)
+		*start = seq1->val.uint16;
+
+	if (end)
+		*end = seq2->val.uint16;
+
+	return TRUE;
+}
+
+gboolean gatt_parse_record(const sdp_record_t *rec,
+					uuid_t *prim_uuid, uint16_t *psm,
+					uint16_t *start, uint16_t *end)
+{
+	sdp_list_t *list;
+	uuid_t uuid;
+	gboolean ret;
+
+	if (sdp_get_service_classes(rec, &list) < 0)
+		return FALSE;
+
+	memcpy(&uuid, list->data, sizeof(uuid));
+	sdp_list_free(list, free);
+
+	if (sdp_get_access_protos(rec, &list) < 0)
+		return FALSE;
+
+	ret = parse_proto_params(list, psm, start, end);
+
+	sdp_list_foreach(list, (sdp_list_func_t) sdp_list_free, NULL);
+	sdp_list_free(list, NULL);
+
+	/* FIXME: replace by bt_uuid_t after uuid_t/sdp code cleanup */
+	if (ret && prim_uuid)
+		memcpy(prim_uuid, &uuid, sizeof(uuid_t));
+
+	return ret;
+}
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 221d94d..2c2f38c 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -24,6 +24,8 @@
 
 #define GATT_CID 4
 
+#include <bluetooth/sdp.h>
+
 typedef void (*gatt_cb_t) (GSList *l, guint8 status, gpointer user_data);
 
 guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
@@ -51,3 +53,7 @@ guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
 
 guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu, GAttribResultFunc func,
 							gpointer user_data);
+
+gboolean gatt_parse_record(const sdp_record_t *rec,
+					uuid_t *prim_uuid, uint16_t *psm,
+					uint16_t *start, uint16_t *end);
diff --git a/src/device.c b/src/device.c
index d567952..ecd1861 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1367,6 +1367,53 @@ static void create_device_reply(struct btd_device *device, struct browse_req *re
 	g_dbus_send_message(req->conn, reply);
 }
 
+static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
+{
+	GSList *l, *prim_list = NULL;
+	char *att_uuid;
+	uuid_t proto_uuid;
+
+	sdp_uuid16_create(&proto_uuid, ATT_UUID);
+	att_uuid = bt_uuid2string(&proto_uuid);
+
+	for (l = profiles; l; l = l->next) {
+		const char *profile_uuid = l->data;
+		const sdp_record_t *rec;
+		struct att_primary *prim;
+		uint16_t start = 0, end = 0, psm = 0;
+		uuid_t prim_uuid;
+
+		rec = btd_device_get_record(device, profile_uuid);
+		if (!rec)
+			continue;
+
+		if (!record_has_uuid(rec, att_uuid))
+			continue;
+
+		if (!gatt_parse_record(rec, &prim_uuid, &psm, &start, &end))
+			continue;
+
+		prim = g_new0(struct att_primary, 1);
+		prim->start = start;
+		prim->end = end;
+		sdp_uuid2strn(&prim_uuid, prim->uuid, sizeof(prim->uuid));
+
+		prim_list = g_slist_append(prim_list, prim);
+	}
+
+	g_free(att_uuid);
+
+	return prim_list;
+}
+
+static void register_primary_services(DBusConnection *conn,
+				struct btd_device *device, GSList *prim_list)
+{
+	/* TODO: PSM is hardcoded */
+	attrib_client_register(conn, device, 31, NULL, prim_list);
+	device->primaries = g_slist_concat(device->primaries, prim_list);
+}
+
 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 {
 	struct browse_req *req = user_data;
@@ -1396,9 +1443,16 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 	}
 
 	/* Probe matching drivers for services added */
-	if (req->profiles_added)
+	if (req->profiles_added) {
+		GSList *list;
+
 		device_probe_drivers(device, req->profiles_added);
 
+		list = primary_from_record(device, req->profiles_added);
+		if (list)
+			register_primary_services(req->conn, device, list);
+	}
+
 	/* Remove drivers for services removed */
 	if (req->profiles_removed)
 		device_remove_drivers(device, req->profiles_removed);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 2/9] Cleanup primary service registration from storage
  2011-04-07 17:30 ` [PATCH 2/9] Cleanup primary service registration from storage Claudio Takahasi
@ 2011-04-11 18:24   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/adapter.c |    9 +--------
 src/device.c  |   20 ++++++--------------
 src/device.h  |    4 ++--
 3 files changed, 9 insertions(+), 24 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index c400bfd..6caff9a 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -58,8 +58,6 @@
 #include "storage.h"
 #include "attrib-server.h"
 #include "att.h"
-#include "gattrib.h"
-#include "attrib/client.h"
 
 /* Interleaved discovery window: 5.12 sec */
 #define GAP_INTER_DISCOV_WIN		5120
@@ -2193,16 +2191,11 @@ static void create_stored_device_from_primary(char *key, char *value,
 	for (l = services, uuids = NULL; l; l = l->next) {
 		struct att_primary *prim = l->data;
 		uuids = g_slist_append(uuids, prim->uuid);
-
-		device_add_primary(device, prim);
 	}
 
-	/* FIXME: Need the correct psm */
-	attrib_client_register(connection, device, -1, NULL, services);
-
 	device_probe_drivers(device, uuids);
+	device_register_services(connection, device, services, -1);
 
-	g_slist_free(services);
 	g_slist_free(uuids);
 }
 
diff --git a/src/device.c b/src/device.c
index ecd1861..f9b7a73 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1406,14 +1406,6 @@ static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
 	return prim_list;
 }
 
-static void register_primary_services(DBusConnection *conn,
-				struct btd_device *device, GSList *prim_list)
-{
-	/* TODO: PSM is hardcoded */
-	attrib_client_register(conn, device, 31, NULL, prim_list);
-	device->primaries = g_slist_concat(device->primaries, prim_list);
-}
-
 static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 {
 	struct browse_req *req = user_data;
@@ -1450,7 +1442,7 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 
 		list = primary_from_record(device, req->profiles_added);
 		if (list)
-			register_primary_services(req->conn, device, list);
+			device_register_services(req->conn, device, list, 31);
 	}
 
 	/* Remove drivers for services removed */
@@ -1592,13 +1584,11 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 	for (l = services; l; l = l->next) {
 		struct att_primary *prim = l->data;
 		uuids = g_slist_append(uuids, prim->uuid);
-		device_add_primary(device, prim);
 	}
 
 	device_probe_drivers(device, uuids);
 
-	/* FIXME: Need the correct psm */
-	attrib_client_register(req->conn, device, -1, req->attrib, services);
+	device_register_services(req->conn, device, services, -1);
 
 	g_slist_free(uuids);
 
@@ -2354,9 +2344,11 @@ void btd_device_add_service(struct btd_device *device, const char *path)
 	device->services = g_slist_append(device->services, g_strdup(path));
 }
 
-void device_add_primary(struct btd_device *device, struct att_primary *prim)
+void device_register_services(DBusConnection *conn, struct btd_device *device,
+						GSList *prim_list, int psm)
 {
-	device->primaries = g_slist_append(device->primaries, prim);
+	attrib_client_register(conn, device, psm, NULL, prim_list);
+	device->primaries = g_slist_concat(device->primaries, prim_list);
 }
 
 GSList *btd_device_get_primaries(struct btd_device *device)
diff --git a/src/device.h b/src/device.h
index 3ce212b..285364f 100644
--- a/src/device.h
+++ b/src/device.h
@@ -25,7 +25,6 @@
 #define DEVICE_INTERFACE	"org.bluez.Device"
 
 struct btd_device;
-struct att_primary;
 
 typedef enum {
 	AUTH_TYPE_PINCODE,
@@ -58,7 +57,8 @@ const sdp_record_t *btd_device_get_record(struct btd_device *device,
 						const char *uuid);
 GSList *btd_device_get_primaries(struct btd_device *device);
 void btd_device_add_service(struct btd_device *device, const char *path);
-void device_add_primary(struct btd_device *device, struct att_primary *prim);
+void device_register_services(DBusConnection *conn, struct btd_device *device,
+						GSList *prim_list, int psm);
 void btd_device_add_uuid(struct btd_device *device, const char *uuid);
 struct btd_adapter *device_get_adapter(struct btd_device *device);
 void device_get_address(struct btd_device *device, bdaddr_t *bdaddr);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 3/9] Remove btd_device_add_service function
  2011-04-07 17:30 ` [PATCH 3/9] Remove btd_device_add_service function Claudio Takahasi
@ 2011-04-11 18:24   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:24 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

btd_device_add_service is no longer necessary if the object paths for
the primary services can be returned during the registration.
---
 attrib/client.c |   16 ++++++++--------
 attrib/client.h |    2 +-
 src/device.c    |   11 ++---------
 src/device.h    |    1 -
 4 files changed, 11 insertions(+), 19 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 28e5704..2dd70c9 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -1020,11 +1020,11 @@ static GDBusMethodTable prim_methods[] = {
 	{ }
 };
 
-static void register_primaries(struct gatt_service *gatt, GSList *primaries)
+static GSList *register_primaries(struct gatt_service *gatt, GSList *primaries)
 {
-	GSList *l;
+	GSList *l, *paths;
 
-	for (l = primaries; l; l = l->next) {
+	for (paths = NULL, l = primaries; l; l = l->next) {
 		struct att_primary *att = l->data;
 		struct primary *prim;
 
@@ -1040,12 +1040,14 @@ static void register_primaries(struct gatt_service *gatt, GSList *primaries)
 		DBG("Registered: %s", prim->path);
 
 		gatt->primary = g_slist_append(gatt->primary, prim);
-		btd_device_add_service(gatt->dev, prim->path);
+		paths = g_slist_append(paths, g_strdup(prim->path));
 		load_characteristics(prim, gatt);
 	}
+
+	return paths;
 }
 
-int attrib_client_register(DBusConnection *connection,
+GSList *attrib_client_register(DBusConnection *connection,
 					struct btd_device *device, int psm,
 					GAttrib *attrib, GSList *primaries)
 {
@@ -1069,11 +1071,9 @@ int attrib_client_register(DBusConnection *connection,
 	if (attrib)
 		gatt->attrib = g_attrib_ref(attrib);
 
-	register_primaries(gatt, primaries);
-
 	gatt_services = g_slist_append(gatt_services, gatt);
 
-	return 0;
+	return register_primaries(gatt, primaries);
 }
 
 void attrib_client_unregister(struct btd_device *device)
diff --git a/attrib/client.h b/attrib/client.h
index b4a4ecc..b29797c 100644
--- a/attrib/client.h
+++ b/attrib/client.h
@@ -22,7 +22,7 @@
  *
  */
 
-int attrib_client_register(DBusConnection *connection,
+GSList *attrib_client_register(DBusConnection *connection,
 					struct btd_device *device, int psm,
 					GAttrib *attrib, GSList *primaries);
 void attrib_client_unregister(struct btd_device *device);
diff --git a/src/device.c b/src/device.c
index f9b7a73..efe9938 100644
--- a/src/device.c
+++ b/src/device.c
@@ -2336,18 +2336,11 @@ void device_set_authorizing(struct btd_device *device, gboolean auth)
 	device->authorizing = auth;
 }
 
-void btd_device_add_service(struct btd_device *device, const char *path)
-{
-	if (g_slist_find_custom(device->services, path, (GCompareFunc) strcmp))
-		return;
-
-	device->services = g_slist_append(device->services, g_strdup(path));
-}
-
 void device_register_services(DBusConnection *conn, struct btd_device *device,
 						GSList *prim_list, int psm)
 {
-	attrib_client_register(conn, device, psm, NULL, prim_list);
+	device->services = attrib_client_register(conn, device, psm, NULL,
+								prim_list);
 	device->primaries = g_slist_concat(device->primaries, prim_list);
 }
 
diff --git a/src/device.h b/src/device.h
index 285364f..2432884 100644
--- a/src/device.h
+++ b/src/device.h
@@ -56,7 +56,6 @@ void device_probe_drivers(struct btd_device *device, GSList *profiles);
 const sdp_record_t *btd_device_get_record(struct btd_device *device,
 						const char *uuid);
 GSList *btd_device_get_primaries(struct btd_device *device);
-void btd_device_add_service(struct btd_device *device, const char *path);
 void device_register_services(DBusConnection *conn, struct btd_device *device,
 						GSList *prim_list, int psm);
 void btd_device_add_uuid(struct btd_device *device, const char *uuid);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 4/9] Move the primary service storage code to a local function
  2011-04-07 17:30 ` [PATCH 4/9] Move the primary service storage code to a local function Claudio Takahasi
@ 2011-04-11 18:25   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:25 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/device.c |   27 ++++++++++++++++-----------
 1 files changed, 16 insertions(+), 11 deletions(-)

diff --git a/src/device.c b/src/device.c
index efe9938..86f605a 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1562,14 +1562,26 @@ static char *primary_list_to_string(GSList *primary_list)
 	return g_string_free(services, FALSE);
 }
 
+static void store_services(struct btd_device *device)
+{
+	struct btd_adapter *adapter = device->adapter;
+	bdaddr_t dba, sba;
+	char *str = primary_list_to_string(device->services);
+
+	adapter_get_address(adapter, &sba);
+	device_get_address(device, &dba);
+
+	write_device_type(&sba, &dba, device->type);
+	write_device_services(&sba, &dba, str);
+
+	g_free(str);
+}
+
 static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 {
 	struct browse_req *req = user_data;
 	struct btd_device *device = req->device;
-	struct btd_adapter *adapter = device->adapter;
 	GSList *l, *uuids = NULL;
-	bdaddr_t dba, sba;
-	char *str;
 
 	if (status) {
 		DBusMessage *reply;
@@ -1594,14 +1606,7 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 
 	create_device_reply(device, req);
 
-	str = primary_list_to_string(services);
-
-	adapter_get_address(adapter, &sba);
-	device_get_address(device, &dba);
-
-	write_device_type(&sba, &dba, device->type);
-	write_device_services(&sba, &dba, str);
-	g_free(str);
+	store_services(device);
 
 done:
 	device->browse = NULL;
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 5/9] Fix device type when creating from primary services storage
  2011-04-07 17:30 ` [PATCH 5/9] Fix device type when creating from primary services storage Claudio Takahasi
@ 2011-04-11 18:25   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:25 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

GATT services exported through basic rate need to be created based
on the "profiles" file. For GATT over LE, "primary" file entries need
to be used to create the devices and primary services objects.
---
 src/adapter.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 6caff9a..8380a58 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2176,7 +2176,7 @@ static void create_stored_device_from_primary(char *key, char *value,
 	if (l)
 		device = l->data;
 	else {
-		device = device_create(connection, adapter, key, DEVICE_TYPE_BREDR);
+		device = device_create(connection, adapter, key, DEVICE_TYPE_LE);
 		if (!device)
 			return;
 
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 6/9] Fix LE device creation from storage
  2011-04-07 17:30 ` [PATCH 6/9] Fix LE device creation from storage Claudio Takahasi
@ 2011-04-11 18:25   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:25 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

Ignore the device if it already created. This patch adds a consistency
check to avoid registering the same service over basic rate and LE.
---
 src/adapter.c |   20 +++++++++-----------
 1 files changed, 9 insertions(+), 11 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 8380a58..9a0f688 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2171,18 +2171,16 @@ static void create_stored_device_from_primary(char *key, char *value,
 	struct btd_device *device;
 	GSList *services, *uuids, *l;
 
-	l = g_slist_find_custom(adapter->devices,
-				key, (GCompareFunc) device_address_cmp);
-	if (l)
-		device = l->data;
-	else {
-		device = device_create(connection, adapter, key, DEVICE_TYPE_LE);
-		if (!device)
-			return;
+	if (g_slist_find_custom(adapter->devices,
+			key, (GCompareFunc) device_address_cmp))
+		return;
 
-		device_set_temporary(device, FALSE);
-		adapter->devices = g_slist_append(adapter->devices, device);
-	}
+	device = device_create(connection, adapter, key, DEVICE_TYPE_LE);
+	if (!device)
+		return;
+
+	device_set_temporary(device, FALSE);
+	adapter->devices = g_slist_append(adapter->devices, device);
 
 	services = string_to_primary_list(value);
 	if (services == NULL)
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 7/9] Fix primary services registration from storage for basic rate
  2011-04-07 17:30 ` [PATCH 7/9] Fix primary services registration from storage for basic rate Claudio Takahasi
@ 2011-04-11 18:26   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 src/adapter.c |    5 ++++-
 src/device.c  |    4 ++--
 src/device.h  |    2 ++
 3 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/src/adapter.c b/src/adapter.c
index 9a0f688..7049ba6 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -2004,7 +2004,7 @@ static void create_stored_device_from_profiles(char *key, char *value,
 						void *user_data)
 {
 	struct btd_adapter *adapter = user_data;
-	GSList *uuids = bt_string2list(value);
+	GSList *list, *uuids = bt_string2list(value);
 	struct btd_device *device;
 
 	if (g_slist_find_custom(adapter->devices,
@@ -2019,6 +2019,9 @@ static void create_stored_device_from_profiles(char *key, char *value,
 	adapter->devices = g_slist_append(adapter->devices, device);
 
 	device_probe_drivers(device, uuids);
+	list = device_services_from_record(device, uuids);
+	if (list)
+		device_register_services(connection, device, list, 31);
 
 	g_slist_foreach(uuids, (GFunc) g_free, NULL);
 	g_slist_free(uuids);
diff --git a/src/device.c b/src/device.c
index 86f605a..44bf76f 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1367,7 +1367,7 @@ static void create_device_reply(struct btd_device *device, struct browse_req *re
 	g_dbus_send_message(req->conn, reply);
 }
 
-static GSList *primary_from_record(struct btd_device *device, GSList *profiles)
+GSList *device_services_from_record(struct btd_device *device, GSList *profiles)
 {
 	GSList *l, *prim_list = NULL;
 	char *att_uuid;
@@ -1440,7 +1440,7 @@ static void search_cb(sdp_list_t *recs, int err, gpointer user_data)
 
 		device_probe_drivers(device, req->profiles_added);
 
-		list = primary_from_record(device, req->profiles_added);
+		list = device_services_from_record(device, req->profiles_added);
 		if (list)
 			device_register_services(req->conn, device, list, 31);
 	}
diff --git a/src/device.h b/src/device.h
index 2432884..370382d 100644
--- a/src/device.h
+++ b/src/device.h
@@ -58,6 +58,8 @@ const sdp_record_t *btd_device_get_record(struct btd_device *device,
 GSList *btd_device_get_primaries(struct btd_device *device);
 void device_register_services(DBusConnection *conn, struct btd_device *device,
 						GSList *prim_list, int psm);
+GSList *device_services_from_record(struct btd_device *device,
+							GSList *profiles);
 void btd_device_add_uuid(struct btd_device *device, const char *uuid);
 struct btd_adapter *device_get_adapter(struct btd_device *device);
 void device_get_address(struct btd_device *device, bdaddr_t *bdaddr);
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 8/9] TODO: Remove item related to GATT service over basic rate
  2011-04-07 17:30 ` [PATCH 8/9] TODO: Remove item related to GATT service over " Claudio Takahasi
@ 2011-04-11 18:26   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 TODO |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

diff --git a/TODO b/TODO
index d52808b..461b179 100644
--- a/TODO
+++ b/TODO
@@ -114,16 +114,6 @@ Low Energy
 ATT/GATT
 ========
 
-- For BR/EDR, primary services can be registered based on the information
-  extracted from the service records. UUIDs, start and end handles information
-  are available in the record, Discover All Primary Services procedure is not
-  necessary. If a GATT service doesn't export a service record means that
-  it should not be used over BR/EDR. Don't start this task before to move the
-  attribute client code to the bluetoothd core.
-
-  Priority: Medium
-  Complexity: C1
-
 - At the moment authentication and authorization is not supported at the
   same time, read/write requirements in the attribute server needs to
   be extended. According to Bluetooth Specification a server shall check
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* [PATCH v2 9/9] TODO: Add hard-coded PSM for GATT over basic rate
  2011-04-07 17:30 ` [PATCH 9/9] TODO: Add hard-coded PSM for GATT " Claudio Takahasi
@ 2011-04-11 18:26   ` Claudio Takahasi
  0 siblings, 0 replies; 21+ messages in thread
From: Claudio Takahasi @ 2011-04-11 18:26 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Claudio Takahasi

---
 TODO |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/TODO b/TODO
index 461b179..fab3ec0 100644
--- a/TODO
+++ b/TODO
@@ -136,6 +136,11 @@ ATT/GATT
   Priority: Medium
   Complexity: C1
 
+- Fix hard-coded PSM for GATT services over basic rate.
+
+  Priority: Low
+  Complexity: C1
+
 - Refactor read_by_group() and read_by_type() in src/attrib-server.c
   (they've grown simply too big). First step could be to move out the
   long for-loops to new functions called e.g. get_groups() and get_types().
-- 
1.7.4.1


^ permalink raw reply related	[flat|nested] 21+ messages in thread

* Re: [PATCH v2 1/9] Register primary services exported over basic rate
  2011-04-11 18:24     ` [PATCH v2 " Claudio Takahasi
@ 2011-04-14 17:13       ` Johan Hedberg
  0 siblings, 0 replies; 21+ messages in thread
From: Johan Hedberg @ 2011-04-14 17:13 UTC (permalink / raw)
  To: Claudio Takahasi; +Cc: linux-bluetooth

Hi Claudio,

On Mon, Apr 11, 2011, Claudio Takahasi wrote:
> This patch registers the object paths for primary services exported
> through SDP. PSM, start and end handle information are available in
> the Protocol Descriptor List.
> ---
>  attrib/gatt.c |   78 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  attrib/gatt.h |    6 ++++
>  src/device.c  |   56 ++++++++++++++++++++++++++++++++++++++++-
>  3 files changed, 139 insertions(+), 1 deletions(-)

All patches in this set have been pushed upstream. Thanks.

Johan

^ permalink raw reply	[flat|nested] 21+ messages in thread

end of thread, other threads:[~2011-04-14 17:13 UTC | newest]

Thread overview: 21+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2011-04-07 17:30 [PATCH 1/9] Register primary services exported over basic rate Claudio Takahasi
2011-04-07 17:30 ` [PATCH 2/9] Cleanup primary service registration from storage Claudio Takahasi
2011-04-11 18:24   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:30 ` [PATCH 3/9] Remove btd_device_add_service function Claudio Takahasi
2011-04-11 18:24   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:30 ` [PATCH 4/9] Move the primary service storage code to a local function Claudio Takahasi
2011-04-11 18:25   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:30 ` [PATCH 5/9] Fix device type when creating from primary services storage Claudio Takahasi
2011-04-11 18:25   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:30 ` [PATCH 6/9] Fix LE device creation from storage Claudio Takahasi
2011-04-11 18:25   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:30 ` [PATCH 7/9] Fix primary services registration from storage for basic rate Claudio Takahasi
2011-04-11 18:26   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:30 ` [PATCH 8/9] TODO: Remove item related to GATT service over " Claudio Takahasi
2011-04-11 18:26   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:30 ` [PATCH 9/9] TODO: Add hard-coded PSM for GATT " Claudio Takahasi
2011-04-11 18:26   ` [PATCH v2 " Claudio Takahasi
2011-04-07 17:58 ` [PATCH 1/9] Register primary services exported " Vinicius Costa Gomes
2011-04-07 18:15   ` Claudio Takahasi
2011-04-11 18:24     ` [PATCH v2 " Claudio Takahasi
2011-04-14 17:13       ` Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).