2014-04-17 11:57:43

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH v2 0/5]android/gatt: GATT Client write types support

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.

v2:
* Rebase
* Remove double empty line from gatt.h as Szymon pointed out

Lukasz Rymanowski (5):
attrib: Add API for reliable write
attrib: Expose write execute
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 | 113 ++++++++++++++++++++++++++++++++++++++++++++++++---------
attrib/gatt.c | 24 ++++++++++++
attrib/gatt.h | 8 ++++
3 files changed, 128 insertions(+), 17 deletions(-)

--
1.8.4



2014-04-23 13:19:18

by Szymon Janc

[permalink] [raw]
Subject: Re: [PATCH v2 0/5]android/gatt: GATT Client write types support

Hi Ɓukasz,

On Thursday 17 of April 2014 13:57:43 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.
>
> v2:
> * Rebase
> * Remove double empty line from gatt.h as Szymon pointed out
>
> Lukasz Rymanowski (5):
> attrib: Add API for reliable write
> attrib: Expose write execute
> 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 | 113
> ++++++++++++++++++++++++++++++++++++++++++++++++--------- attrib/gatt.c |
> 24 ++++++++++++
> attrib/gatt.h | 8 ++++
> 3 files changed, 128 insertions(+), 17 deletions(-)

All patches applied, thanks.

--
BR
Szymon Janc

2014-04-17 11:57:48

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH v2 5/5] android/gatt: Add support for write without response

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

diff --git a/android/gatt.c b/android/gatt.c
index 3f37a44..b367558 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2285,15 +2285,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_TYPE_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_TYPE_NO_RESPONSE:
+ res = gatt_write_cmd(dev->attrib, ch->ch.value_handle,
+ cmd->value, cmd->len,
+ NULL, NULL);
+ break;
case GATT_WRITE_TYPE_PREPARE:
res = gatt_reliable_write_char(dev->attrib, ch->ch.value_handle,
cmd->value, cmd->len,
@@ -2325,10 +2332,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_TYPE_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);
@@ -2588,21 +2599,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_TYPE_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_TYPE_NO_RESPONSE:
+ res = gatt_write_cmd(dev->attrib, descr->handle, cmd->value,
+ cmd->len, NULL , NULL);
+ break;
case GATT_WRITE_TYPE_PREPARE:
res = gatt_reliable_write_char(dev->attrib, descr->handle,
cmd->value, cmd->len,
write_descr_cb,
cb_data);
+
break;
case GATT_WRITE_TYPE_DEFAULT:
res = gatt_write_char(dev->attrib, descr->handle, cmd->value,
@@ -2623,8 +2641,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_TYPE_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


2014-04-17 11:57:46

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH v2 3/5] android/gatt: Add support for reliable write

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

diff --git a/android/gatt.c b/android/gatt.c
index e339789..281f520 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2294,6 +2294,11 @@ static void handle_client_write_characteristic(const void *buf, uint16_t len)
}

switch (cmd->write_type) {
+ case GATT_WRITE_TYPE_PREPARE:
+ res = gatt_reliable_write_char(dev->attrib, ch->ch.value_handle,
+ cmd->value, cmd->len,
+ write_char_cb, cb_data);
+ break;
case GATT_WRITE_TYPE_DEFAULT:
res = gatt_write_char(dev->attrib, ch->ch.value_handle,
cmd->value, cmd->len,
@@ -2593,6 +2598,12 @@ static void handle_client_write_descriptor(const void *buf, uint16_t len)
}

switch (cmd->write_type) {
+ case GATT_WRITE_TYPE_PREPARE:
+ res = gatt_reliable_write_char(dev->attrib, descr->handle,
+ cmd->value, cmd->len,
+ write_descr_cb,
+ cb_data);
+ break;
case GATT_WRITE_TYPE_DEFAULT:
res = gatt_write_char(dev->attrib, descr->handle, cmd->value,
cmd->len, write_descr_cb, cb_data);
--
1.8.4


2014-04-17 11:57:47

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH v2 4/5] android/gatt: Add support for write execute

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 281f520..3f37a44 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -2633,12 +2633,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


2014-04-17 11:57:45

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH v2 2/5] attrib: Expose write execute

This is needed to cover Android API
---
attrib/gatt.c | 6 ++++++
attrib/gatt.h | 3 +++
2 files changed, 9 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 585a876..3fe6041 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -89,6 +89,9 @@ 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


2014-04-17 11:57:44

by Lukasz Rymanowski

[permalink] [raw]
Subject: [PATCH v2 1/5] attrib: Add API for reliable write

Android expose to application api for reliable write. Therefore we need
to add this support to gattrib
---
attrib/gatt.c | 18 ++++++++++++++++++
attrib/gatt.h | 5 +++++
2 files changed, 23 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..585a876 100644
--- a/attrib/gatt.h
+++ b/attrib/gatt.h
@@ -84,6 +84,11 @@ 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