linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH v3 BlueZ 0/4] Support for GATT Find Included
@ 2012-09-24 22:33 Vinicius Costa Gomes
  2012-09-24 22:33 ` [PATCH v3 BlueZ 1/4] gatt: Add support for find included services Vinicius Costa Gomes
                   ` (3 more replies)
  0 siblings, 4 replies; 8+ messages in thread
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Hi,

Changes from v2:
 - Rebased against latest git tree;

Changes from v1:
 - Fixed problems found during PTS tests;

 - Added a reference count for requests that are running in "parallel"
   (if a included service has a 128 bit UUID, it needs to make an
   aditional request to resolve this included service);

--

Jefferson Delfes (1):
  gatttool: Add "included" command

Vinicius Costa Gomes (3):
  gatt: Add support for find included services
  core: Add support for included services
  attrib: Remove opcode parameter from g_attrib_send()

 attrib/client.c                    |   3 +-
 attrib/gatt.c                      | 242 ++++++++++++++++++++++++++++++++-----
 attrib/gatt.h                      |   9 ++
 attrib/gattrib.c                   |   9 +-
 attrib/gattrib.h                   |   6 +-
 attrib/gatttool.c                  |   2 +-
 attrib/interactive.c               |  62 +++++++++-
 profiles/gatt/gas.c                |   2 +-
 profiles/thermometer/thermometer.c |   3 +-
 src/attrib-server.c                |   3 +-
 src/device.c                       | 109 +++++++++++++++--
 11 files changed, 394 insertions(+), 56 deletions(-)

-- 
1.7.12.1


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

* [PATCH v3 BlueZ 1/4] gatt: Add support for find included services
  2012-09-24 22:33 [PATCH v3 BlueZ 0/4] Support for GATT Find Included Vinicius Costa Gomes
@ 2012-09-24 22:33 ` Vinicius Costa Gomes
  2012-09-28 11:08   ` Johan Hedberg
  2012-09-24 22:33 ` [PATCH v3 BlueZ 2/4] gatttool: Add "included" command Vinicius Costa Gomes
                   ` (2 subsequent siblings)
  3 siblings, 1 reply; 8+ messages in thread
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Some services like HID over LE can reference another service using
included services.

See Vol 3, Part G, section 2.6.3 of Core specification for more
details.
---
 attrib/gatt.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 attrib/gatt.h |   9 +++
 2 files changed, 203 insertions(+)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index 6880e2d..902ac23 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -45,6 +45,21 @@ struct discover_primary {
 	void *user_data;
 };
 
+struct find_included {
+	GAttrib		*attrib;
+	int		refs;
+	int		err;
+	uint16_t	end_handle;
+	GSList		*includes;
+	gatt_cb_t	cb;
+	void		*user_data;
+};
+
+struct included_uuid_resolve {
+	struct find_included *fi;
+	struct gatt_included *included;
+};
+
 struct discover_char {
 	GAttrib *attrib;
 	bt_uuid_t *uuid;
@@ -61,6 +76,26 @@ static void discover_primary_free(struct discover_primary *dp)
 	g_free(dp);
 }
 
+static struct find_included *find_included_ref(struct find_included *fi)
+{
+	g_atomic_int_inc(&fi->refs);
+
+	return fi;
+}
+
+static void find_included_unref(struct find_included *fi)
+{
+	if (g_atomic_int_dec_and_test(&fi->refs) == FALSE)
+		return;
+
+	fi->cb(fi->includes, fi->err, fi->user_data);
+
+	g_slist_free_full(fi->includes, g_free);
+	g_attrib_unref(fi->attrib);
+	g_free(fi);
+}
+
+
 static void discover_char_free(struct discover_char *dc)
 {
 	g_slist_free_full(dc->characteristics, g_free);
@@ -248,6 +283,165 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 	return g_attrib_send(attrib, 0, buf[0], buf, plen, cb, dp, NULL);
 }
 
