2014-12-09 08:51:46

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 1/5] shared/att: Handle commands under BT_ATT_ALL_REQUESTS op group type

This is needed for backward compatibility with gattrib.
---
src/shared/att.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/src/shared/att.c b/src/shared/att.c
index ee425d8..3181b36 100644
--- a/src/shared/att.c
+++ b/src/shared/att.c
@@ -666,8 +666,10 @@ struct notify_data {

static bool opcode_match(uint8_t opcode, uint8_t test_opcode)
{
- if (opcode == BT_ATT_ALL_REQUESTS &&
- get_op_type(test_opcode) == ATT_OP_TYPE_REQ)
+ enum att_op_type op_type = get_op_type(test_opcode);
+
+ if (opcode == BT_ATT_ALL_REQUESTS && (op_type == ATT_OP_TYPE_REQ ||
+ op_type == ATT_OP_TYPE_CMD))
return true;

return opcode == test_opcode;
--
1.9.1



2014-12-09 10:05:01

by Luiz Augusto von Dentz

[permalink] [raw]
Subject: Re: [PATCHv2 1/5] shared/att: Handle commands under BT_ATT_ALL_REQUESTS op group type

Hi Jakub,

On Tue, Dec 9, 2014 at 10:51 AM, Jakub Tyszkowski
<[email protected]> wrote:
> This is needed for backward compatibility with gattrib.
> ---
> src/shared/att.c | 6 ++++--
> 1 file changed, 4 insertions(+), 2 deletions(-)
>
> diff --git a/src/shared/att.c b/src/shared/att.c
> index ee425d8..3181b36 100644
> --- a/src/shared/att.c
> +++ b/src/shared/att.c
> @@ -666,8 +666,10 @@ struct notify_data {
>
> static bool opcode_match(uint8_t opcode, uint8_t test_opcode)
> {
> - if (opcode == BT_ATT_ALL_REQUESTS &&
> - get_op_type(test_opcode) == ATT_OP_TYPE_REQ)
> + enum att_op_type op_type = get_op_type(test_opcode);
> +
> + if (opcode == BT_ATT_ALL_REQUESTS && (op_type == ATT_OP_TYPE_REQ ||
> + op_type == ATT_OP_TYPE_CMD))
> return true;
>
> return opcode == test_opcode;
> --
> 1.9.1

Applied, thanks.


--
Luiz Augusto von Dentz

2014-12-09 08:51:47

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 2/5] android/gatt: Fix write confirm callback being not set

Currently this callback is required or previously registered write
callback function wont be called.
---
android/gatt.c | 22 +++++++++++-----------
1 file changed, 11 insertions(+), 11 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index 720a205..841f08c 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -6179,6 +6179,15 @@ static uint8_t find_by_type_request(const uint8_t *cmd, uint16_t cmd_len,
return 0;
}

+static void write_confirm(struct gatt_db_attribute *attrib,
+ int err, void *user_data)
+{
+ if (!err)
+ return;
+
+ error("Error writting attribute %p", attrib);
+}
+
static void write_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
struct gatt_device *dev)
{
@@ -6207,7 +6216,7 @@ static void write_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
return;

gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0], &dev->bdaddr,
- NULL, NULL);
+ write_confirm, NULL);
}

static void write_signed_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
@@ -6279,7 +6288,7 @@ static void write_signed_cmd_request(const uint8_t *cmd, uint16_t cmd_len,
/* Signature OK, proceed with write */
bt_update_sign_counter(&dev->bdaddr, REMOTE_CSRK, r_sign_cnt);
gatt_db_attribute_write(attrib, 0, value, vlen, cmd[0],
- &dev->bdaddr, NULL, NULL);
+ &dev->bdaddr, write_confirm, NULL);
}
}

@@ -6641,15 +6650,6 @@ static void device_name_read_cb(struct gatt_db_attribute *attrib,
strlen(name));
}

-static void write_confirm(struct gatt_db_attribute *attrib,
- int err, void *user_data)
-{
- if (!err)
- return;
-
- error("Error writting attribute %p", attrib);
-}
-
static void register_gap_service(void)
{
uint16_t start, end;
--
1.9.1


2014-12-09 08:51:50

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 5/5] android/gatt: Remove invalid cases from att_handler

