Linux bluetooth development
 help / color / mirror / Atom feed
* [PATCH BlueZ v4 11/18] gatt: Add Discover All Primary Services
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

From: Alvaro Silva <alvaro.silva@openbossa.org>

This patch adds ATT Read By Group request handling to the attribute
server. It is the primitive to implement Discover All Primary Services
procedure.
---
 src/gatt.c | 135 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 131 insertions(+), 4 deletions(-)

diff --git a/src/gatt.c b/src/gatt.c
index 04186b6..42d2440 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -107,14 +107,138 @@ static int send_error(int sk, uint8_t opcode, uint16_t handle, uint8_t ecode)
 	return write(sk, pdu, plen);
 }
 
+static void read_by_group_resp(int sk, uint16_t start,
+					uint16_t end, bt_uuid_t *pattern)
+{
+	uint8_t opdu[ATT_DEFAULT_LE_MTU];
+	GList *list;
+	struct btd_attribute *last = NULL;
+	uint8_t *group_start, *group_end = NULL, *group_uuid;
+	unsigned int uuid_type = BT_UUID_UNSPEC;
+	size_t group_len = 0, plen = 0;
+
+	/*
+	 * Read By Group Type Response format:
+	 *    Attribute Opcode: 1 byte
+	 *    Length: 1 byte (size of each group)
+	 *    Group: start | end | <<UUID>>
+	 */
+
+	opdu[0] = ATT_OP_READ_BY_GROUP_RESP;
+	group_start = &opdu[2];
+	group_uuid = &opdu[6];
+
+	for (list = local_attribute_db; list;
+			last = list->data, list = g_list_next(list)) {
+		struct btd_attribute *attr = list->data;
+
+		if (attr->handle < start)
+			continue;
+
+		if (attr->handle > end)
+			break;
+
+		if (bt_uuid_cmp(&attr->type, pattern) != 0)
+			continue;
+
+		if (uuid_type != BT_UUID_UNSPEC &&
+						uuid_type != attr->type.type) {
+			/*
+			 * Groups should contain the same length: UUID16 and
+			 * UUID128 should be sent on different ATT PDUs
+			 */
+			break;
+		}
+
+		/*
+		 * MTU checking should not be shifted up, otherwise the
+		 * handle of last end group will not be set properly.
+		 */
+		if ((plen + group_len) >= ATT_DEFAULT_LE_MTU)
+			break;
+
+		/* Start Grouping handle */
+		att_put_u16(attr->handle, group_start);
+
+		/* Grouping <<UUID>>: Value is little endian */
+		memcpy(group_uuid, attr->value, attr->value_len);
+
+		if (last && group_end) {
+			att_put_u16(last->handle, group_end);
+			group_end += group_len;
+			plen += group_len;
+		}
+
+		/* Grouping initial settings: First grouping */
+		if (uuid_type == BT_UUID_UNSPEC) {
+			uuid_type = attr->type.type;
+
+			/* start(0xXXXX) | end(0xXXXX) | <<UUID>> */
+			group_len = 2 + 2 + bt_uuid_len(&attr->type);
+
+			/* 2: ATT Opcode and Length */
+			plen = 2 + group_len;
+
+			/* Size of each Attribute Data */
+			opdu[1] = group_len;
+
+			group_end = &opdu[4];
+		}
+
+		group_start += group_len;
+		group_uuid += group_len;
+	}
+
+	if (plen == 0) {
+		send_error(sk, ATT_OP_READ_BY_GROUP_REQ, start,
+						ATT_ECODE_ATTR_NOT_FOUND);
+		return;
+	}
+
+	if (group_end)
+		att_put_u16(last->handle, group_end);
+
+	write(sk, opdu, plen);
+}
+
+static void read_by_group(int sk, const uint8_t *ipdu, ssize_t ilen)
+{
+	uint16_t decoded, start, end;
+	bt_uuid_t pattern;
+
+	decoded = dec_read_by_grp_req(ipdu, ilen, &start, &end, &pattern);
+	if (decoded == 0) {
+		send_error(sk, ipdu[0], 0x0000, ATT_ECODE_INVALID_PDU);
+		return;
+	}
+
+	if (start > end || start == 0x0000) {
+		send_error(sk, ipdu[0], start, ATT_ECODE_INVALID_HANDLE);
+		return;
+	}
+
+	 /*
+	  * Restricting Read By Group Type to <<Primary>>.
+	  * Removing the checking below requires changes to support
+	  * dynamic values(defined in the upper layer) and additional
+	  * security verification.
+	  */
+	if (bt_uuid_cmp(&pattern, &primary_uuid) != 0) {
+		send_error(sk, ipdu[0], start, ATT_ECODE_UNSUPP_GRP_TYPE);
+		return;
+	}
+
+	read_by_group_resp(sk, start, end, &pattern);
+}
+
 static bool channel_handler_cb(struct io *io, void *user_data)
 {
 	uint8_t ipdu[ATT_DEFAULT_LE_MTU];
-	ssize_t len;
+	ssize_t ilen;
 	int sk = io_get_fd(io);
 
-	len = read(sk, ipdu, sizeof(ipdu));
-	if (len < 0) {
+	ilen = read(sk, ipdu, sizeof(ipdu));
+	if (ilen < 0) {
 		int err = errno;
 		DBG("ATT channel read: %s(%d)", strerror(err), err);
 		return false;
@@ -136,11 +260,14 @@ static bool channel_handler_cb(struct io *io, void *user_data)
 	case ATT_OP_READ_MULTI_REQ:
 	case ATT_OP_PREP_WRITE_REQ:
 	case ATT_OP_EXEC_WRITE_REQ:
-	case ATT_OP_READ_BY_GROUP_REQ:
 	case ATT_OP_SIGNED_WRITE_CMD:
 		send_error(sk, ipdu[0], 0x0000, ATT_ECODE_REQ_NOT_SUPP);
 		break;
 
+	case ATT_OP_READ_BY_GROUP_REQ:
+		read_by_group(sk, ipdu, ilen);
+		break;
+
 	/* Responses */
 	case ATT_OP_MTU_RESP:
 	case ATT_OP_FIND_INFO_RESP:
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 10/18] gatt: Register ATT command/event handler
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

From: Alvaro Silva <alvaro.silva@openbossa.org>

This patch registers the ATT channel handler to manage incoming ATT
commands and events.
---
 src/gatt.c | 84 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 82 insertions(+), 2 deletions(-)

diff --git a/src/gatt.c b/src/gatt.c
index 2f0466a..04186b6 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -98,10 +98,85 @@ struct btd_attribute *btd_gatt_add_service(const bt_uuid_t *uuid)
 	return attr;
 }
 
+static int send_error(int sk, uint8_t opcode, uint16_t handle, uint8_t ecode)
+{
+	uint8_t pdu[ATT_DEFAULT_LE_MTU];
+	size_t plen;
+
+	plen = enc_error_resp(opcode, handle, ecode, pdu, sizeof(pdu));
+	return write(sk, pdu, plen);
+}
+
+static bool channel_handler_cb(struct io *io, void *user_data)
+{
+	uint8_t ipdu[ATT_DEFAULT_LE_MTU];
+	ssize_t len;
+	int sk = io_get_fd(io);
+
+	len = read(sk, ipdu, sizeof(ipdu));
+	if (len < 0) {
+		int err = errno;
+		DBG("ATT channel read: %s(%d)", strerror(err), err);
+		return false;
+	}
+
+	switch (ipdu[0]) {
+	case ATT_OP_ERROR:
+		break;
+
+	/* Requests */
+	case ATT_OP_WRITE_CMD:
+	case ATT_OP_WRITE_REQ:
+	case ATT_OP_READ_REQ:
+	case ATT_OP_READ_BY_TYPE_REQ:
+	case ATT_OP_MTU_REQ:
+	case ATT_OP_FIND_INFO_REQ:
+	case ATT_OP_FIND_BY_TYPE_REQ:
+	case ATT_OP_READ_BLOB_REQ:
+	case ATT_OP_READ_MULTI_REQ:
+	case ATT_OP_PREP_WRITE_REQ:
+	case ATT_OP_EXEC_WRITE_REQ:
+	case ATT_OP_READ_BY_GROUP_REQ:
+	case ATT_OP_SIGNED_WRITE_CMD:
+		send_error(sk, ipdu[0], 0x0000, ATT_ECODE_REQ_NOT_SUPP);
+		break;
+
+	/* Responses */
+	case ATT_OP_MTU_RESP:
+	case ATT_OP_FIND_INFO_RESP:
+	case ATT_OP_FIND_BY_TYPE_RESP:
+	case ATT_OP_READ_BY_TYPE_RESP:
+	case ATT_OP_READ_RESP:
+	case ATT_OP_READ_BLOB_RESP:
+	case ATT_OP_READ_MULTI_RESP:
+	case ATT_OP_READ_BY_GROUP_RESP:
+	case ATT_OP_WRITE_RESP:
+	case ATT_OP_PREP_WRITE_RESP:
+	case ATT_OP_EXEC_WRITE_RESP:
+	case ATT_OP_HANDLE_CNF:
+		break;
+
+	/* Notification & Indication */
+	case ATT_OP_HANDLE_NOTIFY:
+	case ATT_OP_HANDLE_IND:
+		break;
+	}
+
+	return true;
+}
+
+static void channel_watch_destroy(void *user_data)
+{
+	struct io *io = user_data;
+
+	io_destroy(io);
+}
+
 static bool unix_accept_cb(struct io *io, void *user_data)
 {
 	struct sockaddr_un uaddr;
 	socklen_t len = sizeof(uaddr);
+	struct io *nio;
 	int err, nsk, sk;
 
 	sk = io_get_fd(io);
@@ -110,12 +185,17 @@ static bool unix_accept_cb(struct io *io, void *user_data)
 	if (nsk < 0) {
 		err = errno;
 		error("ATT UNIX socket accept: %s(%d)", strerror(err), err);
-		return TRUE;
+		return true;
 	}
 
 	DBG("ATT UNIX socket: %d", nsk);
+	nio = io_new(nsk);
+
+	io_set_close_on_destroy(nio, true);
+	io_set_read_handler(nio, channel_handler_cb, nio,
+						channel_watch_destroy);
 
-	return TRUE;
+	return true;
 }
 
 static void accept_watch_destroy(void *user_data)
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 09/18] gattrib: Use default ATT LE MTU for non-standard sockets
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

