summaryrefslogtreecommitdiff
path: root/client/gatt.c
diff options
context:
space:
mode:
authorGrzegorz Kolodziejczyk <grzegorz.kolodziejczyk@codecoup.pl>2018-03-20 15:05:16 +0100
committerSzymon Janc <szymon.janc@codecoup.pl>2018-03-21 10:47:07 +0100
commit1abee58711bd10534d958e0fefe551b1d70dde2b (patch)
treeaf590958b91d86c6ce530f822ca5783c9f1e9542 /client/gatt.c
parent9786f580723dd2341b962d7b7ab9d9e6fc380202 (diff)
downloadbluez-1abee58711bd10534d958e0fefe551b1d70dde2b.tar.gz
client: Fix reading long values
While value has more than single MTU can carry long read procedure will be triggered. In such cases offset need to bo considered while getting value from storage.
Diffstat (limited to 'client/gatt.c')
-rw-r--r--client/gatt.c49
1 files changed, 47 insertions, 2 deletions
diff --git a/client/gatt.c b/client/gatt.c
index 8c818d8c1..7a6035ac1 100644
--- a/client/gatt.c
+++ b/client/gatt.c
@@ -1412,6 +1412,39 @@ static const GDBusPropertyTable chrc_properties[] = {
{ }
};
+static int parse_offset(DBusMessageIter *iter, uint16_t *offset)
+{
+ DBusMessageIter dict;
+
+ if (dbus_message_iter_get_arg_type(iter) != DBUS_TYPE_ARRAY)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(iter, &dict);
+
+ while (dbus_message_iter_get_arg_type(&dict) == DBUS_TYPE_DICT_ENTRY) {
+ const char *key;
+ DBusMessageIter value, entry;
+ int var;
+
+ dbus_message_iter_recurse(&dict, &entry);
+ dbus_message_iter_get_basic(&entry, &key);
+
+ dbus_message_iter_next(&entry);
+ dbus_message_iter_recurse(&entry, &value);
+
+ var = dbus_message_iter_get_arg_type(&value);
+ if (strcasecmp(key, "offset") == 0) {
+ if (var != DBUS_TYPE_UINT16)
+ return -EINVAL;
+ dbus_message_iter_get_basic(&value, offset);
+ }
+
+ dbus_message_iter_next(&dict);
+ }
+
+ return 0;
+}
+
static DBusMessage *read_value(DBusMessage *msg, uint8_t *value,
uint16_t value_len)
{
@@ -1433,8 +1466,14 @@ static DBusMessage *chrc_read_value(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
struct chrc *chrc = user_data;
+ DBusMessageIter iter;
+ uint16_t offset = 0;
+
+ dbus_message_iter_init(msg, &iter);
+
+ parse_offset(&iter, &offset);
- return read_value(msg, chrc->value, chrc->value_len);
+ return read_value(msg, &chrc->value[offset], chrc->value_len - offset);
}
static int parse_value_arg(DBusMessageIter *iter, uint8_t **value, int *len)
@@ -1785,8 +1824,14 @@ static DBusMessage *desc_read_value(DBusConnection *conn, DBusMessage *msg,
void *user_data)
{
struct desc *desc = user_data;
+ DBusMessageIter iter;
+ uint16_t offset = 0;
+
+ dbus_message_iter_init(msg, &iter);
+
+ parse_offset(&iter, &offset);
- return read_value(msg, desc->value, desc->value_len);
+ return read_value(msg, &desc->value[offset], desc->value_len - offset);
}
static DBusMessage *desc_write_value(DBusConnection *conn, DBusMessage *msg,