For these att opcodes callback will never be called as its registered
for requests and commands.
---
android/gatt.c | 4 ----
1 file changed, 4 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index e7ca147..ac45ffc 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -6564,15 +6564,11 @@ static void att_handler(const uint8_t *ipdu, uint16_t len, gpointer user_data)
case ATT_OP_FIND_BY_TYPE_REQ:
status = find_by_type_request(ipdu, len, dev);
break;
- case ATT_OP_HANDLE_NOTIFY:
- /* Client will handle this */
- return;
case ATT_OP_EXEC_WRITE_REQ:
status = write_execute_request(ipdu, len, dev);
if (!status)
return;
break;
- case ATT_OP_HANDLE_CNF:
case ATT_OP_READ_MULTI_REQ:
default:
DBG("Unsupported request 0x%02x", ipdu[0]);
--
1.9.1


2014-12-09 08:51:49

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 4/5] android/gatt: Handle indications in a separate function

Indications needs their own handler as they do not fall under the
ALL_REQUESTS op type.
---
android/gatt.c | 40 ++++++++++++++++++++++++++++++----------
1 file changed, 30 insertions(+), 10 deletions(-)

diff --git a/android/gatt.c b/android/gatt.c
index 536a7fe..e7ca147 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -162,6 +162,7 @@ struct gatt_device {

guint watch_id;
guint server_id;
+ guint ind_id;

int ref;
int conn_cnt;
@@ -633,6 +634,10 @@ static void connection_cleanup(struct gatt_device *device)
if (device->server_id > 0)
g_attrib_unregister(device->attrib, device->server_id);

+ if (device->ind_id > 0)
+ g_attrib_unregister(device->attrib,
+ device->ind_id);
+
device->attrib = NULL;
g_attrib_cancel_all(attrib);
g_attrib_unref(attrib);
@@ -1431,6 +1436,27 @@ static void create_app_connection(void *data, void *user_data)
create_connection(dev, app);
}

+static void ind_handler(const uint8_t *cmd, uint16_t cmd_len,
+ gpointer user_data)
+{
+ struct gatt_device *dev = user_data;
+ uint16_t resp_length = 0;
+ size_t length;
+
+ uint8_t *opdu = g_attrib_get_buffer(dev->attrib, &length);
+
+ /*
+ * We have to send confirmation here. If some client is
+ * registered for this indication, event will be send in
+ * handle_notification
+ */
+
+ resp_length = enc_confirmation(opdu, length);
+ if (resp_length)
+ g_attrib_send(dev->attrib, 0, opdu, resp_length, NULL, NULL,
+ NULL);
+}
+
static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
{
struct gatt_device *dev = user_data;
@@ -1478,7 +1504,10 @@ static void connect_cb(GIOChannel *io, GError *gerr, gpointer user_data)
dev->server_id = g_attrib_register(attrib, GATTRIB_ALL_REQS,
GATTRIB_ALL_HANDLES,
att_handler, dev, NULL);
- if (dev->server_id == 0)
+ dev->ind_id = g_attrib_register(attrib, ATT_OP_HANDLE_IND,
+ GATTRIB_ALL_HANDLES,
+ ind_handler, dev, NULL);
+ if ((dev->server_id && dev->ind_id) == 0)
error("gatt: Could not attach to server");

device_set_state(dev, DEVICE_CONNECTED);
@@ -6535,15 +6564,6 @@ static void att_handler(const uint8_t *ipdu, uint16_t len, gpointer user_data)
case ATT_OP_FIND_BY_TYPE_REQ:
status = find_by_type_request(ipdu, len, dev);
break;
- case ATT_OP_HANDLE_IND:
- /*
- * We have to send confirmation here. If some client is
- * registered for this indication, event will be send in
- * handle_notification
- */
- resp_length = enc_confirmation(opdu, length);
- status = 0;
- break;
case ATT_OP_HANDLE_NOTIFY:
/* Client will handle this */
return;
--
1.9.1


2014-12-09 08:51:48

by Jakub Tyszkowski

[permalink] [raw]
Subject: [PATCHv2 3/5] android/gatt: Fix not confirming write commands in database

App will never confirm write command as commands dont need one but we
still need to confirm in databasse. We confirm immediately.
---
android/gatt.c | 2 ++
1 file changed, 2 insertions(+)

diff --git a/android/gatt.c b/android/gatt.c
index 841f08c..536a7fe 100644
--- a/android/gatt.c
+++ b/android/gatt.c
@@ -4904,6 +4904,8 @@ static void write_cb(struct gatt_db_attribute *attrib, unsigned int id,

if (opcode == ATT_OP_WRITE_REQ || opcode == ATT_OP_PREP_WRITE_REQ)
ev->need_rsp = 0x01;
+ else
+ gatt_db_attribute_write_result(attrib, id, 0);

ev->length = len;
memcpy(ev->value, value, len);
--
1.9.1