This patch forces the MTU to 23 (default ATT MTU) if the transport
is not Bluetooth. This is a development purpose change to allow
testing GATT procedures over non-Bluetooth sockets.
---
 attrib/gattrib.c | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index daf6312..b5b8529 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -468,18 +468,18 @@ GAttrib *g_attrib_new(GIOChannel *io)
 	struct _GAttrib *attrib;
 	uint16_t imtu;
 	uint16_t att_mtu;
-	uint16_t cid;
-	GError *gerr = NULL;
+	uint16_t cid = 0;
 
 	g_io_channel_set_encoding(io, NULL, NULL);
 	g_io_channel_set_buffered(io, FALSE);
 
-	bt_io_get(io, &gerr, BT_IO_OPT_IMTU, &imtu,
-				BT_IO_OPT_CID, &cid, BT_IO_OPT_INVALID);
-	if (gerr) {
-		error("%s", gerr->message);
-		g_error_free(gerr);
-		return NULL;
+	if (bt_io_get(io, NULL, BT_IO_OPT_IMTU, &imtu, BT_IO_OPT_CID, &cid,
+						BT_IO_OPT_INVALID) == FALSE) {
+		/*
+		 * Use default ATT LE MTU for non-standard transports. Used
+		 * for testing purpose only. eg: Unix sockets
+		 */
+		imtu = ATT_DEFAULT_LE_MTU;
 	}
 
 	attrib = g_try_new0(struct _GAttrib, 1);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 08/18] gatt: Add server unix socket
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

This patch adds a server unix socket to handle local ATT traffic. This
is a development purpose feature used to allow local testing without
breaking the current attribute server.
---
 src/gatt.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 66 insertions(+)

diff --git a/src/gatt.c b/src/gatt.c
index f7b74d6..2f0466a 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -25,11 +25,17 @@
 #include <config.h>
 #endif
 
+#include <unistd.h>
+#include <errno.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
 #include <glib.h>
 
 #include "log.h"
 #include "lib/uuid.h"
 #include "attrib/att.h"
+#include "src/shared/io.h"
 
 #include "gatt-dbus.h"
 #include "gatt.h"
@@ -47,6 +53,7 @@ struct btd_attribute {
 
 static GList *local_attribute_db;
 static uint16_t next_handle = 0x0001;
+static guint unix_watch;
 
 static int local_database_add(uint16_t handle, struct btd_attribute *attr)
 {
@@ -91,11 +98,69 @@ struct btd_attribute *btd_gatt_add_service(const bt_uuid_t *uuid)
 	return attr;
 }
 
+static bool unix_accept_cb(struct io *io, void *user_data)
+{
+	struct sockaddr_un uaddr;
+	socklen_t len = sizeof(uaddr);
+	int err, nsk, sk;
+
+	sk = io_get_fd(io);
+
+	nsk = accept(sk, (struct sockaddr *) &uaddr, &len);
+	if (nsk < 0) {
+		err = errno;
+		error("ATT UNIX socket accept: %s(%d)", strerror(err), err);
+		return TRUE;
+	}
+
+	DBG("ATT UNIX socket: %d", nsk);
+
+	return TRUE;
+}
+
+static void accept_watch_destroy(void *user_data)
+{
+	struct io *io = user_data;
+
+	io_destroy(io);
+}
+
 void gatt_init(void)
 {
+	struct sockaddr_un uaddr  = {
+		.sun_family     = AF_UNIX,
+		.sun_path       = "\0/bluetooth/unix_att",
+	};
+	struct io *io;
+	int sk, err;
+
 	DBG("Starting GATT server");
 
 	gatt_dbus_manager_register();
+
+	sk = socket(AF_UNIX, SOCK_SEQPACKET | SOCK_NONBLOCK | SOCK_CLOEXEC , 0);
+	if (sk < 0) {
+		err = errno;
+		error("ATT UNIX socket: %s(%d)", strerror(err), err);
+		return;
+	}
+
+	if (bind(sk, (struct sockaddr *) &uaddr, sizeof(uaddr)) < 0) {
+		err = errno;
+		error("binding ATT UNIX socket: %s(%d)", strerror(err), err);
+		close(sk);
+		return;
+	}
+
+	if (listen(sk, 5) < 0) {
+		err = errno;
+		error("listen ATT UNIX socket: %s(%d)", strerror(err), err);
+		close(sk);
+		return;
+	}
+
+	io = io_new(sk);
+	io_set_read_handler(io, unix_accept_cb, io, accept_watch_destroy);
 }
 
 void gatt_cleanup(void)
@@ -103,4 +168,5 @@ void gatt_cleanup(void)
 	DBG("Stopping GATT server");
 
 	gatt_dbus_manager_unregister();
+	g_source_remove(unix_watch);
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 07/18] gatt: Add external services tracking
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

From: Alvaro Silva <alvaro.silva@openbossa.org>

All primary services declarations provided by an external application
will be automatically inserted in the attribute database.
---
 src/gatt-dbus.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 109 insertions(+)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index fd614f9..000d7ae 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -39,15 +39,21 @@
 #include "log.h"
 
 #include "error.h"
+#include "gatt.h"
 #include "gatt-dbus.h"
 
 #define GATT_MGR_IFACE			"org.bluez.GattManager1"
+#define SERVICE_IFACE			"org.bluez.GattService1"
+
+#define REGISTER_TIMER         1
 
 struct external_app {
 	char *owner;
 	char *path;
 	GDBusClient *client;
+	GSList *proxies;
 	unsigned int watch;
+	guint register_timer;
 };
 
 static GSList *external_apps;
@@ -60,6 +66,36 @@ static int external_app_path_cmp(gconstpointer a, gconstpointer b)
 	return g_strcmp0(eapp->path, path);
 }
 
