linux-bluetooth.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 00/10] android/gatt: GATT Client write types support
@ 2014-04-12 22:00 Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 01/10] attrib: Add API for reliable write Lukasz Rymanowski
                   ` (10 more replies)
  0 siblings, 11 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

This patch set adds support for different write types.
For this I had to expose some additional API from attrib.

Only signed write left to implement.

This patch set also do some code cleaning.

Lukasz Rymanowski (10):
  attrib: Add API for reliable write
  attrib: Expose write execute
  android/gatt: Add helper to create descr_data
  android/gatt: Avoid double helper struct for read/write characteristic
  android/gatt: Add helper to create characteristic op data
  android/gatt: Fix error msg
  android/gatt: Daemon accepts only default write type
  android/gatt: Add support for reliable write
  android/gatt: Add support for write execute
  android/gatt: Add support for write without response

 android/gatt.c | 264 ++++++++++++++++++++++++++++++++++++++++++---------------
 attrib/gatt.c  |  24 ++++++
 attrib/gatt.h  |   8 ++
 3 files changed, 226 insertions(+), 70 deletions(-)

-- 
1.8.4


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

* [PATCH 01/10] attrib: Add API for reliable write
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-14 14:28   ` Szymon Janc
  2014-04-12 22:00 ` [PATCH 02/10] attrib: Expose write execute Lukasz Rymanowski
                   ` (9 subsequent siblings)
  10 siblings, 1 reply; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

Android expose to application api for reliable write. Therefore we need
to add this support to gattrib
---
 attrib/gatt.c | 18 ++++++++++++++++++
 attrib/gatt.h |  6 ++++++
 2 files changed, 24 insertions(+)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index 49cd1a3..e461ab7 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -871,6 +871,24 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, const uint8_t *value,
 	return prepare_write(long_write);
 }
 
+guint gatt_reliable_write_char(GAttrib *attrib, uint16_t handle,
+					const uint8_t *value, size_t vlen,
+					GAttribResultFunc func,
+					gpointer user_data)
+{
+	uint8_t *buf;
+	guint16 plen;
+	size_t buflen;
+
+	buf = g_attrib_get_buffer(attrib, &buflen);
+
+	plen = enc_prep_write_req(handle, 0, value, vlen, buf, buflen);
+	if (!plen)
+		return 0;
+
+	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
+}
+
 guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu, GAttribResultFunc func,
 							gpointer user_data)
 {
diff --git a/attrib/gatt.h b/attrib/gatt.h
index c65bf6c..76820e0 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -84,6 +84,12 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, const uint8_t *value,
 					size_t vlen, GAttribResultFunc func,
 					gpointer user_data);
 
+guint gatt_reliable_write_char(GAttrib *attrib, uint16_t handle,
+					const uint8_t *value, size_t vlen,
+					GAttribResultFunc func,
+					gpointer user_data);
+
+
 guint gatt_discover_char_desc(GAttrib *attrib, uint16_t start, uint16_t end,
 				GAttribResultFunc func, gpointer user_data);
 
-- 
1.8.4


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