+static void resolve_included_uuid_cb(uint8_t status, const uint8_t *pdu,
+					uint16_t len, gpointer user_data)
+{
+	struct included_uuid_resolve *resolve = user_data;
+	struct find_included *fi = resolve->fi;
+	struct gatt_included *incl = resolve->included;
+	bt_uuid_t uuid;
+	unsigned int err = status;
+	size_t buflen;
+	uint8_t *buf;
+
+	if (err)
+		goto done;
+
+	buf = g_attrib_get_buffer(fi->attrib, &buflen);
+	if (dec_read_resp(pdu, len, buf, buflen) != 16) {
+		err = ATT_ECODE_IO;
+		goto done;
+	}
+
+	uuid = att_get_uuid128(buf);
+	bt_uuid_to_string(&uuid, incl->uuid, sizeof(incl->uuid));
+	fi->includes = g_slist_append(fi->includes, incl);
+
+done:
+	if (err)
+		g_free(incl);
+
+	if (fi->err == 0)
+		fi->err = err;
+
+	find_included_unref(fi);
+
+	g_free(resolve);
+}
+
+static guint resolve_included_uuid(struct find_included *fi,
+					struct gatt_included *incl)
+{
+	size_t buflen;
+	uint8_t *buf = g_attrib_get_buffer(fi->attrib, &buflen);
+	guint16 oplen = enc_read_req(incl->range.start, buf, buflen);
+	struct included_uuid_resolve *resolve;
+
+	resolve = g_new0(struct included_uuid_resolve, 1);
+	resolve->fi = find_included_ref(fi);
+	resolve->included = incl;
+
+	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
+					resolve_included_uuid_cb, resolve, NULL);
+}
+
+static struct gatt_included *included_from_buf(const uint8_t *buf, gsize buflen)
+{
+	struct gatt_included *incl = g_new0(struct gatt_included, 1);
+
+	incl->handle = att_get_u16(&buf[0]);
+	incl->range.start = att_get_u16(&buf[2]);
+	incl->range.end = att_get_u16(&buf[4]);
+
+	if (buflen == 8) {
+		bt_uuid_t uuid128;
+		bt_uuid_t uuid16 = att_get_uuid16(&buf[6]);
+
+		bt_uuid_to_uuid128(&uuid16, &uuid128);
+		bt_uuid_to_string(&uuid128, incl->uuid, sizeof(incl->uuid));
+	}
+
+	return incl;
+}
+
+static void find_included_cb(uint8_t status, const uint8_t *pdu, uint16_t len,
+							gpointer user_data);
+
+static guint find_included(struct find_included *fi, uint16_t start)
+{
+	bt_uuid_t uuid;
+	size_t buflen;
+	uint8_t *buf = g_attrib_get_buffer(fi->attrib, &buflen);
+	guint16 oplen;
+
+	bt_uuid16_create(&uuid, GATT_INCLUDE_UUID);
+	oplen = enc_read_by_type_req(start, fi->end_handle, &uuid,
+							buf, buflen);
+
+	find_included_ref(fi);
+
+	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
+						find_included_cb, fi, NULL);
+}
+
+static void find_included_cb(uint8_t status, const uint8_t *pdu, uint16_t len,
+							gpointer user_data)
+{
+	struct find_included *fi = user_data;
+	uint16_t last_handle = fi->end_handle;
+	unsigned int err = status;
+	struct att_data_list *list;
+	int i;
+
+	if (err == ATT_ECODE_ATTR_NOT_FOUND)
+		err = 0;
+
+	if (status)
+		goto done;
+
+	list = dec_read_by_type_resp(pdu, len);
+	if (list == NULL) {
+		err = ATT_ECODE_IO;
+		goto done;
+	}
+
+	if (list->len != 6 && list->len != 8) {
+		err = ATT_ECODE_IO;
+		att_data_list_free(list);
+		goto done;
+	}
+
+	for (i = 0; i < list->num; i++) {
+		struct gatt_included *incl;
+
+		incl = included_from_buf(list->data[i], list->len);
+		last_handle = incl->handle;
+
+		/* 128 bit UUID, needs resolving */
+		if (list->len == 6) {
+			resolve_included_uuid(fi, incl);
+			continue;
+		}
+
+		fi->includes = g_slist_append(fi->includes, incl);
+	}
+
+	att_data_list_free(list);
+
+	if (last_handle < fi->end_handle)
+		find_included(fi, last_handle + 1);
+
+done:
+	if (fi->err == 0)
+		fi->err = err;
+
+	find_included_unref(fi);
+}
+
+unsigned int gatt_find_included(GAttrib *attrib, uint16_t start, uint16_t end,
+					gatt_cb_t func, gpointer user_data)
+{
+	struct find_included *fi;
+
+	fi = g_new0(struct find_included, 1);
+	fi->attrib = g_attrib_ref(attrib);
+	fi->end_handle = end;
+	fi->cb = func;
+	fi->user_data = user_data;
+
+	return find_included(fi, start);
+}
+
 static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 							gpointer user_data)
 {
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 6bb6f0f..2897482 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -61,6 +61,12 @@ struct gatt_primary {
 	struct att_range range;
 };
 
+struct gatt_included {
+	char uuid[MAX_LEN_UUID_STR + 1];
+	uint16_t handle;
+	struct att_range range;
+};
+
 struct gatt_char {
 	char uuid[MAX_LEN_UUID_STR + 1];
 	uint16_t handle;
@@ -71,6 +77,9 @@ struct gatt_char {
 guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 							gpointer user_data);
 
+unsigned int gatt_find_included(GAttrib *attrib, uint16_t start, uint16_t end,
+					gatt_cb_t func, gpointer user_data);
+
 guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 					bt_uuid_t *uuid, gatt_cb_t func,
 					gpointer user_data);
-- 
1.7.12.1


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

* [PATCH v3 BlueZ 2/4] gatttool: Add "included" command
  2012-09-24 22:33 [PATCH v3 BlueZ 0/4] Support for GATT Find Included Vinicius Costa Gomes
  2012-09-24 22:33 ` [PATCH v3 BlueZ 1/4] gatt: Add support for find included services Vinicius Costa Gomes
@ 2012-09-24 22:33 ` Vinicius Costa Gomes
  2012-09-24 22:33 ` [PATCH v3 BlueZ 3/4] core: Add support for included services Vinicius Costa Gomes
  2012-09-24 22:33 ` [PATCH v3 BlueZ 4/4] attrib: Remove opcode parameter from g_attrib_send() Vinicius Costa Gomes
  3 siblings, 0 replies; 8+ messages in thread
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Jefferson Delfes

From: Jefferson Delfes <jefferson.delfes@openbossa.org>

New command to find included services in interactive mode.
---
 attrib/interactive.c | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 60 insertions(+)

diff --git a/attrib/interactive.c b/attrib/interactive.c
index 38ac30f..9f1192e 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -211,6 +211,34 @@ static void primary_by_uuid_cb(GSList *ranges, guint8 status,
 	rl_forced_update_display();
 }
 
+static void included_cb(GSList *includes, guint8 status, gpointer user_data)
+{
+	GSList *l;
+
+	if (status) {
+		printf("Find included services failed: %s\n",
+							att_ecode2str(status));
+		goto done;
+	}
+
+	if (includes == NULL) {
+		printf("No included services found for this range\n");
+		goto done;
+	}
+
+	printf("\n");
+	for (l = includes; l; l = l->next) {
+		struct gatt_included *incl = l->data;
+		printf("handle: 0x%04x, start handle: 0x%04x, "
+						"end handle: 0x%04x uuid: %s\n",
+						incl->handle, incl->range.start,
+						incl->range.end, incl->uuid);
+	}
+
+done:
+	rl_forced_update_display();
+}
+
 static void char_cb(GSList *characteristics, guint8 status, gpointer user_data)
 {
 	GSList *l;
@@ -431,6 +459,36 @@ static int strtohandle(const char *src)
 	return dst;
 }
 
+static void cmd_included(int argcp, char **argvp)
+{
+	int start = 0x0001;
+	int end = 0xffff;
+
+	if (conn_state != STATE_CONNECTED) {
+		printf("Command failed: disconnected\n");
+		return;
+	}
+
+	if (argcp > 1) {
+		start = strtohandle(argvp[1]);
+		if (start < 0) {
+			printf("Invalid start handle: %s\n", argvp[1]);
+			return;
+		}
+		end = start;
+	}
+
+	if (argcp > 2) {
+		end = strtohandle(argvp[2]);
+		if (end < 0) {
+			printf("Invalid end handle: %s\n", argvp[2]);
+			return;
+		}
+	}
+
+	gatt_find_included(attrib, start, end, included_cb, NULL);
+}
+
 static void cmd_char(int argcp, char **argvp)
 {
 	int start = 0x0001;
@@ -755,6 +813,8 @@ static struct {
 		"Disconnect from a remote device" },
 	{ "primary",		cmd_primary,	"[UUID]",
 		"Primary Service Discovery" },
+	{ "included",		cmd_included,	"[start hnd [end hnd]]",
+		"Find Included Services" },
 	{ "characteristics",	cmd_char,	"[start hnd [end hnd [UUID]]]",
 		"Characteristics Discovery" },
 	{ "char-desc",		cmd_char_desc,	"[start hnd] [end hnd]",
-- 
1.7.12.1


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

* [PATCH v3 BlueZ 3/4] core: Add support for included services
  2012-09-24 22:33 [PATCH v3 BlueZ 0/4] Support for GATT Find Included Vinicius Costa Gomes
  2012-09-24 22:33 ` [PATCH v3 BlueZ 1/4] gatt: Add support for find included services Vinicius Costa Gomes
  2012-09-24 22:33 ` [PATCH v3 BlueZ 2/4] gatttool: Add "included" command Vinicius Costa Gomes
@ 2012-09-24 22:33 ` Vinicius Costa Gomes
  2012-09-24 22:33 ` [PATCH v3 BlueZ 4/4] attrib: Remove opcode parameter from g_attrib_send() Vinicius Costa Gomes
  3 siblings, 0 replies; 8+ messages in thread
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

Soon after the primary service discovery is complete, we do a included
services discovery for all found services and add each included service
to the 'services' list so they can be probe()'d as a normal profile.

This will also make these services to appear on the D-Bus object tree.
---
 src/device.c | 109 ++++++++++++++++++++++++++++++++++++++++++++++++++++-------
 1 file changed, 96 insertions(+), 13 deletions(-)

diff --git a/src/device.c b/src/device.c
index aa3a607..932f1f9 100644
--- a/src/device.c
+++ b/src/device.c
@@ -104,6 +104,12 @@ struct browse_req {
 	guint listener_id;
 };
 
+struct included_search {
+	struct browse_req *req;
+	GSList *services;
+	GSList *current;
+};
+
 struct attio_data {
 	guint id;
 	attio_connect_cb cfunc;
@@ -1822,21 +1828,10 @@ static void device_unregister_services(struct btd_device *device)
 	device->services = NULL;
 }
 
-static void primary_cb(GSList *services, guint8 status, gpointer user_data)
+static void register_all_services(struct browse_req *req, GSList *services)
 {
-	struct browse_req *req = user_data;
 	struct btd_device *device = req->device;
 
-	if (status) {
-		if (req->msg) {
-			DBusMessage *reply;
-			reply = btd_error_failed(req->msg,
-							att_ecode2str(status));
-			g_dbus_send_message(btd_get_dbus_connection(), reply);
-		}
-		goto done;
-	}
-
 	device_set_temporary(device, FALSE);
 
 	if (device->services)
@@ -1861,11 +1856,99 @@ static void primary_cb(GSList *services, guint8 status, gpointer user_data)
 
 	store_services(device);
 
-done:
 	device->browse = NULL;
 	browse_request_free(req);
 }
 
+static int service_by_range_cmp(gconstpointer a, gconstpointer b)
+{
+	const struct gatt_primary *prim = a;
+	const struct att_range *range = b;
+
+	return memcmp(&prim->range, range, sizeof(*range));
+}
+
+static void find_included_cb(GSList *includes, uint8_t status,
+						gpointer user_data)
+{
+	struct included_search *search = user_data;
+	struct btd_device *device = search->req->device;
+	struct gatt_primary *prim;
+	GSList *l;
+
+	if (includes == NULL)
+		goto done;
+
+	for (l = includes; l; l = l->next) {
+		struct gatt_included *incl = l->data;
+
+		if (g_slist_find_custom(search->services, &incl->range,
+						service_by_range_cmp))
+			continue;
+
+		prim = g_new0(struct gatt_primary, 1);
+		memcpy(prim->uuid, incl->uuid, sizeof(prim->uuid));
+		memcpy(&prim->range, &incl->range, sizeof(prim->range));
+
+		search->services = g_slist_append(search->services, prim);
+	}
+
+done:
+	search->current = search->current->next;
+	if (search->current == NULL) {
+		register_all_services(search->req, search->services);
+		g_slist_free(search->services);
+		g_free(search);
+		return;
+	}
+
+	prim = search->current->data;
+	gatt_find_included(device->attrib, prim->range.start, prim->range.end,
+					find_included_cb, search);
+}
+
+static void find_included_services(struct browse_req *req, GSList *services)
+{
+	struct btd_device *device = req->device;
+	struct included_search *search;
+	struct gatt_primary *prim;
+
+	if (services == NULL)
+		return;
+
+	search = g_new0(struct included_search, 1);
+	search->req = req;
+	search->services = g_slist_copy(services);
+	search->current = search->services;
+
+	prim = search->current->data;
+	gatt_find_included(device->attrib, prim->range.start, prim->range.end,
+					find_included_cb, search);
+
+}
+
+static void primary_cb(GSList *services, guint8 status, gpointer user_data)
+{
+	struct browse_req *req = user_data;
+
+	if (status) {
+		struct btd_device *device = req->device;
+
+		if (req->msg) {
+			DBusMessage *reply;
+			reply = btd_error_failed(req->msg,
+							att_ecode2str(status));
+			g_dbus_send_message(btd_get_dbus_connection(), reply);
+		}
+
+		device->browse = NULL;
+		browse_request_free(req);
+		return;
+	}
+
+	find_included_services(req, services);
+}
+
 static void att_connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
 {
 	struct att_callbacks *attcb = user_data;
-- 
1.7.12.1


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

* [PATCH v3 BlueZ 4/4] attrib: Remove opcode parameter from g_attrib_send()
  2012-09-24 22:33 [PATCH v3 BlueZ 0/4] Support for GATT Find Included Vinicius Costa Gomes
                   ` (2 preceding siblings ...)
  2012-09-24 22:33 ` [PATCH v3 BlueZ 3/4] core: Add support for included services Vinicius Costa Gomes
@ 2012-09-24 22:33 ` Vinicius Costa Gomes
  3 siblings, 0 replies; 8+ messages in thread
From: Vinicius Costa Gomes @ 2012-09-24 22:33 UTC (permalink / raw)
  To: linux-bluetooth; +Cc: Vinicius Costa Gomes

In all uses of g_attrib_send() the opcode of the command/event is
already clear because of the att.h functions used to build the ATT
PDU.
---
 attrib/client.c                    |  3 +-
 attrib/gatt.c                      | 56 ++++++++++++++++----------------------
 attrib/gattrib.c                   |  9 ++++--
 attrib/gattrib.h                   |  6 ++--
 attrib/gatttool.c                  |  2 +-
 attrib/interactive.c               |  2 +-
 profiles/gatt/gas.c                |  2 +-
 profiles/thermometer/thermometer.c |  3 +-
 src/attrib-server.c                |  3 +-
 9 files changed, 39 insertions(+), 47 deletions(-)

diff --git a/attrib/client.c b/attrib/client.c
index 2423fad..a1cc2f3 100644
--- a/attrib/client.c
+++ b/attrib/client.c
@@ -365,8 +365,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len,
 	case ATT_OP_HANDLE_IND:
 		opdu = g_attrib_get_buffer(gatt->attrib, &plen);
 		olen = enc_confirmation(opdu, plen);
-		g_attrib_send(gatt->attrib, 0, opdu[0], opdu, olen,
-						NULL, NULL, NULL);
+		g_attrib_send(gatt->attrib, 0, opdu, olen, NULL, NULL, NULL);
 	case ATT_OP_HANDLE_NOTIFY:
 		if (characteristic_set_value(chr, &pdu[3], len - 3) < 0)
 			DBG("Can't change Characteristic 0x%02x", handle);
diff --git a/attrib/gatt.c b/attrib/gatt.c
index 902ac23..e6db227 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -176,8 +176,7 @@ static void primary_by_uuid_cb(guint8 status, const guint8 *ipdu,
 	if (oplen == 0)
 		goto done;
 
-	g_attrib_send(dp->attrib, 0, buf[0], buf, oplen, primary_by_uuid_cb,
-								dp, NULL);
+	g_attrib_send(dp->attrib, 0, buf, oplen, primary_by_uuid_cb, dp, NULL);
 	return;
 
 done:
@@ -242,7 +241,7 @@ static void primary_all_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		guint16 oplen = encode_discover_primary(end + 1, 0xffff, NULL,
 								buf, buflen);
 
-		g_attrib_send(dp->attrib, 0, buf[0], buf, oplen, primary_all_cb,
+		g_attrib_send(dp->attrib, 0, buf, oplen, primary_all_cb,
 								dp, NULL);
 
 		return;
@@ -280,7 +279,7 @@ guint gatt_discover_primary(GAttrib *attrib, bt_uuid_t *uuid, gatt_cb_t func,
 	} else
 		cb = primary_all_cb;
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, cb, dp, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, cb, dp, NULL);
 }
 
 static void resolve_included_uuid_cb(uint8_t status, const uint8_t *pdu,
@@ -331,8 +330,8 @@ static guint resolve_included_uuid(struct find_included *fi,
 	resolve->fi = find_included_ref(fi);
 	resolve->included = incl;
 
-	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
-					resolve_included_uuid_cb, resolve, NULL);
+	return g_attrib_send(fi->attrib, 0, buf, oplen,
+				resolve_included_uuid_cb, resolve, NULL);
 }
 
 static struct gatt_included *included_from_buf(const uint8_t *buf, gsize buflen)
@@ -370,8 +369,8 @@ static guint find_included(struct find_included *fi, uint16_t start)
 
 	find_included_ref(fi);
 
-	return g_attrib_send(fi->attrib, 0, buf[0], buf, oplen,
-						find_included_cb, fi, NULL);
+	return g_attrib_send(fi->attrib, 0, buf, oplen, find_included_cb,
+								fi, NULL);
 }
 
 static void find_included_cb(uint8_t status, const uint8_t *pdu, uint16_t len,
@@ -508,8 +507,8 @@ static void char_discovered_cb(guint8 status, const guint8 *ipdu, guint16 iplen,
 		if (oplen == 0)
 			return;
 
-		g_attrib_send(dc->attrib, 0, buf[0], buf, oplen,
-						char_discovered_cb, dc, NULL);
+		g_attrib_send(dc->attrib, 0, buf, oplen, char_discovered_cb,
+								dc, NULL);
 
 		return;
 	}
@@ -547,7 +546,7 @@ guint gatt_discover_char(GAttrib *attrib, uint16_t start, uint16_t end,
 	dc->end = end;
 	dc->uuid = g_memdup(uuid, sizeof(bt_uuid_t));
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, char_discovered_cb,
+	return g_attrib_send(attrib, 0, buf, plen, char_discovered_cb,
 								dc, NULL);
 }
 
@@ -563,8 +562,7 @@ guint gatt_read_char_by_uuid(GAttrib *attrib, uint16_t start, uint16_t end,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, ATT_OP_READ_BY_TYPE_REQ,
-					buf, plen, func, user_data, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 struct read_long_data {
@@ -623,8 +621,7 @@ static void read_blob_helper(guint8 status, const guint8 *rpdu, guint16 rlen,
 
 	plen = enc_read_blob_req(long_read->handle, long_read->size - 1,
 								buf, buflen);
-	id = g_attrib_send(long_read->attrib, long_read->id,
-				ATT_OP_READ_BLOB_REQ, buf, plen,
+	id = g_attrib_send(long_read->attrib, long_read->id, buf, plen,
 				read_blob_helper, long_read, read_long_destroy);
 
 	if (id != 0) {
@@ -660,9 +657,8 @@ static void read_char_helper(guint8 status, const guint8 *rpdu,
 	long_read->size = rlen;
 
 	plen = enc_read_blob_req(long_read->handle, rlen - 1, buf, buflen);
-	id = g_attrib_send(long_read->attrib, long_read->id,
-			ATT_OP_READ_BLOB_REQ, buf, plen, read_blob_helper,
-			long_read, read_long_destroy);
+	id = g_attrib_send(long_read->attrib, long_read->id, buf, plen,
+			read_blob_helper, long_read, read_long_destroy);
 
 	if (id != 0) {
 		g_atomic_int_inc(&long_read->ref);
@@ -698,12 +694,12 @@ guint gatt_read_char(GAttrib *attrib, uint16_t handle, uint16_t offset,
 	if (offset > 0) {
 		plen = enc_read_blob_req(long_read->handle, offset, buf,
 									buflen);
-		id = g_attrib_send(attrib, 0, ATT_OP_READ_BLOB_REQ, buf, plen,
-				read_blob_helper, long_read, read_long_destroy);
+		id = g_attrib_send(attrib, 0, buf, plen, read_blob_helper,
+						long_read, read_long_destroy);
 	} else {
 		plen = enc_read_req(handle, buf, buflen);
-		id = g_attrib_send(attrib, 0, ATT_OP_READ_REQ, buf, plen,
-				read_char_helper, long_read, read_long_destroy);
+		id = g_attrib_send(attrib, 0, buf, plen, read_char_helper,
+						long_read, read_long_destroy);
 	}
 
 	if (id == 0)
@@ -738,8 +734,7 @@ static guint execute_write(GAttrib *attrib, uint8_t flags,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, func, user_data,
-									NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 static guint prepare_write(GAttrib *attrib, uint16_t handle, uint16_t offset,
@@ -788,7 +783,7 @@ static guint prepare_write(GAttrib *attrib, uint16_t handle, uint16_t offset,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, buf[0], buf, plen, prepare_write_cb,
+	return g_attrib_send(attrib, 0, buf, plen, prepare_write_cb,
 							user_data, NULL);
 }
 
@@ -812,7 +807,7 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, uint8_t *value,
 			plen = enc_write_cmd(handle, value, vlen, buf,
 								buflen);
 
-		return g_attrib_send(attrib, 0, buf[0], buf, plen, func,
+		return g_attrib_send(attrib, 0, buf, plen, func,
 							user_data, NULL);
 	}
 
@@ -841,8 +836,7 @@ guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu, GAttribResultFunc func,
 
 	buf = g_attrib_get_buffer(attrib, &buflen);
 	plen = enc_mtu_req(mtu, buf, buflen);
-	return g_attrib_send(attrib, 0, ATT_OP_MTU_REQ, buf, plen, func,
-							user_data, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 guint gatt_find_info(GAttrib *attrib, uint16_t start, uint16_t end,
@@ -857,8 +851,7 @@ guint gatt_find_info(GAttrib *attrib, uint16_t start, uint16_t end,
 	if (plen == 0)
 		return 0;
 
-	return g_attrib_send(attrib, 0, ATT_OP_FIND_INFO_REQ, buf, plen, func,
-							user_data, NULL);
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
 }
 
 guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
@@ -870,8 +863,7 @@ guint gatt_write_cmd(GAttrib *attrib, uint16_t handle, uint8_t *value, int vlen,
 
 	buf = g_attrib_get_buffer(attrib, &buflen);
 	plen = enc_write_cmd(handle, value, vlen, buf, buflen);
-	return g_attrib_send(attrib, 0, ATT_OP_WRITE_CMD, buf, plen, NULL,
-							user_data, notify);
+	return g_attrib_send(attrib, 0, buf, plen, NULL, user_data, notify);
 }
 
 static sdp_data_t *proto_seq_find(sdp_list_t *proto_list)
diff --git a/attrib/gattrib.c b/attrib/gattrib.c
index 108d1d3..6f6942f 100644
--- a/attrib/gattrib.c
+++ b/attrib/gattrib.c
@@ -472,12 +472,13 @@ GAttrib *g_attrib_new(GIOChannel *io)
 	return g_attrib_ref(attrib);
 }
 
-guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
-			const guint8 *pdu, guint16 len, GAttribResultFunc func,
-			gpointer user_data, GDestroyNotify notify)
+guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len,
+			GAttribResultFunc func, gpointer user_data,
+			GDestroyNotify notify)
 {
 	struct command *c;
 	GQueue *queue;
+	uint8_t opcode;
 
 	if (attrib->stale)
 		return 0;
@@ -486,6 +487,8 @@ guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
 	if (c == NULL)
 		return 0;
 
+	opcode = pdu[0];
+
 	c->opcode = opcode;
 	c->expected = opcode2expected(opcode);
 	c->pdu = g_malloc(len);
diff --git a/attrib/gattrib.h b/attrib/gattrib.h
index bcff039..bca966f 100644
--- a/attrib/gattrib.h
+++ b/attrib/gattrib.h
@@ -50,9 +50,9 @@ GIOChannel *g_attrib_get_channel(GAttrib *attrib);
 gboolean g_attrib_set_destroy_function(GAttrib *attrib,
 		GDestroyNotify destroy, gpointer user_data);
 
-guint g_attrib_send(GAttrib *attrib, guint id, guint8 opcode,
-			const guint8 *pdu, guint16 len, GAttribResultFunc func,
-			gpointer user_data, GDestroyNotify notify);
+guint g_attrib_send(GAttrib *attrib, guint id, const guint8 *pdu, guint16 len,
+			GAttribResultFunc func, gpointer user_data,
+			GDestroyNotify notify);
 
 gboolean g_attrib_cancel(GAttrib *attrib, guint id);
 gboolean g_attrib_cancel_all(GAttrib *attrib);
diff --git a/attrib/gatttool.c b/attrib/gatttool.c
index 416bb71..dea1fc4 100644
--- a/attrib/gatttool.c
+++ b/attrib/gatttool.c
@@ -105,7 +105,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	olen = enc_confirmation(opdu, plen);
 
 	if (olen > 0)
-		g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
+		g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
 }
 
 static gboolean listen_start(gpointer user_data)
diff --git a/attrib/interactive.c b/attrib/interactive.c
index 9f1192e..1b0b9cf 100644
--- a/attrib/interactive.c
+++ b/attrib/interactive.c
@@ -135,7 +135,7 @@ static void events_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	olen = enc_confirmation(opdu, plen);
 
 	if (olen > 0)
-		g_attrib_send(attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
+		g_attrib_send(attrib, 0, opdu, olen, NULL, NULL, NULL);
 }
 
 static void connect_cb(GIOChannel *io, GError *err, gpointer user_data)
diff --git a/profiles/gatt/gas.c b/profiles/gatt/gas.c
index 28d7fbf..4d8797e 100644
--- a/profiles/gatt/gas.c
+++ b/profiles/gatt/gas.c
@@ -150,7 +150,7 @@ static void indication_cb(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	/* Confirming indication received */
 	opdu = g_attrib_get_buffer(gas->attrib, &plen);
 	olen = enc_confirmation(opdu, plen);
-	g_attrib_send(gas->attrib, 0, opdu[0], opdu, olen, NULL, NULL, NULL);
+	g_attrib_send(gas->attrib, 0, opdu, olen, NULL, NULL, NULL);
 
 	if (gas->changed.start == start && gas->changed.end == end)
 		return;
diff --git a/profiles/thermometer/thermometer.c b/profiles/thermometer/thermometer.c
index 77dcb26..e9f61b1 100644
--- a/profiles/thermometer/thermometer.c
+++ b/profiles/thermometer/thermometer.c
@@ -1167,8 +1167,7 @@ static void ind_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
 	olen = enc_confirmation(opdu, plen);
 
 	if (olen > 0)
-		g_attrib_send(t->attrib, 0, opdu[0], opdu, olen, NULL, NULL,
-									NULL);
+		g_attrib_send(t->attrib, 0, opdu, olen, NULL, NULL, NULL);
 }
 
 static void notif_handler(const uint8_t *pdu, uint16_t len, gpointer user_data)
diff --git a/src/attrib-server.c b/src/attrib-server.c
index 9b03e54..afe5e48 100644
--- a/src/attrib-server.c
+++ b/src/attrib-server.c
@@ -1031,8 +1031,7 @@ done:
 		length = enc_error_resp(ipdu[0], 0x0000, status, opdu,
 								channel->mtu);
 
-	g_attrib_send(channel->attrib, 0, opdu[0], opdu, length,
-							NULL, NULL, NULL);
+	g_attrib_send(channel->attrib, 0, opdu, length, NULL, NULL, NULL);
 }
 
 guint attrib_channel_attach(GAttrib *attrib)
-- 
1.7.12.1


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

* Re: [PATCH v3 BlueZ 1/4] gatt: Add support for find included services
  2012-09-24 22:33 ` [PATCH v3 BlueZ 1/4] gatt: Add support for find included services Vinicius Costa Gomes
@ 2012-09-28 11:08   ` Johan Hedberg
  2012-09-28 11:28     ` Anderson Lizardo
  0 siblings, 1 reply; 8+ messages in thread
From: Johan Hedberg @ 2012-09-28 11:08 UTC (permalink / raw)
  To: Vinicius Costa Gomes; +Cc: linux-bluetooth

Hi Vinicius,

On Mon, Sep 24, 2012, Vinicius Costa Gomes wrote:
> Some services like HID over LE can reference another service using
> included services.
> 
> See Vol 3, Part G, section 2.6.3 of Core specification for more
> details.
> ---
>  attrib/gatt.c | 194 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
>  attrib/gatt.h |   9 +++
>  2 files changed, 203 insertions(+)

This one doesn't apply:

Applying: gatt: Add support for find included services
WARNING:LONG_LINE: line over 80 characters
#107: FILE: attrib/gatt.c:335:
+					resolve_included_uuid_cb, resolve, NULL);

Btw, if you guys are wondering why the stricter coding style checks,
I've added the following to .git/hooks/pre-{commit,applypatch}:

git diff --cached | ~/src/linux/scripts/checkpatch.pl --no-signoff --ignore INITIALISED_STATIC,NEW_TYPEDEFS,VOLATILE --show-types --mailback -

You might want to do the same (with the correct path to checkpatch.pl)).
And thanks to Luiz for the idea (he's using the same when applying
patches).

Johan

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

* Re: [PATCH v3 BlueZ 1/4] gatt: Add support for find included services
  2012-09-28 11:08   ` Johan Hedberg
@ 2012-09-28 11:28     ` Anderson Lizardo
  2012-09-28 11:32       ` Johan Hedberg
  0 siblings, 1 reply; 8+ messages in thread
From: Anderson Lizardo @ 2012-09-28 11:28 UTC (permalink / raw)
  To: Vinicius Costa Gomes, linux-bluetooth

Hi Johan,

On Fri, Sep 28, 2012 at 7:08 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> Btw, if you guys are wondering why the stricter coding style checks,
> I've added the following to .git/hooks/pre-{commit,applypatch}:
>
> git diff --cached | ~/src/linux/scripts/checkpatch.pl --no-signoff --ignore INITIALISED_STATIC,NEW_TYPEDEFS,VOLATILE --show-types --mailback -
>
> You might want to do the same (with the correct path to checkpatch.pl)).
> And thanks to Luiz for the idea (he's using the same when applying
> patches).

Thanks for the very useful tip! But which checkpatch.pl version are
you using? Mine (from bluetooth-next tree) lacks --ignore and
--show-types options.

Regards,
-- 
Anderson Lizardo
Instituto Nokia de Tecnologia - INdT
Manaus - Brazil

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

* Re: [PATCH v3 BlueZ 1/4] gatt: Add support for find included services
  2012-09-28 11:28     ` Anderson Lizardo
@ 2012-09-28 11:32       ` Johan Hedberg
  0 siblings, 0 replies; 8+ messages in thread
From: Johan Hedberg @ 2012-09-28 11:32 UTC (permalink / raw)
  To: Anderson Lizardo; +Cc: Vinicius Costa Gomes, linux-bluetooth

Hi Lizardo,

On Fri, Sep 28, 2012, Anderson Lizardo wrote:
> On Fri, Sep 28, 2012 at 7:08 AM, Johan Hedberg <johan.hedberg@gmail.com> wrote:
> > Btw, if you guys are wondering why the stricter coding style checks,
> > I've added the following to .git/hooks/pre-{commit,applypatch}:
> >
> > git diff --cached | ~/src/linux/scripts/checkpatch.pl --no-signoff --ignore INITIALISED_STATIC,NEW_TYPEDEFS,VOLATILE --show-types --mailback -
> >
> > You might want to do the same (with the correct path to checkpatch.pl)).
> > And thanks to Luiz for the idea (he's using the same when applying
> > patches).
> 
> Thanks for the very useful tip! But which checkpatch.pl version are
> you using? Mine (from bluetooth-next tree) lacks --ignore and
> --show-types options.

I'm using Linus' tree.

Johan

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

end of thread, other threads:[~2012-09-28 11:32 UTC | newest]

Thread overview: 8+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2012-09-24 22:33 [PATCH v3 BlueZ 0/4] Support for GATT Find Included Vinicius Costa Gomes
2012-09-24 22:33 ` [PATCH v3 BlueZ 1/4] gatt: Add support for find included services Vinicius Costa Gomes
2012-09-28 11:08   ` Johan Hedberg
2012-09-28 11:28     ` Anderson Lizardo
2012-09-28 11:32       ` Johan Hedberg
2012-09-24 22:33 ` [PATCH v3 BlueZ 2/4] gatttool: Add "included" command Vinicius Costa Gomes
2012-09-24 22:33 ` [PATCH v3 BlueZ 3/4] core: Add support for included services Vinicius Costa Gomes
2012-09-24 22:33 ` [PATCH v3 BlueZ 4/4] attrib: Remove opcode parameter from g_attrib_send() Vinicius Costa Gomes

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).