+static void proxy_added(GDBusProxy *proxy, void *user_data)
+{
+	struct external_app *eapp = user_data;
+	const char *interface, *path;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+	path = g_dbus_proxy_get_path(proxy);
+
+	DBG("path %s iface %s", path, interface);
+
+	if (g_strcmp0(interface, SERVICE_IFACE) != 0)
+		return;
+
+	eapp->proxies = g_slist_append(eapp->proxies, proxy);
+}
+
+static void proxy_removed(GDBusProxy *proxy, void *user_data)
+{
+	struct external_app *eapp = user_data;
+	const char *interface, *path;
+
+	interface = g_dbus_proxy_get_interface(proxy);
+	path = g_dbus_proxy_get_path(proxy);
+
+	DBG("path %s iface %s", path, interface);
+
+	eapp->proxies = g_slist_remove(eapp->proxies, proxy);
+}
+
+
 static void external_app_watch_destroy(gpointer user_data)
 {
 	struct external_app *eapp = user_data;
@@ -70,6 +106,9 @@ static void external_app_watch_destroy(gpointer user_data)
 
 	g_dbus_client_unref(eapp->client);
 
+	if (eapp->register_timer)
+		g_source_remove(eapp->register_timer);
+
 	g_free(eapp->owner);
 	g_free(eapp->path);
 	g_free(eapp);
@@ -99,9 +138,75 @@ static struct external_app *new_external_app(DBusConnection *conn,
 	eapp->client = client;
 	eapp->path = g_strdup(path);
 
+	g_dbus_client_set_proxy_handlers(client, proxy_added, proxy_removed,
+								NULL, eapp);
+
 	return eapp;
 }
 
+static int register_external_service(GDBusProxy *proxy)
+{
+	DBusMessageIter iter;
+	const char *uuid;
+	bt_uuid_t btuuid;
+
+	if (!g_dbus_proxy_get_property(proxy, "UUID", &iter))
+		return -EINVAL;
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+		return -EINVAL;
+
+	dbus_message_iter_get_basic(&iter, &uuid);
+
+	if (bt_string_to_uuid(&btuuid, uuid) < 0)
+		return -EINVAL;
+
+	if (btd_gatt_add_service(&btuuid) == NULL)
+		return -EINVAL;
+
+	return 0;
+}
+
+static gboolean finish_register(gpointer user_data)
+{
+	struct external_app *eapp = user_data;
+	GSList *list;
+
+	/*
+	 * It is not possible to detect when the last proxy object
+	 * was reported. "Proxy added" handler reports objects
+	 * added on demand or returned by GetManagedObjects().
+	 * This timer helps to register all the GATT declarations
+	 * (services, characteristics and descriptors) after fetching
+	 * all the D-Bus objects.
+	 */
+
+	eapp->register_timer = 0;
+
+	for (list = eapp->proxies; list; list = g_slist_next(list)) {
+		const char *interface, *path;
+		GDBusProxy *proxy = list->data;
+
+		interface = g_dbus_proxy_get_interface(proxy);
+		path = g_dbus_proxy_get_path(proxy);
+
+		if (g_strcmp0(SERVICE_IFACE, interface) != 0)
+			continue;
+
+		if (g_strcmp0(path, eapp->path) != 0)
+			continue;
+
+		if (register_external_service(proxy) < 0) {
+			DBG("Inconsistent external service: %s", path);
+			continue;
+		}
+
+		DBG("External service: %s", path);
+	}
+
+	return FALSE;
+}
+
 static DBusMessage *register_service(DBusConnection *conn,
 					DBusMessage *msg, void *user_data)
 {
@@ -109,6 +214,8 @@ static DBusMessage *register_service(DBusConnection *conn,
 	DBusMessageIter iter;
 	const char *path;
 
+	DBG("Registering GATT Service");
+
 	if (!dbus_message_iter_init(msg, &iter))
 		return btd_error_invalid_args(msg);
 
@@ -127,6 +234,8 @@ static DBusMessage *register_service(DBusConnection *conn,
 	external_apps = g_slist_prepend(external_apps, eapp);
 
 	DBG("New app %p: %s", eapp, path);
+	eapp->register_timer = g_timeout_add_seconds(REGISTER_TIMER,
+							finish_register, eapp);
 
 	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 06/18] gatt: Add helper for creating GATT services
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Andre Guedes
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

From: Andre Guedes <andre.guedes@openbossa.org>

This patch adds the btd_gatt_add_service() helper which adds a
GATT Service declaration to the local attribute database.
---
 lib/uuid.h |  5 +++++
 src/gatt.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gatt.h | 10 ++++++++++
 3 files changed, 74 insertions(+)

diff --git a/lib/uuid.h b/lib/uuid.h
index c24cee5..237145b 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -158,6 +158,11 @@ void bt_uuid_to_uuid128(const bt_uuid_t *src, bt_uuid_t *dst);
 int bt_uuid_to_string(const bt_uuid_t *uuid, char *str, size_t n);
 int bt_string_to_uuid(bt_uuid_t *uuid, const char *string);
 
+static inline int bt_uuid_len(const bt_uuid_t *uuid)
+{
+	return uuid->type / 8;
+}
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/src/gatt.c b/src/gatt.c
index e8b691a..f7b74d6 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -28,10 +28,69 @@
 #include <glib.h>
 
 #include "log.h"
+#include "lib/uuid.h"
+#include "attrib/att.h"
 
 #include "gatt-dbus.h"
 #include "gatt.h"
 
+/* Common GATT UUIDs */
+static const bt_uuid_t primary_uuid  = { .type = BT_UUID16,
+					.value.u16 = GATT_PRIM_SVC_UUID };
+
+struct btd_attribute {
+	uint16_t handle;
+	bt_uuid_t type;
+	uint16_t value_len;
+	uint8_t value[0];
+};
+
+static GList *local_attribute_db;
+static uint16_t next_handle = 0x0001;
+
+static int local_database_add(uint16_t handle, struct btd_attribute *attr)
+{
+	attr->handle = handle;
+
+	local_attribute_db = g_list_append(local_attribute_db, attr);
+
+	return 0;
+}
+
+struct btd_attribute *btd_gatt_add_service(const bt_uuid_t *uuid)
+{
+	uint16_t len = bt_uuid_len(uuid);
+	struct btd_attribute *attr = g_malloc0(sizeof(struct btd_attribute) +
+									len);
+
+	/*
+	 * Service DECLARATION
+	 *
+	 *   TYPE         ATTRIBUTE VALUE
+	 * +-------+---------------------------------+
+	 * |0x2800 | 0xYYYY...                       |
+	 * | (1)   | (2)                             |
+	 * +------+----------------------------------+
+	 * (1) - 2 octets: Primary/Secondary Service UUID
+	 * (2) - 2 or 16 octets: Service UUID
+	 */
+
+	attr->type = primary_uuid;
+
+	att_put_uuid(*uuid, attr->value);
+	attr->value_len = len;
+
+	if (local_database_add(next_handle, attr) < 0) {
+		g_free(attr);
+		return NULL;
+	}
+
+	/* TODO: missing overflow checking */
+	next_handle = next_handle + 1;
+
+	return attr;
+}
+
 void gatt_init(void)
 {
 	DBG("Starting GATT server");
diff --git a/src/gatt.h b/src/gatt.h
index 3a320b4..8dd1312 100644
--- a/src/gatt.h
+++ b/src/gatt.h
@@ -21,6 +21,16 @@
  *
  */
 
+struct btd_attribute;
+
 void gatt_init(void);
 
 void gatt_cleanup(void);
+
+/* btd_gatt_add_service - Add a service declaration to local attribute database.
+ * @uuid:	Service UUID.
+ *
+ * Returns a reference to service declaration attribute. In case of error,
+ * NULL is returned.
+ */
+struct btd_attribute *btd_gatt_add_service(const bt_uuid_t *uuid);
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 05/18] lib: Move GATT UUID to uuid.h
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

This patch moves GATT UUIDs definitions to a common header. uuid.h contains
helper functions to manipulate Bluetooth UUIDs and some common BR/EDR services
UUIDs.
---
 attrib/gatt.h | 25 -------------------------
 lib/uuid.h    | 25 +++++++++++++++++++++++++
 2 files changed, 25 insertions(+), 25 deletions(-)

diff --git a/attrib/gatt.h b/attrib/gatt.h
index 0f113e7..4fea3eb 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -24,31 +24,6 @@
 
 #include <bluetooth/sdp.h>
 
-/* GATT Profile Attribute types */
-#define GATT_PRIM_SVC_UUID		0x2800
-#define GATT_SND_SVC_UUID		0x2801
-#define GATT_INCLUDE_UUID		0x2802
-#define GATT_CHARAC_UUID		0x2803
-
-/* GATT Characteristic Types */
-#define GATT_CHARAC_DEVICE_NAME			0x2A00
-#define GATT_CHARAC_APPEARANCE			0x2A01
-#define GATT_CHARAC_PERIPHERAL_PRIV_FLAG	0x2A02
-#define GATT_CHARAC_RECONNECTION_ADDRESS	0x2A03
-#define GATT_CHARAC_PERIPHERAL_PREF_CONN	0x2A04
-#define GATT_CHARAC_SERVICE_CHANGED		0x2A05
-
-/* GATT Characteristic Descriptors */
-#define GATT_CHARAC_EXT_PROPER_UUID	0x2900
-#define GATT_CHARAC_USER_DESC_UUID	0x2901
-#define GATT_CLIENT_CHARAC_CFG_UUID	0x2902
-#define GATT_SERVER_CHARAC_CFG_UUID	0x2903
-#define GATT_CHARAC_FMT_UUID		0x2904
-#define GATT_CHARAC_AGREG_FMT_UUID	0x2905
-#define GATT_CHARAC_VALID_RANGE_UUID	0x2906
-#define GATT_EXTERNAL_REPORT_REFERENCE	0x2907
-#define GATT_REPORT_REFERENCE		0x2908
-
 /* Client Characteristic Configuration bit field */
 #define GATT_CLIENT_CHARAC_CFG_NOTIF_BIT	0x0001
 #define GATT_CLIENT_CHARAC_CFG_IND_BIT		0x0002
diff --git a/lib/uuid.h b/lib/uuid.h
index 95e5a9a..c24cee5 100644
--- a/lib/uuid.h
+++ b/lib/uuid.h
@@ -105,6 +105,31 @@ extern "C" {
 #define OBEX_MNS_UUID		"00001133-0000-1000-8000-00805f9b34fb"
 #define OBEX_MAP_UUID		"00001134-0000-1000-8000-00805f9b34fb"
 
+/* GATT UUIDs section */
+#define GATT_PRIM_SVC_UUID				0x2800
+#define GATT_SND_SVC_UUID				0x2801
+#define GATT_INCLUDE_UUID				0x2802
+#define GATT_CHARAC_UUID				0x2803
+
+/* GATT Characteristic Types */
+#define GATT_CHARAC_DEVICE_NAME				0x2A00
+#define GATT_CHARAC_APPEARANCE				0x2A01
+#define GATT_CHARAC_PERIPHERAL_PRIV_FLAG		0x2A02
+#define GATT_CHARAC_RECONNECTION_ADDRESS		0x2A03
+#define GATT_CHARAC_PERIPHERAL_PREF_CONN		0x2A04
+#define GATT_CHARAC_SERVICE_CHANGED			0x2A05
+
+/* GATT Characteristic Descriptors */
+#define GATT_CHARAC_EXT_PROPER_UUID			0x2900
+#define GATT_CHARAC_USER_DESC_UUID			0x2901
+#define GATT_CLIENT_CHARAC_CFG_UUID			0x2902
+#define GATT_SERVER_CHARAC_CFG_UUID			0x2903
+#define GATT_CHARAC_FMT_UUID				0x2904
+#define GATT_CHARAC_AGREG_FMT_UUID			0x2905
+#define GATT_CHARAC_VALID_RANGE_UUID			0x2906
+#define GATT_EXTERNAL_REPORT_REFERENCE			0x2907
+#define GATT_REPORT_REFERENCE				0x2908
+
 typedef struct {
 	enum {
 		BT_UUID_UNSPEC = 0,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 04/18] gatt: Add registering external service
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

From: Alvaro Silva <alvaro.silva@openbossa.org>

This patch allows external applications register a given service on
Bluez. Applications must provide an object path and a dictionary of
options. Options dictionary will be used later to provide additional
service information.
---
 src/gatt-dbus.c | 89 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 88 insertions(+), 1 deletion(-)

diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
index 183c611..fd614f9 100644
--- a/src/gatt-dbus.c
+++ b/src/gatt-dbus.c
@@ -26,22 +26,109 @@
 #endif
 
 #include <stdint.h>
+#include <errno.h>
 
 #include <glib.h>
 #include <dbus/dbus.h>
 #include <gdbus/gdbus.h>
 
+#include "adapter.h"
+#include "device.h"
+#include "lib/uuid.h"
 #include "dbus-common.h"
 #include "log.h"
 
+#include "error.h"
 #include "gatt-dbus.h"
 
 #define GATT_MGR_IFACE			"org.bluez.GattManager1"
 
+struct external_app {
+	char *owner;
+	char *path;
+	GDBusClient *client;
+	unsigned int watch;
+};
+
+static GSList *external_apps;
+
+static int external_app_path_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct external_app *eapp = a;
+	const char *path = b;
+
+	return g_strcmp0(eapp->path, path);
+}
+
+static void external_app_watch_destroy(gpointer user_data)
+{
+	struct external_app *eapp = user_data;
+
+	/* TODO: Remove from the database */
+
+	external_apps = g_slist_remove(external_apps, eapp);
+
+	g_dbus_client_unref(eapp->client);
+
+	g_free(eapp->owner);
+	g_free(eapp->path);
+	g_free(eapp);
+}
+
+static struct external_app *new_external_app(DBusConnection *conn,
+					const char *sender, const char *path)
+{
+	struct external_app *eapp;
+	GDBusClient *client;
+
+	client = g_dbus_client_new(conn, sender, "/");
+	if (client == NULL)
+		return NULL;
+
+	eapp = g_new0(struct external_app, 1);
+
+	eapp->watch = g_dbus_add_disconnect_watch(btd_get_dbus_connection(),
+			sender, NULL, eapp, external_app_watch_destroy);
+	if (eapp->watch == 0) {
+		g_dbus_client_unref(client);
+		g_free(eapp);
+		return NULL;
+	}
+
+	eapp->owner = g_strdup(sender);
+	eapp->client = client;
+	eapp->path = g_strdup(path);
+
+	return eapp;
+}
+
 static DBusMessage *register_service(DBusConnection *conn,
 					DBusMessage *msg, void *user_data)
 {
-	return dbus_message_new_method_return(msg);
+	struct external_app *eapp;
+	DBusMessageIter iter;
+	const char *path;
+
+	if (!dbus_message_iter_init(msg, &iter))
+		return btd_error_invalid_args(msg);
+
+	if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_OBJECT_PATH)
+		return btd_error_invalid_args(msg);
+
+	dbus_message_iter_get_basic(&iter, &path);
+
+	if (g_slist_find_custom(external_apps, path, external_app_path_cmp))
+		return btd_error_already_exists(msg);
+
+	eapp = new_external_app(conn, dbus_message_get_sender(msg), path);
+	if (eapp == NULL)
+		return btd_error_failed(msg, "Not enough resources");
+
+	external_apps = g_slist_prepend(external_apps, eapp);
+
+	DBG("New app %p: %s", eapp, path);
+
+	return g_dbus_create_reply(msg, DBUS_TYPE_INVALID);
 }
 
 static DBusMessage *unregister_service(DBusConnection *conn,
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 03/18] gatt: Register Manager D-Bus Interface
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

From: Alvaro Silva <alvaro.silva@openbossa.org>

This patch registers GATT Service Manager D-Bus Interface. This
interface implements the methods to allow external application register
and unregister GATT Services.
---
 Makefile.am     |  1 +
 src/gatt-dbus.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gatt-dbus.h | 25 +++++++++++++++++++
 src/gatt.c      |  9 +++++++
 4 files changed, 110 insertions(+)
 create mode 100644 src/gatt-dbus.c
 create mode 100644 src/gatt-dbus.h

diff --git a/Makefile.am b/Makefile.am
index 101d5de..fbae2c8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
 			src/adapter.h src/adapter.c \
 			src/profile.h src/profile.c \
 			src/service.h src/service.c \
+			src/gatt-dbus.h src/gatt-dbus.c \
 			src/gatt.h src/gatt.c \
 			src/device.h src/device.c src/attio.h \
 			src/dbus-common.c src/dbus-common.h \
diff --git a/src/gatt-dbus.c b/src/gatt-dbus.c
new file mode 100644
index 0000000..183c611
--- /dev/null
+++ b/src/gatt-dbus.c
@@ -0,0 +1,75 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdint.h>
+
+#include <glib.h>
+#include <dbus/dbus.h>
+#include <gdbus/gdbus.h>
+
+#include "dbus-common.h"
+#include "log.h"
+
+#include "gatt-dbus.h"
+
+#define GATT_MGR_IFACE			"org.bluez.GattManager1"
+
+static DBusMessage *register_service(DBusConnection *conn,
+					DBusMessage *msg, void *user_data)
+{
+	return dbus_message_new_method_return(msg);
+}
+
+static DBusMessage *unregister_service(DBusConnection *conn,
+					DBusMessage *msg, void *user_data)
+{
+	return dbus_message_new_method_return(msg);
+}
+
+static const GDBusMethodTable methods[] = {
+	{ GDBUS_EXPERIMENTAL_METHOD("RegisterService",
+				GDBUS_ARGS({ "service", "o"},
+						{ "options", "a{sv}"}),
+				NULL, register_service) },
+	{ GDBUS_EXPERIMENTAL_METHOD("UnregisterService",
+				GDBUS_ARGS({"service", "o"}),
+				NULL, unregister_service) },
+	{ }
+};
+
+gboolean gatt_dbus_manager_register(void)
+{
+	return g_dbus_register_interface(btd_get_dbus_connection(),
+					"/org/bluez", GATT_MGR_IFACE,
+					methods, NULL, NULL, NULL, NULL);
+}
+
+void gatt_dbus_manager_unregister(void)
+{
+	g_dbus_unregister_interface(btd_get_dbus_connection(), "/org/bluez",
+							GATT_MGR_IFACE);
+}
diff --git a/src/gatt-dbus.h b/src/gatt-dbus.h
new file mode 100644
index 0000000..310cfa9
--- /dev/null
+++ b/src/gatt-dbus.h
@@ -0,0 +1,25 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+gboolean gatt_dbus_manager_register(void);
+void gatt_dbus_manager_unregister(void);
diff --git a/src/gatt.c b/src/gatt.c
index 06619f0..e8b691a 100644
--- a/src/gatt.c
+++ b/src/gatt.c
@@ -25,14 +25,23 @@
 #include <config.h>
 #endif
 
+#include <glib.h>
+
+#include "log.h"
+
+#include "gatt-dbus.h"
 #include "gatt.h"
 
 void gatt_init(void)
 {
+	DBG("Starting GATT server");
 
+	gatt_dbus_manager_register();
 }
 
 void gatt_cleanup(void)
 {
+	DBG("Stopping GATT server");
 
+	gatt_dbus_manager_unregister();
 }
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 02/18] gatt: Add stub for gatt.{c, h} files
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi, Alvaro Silva
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

From: Alvaro Silva <alvaro.silva@openbossa.org>

These files implement functions to handle ATT transactions, and expose
functions to allow other entities to manage GATT based services. It
is a replacement for src/attrib-server.c.
---
 Makefile.am |  1 +
 src/gatt.c  | 38 ++++++++++++++++++++++++++++++++++++++
 src/gatt.h  | 26 ++++++++++++++++++++++++++
 src/main.c  |  4 ++++
 4 files changed, 69 insertions(+)
 create mode 100644 src/gatt.c
 create mode 100644 src/gatt.h

diff --git a/Makefile.am b/Makefile.am
index 3a1e6dc..101d5de 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -146,6 +146,7 @@ src_bluetoothd_SOURCES = $(builtin_sources) \
 			src/adapter.h src/adapter.c \
 			src/profile.h src/profile.c \
 			src/service.h src/service.c \
+			src/gatt.h src/gatt.c \
 			src/device.h src/device.c src/attio.h \
 			src/dbus-common.c src/dbus-common.h \
 			src/eir.h src/eir.c \
diff --git a/src/gatt.c b/src/gatt.c
new file mode 100644
index 0000000..06619f0
--- /dev/null
+++ b/src/gatt.c
@@ -0,0 +1,38 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "gatt.h"
+
+void gatt_init(void)
+{
+
+}
+
+void gatt_cleanup(void)
+{
+
+}
diff --git a/src/gatt.h b/src/gatt.h
new file mode 100644
index 0000000..3a320b4
--- /dev/null
+++ b/src/gatt.h
@@ -0,0 +1,26 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2014  Instituto Nokia de Tecnologia - INdT
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+void gatt_init(void);
+
+void gatt_cleanup(void);
diff --git a/src/main.c b/src/main.c
index 91d90b4..fccc838 100644
--- a/src/main.c
+++ b/src/main.c
@@ -55,6 +55,7 @@
 #include "dbus-common.h"
 #include "agent.h"
 #include "profile.h"
+#include "gatt.h"
 #include "systemd.h"
 
 #define BLUEZ_NAME "org.bluez"
@@ -545,6 +546,8 @@ int main(int argc, char *argv[])
 
 	g_dbus_set_flags(gdbus_flags);
 
+	gatt_init();
+
 	if (option_compat == TRUE)
 		sdp_flags |= SDP_SERVER_COMPAT;
 
@@ -595,6 +598,7 @@ int main(int argc, char *argv[])
 	btd_profile_cleanup();
 	btd_agent_cleanup();
 	btd_device_cleanup();
+	gatt_cleanup();
 
 	adapter_cleanup();
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 01/18] doc: Add GATT API
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390845656-29880-1-git-send-email-claudio.takahasi@openbossa.org>

This patch proposes an unified GATT API for local and remote services.
---
 doc/gatt-api.txt | 145 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 145 insertions(+)
 create mode 100644 doc/gatt-api.txt

diff --git a/doc/gatt-api.txt b/doc/gatt-api.txt
new file mode 100644
index 0000000..2d92f03
--- /dev/null
+++ b/doc/gatt-api.txt
@@ -0,0 +1,145 @@
+BlueZ D-Bus GATT API description
+********************************
+
+GATT local and remote services share the same high-level D-Bus API. Local
+refers to GATT based service exported by a BlueZ plugin or an external
+application. Remote refers to GATT services exported by the peer.
+
+BlueZ acts as a proxy, translating ATT operations to D-Bus method calls and
+Properties (or the opposite). Support for D-Bus Object Manager is mandatory for
+external services to allow seamless GATT declarations (Service, Characteristic
+and Descriptors) discovery.
+
+Service hierarchy
+=================
+
+GATT remote and local service representation. Object path for local services
+is freely definable.
+
+External applications implementing local services must register the services
+using GattManager1 registration method and must implement the methods and
+properties defined in GattService1 interface.
+
+Service		org.bluez
+Interface	org.bluez.GattService1 [Experimental]
+Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX
+
+Methods		void Release()
+
+			Release this service. At this point, it will not be
+			used by BlueZ anymore and can be destroyed by the
+			owner. Method applicable to external GATT services
+			implementations only (GATT servers).
+
+Properties	string UUID [read-only]
+
+			128-bit service UUID.
+
+		array{object} Includes [read-only]: Not implemented
+
+			Array of object paths representing the included
+			services of this service.
+
+
+Characteristic hierarchy
+========================
+
+For local GATT defined services, the object paths need to follow the service
+path hierarchy and are freely definable.
+
+Service		org.bluez
+Interface	org.bluez.GattCharacteristic1 [Experimental]
+Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY
+
+Properties	string UUID [read-only]
+
+			128-bit characteristic UUID.
+
+		object Service [read-only]
+
+			Object path of the GATT service the characteristc
+			belongs to.
+
+		array{byte} Value [read-write]
+
+			Value read from the remote Bluetooth device or from
+			the external application implementing GATT services.
+
+		array{string} Flags [read-only, optional]
+
+			Defines how the characteristic value can be used. See
+			Core spec page 1898, "Table 3.5: Characteristic
+			Properties bit field" and page 1900, "Table 3.8:
+			Characteristic Extended Properties bit field". Allowed
+			values: "broadcast", "read", "write-without-response",
+			"write", "notify", "indicate",
+			"authenticated-signed-writes", "reliable-write", and
+			"writable-auxiliaries".
+
+
+Characteristic Descriptors hierarchy
+====================================
+
+Local or remote GATT characteristic descriptors hierarchy.
+
+Service		org.bluez
+Interface	org.bluez.GattDescriptor1 [Experimental]
+Object path	[variable prefix]/{hci0,hci1,...}/dev_XX_XX_XX_XX_XX_XX/serviceXX/charYYYY/descriptorZZZ
+
+Properties	string UUID [read-only]
+
+			128-bit descriptor UUID.
+
+		object Characteristic [read-only]
+
+			Object path of the GATT characteristc the descriptor
+			belongs to.
+
+		array{byte} Value [read-write]
+
+			Raw characteristic descriptor value read from the
+			remote Bluetooth device or from the external
+			application implementing GATT services.
+
+		string Permissions [read-only]: To be defined
+
+			Defines read/write authentication and authorization
+			requirements.
+
+Service Manager hierarchy
+=============================
+
+Service Manager allows external applications to register GATT based
+services. Services must follow the API for Service and Characteristic
+described above.
+
+Local GATT services, characteristics and characteristic descriptors are
+discovered automatically using the D-Bus Object Manager interface.
+
+Service		org.bluez
+Interface	org.bluez.GattManager1 [Experimental]
+Object path	/org/bluez
+
+Methods		RegisterService(object service, dict options)
+
+			Registers remote application service exported under
+			interface GattService1. Characteristic objects must
+			be hierarchical to their service and must use the
+			interface GattCharacteristic1. D-Bus Object Manager
+			is used to fetch the exported objects.
+
+			"service" object path together with the D-Bus system
+			bus connection ID define the identification of the
+			application registering a GATT based service.
+
+			Possible errors: org.bluez.Error.InvalidArguments
+					 org.bluez.Error.AlreadyExists
+
+		UnregisterService(object service)
+
+			This unregisters the service that has been
+			previously registered. The object path parameter
+			must match the same value that has been used
+			on registration.
+
+			Possible errors: org.bluez.Error.DoesNotExist
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH BlueZ v4 00/18] GATT API: External Services
From: Claudio Takahasi @ 2014-01-27 18:00 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: claudio.takahasi
In-Reply-To: <1390398025-28340-1-git-send-email-claudio.takahasi@openbossa.org>