* [PATCH 02/10] attrib: Expose write execute
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 01/10] attrib: Add API for reliable write Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 03/10] android/gatt: Add helper to create descr_data Lukasz Rymanowski
                   ` (8 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

This is needed to cover Android API
---
 attrib/gatt.c | 6 ++++++
 attrib/gatt.h | 2 ++
 2 files changed, 8 insertions(+)

diff --git a/attrib/gatt.c b/attrib/gatt.c
index e461ab7..f5917db 100644
--- a/attrib/gatt.c
+++ b/attrib/gatt.c
@@ -871,6 +871,12 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, const uint8_t *value,
 	return prepare_write(long_write);
 }
 
+guint gatt_execute_write(GAttrib *attrib, uint8_t flags,
+				GAttribResultFunc func, gpointer user_data)
+{
+	return execute_write(attrib, flags, func, user_data);
+}
+
 guint gatt_reliable_write_char(GAttrib *attrib, uint16_t handle,
 					const uint8_t *value, size_t vlen,
 					GAttribResultFunc func,
diff --git a/attrib/gatt.h b/attrib/gatt.h
index 76820e0..3fe6041 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -89,6 +89,8 @@ guint gatt_reliable_write_char(GAttrib *attrib, uint16_t handle,
 					GAttribResultFunc func,
 					gpointer user_data);
 
+guint gatt_execute_write(GAttrib *attrib, uint8_t flags,
+				GAttribResultFunc func, gpointer user_data);
 
 guint gatt_discover_char_desc(GAttrib *attrib, uint16_t start, uint16_t end,
 				GAttribResultFunc func, gpointer user_data);
-- 
1.8.4


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

* [PATCH 03/10] android/gatt: Add helper to create descr_data
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 01/10] attrib: Add API for reliable write Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 02/10] attrib: Expose write execute Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 04/10] android/gatt: Avoid double helper struct for read/write characteristic Lukasz Rymanowski
                   ` (7 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

---
 android/gatt.c | 39 +++++++++++++++++++++++++--------------
 1 file changed, 25 insertions(+), 14 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index 243e02f..d04294c 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2155,6 +2155,27 @@ static void read_desc_cb(guint8 status, const guint8 *pdu, guint16 len,
 	free(cb_data);
 }
 
+static struct desc_data *create_desc_data(int32_t conn_id,
+						const struct element_id *s_id,
+						const struct element_id *ch_id,
+						const struct element_id *d_id,
+						uint8_t primary)
+{
+	struct desc_data *d;
+
+	d = new0(struct desc_data, 1);
+	if (!d)
+		return NULL;
+
+	d->conn_id = conn_id;
+	d->srvc_id = s_id;
+	d->char_id = ch_id;
+	d->descr_id = d_id;
+	d->primary = primary;
+
+	return d;
+}
+
 static void handle_client_read_descriptor(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_gatt_client_read_descriptor *cmd = buf;
@@ -2203,7 +2224,8 @@ static void handle_client_read_descriptor(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = new0(struct desc_data, 1);
+	cb_data = create_desc_data(conn_id, &srvc->id, &ch->id, &descr->id,
+								primary);
 	if (!cb_data) {
 		error("gatt: Read descr. could not allocate callback data");
 
@@ -2211,12 +2233,6 @@ static void handle_client_read_descriptor(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data->conn_id = conn_id;
-	cb_data->srvc_id = &srvc->id;
-	cb_data->char_id = &ch->id;
-	cb_data->descr_id = &descr->id;
-	cb_data->primary = primary;
-
 	if (!gatt_read_char(dev->attrib, descr->handle, read_desc_cb,
 								cb_data)) {
 		free(cb_data);
@@ -2330,7 +2346,8 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = new0(struct desc_data, 1);
+	cb_data = create_desc_data(conn_id, &srvc->id, &ch->id, &descr->id,
+								primary);
 	if (!cb_data) {
 		error("gatt: Write descr. could not allocate callback data");
 
@@ -2338,12 +2355,6 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data->conn_id = conn_id;
-	cb_data->srvc_id = &srvc->id;
-	cb_data->char_id = &ch->id;
-	cb_data->descr_id = &descr->id;
-	cb_data->primary = primary;
-
 	if (!gatt_write_char(dev->attrib, descr->handle, cmd->value, cmd->len,
 						write_descr_cb, cb_data)) {
 		free(cb_data);
-- 
1.8.4


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

* [PATCH 04/10] android/gatt: Avoid double helper struct for read/write characteristic
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (2 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 03/10] android/gatt: Add helper to create descr_data Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 05/10] android/gatt: Add helper to create characteristic op data Lukasz Rymanowski
                   ` (6 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

This patch combine two helper structs for operations on characteristics
to one.

Also use pointers inside this struct instread of raw data.
---
 android/gatt.c | 51 ++++++++++++++++++++++-----------------------------
 1 file changed, 22 insertions(+), 29 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index d04294c..adba29e 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -1864,17 +1864,17 @@ failed:
 				HAL_OP_GATT_CLIENT_GET_DESCRIPTOR, status);
 }
 
-struct read_char_data {
+struct char_op_data {
 	int32_t conn_id;
-	struct element_id srvc_id;
-	struct element_id char_id;
+	const struct element_id *srvc_id;
+	const struct element_id *char_id;
 	uint8_t primary;
 };
 
 static void send_client_read_char_notify(int32_t status, const uint8_t *pdu,
 						uint16_t len, int32_t conn_id,
-						struct element_id *srvc_id,
-						struct element_id *char_id,
+						const struct element_id *s_id,
+						const struct element_id *ch_id,
 						uint8_t primary)
 {
 	uint8_t buf[IPC_MTU];
@@ -1886,8 +1886,8 @@ static void send_client_read_char_notify(int32_t status, const uint8_t *pdu,
 	ev->conn_id = conn_id;
 	ev->status = status;
 
-	element_id_to_hal_srvc_id(srvc_id, primary, &ev->data.srvc_id);
-	element_id_to_hal_gatt_id(char_id, &ev->data.char_id);
+	element_id_to_hal_srvc_id(s_id, primary, &ev->data.srvc_id);
+	element_id_to_hal_gatt_id(ch_id, &ev->data.char_id);
 
 	if (pdu) {
 		vlen = dec_read_resp(pdu, len, ev->data.value, sizeof(buf));
@@ -1907,10 +1907,10 @@ static void send_client_read_char_notify(int32_t status, const uint8_t *pdu,
 static void read_char_cb(guint8 status, const guint8 *pdu, guint16 len,
 							gpointer user_data)
 {
-	struct read_char_data *data = user_data;
+	struct char_op_data *data = user_data;
 
 	send_client_read_char_notify(status, pdu, len, data->conn_id,
-						&data->srvc_id, &data->char_id,
+						data->srvc_id, data->char_id,
 						data->primary);
 
 	free(data);
@@ -1919,7 +1919,7 @@ static void read_char_cb(guint8 status, const guint8 *pdu, guint16 len,
 static void handle_client_read_characteristic(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_gatt_client_read_characteristic *cmd = buf;
-	struct read_char_data *cb_data;
+	struct char_op_data *cb_data;
 	struct characteristic *ch;
 	struct gatt_device *dev;
 	struct service *srvc;
@@ -1948,7 +1948,7 @@ static void handle_client_read_characteristic(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = new0(struct read_char_data, 1);
+	cb_data = new0(struct char_op_data, 1);
 	if (!cb_data) {
 		error("gatt: Cannot allocate cb data");
 		status = HAL_STATUS_NOMEM;
@@ -1957,8 +1957,8 @@ static void handle_client_read_characteristic(const void *buf, uint16_t len)
 
 	cb_data->conn_id = cmd->conn_id;
 	cb_data->primary = cmd->srvc_id.is_primary;
-	cb_data->srvc_id = srvc_id;
-	cb_data->char_id = char_id;
+	cb_data->srvc_id = &srvc->id;
+	cb_data->char_id = &ch->id;
 
 	if (!gatt_read_char(dev->attrib, ch->ch.value_handle,
 						read_char_cb, cb_data)) {
@@ -1984,16 +1984,9 @@ failed:
 					cmd->srvc_id.is_primary);
 }
 
-struct write_char_data {
-	int32_t conn_id;
-	struct element_id srvc_id;
-	struct element_id char_id;
-	uint8_t primary;
-};
-
 static void send_client_write_char_notify(int32_t status, int32_t conn_id,
-					struct element_id *srvc_id,
-					struct element_id *char_id,
+					const struct element_id *srvc_id,
+					const struct element_id *char_id,
 					uint8_t primary)
 {
 	struct hal_ev_gatt_client_write_characteristic ev;
@@ -2014,10 +2007,10 @@ static void send_client_write_char_notify(int32_t status, int32_t conn_id,
 static void write_char_cb(guint8 status, const guint8 *pdu, guint16 len,
 							gpointer user_data)
 {
-	struct write_char_data *data = user_data;
+	struct char_op_data *data = user_data;
 
-	send_client_write_char_notify(status, data->conn_id, &data->srvc_id,
-					&data->char_id, data->primary);
+	send_client_write_char_notify(status, data->conn_id, data->srvc_id,
+						data->char_id, data->primary);
 
 	free(data);
 }
@@ -2025,7 +2018,7 @@ static void write_char_cb(guint8 status, const guint8 *pdu, guint16 len,
 static void handle_client_write_characteristic(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_gatt_client_write_characteristic *cmd = buf;
-	struct write_char_data *cb_data;
+	struct char_op_data *cb_data;
 	struct characteristic *ch;
 	struct gatt_device *dev;
 	struct service *srvc;
@@ -2058,7 +2051,7 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = new0(struct write_char_data, 1);
+	cb_data = new0(struct char_op_data, 1);
 	if (!cb_data) {
 		error("gatt: Cannot allocate call data");
 		status = HAL_STATUS_NOMEM;
@@ -2067,8 +2060,8 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
 
 	cb_data->conn_id = cmd->conn_id;
 	cb_data->primary = cmd->srvc_id.is_primary;
-	cb_data->srvc_id = srvc_id;
-	cb_data->char_id = char_id;
+	cb_data->srvc_id = &srvc->id;
+	cb_data->char_id = &ch->id;
 
 	if (!gatt_write_char(dev->attrib, ch->ch.value_handle, cmd->value,
 					cmd->len, write_char_cb, cb_data)) {
-- 
1.8.4


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

* [PATCH 05/10] android/gatt: Add helper to create characteristic op data
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (3 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 04/10] android/gatt: Avoid double helper struct for read/write characteristic Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 06/10] android/gatt: Fix error msg Lukasz Rymanowski
                   ` (5 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

This patch adds helper to create data needed for read/write
characteristic
---
 android/gatt.c | 35 +++++++++++++++++++++++------------
 1 file changed, 23 insertions(+), 12 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index adba29e..9d45968 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -1871,6 +1871,25 @@ struct char_op_data {
 	uint8_t primary;
 };
 
+static struct char_op_data *create_char_op_data(int32_t conn_id,
+						const struct element_id *s_id,
+						const struct element_id *ch_id,
+						bool primary)
+{
+	struct char_op_data *d;
+
+	d = new0(struct char_op_data, 1);
+	if (!d)
+		return NULL;
+
+	d->conn_id = conn_id;
+	d->srvc_id = s_id;
+	d->char_id = ch_id;
+	d->primary = primary;
+
+	return d;
+}
+
 static void send_client_read_char_notify(int32_t status, const uint8_t *pdu,
 						uint16_t len, int32_t conn_id,
 						const struct element_id *s_id,
@@ -1948,18 +1967,14 @@ static void handle_client_read_characteristic(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = new0(struct char_op_data, 1);
+	cb_data = create_char_op_data(cmd->conn_id, &srvc->id, &ch->id,
+						cmd->srvc_id.is_primary);
 	if (!cb_data) {
 		error("gatt: Cannot allocate cb data");
 		status = HAL_STATUS_NOMEM;
 		goto failed;
 	}
 
-	cb_data->conn_id = cmd->conn_id;
-	cb_data->primary = cmd->srvc_id.is_primary;
-	cb_data->srvc_id = &srvc->id;
-	cb_data->char_id = &ch->id;
-
 	if (!gatt_read_char(dev->attrib, ch->ch.value_handle,
 						read_char_cb, cb_data)) {
 		error("gatt: Cannot read characteristic with inst_id: %d",
@@ -2051,18 +2066,14 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = new0(struct char_op_data, 1);
+	cb_data = create_char_op_data(cmd->conn_id, &srvc->id, &ch->id,
+						cmd->srvc_id.is_primary);
 	if (!cb_data) {
 		error("gatt: Cannot allocate call data");
 		status = HAL_STATUS_NOMEM;
 		goto failed;
 	}
 
-	cb_data->conn_id = cmd->conn_id;
-	cb_data->primary = cmd->srvc_id.is_primary;
-	cb_data->srvc_id = &srvc->id;
-	cb_data->char_id = &ch->id;
-
 	if (!gatt_write_char(dev->attrib, ch->ch.value_handle, cmd->value,
 					cmd->len, write_char_cb, cb_data)) {
 		error("gatt: Cannot read characteristic with inst_id: %d",
-- 
1.8.4


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

* [PATCH 06/10] android/gatt: Fix error msg
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (4 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 05/10] android/gatt: Add helper to create characteristic op data Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 07/10] android/gatt: Daemon accepts only default write type Lukasz Rymanowski
                   ` (4 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

---
 android/gatt.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index 9d45968..523a141 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2076,7 +2076,7 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
 
 	if (!gatt_write_char(dev->attrib, ch->ch.value_handle, cmd->value,
 					cmd->len, write_char_cb, cb_data)) {
-		error("gatt: Cannot read characteristic with inst_id: %d",
+		error("gatt: Cannot write characteristic with inst_id: %d",
 							cmd->gatt_id.inst_id);
 		status = HAL_STATUS_FAILED;
 		free(cb_data);
-- 
1.8.4


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

* [PATCH 07/10] android/gatt: Daemon accepts only default write type
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (5 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 06/10] android/gatt: Fix error msg Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 08/10] android/gatt: Add support for reliable write Lukasz Rymanowski
                   ` (3 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

With this patch daemon accepts only default write type. For other types
it correctly replies with HAL_STATUS_UNSUPPORTED
---
 android/gatt.c | 50 +++++++++++++++++++++++++++++++++++++++-----------
 1 file changed, 39 insertions(+), 11 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index 523a141..c98a4f1 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -54,6 +54,8 @@
 #define GATT_SUCCESS	0x00000000
 #define GATT_FAILURE	0x00000101
 
+#define GATT_WRITE_DEFAULT	0x02
+
 struct gatt_client {
 	int32_t id;
 	uint8_t uuid[16];
@@ -2033,13 +2035,14 @@ static void write_char_cb(guint8 status, const guint8 *pdu, guint16 len,
 static void handle_client_write_characteristic(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_gatt_client_write_characteristic *cmd = buf;
-	struct char_op_data *cb_data;
+	struct char_op_data *cb_data = NULL;
 	struct characteristic *ch;
 	struct gatt_device *dev;
 	struct service *srvc;
 	struct element_id srvc_id;
 	struct element_id char_id;
 	uint8_t status;
+	guint res;
 
 	DBG("");
 
@@ -2074,28 +2077,41 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	if (!gatt_write_char(dev->attrib, ch->ch.value_handle, cmd->value,
-					cmd->len, write_char_cb, cb_data)) {
-		error("gatt: Cannot write characteristic with inst_id: %d",
+	switch (cmd->write_type) {
+	case GATT_WRITE_DEFAULT:
+		res = gatt_write_char(dev->attrib, ch->ch.value_handle,
+							cmd->value, cmd->len,
+							write_char_cb, cb_data);
+		break;
+	default:
+		error("gatt: Write type %d unsupported", cmd->write_type);
+		status = HAL_STATUS_UNSUPPORTED;
+		goto failed;
+	}
+
+	if (!res) {
+		error("gatt: Cannot write char. with inst_id: %d",
 							cmd->gatt_id.inst_id);
 		status = HAL_STATUS_FAILED;
-		free(cb_data);
 		goto failed;
 	}
 
 	status = HAL_STATUS_SUCCESS;
 
 failed:
+
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
 			HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC, status);
 
 	/* We should send notification with service, characteristic id in case
 	 * of errors.
 	 */
-	if (status != HAL_STATUS_SUCCESS)
+	if (status != HAL_STATUS_SUCCESS) {
 		send_client_write_char_notify(GATT_FAILURE, cmd->conn_id,
 						&srvc_id, &char_id,
 						cmd->srvc_id.is_primary);
+		free(cb_data);
+	}
 }
 
 static void send_client_descr_read_notify(int32_t status, const uint8_t *pdu,
@@ -2298,7 +2314,7 @@ static void write_descr_cb(guint8 status, const guint8 *pdu, guint16 len,
 static void handle_client_write_descriptor(const void *buf, uint16_t len)
 {
 	const struct hal_cmd_gatt_client_write_descriptor *cmd = buf;
-	struct desc_data *cb_data;
+	struct desc_data *cb_data = NULL;
 	struct characteristic *ch;
 	struct descriptor *descr;
 	struct service *srvc;
@@ -2309,6 +2325,7 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 	int32_t conn_id;
 	uint8_t primary;
 	uint8_t status;
+	guint res;
 
 	DBG("");
 
@@ -2359,10 +2376,19 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	if (!gatt_write_char(dev->attrib, descr->handle, cmd->value, cmd->len,
-						write_descr_cb, cb_data)) {
-		free(cb_data);
+	switch (cmd->write_type) {
+	case GATT_WRITE_DEFAULT:
+		res = gatt_write_char(dev->attrib, descr->handle, cmd->value,
+					cmd->len, write_descr_cb, cb_data);
+		break;
+	default:
+		error("gatt: Write type %d unsupported", cmd->write_type);
+		status = HAL_STATUS_UNSUPPORTED;
+		goto failed;
+	}
 
+	if (!res) {
+		error("gatt: Write desc, could not write desc");
 		status = HAL_STATUS_FAILED;
 		goto failed;
 	}
@@ -2370,9 +2396,11 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	if (status != HAL_STATUS_SUCCESS)
+	if (status != HAL_STATUS_SUCCESS) {
 		send_client_descr_write_notify(GATT_FAILURE, conn_id, &srvc_id,
 						&char_id, &descr_id, primary);
+		free(cb_data);
+	}
 
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
 				HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR, status);
-- 
1.8.4


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

* [PATCH 08/10] android/gatt: Add support for reliable write
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (6 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 07/10] android/gatt: Daemon accepts only default write type Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 09/10] android/gatt: Add support for write execute Lukasz Rymanowski
                   ` (2 subsequent siblings)
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

This patch add support for reliable write
---
 android/gatt.c | 12 ++++++++++++
 1 file changed, 12 insertions(+)

diff --git a/android/gatt.c b/android/gatt.c
index c98a4f1..e5da1b2 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -55,6 +55,7 @@
 #define GATT_FAILURE	0x00000101
 
 #define GATT_WRITE_DEFAULT	0x02
+#define GATT_WRITE_RELIABLE	0x03
 
 struct gatt_client {
 	int32_t id;
@@ -2078,6 +2079,11 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
 	}
 
 	switch (cmd->write_type) {
+	case GATT_WRITE_RELIABLE:
+		res = gatt_reliable_write_char(dev->attrib, ch->ch.value_handle,
+							cmd->value, cmd->len,
+							write_char_cb, cb_data);
+		break;
 	case GATT_WRITE_DEFAULT:
 		res = gatt_write_char(dev->attrib, ch->ch.value_handle,
 							cmd->value, cmd->len,
@@ -2377,6 +2383,12 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 	}
 
 	switch (cmd->write_type) {
+	case GATT_WRITE_RELIABLE:
+		res = gatt_reliable_write_char(dev->attrib, descr->handle,
+							cmd->value, cmd->len,
+							write_descr_cb,
+							cb_data);
+		break;
 	case GATT_WRITE_DEFAULT:
 		res = gatt_write_char(dev->attrib, descr->handle, cmd->value,
 					cmd->len, write_descr_cb, cb_data);
-- 
1.8.4


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

* [PATCH 09/10] android/gatt: Add support for write execute
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (7 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 08/10] android/gatt: Add support for reliable write Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-12 22:00 ` [PATCH 10/10] android/gatt: Add support for write without response Lukasz Rymanowski
  2014-04-14 14:23 ` [PATCH 00/10] android/gatt: GATT Client write types support Szymon Janc
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

This patch add support for write execute. There is possible to write or
cancel all prepared data
---
 android/gatt.c | 48 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 47 insertions(+), 1 deletion(-)

diff --git a/android/gatt.c b/android/gatt.c
index e5da1b2..6fcc977 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2418,12 +2418,58 @@ failed:
 				HAL_OP_GATT_CLIENT_WRITE_DESCRIPTOR, status);
 }
 
+static void send_client_write_execute_notify(int32_t id, int32_t status)
+{
+	struct hal_ev_gatt_client_exec_write ev;
+
+	ev.conn_id = id;
+	ev.status = status;
+
+	ipc_send_notif(hal_ipc, HAL_SERVICE_ID_GATT,
+					HAL_EV_GATT_CLIENT_EXEC_WRITE,
+					sizeof(ev), &ev);
+}
+
+static void write_execute_cb(guint8 status, const guint8 *pdu, guint16 len,
+							gpointer user_data)
+{
+	send_client_write_execute_notify(PTR_TO_INT(user_data), status);
+}
+
 static void handle_client_execute_write(const void *buf, uint16_t len)
 {
+	const struct hal_cmd_gatt_client_execute_write *cmd = buf;
+	struct gatt_device *dev;
+	uint8_t status;
+	uint8_t flags;
+
 	DBG("");
 
+	dev = queue_find(conn_list, match_dev_by_conn_id,
+						INT_TO_PTR(cmd->conn_id));
+	if (!dev) {
+		status = HAL_STATUS_FAILED;
+		goto reply;
+	}
+
+	flags = cmd->execute ? ATT_WRITE_ALL_PREP_WRITES :
+						ATT_CANCEL_ALL_PREP_WRITES;
+
+	if (!gatt_execute_write(dev->attrib, flags, write_execute_cb,
+						INT_TO_PTR(cmd->conn_id))) {
+		error("gatt: Could not send execute write");
+		status = HAL_STATUS_FAILED;
+		goto reply;
+	}
+
+	status = HAL_STATUS_SUCCESS;
+reply:
 	ipc_send_rsp(hal_ipc, HAL_SERVICE_ID_GATT,
-			HAL_OP_GATT_CLIENT_EXECUTE_WRITE, HAL_STATUS_FAILED);
+			HAL_OP_GATT_CLIENT_EXECUTE_WRITE, status);
+
+	/* In case of early error send also notification.*/
+	if (status != HAL_STATUS_SUCCESS)
+		send_client_write_execute_notify(cmd->conn_id, GATT_FAILURE);
 }
 
 static void handle_notification(const uint8_t *pdu, uint16_t len,
-- 
1.8.4


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

* [PATCH 10/10] android/gatt: Add support for write without response
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (8 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 09/10] android/gatt: Add support for write execute Lukasz Rymanowski
@ 2014-04-12 22:00 ` Lukasz Rymanowski
  2014-04-14 14:23 ` [PATCH 00/10] android/gatt: GATT Client write types support Szymon Janc
  10 siblings, 0 replies; 13+ messages in thread
From: Lukasz Rymanowski @ 2014-04-12 22:00 UTC (permalink / raw)
  To: linux-bluetooth
  Cc: szymon.janc, johan.hedberg, claudio.takahasi, anderson.lizardo,
	armansito, Lukasz Rymanowski

---
 android/gatt.c | 55 +++++++++++++++++++++++++++++++++++++++----------------
 1 file changed, 39 insertions(+), 16 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index 6fcc977..ce7c0d3 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -54,6 +54,7 @@
 #define GATT_SUCCESS	0x00000000
 #define GATT_FAILURE	0x00000101
 
+#define GATT_WRITE_NO_RESPONSE	0x01
 #define GATT_WRITE_DEFAULT	0x02
 #define GATT_WRITE_RELIABLE	0x03
 
@@ -2070,15 +2071,22 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = create_char_op_data(cmd->conn_id, &srvc->id, &ch->id,
+	if (cmd->write_type != GATT_WRITE_NO_RESPONSE) {
+		cb_data = create_char_op_data(cmd->conn_id, &srvc->id, &ch->id,
 						cmd->srvc_id.is_primary);
-	if (!cb_data) {
-		error("gatt: Cannot allocate call data");
-		status = HAL_STATUS_NOMEM;
-		goto failed;
+		if (!cb_data) {
+			error("gatt: Cannot allocate call data");
+			status = HAL_STATUS_NOMEM;
+			goto failed;
+		}
 	}
 
 	switch (cmd->write_type) {
+	case GATT_WRITE_NO_RESPONSE:
+		res = gatt_write_cmd(dev->attrib, ch->ch.value_handle,
+							cmd->value, cmd->len,
+							NULL, NULL);
+		break;
 	case GATT_WRITE_RELIABLE:
 		res = gatt_reliable_write_char(dev->attrib, ch->ch.value_handle,
 							cmd->value, cmd->len,
@@ -2110,10 +2118,14 @@ failed:
 			HAL_OP_GATT_CLIENT_WRITE_CHARACTERISTIC, status);
 
 	/* We should send notification with service, characteristic id in case
-	 * of errors.
+	 * of error and write with no response
 	 */
-	if (status != HAL_STATUS_SUCCESS) {
-		send_client_write_char_notify(GATT_FAILURE, cmd->conn_id,
+	if (status != HAL_STATUS_SUCCESS ||
+				cmd->write_type == GATT_WRITE_NO_RESPONSE) {
+		int32_t gatt_status = (status == HAL_STATUS_SUCCESS) ?
+						GATT_SUCCESS : GATT_FAILURE;
+
+		send_client_write_char_notify(gatt_status, cmd->conn_id,
 						&srvc_id, &char_id,
 						cmd->srvc_id.is_primary);
 		free(cb_data);
@@ -2373,21 +2385,28 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 		goto failed;
 	}
 
-	cb_data = create_desc_data(conn_id, &srvc->id, &ch->id, &descr->id,
-								primary);
-	if (!cb_data) {
-		error("gatt: Write descr. could not allocate callback data");
+	if (cmd->write_type != GATT_WRITE_NO_RESPONSE) {
+		cb_data = create_desc_data(conn_id, &srvc->id, &ch->id,
+							&descr->id, primary);
+		if (!cb_data) {
+			error("gatt: Write descr. could not allocate cb_data");
 
-		status = HAL_STATUS_NOMEM;
-		goto failed;
+			status = HAL_STATUS_NOMEM;
+			goto failed;
+		}
 	}
 
 	switch (cmd->write_type) {
+	case GATT_WRITE_NO_RESPONSE:
+		res = gatt_write_cmd(dev->attrib, descr->handle, cmd->value,
+					cmd->len, NULL , NULL);
+		break;
 	case GATT_WRITE_RELIABLE:
 		res = gatt_reliable_write_char(dev->attrib, descr->handle,
 							cmd->value, cmd->len,
 							write_descr_cb,
 							cb_data);
+
 		break;
 	case GATT_WRITE_DEFAULT:
 		res = gatt_write_char(dev->attrib, descr->handle, cmd->value,
@@ -2408,8 +2427,12 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
 	status = HAL_STATUS_SUCCESS;
 
 failed:
-	if (status != HAL_STATUS_SUCCESS) {
-		send_client_descr_write_notify(GATT_FAILURE, conn_id, &srvc_id,
+	if (status != HAL_STATUS_SUCCESS ||
+				cmd->write_type == GATT_WRITE_NO_RESPONSE) {
+		int32_t gatt_status = (status == HAL_STATUS_SUCCESS) ?
+						GATT_SUCCESS : GATT_FAILURE;
+
+		send_client_descr_write_notify(gatt_status, conn_id, &srvc_id,
 						&char_id, &descr_id, primary);
 		free(cb_data);
 	}
-- 
1.8.4


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

* Re: [PATCH 00/10] android/gatt: GATT Client write types support
  2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
                   ` (9 preceding siblings ...)
  2014-04-12 22:00 ` [PATCH 10/10] android/gatt: Add support for write without response Lukasz Rymanowski
@ 2014-04-14 14:23 ` Szymon Janc
  10 siblings, 0 replies; 13+ messages in thread
From: Szymon Janc @ 2014-04-14 14:23 UTC (permalink / raw)
  To: Lukasz Rymanowski
  Cc: linux-bluetooth, johan.hedberg, claudio.takahasi,
	anderson.lizardo, armansito

Hi Łukasz,

On Sunday 13 of April 2014 00:00:21 Lukasz Rymanowski wrote:
> This patch set adds support for different write types.
> For this I had to expose some additional API from attrib.
> 
> Only signed write left to implement.
> 
> This patch set also do some code cleaning.
> 
> Lukasz Rymanowski (10):
>   attrib: Add API for reliable write
>   attrib: Expose write execute
>   android/gatt: Add helper to create descr_data
>   android/gatt: Avoid double helper struct for read/write characteristic
>   android/gatt: Add helper to create characteristic op data
>   android/gatt: Fix error msg
>   android/gatt: Daemon accepts only default write type
>   android/gatt: Add support for reliable write
>   android/gatt: Add support for write execute
>   android/gatt: Add support for write without response
> 
>  android/gatt.c | 264 ++++++++++++++++++++++++++++++++++++++++++---------------
>  attrib/gatt.c  |  24 ++++++
>  attrib/gatt.h  |   8 ++
>  3 files changed, 226 insertions(+), 70 deletions(-)
> 
> 

Patches 3-7 are now pushed. Thanks.

I moved GATT write types definitions to HAL IPC.

-- 
Best regards, 
Szymon Janc

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

* Re: [PATCH 01/10] attrib: Add API for reliable write
  2014-04-12 22:00 ` [PATCH 01/10] attrib: Add API for reliable write Lukasz Rymanowski
@ 2014-04-14 14:28   ` Szymon Janc
  0 siblings, 0 replies; 13+ messages in thread
From: Szymon Janc @ 2014-04-14 14:28 UTC (permalink / raw)
  To: Lukasz Rymanowski
  Cc: linux-bluetooth, johan.hedberg, claudio.takahasi,
	anderson.lizardo, armansito

Hi Łukasz,

On Sunday 13 of April 2014 00:00:22 Lukasz Rymanowski wrote:
> Android expose to application api for reliable write. Therefore we need
> to add this support to gattrib
> ---
>  attrib/gatt.c | 18 ++++++++++++++++++
>  attrib/gatt.h |  6 ++++++
>  2 files changed, 24 insertions(+)
> 
> diff --git a/attrib/gatt.c b/attrib/gatt.c
> index 49cd1a3..e461ab7 100644
> --- a/attrib/gatt.c
> +++ b/attrib/gatt.c
> @@ -871,6 +871,24 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, const uint8_t *value,
>  	return prepare_write(long_write);
>  }
>  
> +guint gatt_reliable_write_char(GAttrib *attrib, uint16_t handle,
> +					const uint8_t *value, size_t vlen,
> +					GAttribResultFunc func,
> +					gpointer user_data)
> +{
> +	uint8_t *buf;
> +	guint16 plen;
> +	size_t buflen;
> +
> +	buf = g_attrib_get_buffer(attrib, &buflen);
> +
> +	plen = enc_prep_write_req(handle, 0, value, vlen, buf, buflen);
> +	if (!plen)
> +		return 0;
> +
> +	return g_attrib_send(attrib, 0, buf, plen, func, user_data, NULL);
> +}
> +
>  guint gatt_exchange_mtu(GAttrib *attrib, uint16_t mtu, GAttribResultFunc func,
>  							gpointer user_data)
>  {
> diff --git a/attrib/gatt.h b/attrib/gatt.h
> index c65bf6c..76820e0 100644
> --- a/attrib/gatt.h
> +++ b/attrib/gatt.h
> @@ -84,6 +84,12 @@ guint gatt_write_char(GAttrib *attrib, uint16_t handle, const uint8_t *value,
>  					size_t vlen, GAttribResultFunc func,
>  					gpointer user_data);
>  
> +guint gatt_reliable_write_char(GAttrib *attrib, uint16_t handle,
> +					const uint8_t *value, size_t vlen,
> +					GAttribResultFunc func,
> +					gpointer user_data);
> +
> +

Just a minor: double empty line.

>  guint gatt_discover_char_desc(GAttrib *attrib, uint16_t start, uint16_t end,
>  				GAttribResultFunc func, gpointer user_data);
>  
> 

-- 
Best regards, 
Szymon Janc

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

end of thread, other threads:[~2014-04-14 14:28 UTC | newest]

Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-04-12 22:00 [PATCH 00/10] android/gatt: GATT Client write types support Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 01/10] attrib: Add API for reliable write Lukasz Rymanowski
2014-04-14 14:28   ` Szymon Janc
2014-04-12 22:00 ` [PATCH 02/10] attrib: Expose write execute Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 03/10] android/gatt: Add helper to create descr_data Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 04/10] android/gatt: Avoid double helper struct for read/write characteristic Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 05/10] android/gatt: Add helper to create characteristic op data Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 06/10] android/gatt: Fix error msg Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 07/10] android/gatt: Daemon accepts only default write type Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 08/10] android/gatt: Add support for reliable write Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 09/10] android/gatt: Add support for write execute Lukasz Rymanowski
2014-04-12 22:00 ` [PATCH 10/10] android/gatt: Add support for write without response Lukasz Rymanowski
2014-04-14 14:23 ` [PATCH 00/10] android/gatt: GATT Client write types support Szymon Janc

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