This patchset implements the minimal support for adding local services
declarations.

Limitation: Remove services and multiple services exported by the same
remote will be implemented the next series.

Changes from PATCH v3 to PATCH v4:
* Rebase
* src/gatt.c: Replaced GIOChannel/GAttrib by "io".

Changes from PATCH v2 to PATCH v3:
* Rebase
* Interfaces renamed: s/GattServiceManager1/GattManager1,
  s/Characteristic1/GattCharacteristic1, s/Descriptor/GattDescriptor1
* test/gatt-service.c: s/fprintf/printf

Changes from PATCH v1 to PATCH v2:
* Rebase
* Included patch "doc: Add GATT API"
* Interfaces renamed: s/Service1/GattService1, and
  s/ServiceManager1/GattServiceManager1
* Removed patch "gatt: Implement UnregisterService" from this patchset

Changes from PATCH v0 to PATCH v1:
* Rebase

Changes from RFC v0 to PATCH v0:
* Changed copyright year : s/2013/2014
* Fixed coding style
* Added gatt-service binary to gitignore
* Added extra comment in the source code

Features:
* API for internal and external services declaration
* Unix socket for testing purpose: services are exported through unix
  sockets to avoid breaking the current attribute server.

How to test:
Run bluetoothd with EXPERIMENTAL flag (-E)
Replace /etc/dbus-1/system.d/bluetooth.conf and reload DBus settings
$gatttool -L --primary (or interactive mode)

Roughly upstreaming plan (steps):
* GATT Server: External Services -> pathset GATT API: External Services
* GATT Server: External Characteristics (Server)
* GATT Server: External Descriptors (Server)
* Replace attribute server
* Remove ATTIO and automatic connection mechanism from userspace
* Fix all GATT internal plugins
* GATT Client: Remote Services

Alvaro Silva (6):
  gatt: Add stub for gatt.{c, h} files
  gatt: Register Manager D-Bus Interface
  gatt: Add registering external service
  gatt: Add external services tracking
  gatt: Register ATT command/event handler
  gatt: Add Discover All Primary Services

Andre Guedes (1):
  gatt: Add helper for creating GATT services

Claudio Takahasi (11):
  doc: Add GATT API
  lib: Move GATT UUID to uuid.h
  gatt: Add server unix socket
  gattrib: Use default ATT LE MTU for non-standard sockets
  test: Add external service GATT skeleton
  gitignore: Add test/gatt-service
  test: Add signal handling for gatt-service
  test: Add registering external service
  gatttool: Add unix socket connect
  gatttool: Add unix socket support for interactive mode
  bluetooth.conf: Add ObjectManager interface

 .gitignore           |   1 +
 Makefile.am          |   2 +
 Makefile.tools       |   5 +
 attrib/gatt.h        |  25 ----
 attrib/gattrib.c     |  16 +--
 attrib/gatttool.c    |  27 +++-
 attrib/gatttool.h    |   1 +
 attrib/interactive.c |  19 +--
 attrib/utils.c       |  54 ++++++++
 doc/gatt-api.txt     | 145 ++++++++++++++++++++
 lib/uuid.h           |  30 ++++
 src/bluetooth.conf   |   1 +
 src/gatt-dbus.c      | 271 ++++++++++++++++++++++++++++++++++++
 src/gatt-dbus.h      |  25 ++++
 src/gatt.c           | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gatt.h           |  36 +++++
 src/main.c           |   4 +
 test/gatt-service.c  | 282 ++++++++++++++++++++++++++++++++++++++
 18 files changed, 1275 insertions(+), 48 deletions(-)
 create mode 100644 doc/gatt-api.txt
 create mode 100644 src/gatt-dbus.c
 create mode 100644 src/gatt-dbus.h
 create mode 100644 src/gatt.c
 create mode 100644 src/gatt.h
 create mode 100644 test/gatt-service.c

-- 
1.8.3.1

^ permalink raw reply

* Re: [PATCH BlueZ 4/4] emulator: Fix crash if socket(AF_ALG) is not supported by the kernel
From: Johan Hedberg @ 2014-01-27 17:59 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1390700642-10482-5-git-send-email-anderson.lizardo@openbossa.org>

Hi Lizardo,

On Sat, Jan 25, 2014, Anderson Lizardo wrote:
> In this situation, smp_stop() was being called with NULL pointer.
> 
> Crash detected by valgrind:
> 
> ==7925== Invalid read of size 4
> ==7925==    at 0x8052F18: smp_stop (smp.c:480)
> ==7925==    by 0x8052542: bthost_stop (bthost.c:2073)
> ==7925==    by 0x805521D: hciemu_unref (hciemu.c:372)
> ==7925==    by 0x8058C65: test_post_teardown (android-tester.c:464)
> ==7925==    by 0x8055DE7: tester_teardown_complete (tester.c:533)
> ==7925==    by 0x8055501: teardown_callback (tester.c:312)
> ==7925==    by 0x408348F: g_idle_dispatch (gmain.c:5250)
> ==7925==    by 0x4086A75: g_main_context_dispatch (gmain.c:3065)
> ==7925==    by 0x4086E14: g_main_context_iterate.isra.23 (gmain.c:3712)
> ==7925==    by 0x40872FA: g_main_loop_run (gmain.c:3906)
> ==7925==    by 0x41744D2: (below main) (libc-start.c:226)
> ==7925==  Address 0x8 is not stack'd, malloc'd or (recently) free'd
> ---
>  emulator/bthost.c | 6 ++++--
>  1 file changed, 4 insertions(+), 2 deletions(-)

This patch has been applied. Thanks.

Johan

^ permalink raw reply

* Re: [PATCH BlueZ 1/2] unit/test-ringbuf: Fix indentation
From: Johan Hedberg @ 2014-01-27 17:56 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: linux-bluetooth
In-Reply-To: <1390700061-18666-1-git-send-email-anderson.lizardo@openbossa.org>

Hi Lizardo,

On Sat, Jan 25, 2014, Anderson Lizardo wrote:
> ---
>  unit/test-ringbuf.c | 3 ++-
>  1 file changed, 2 insertions(+), 1 deletion(-)

Both patches have been applied. Thanks.

Johan

^ permalink raw reply

* [PATCH 2/2] android/avctp: Trivial cleanup code
From: Andrei Emeltchenko @ 2014-01-27 16:01 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390838504-25456-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Avoid extra header calculation and fix wrong line indentation.
---
 android/avctp.c | 5 ++---
 1 file changed, 2 insertions(+), 3 deletions(-)

diff --git a/android/avctp.c b/android/avctp.c
index 615fecf..6f9b33b 100644
--- a/android/avctp.c
+++ b/android/avctp.c
@@ -798,8 +798,7 @@ failed:
 	return FALSE;
 }
 
-static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
-				gpointer data)
+static gboolean session_cb(GIOChannel *chan, GIOCondition cond, gpointer data)
 {
 	struct avctp *session = data;
 	struct avctp_channel *control = session->control;
@@ -836,7 +835,7 @@ static gboolean session_cb(GIOChannel *chan, GIOCondition cond,
 
 	ret -= sizeof(struct avc_header);
 
-	operands = buf + sizeof(struct avctp_header) + sizeof(struct avc_header);
+	operands = (uint8_t *) avc + sizeof(struct avc_header);
 	operand_count = ret;
 
 	if (avctp->cr == AVCTP_RESPONSE) {
-- 
1.8.3.2


^ permalink raw reply related

* [PATCH 1/2] unit/avdtp: trivial: Remove empty line
From: Andrei Emeltchenko @ 2014-01-27 16:01 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 unit/test-avdtp.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/unit/test-avdtp.c b/unit/test-avdtp.c
index 4726c4b..8fe5ce3 100644
--- a/unit/test-avdtp.c
+++ b/unit/test-avdtp.c
@@ -216,7 +216,6 @@ static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
 	return TRUE;
 }
 
-
 static struct context *context_new(uint16_t version, uint16_t imtu,
 					uint16_t omtu, gconstpointer data)
 {
-- 
1.8.3.2


^ permalink raw reply related

* [PATCHv2] avctp: Fix unchecked return value
From: Andrei Emeltchenko @ 2014-01-27 15:59 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <CAJdJm_P5JwjNhRuqz0gFYJ7QZMPmcHNVSvSa+SAQ11ftM8z0WQ@mail.gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

Refactor code so that ioctl() return value is checked.
---
 profiles/audio/avctp.c | 47 +++++++++++++++++++++++++++++++++++++----------
 1 file changed, 37 insertions(+), 10 deletions(-)

diff --git a/profiles/audio/avctp.c b/profiles/audio/avctp.c
index 6fd1454..bf44f9c 100644
--- a/profiles/audio/avctp.c
+++ b/profiles/audio/avctp.c
@@ -1027,27 +1027,54 @@ static int uinput_create(char *name)
 		err = -errno;
 		error("Can't write device information: %s (%d)",
 						strerror(-err), -err);
-		close(fd);
-		return err;
+		goto fail;
+	}
+
+	if (ioctl(fd, UI_SET_EVBIT, EV_KEY) < 0) {
+		err = -errno;
+		error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
+		goto fail;
 	}
 
-	ioctl(fd, UI_SET_EVBIT, EV_KEY);
-	ioctl(fd, UI_SET_EVBIT, EV_REL);
-	ioctl(fd, UI_SET_EVBIT, EV_REP);
-	ioctl(fd, UI_SET_EVBIT, EV_SYN);
+	if (ioctl(fd, UI_SET_EVBIT, EV_REL) < 0) {
+		err = -errno;
+		error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
+		goto fail;
+	}
 
-	for (i = 0; key_map[i].name != NULL; i++)
-		ioctl(fd, UI_SET_KEYBIT, key_map[i].uinput);
+	if (ioctl(fd, UI_SET_EVBIT, EV_REP) < 0) {
+		err = -errno;
+		error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
+		goto fail;
+	}
+
+	if (ioctl(fd, UI_SET_EVBIT, EV_SYN) < 0) {
+		err = -errno;
+		error("ioctl UI_SET_EVBIT: %s (%d)", strerror(-err), -err);
+		goto fail;
+	}
+
+	for (i = 0; key_map[i].name != NULL; i++) {
+		if (ioctl(fd, UI_SET_KEYBIT, key_map[i].uinput) < 0) {
+			err = -errno;
+			error("ioctl UI_SET_KEYBIT: %s (%d)", strerror(-err),
+									-err);
+			goto fail;
+		}
+	}
 
 	if (ioctl(fd, UI_DEV_CREATE, NULL) < 0) {
 		err = -errno;
 		error("Can't create uinput device: %s (%d)",
 						strerror(-err), -err);
-		close(fd);
-		return err;
+		goto fail;
 	}
 
 	return fd;
+
+fail:
+	close(fd);
+	return err;
 }
 
 static void init_uinput(struct avctp *session)
-- 
1.8.3.2


^ permalink raw reply related

* [RFC] unit/avctp: Add initial AVCTP test setup
From: Andrei Emeltchenko @ 2014-01-27 15:56 UTC (permalink / raw)
  To: linux-bluetooth
In-Reply-To: <1390838187-25006-1-git-send-email-Andrei.Emeltchenko.news@gmail.com>

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

---
 Makefile.am       |   8 ++
 unit/test-avctp.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 270 insertions(+)
 create mode 100644 unit/test-avctp.c

diff --git a/Makefile.am b/Makefile.am
index 3a1e6dc..1a44a9f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -273,6 +273,14 @@ unit_test_avdtp_SOURCES = unit/test-avdtp.c \
 				android/avdtp.c android/avdtp.h
 unit_test_avdtp_LDADD = @GLIB_LIBS@
 
+unit_tests += unit/test-avctp
+
+unit_test_avctp_SOURCES = unit/test-avctp.c \
+				src/shared/util.h src/shared/util.c \
+				src/log.h src/log.c \
+				android/avctp.c android/avctp.h
+unit_test_avctp_LDADD = @GLIB_LIBS@
+
 unit_tests += unit/test-gdbus-client
 
 unit_test_gdbus_client_SOURCES = unit/test-gdbus-client.c
diff --git a/unit/test-avctp.c b/unit/test-avctp.c
new file mode 100644
index 0000000..236b34a
--- /dev/null
+++ b/unit/test-avctp.c
@@ -0,0 +1,262 @@
+/*
+ *
+ *  BlueZ - Bluetooth protocol stack for Linux
+ *
+ *  Copyright (C) 2012  Intel Corporation. All rights reserved.
+ *
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ *
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <unistd.h>
+#include <stdlib.h>
+#include <stdbool.h>
+#include <inttypes.h>
+#include <string.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+
+#include <glib.h>
+
+#include "src/shared/util.h"
+#include "src/log.h"
+
+#include "android/avctp.h"
+
+struct test_pdu {
+	bool valid;
+	bool fragmented;
+	const uint8_t *data;
+	size_t size;
+};
+
+struct test_data {
+	char *test_name;
+	struct test_pdu *pdu_list;
+};
+
+struct context {
+	GMainLoop *main_loop;
+	struct avctp *session;
+	guint source;
+	guint process;
+	int fd;
+	unsigned int pdu_offset;
+	const struct test_data *data;
+};
+
+#define data(args...) ((const unsigned char[]) { args })
+
+#define raw_pdu(args...)					\
+	{							\
+		.valid = true,					\
+		.data = data(args),				\
+		.size = sizeof(data(args)),			\
+	}
+
+#define frg_pdu(args...)					\
+	{							\
+		.valid = true,					\
+		.fragmented = true,				\
+		.data = data(args),				\
+		.size = sizeof(data(args)),			\
+	}
+
+#define define_test(name, function, args...)				\
+	do {								\
+		const struct test_pdu pdus[] = {			\
+			args, { }					\
+		};							\
+		static struct test_data data;				\
+		data.test_name = g_strdup(name);			\
+		data.pdu_list = g_malloc(sizeof(pdus));			\
+		memcpy(data.pdu_list, pdus, sizeof(pdus));		\
+		g_test_add_data_func(name, &data, function);		\
+	} while (0)
+
+static void test_debug(const char *str, void *user_data)
+{
+	const char *prefix = user_data;
+
+	g_print("%s%s\n", prefix, str);
+}
+
+static void test_free(gconstpointer user_data)
+{
+	const struct test_data *data = user_data;
+
+	g_free(data->test_name);
+	g_free(data->pdu_list);
+}
+
+static gboolean context_quit(gpointer user_data)
+{
+	struct context *context = user_data;
+
+	if (context->process > 0)
+		g_source_remove(context->process);
+
+	g_main_loop_quit(context->main_loop);
+
+	return FALSE;
+}
+
+static gboolean send_pdu(gpointer user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	ssize_t len;
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	len = write(context->fd, pdu->data, pdu->size);
+
+	if (g_test_verbose())
+		util_hexdump('<', pdu->data, len, test_debug, "AVCTP: ");
+
+	g_assert_cmpint(len, ==, pdu->size);
+
+	if (pdu->fragmented)
+		return send_pdu(user_data);
+
+	context->process = 0;
+	return FALSE;
+}
+
+static void context_process(struct context *context)
+{
+	if (!context->data->pdu_list[context->pdu_offset].valid) {
+		context_quit(context);
+		return;
+	}
+
+	context->process = g_idle_add(send_pdu, context);
+}
+
+static gboolean test_handler(GIOChannel *channel, GIOCondition cond,
+							gpointer user_data)
+{
+	struct context *context = user_data;
+	const struct test_pdu *pdu;
+	unsigned char buf[512];
+	ssize_t len;
+	int fd;
+
+	g_print("%s\n", __func__);
+
+	pdu = &context->data->pdu_list[context->pdu_offset++];
+
+	if (cond & (G_IO_NVAL | G_IO_ERR | G_IO_HUP)) {
+		context->source = 0;
+		g_print("%s: cond %x\n", __func__, cond);
+		if (g_str_equal(context->data->test_name, "/Test small packet"))
+			return context_quit(context);
+
+		return FALSE;
+	}
+
+	fd = g_io_channel_unix_get_fd(channel);
+
+	len = read(fd, buf, sizeof(buf));
+
+	g_assert(len > 0);
+
+	if (g_test_verbose())
+		util_hexdump('>', buf, len, test_debug, "AVCTP: ");
+
+	g_assert_cmpint(len, ==, pdu->size);
+
+	g_assert(memcmp(buf, pdu->data, pdu->size) == 0);
+
+	if (!pdu->fragmented)
+		context_process(context);
+
+	g_print("Test handler ended\n");
+
+	return TRUE;
+}
+
+static struct context *create_context(uint16_t version, gconstpointer data)
+{
+	struct context *context = g_new0(struct context, 1);
+	GIOChannel *channel;
+	int err, sv[2];
+
+	context->main_loop = g_main_loop_new(NULL, FALSE);
+	g_assert(context->main_loop);
+
+	err = socketpair(AF_UNIX, SOCK_SEQPACKET | SOCK_CLOEXEC, 0, sv);
+	g_assert(err == 0);
+
+	context->session = avctp_new(sv[0], 672, 672, version);
+	g_assert(context->session != NULL);
+
+	channel = g_io_channel_unix_new(sv[1]);
+
+	g_io_channel_set_close_on_unref(channel, TRUE);
+	g_io_channel_set_encoding(channel, NULL, NULL);
+	g_io_channel_set_buffered(channel, FALSE);
+
+	context->source = g_io_add_watch(channel,
+				G_IO_IN | G_IO_HUP | G_IO_ERR | G_IO_NVAL,
+				test_handler, context);
+	g_assert(context->source > 0);
+
+	g_io_channel_unref(channel);
+
+	context->fd = sv[1];
+	context->data = data;
+
+	return context;
+}
+
+static void execute_context(struct context *context)
+{
+	g_main_loop_run(context->main_loop);
+
+	if (context->source > 0)
+		g_source_remove(context->source);
+
+	g_main_loop_unref(context->main_loop);
+
+	test_free(context->data);
+	g_free(context);
+}
+
+static void test_server(gconstpointer data)
+{
+	struct context *context = create_context(0x0100, data);
+
+	g_idle_add(send_pdu, context);
+
+	execute_context(context);
+}
+
+int main(int argc, char *argv[])
+{
+	g_test_init(&argc, &argv, NULL);
+
+	if (g_test_verbose())
+		__btd_log_init("*", 0);
+
+	define_test("/Test small packet", test_server, raw_pdu(0x00, 0x00));
+
+	return g_test_run();
+}
-- 
1.8.3.2


^ permalink raw reply related

* [RFC] Initial avctp test
From: Andrei Emeltchenko @ 2014-01-27 15:56 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

This is initial invalid packet size test, sent as RFC since I am not
sure what might be tested for avctp. 

Andrei Emeltchenko (1):
  unit/avctp: Add initial AVCTP test setup

 Makefile.am       |   8 ++
 unit/test-avctp.c | 262 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 270 insertions(+)
 create mode 100644 unit/test-avctp.c

-- 
1.8.3.2


^ permalink raw reply

* Getting channel info for LE scan
From: Robert @ 2014-01-27 15:08 UTC (permalink / raw)
  To: linux-bluetooth

Hello,

I'm looking to extract the channel information for each lescan result 
but this isn't obviously available to me.  Is such information held in 
the hci event
  perhaps?

Thanks for any help,
Rob.

^ permalink raw reply

* Re: [PATCH 3/3] Bluetooth: Fix CID initialization for fixed channels
From: Marcel Holtmann @ 2014-01-27 13:51 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: BlueZ development
In-Reply-To: <1390687809-14408-3-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> Fixed channels have the same source and destination CID. Ensure that the
> values get properly initialized when receiving incoming connections and
> deriving values from the parent socket.
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/l2cap_core.c | 2 --
> net/bluetooth/l2cap_sock.c | 5 +++++
> 2 files changed, 5 insertions(+), 2 deletions(-)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* Re: [PATCH 1/3] Bluetooth: Fix BT_SECURITY socket option for fixed channels (ATT)
From: Marcel Holtmann @ 2014-01-27 13:50 UTC (permalink / raw)
  To: Johan Hedberg; +Cc: BlueZ development
In-Reply-To: <1390687809-14408-1-git-send-email-johan.hedberg@gmail.com>

Hi Johan,

> The BT_SECURITY option should also be allowed for fixed channels, so
> punch the appropriate hole for it when checking for the channel type.
> The main user of fixed CID user space sockets is right now ATT (which is
> broken without this patch).
> 
> Signed-off-by: Johan Hedberg <johan.hedberg@intel.com>
> ---
> net/bluetooth/l2cap_sock.c | 2 ++
> 1 file changed, 2 insertions(+)

patch has been applied to bluetooth-next tree.

Regards

Marcel


^ permalink raw reply

* [PATCH] unit/ringbuf: Fix memory leak
From: Andrei Emeltchenko @ 2014-01-27  8:36 UTC (permalink / raw)
  To: linux-bluetooth

From: Andrei Emeltchenko <andrei.emeltchenko@intel.com>

free allocated memory before exit
---
 src/shared/ringbuf.c | 7 ++++++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/src/shared/ringbuf.c b/src/shared/ringbuf.c
index 3e5c7d3..d59dc5c 100644
--- a/src/shared/ringbuf.c
+++ b/src/shared/ringbuf.c
@@ -228,9 +228,14 @@ int ringbuf_vprintf(struct ringbuf *ringbuf, const char *format, va_list ap)
 		return -1;
 
 	len = vasprintf(&str, format, ap);
-	if (len < 0 || (size_t) len > avail)
+	if (len < 0)
 		return -1;
 
+	if ((size_t) len > avail) {
+		free(str);
+		return -1;
+	}
+
 	/* Determine possible length of string before wrapping */
 	offset = ringbuf->in & (ringbuf->size - 1);
 	end = MIN((size_t) len, ringbuf->size - offset);
-- 
1.8.3.2


^ permalink raw reply related

* Re: [PATCH] Rename adapter_remove_device to btd_adapter_remove_device
From: Petri Gynther @ 2014-01-27  4:07 UTC (permalink / raw)
  To: linux-bluetooth, johan.hedberg
In-Reply-To: <20140125221329.GB14531@x220.p-661hnu-f1>

Hi Johan,

I would need this for the IR-assist device discovery plugin that I'm
writing. Basically, I have a HID remote control which is not
discoverable (but it is connectable). When this HID remote is in
unpaired state, it sends its BD address to the host via IR. The plugin
will get the BD address and do the following:

device = btd_adapter_find_device(adapter, &device_bdaddr);
if (device) {
    /* remove old pairing and device info */
    btd_device_set_temporary(device, TRUE);
    btd_adapter_remove_device(adapter, device);
}

/* (re)create the device */
device = btd_adapter_get_device(adapter, &device_bdaddr, BDADDR_BREDR);
btd_device_device_set_name(device, ...);
btd_device_set_pnpid(device, ...);
btd_device_set_temporary(device, FALSE);

-- Petri

On Sat, Jan 25, 2014 at 2:13 PM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Hi Petri,
>
> On Fri, Jan 24, 2014, Petri Gynther wrote:
>> Allow this symbol to be exported and usable from external plugins.
>> ---
>>  src/adapter.c | 14 +++++++-------
>>  src/adapter.h |  3 +++
>>  2 files changed, 10 insertions(+), 7 deletions(-)
>
> The patch looks fine, but we usually don't export symbols without
> knowing that there exists a valid use case for it. So could you perhaps
> give some background (or even a follow-up patch) to explain what you
> need this for?
>
> Johan

^ permalink raw reply

* Re: [PATCH BlueZ v3 1/8] android: Add copy of current AVCTP implemention
From: Luiz Augusto von Dentz @ 2014-01-27  0:20 UTC (permalink / raw)
  To: linux-bluetooth@vger.kernel.org
In-Reply-To: <1390780546-18402-1-git-send-email-luiz.dentz@gmail.com>

Hi,

On Sun, Jan 26, 2014 at 3:55 PM, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
> From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
>
> These files are not added to any makefile on purpose because they still
> have external dependencies.
> ---
> v2: Fix issues with dependencies in Android, adds proper reject for messages
> that cannot be handled, fix avctp_new not initializing the handlers properly
> and finally fixes using 0 instead of NULL in various places.
> v3: Rebase
>
>  {profiles/audio => android}/avctp.c | 0
>  {profiles/audio => android}/avctp.h | 0
>  2 files changed, 0 insertions(+), 0 deletions(-)
>  copy {profiles/audio => android}/avctp.c (100%)
>  copy {profiles/audio => android}/avctp.h (100%)
>
> diff --git a/profiles/audio/avctp.c b/android/avctp.c
> similarity index 100%
> copy from profiles/audio/avctp.c
> copy to android/avctp.c
> diff --git a/profiles/audio/avctp.h b/android/avctp.h
> similarity index 100%
> copy from profiles/audio/avctp.h
> copy to android/avctp.h
> --
> 1.8.4.2

Pushed.


-- 
Luiz Augusto von Dentz

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox