diff --git a/src/gatt-client.c b/src/gatt-client.c
index 8e76503..1ff14dc 100644
--- a/src/gatt-client.c
+++ b/src/gatt-client.c
struct characteristic {
struct service *service;
+ struct gatt_db_attribute *attr;
uint16_t handle;
uint16_t value_handle;
uint8_t props;
char *path;
bool in_read;
- bool value_known;
- uint8_t *value;
- size_t value_len;
struct queue *descs;
};
struct descriptor {
struct characteristic *chrc;
+ struct gatt_db_attribute *attr;
uint16_t handle;
bt_uuid_t uuid;
char *path;
bool in_read;
- bool value_known;
- uint8_t *value;
- size_t value_len;
};
static gboolean descriptor_get_uuid(const GDBusPropertyTable *property,
return TRUE;
}
+static void read_cb(struct gatt_db_attribute *attrib, int err,
+ const uint8_t *value, size_t length,
+ void *user_data)
+{
+ DBusMessageIter *array = user_data;
+
+ if (err)
+ return;
+
+ dbus_message_iter_append_fixed_array(array, DBUS_TYPE_BYTE, &value,
+ length);
+}
+
static gboolean descriptor_get_value(const GDBusPropertyTable *property,
DBusMessageIter *iter, void *data)
{
struct descriptor *desc = data;
DBusMessageIter array;
- size_t i;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array);
- if (desc->value_known) {
- for (i = 0; i < desc->value_len; i++)
- dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE,
- desc->value + i);
- }
+ gatt_db_attribute_read(desc->attr, 0, 0, NULL, read_cb, &array);
dbus_message_iter_close_container(iter, &array);
return TRUE;
}
-static gboolean descriptor_value_exists(const GDBusPropertyTable *property,
- void *data)
+static void read_check_cb(struct gatt_db_attribute *attrib, int err,
+ const uint8_t *value, size_t length,
+ void *user_data)
{
- struct descriptor *desc = data;
+ gboolean *ret = user_data;
- return desc->value_known ? TRUE : FALSE;
-}
-
-static bool resize_value_buffer(size_t new_len, uint8_t **value, size_t *len)
-{
- uint8_t *ptr;
-
- if (*len == new_len)
- return true;
-
- if (!new_len) {
- free(*value);
- *value = NULL;
- *len = 0;
-
- return true;
+ if (err || length == 0) {
+ *ret = FALSE;
+ return;
}
- ptr = realloc(*value, sizeof(uint8_t) * new_len);
- if (!ptr)
- return false;
-
- *value = ptr;
- *len = new_len;
-
- return true;
+ *ret = TRUE;
}
-static void update_value_property(const uint8_t *value, size_t len,
- uint8_t **cur_value, size_t *cur_len,
- bool *value_known,
- const char *path, const char *iface)
+static gboolean descriptor_value_exists(const GDBusPropertyTable *property,
+ void *data)
{
- /*
- * If the value is the same, then only updated it if wasn't previously
- * known.
- */
- if (*value_known && *cur_len == len &&
- !memcmp(*cur_value, value, sizeof(uint8_t) * len))
- return;
+ struct descriptor *desc = data;
+ gboolean ret;
- if (resize_value_buffer(len, cur_value, cur_len)) {
- *value_known = true;
- memcpy(*cur_value, value, sizeof(uint8_t) * len);
- } else {
- /*
- * Failed to resize the buffer. Since we don't want to show a
- * stale value, if the value was previously known then free and
- * hide it.
- */
- free(*cur_value);
- *cur_value = NULL;
- *cur_len = 0;
- *value_known = false;
- }
+ gatt_db_attribute_read(desc->attr, 0, 0, NULL, read_check_cb, &ret);
- g_dbus_emit_property_changed(btd_get_dbus_connection(), path, iface,
- "Value");
+ return ret;
}
struct async_dbus_op {
return NULL;
}
+static void write_descriptor_cb(struct gatt_db_attribute *attr, int err,
+ void *user_data)
+{
+ struct descriptor *desc = user_data;
+
+ if (err)
+ return;
+
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), desc->path,
+ GATT_DESCRIPTOR_IFACE, "Value");
+}
+
static void desc_read_long_cb(bool success, uint8_t att_ecode,
const uint8_t *value, uint16_t length,
void *user_data)
goto done;
}
- update_value_property(value, length, &desc->value, &desc->value_len,
- &desc->value_known, desc->path,
- GATT_DESCRIPTOR_IFACE);
+ gatt_db_attribute_write(desc->attr, 0, value, length, 0, NULL,
+ write_descriptor_cb, desc);
reply = g_dbus_create_reply(op->msg, DBUS_TYPE_INVALID);
if (!reply) {
{
struct descriptor *desc = data;
- free(desc->value);
g_free(desc->path);
free(desc);
}
return NULL;
desc->chrc = chrc;
+ desc->attr = attr;
desc->handle = gatt_db_attribute_get_handle(attr);
bt_uuid_to_uuid128(gatt_db_attribute_get_type(attr), &desc->uuid);
{
struct characteristic *chrc = data;
DBusMessageIter array;
- size_t i;
dbus_message_iter_open_container(iter, DBUS_TYPE_ARRAY, "y", &array);
- if (chrc->value_known) {
- for (i = 0; i < chrc->value_len; i++)
- dbus_message_iter_append_basic(&array, DBUS_TYPE_BYTE,
- chrc->value + i);
- }
+ gatt_db_attribute_read(chrc->attr, 0, 0, NULL, read_cb, &array);
dbus_message_iter_close_container(iter, &array);
void *data)
{
struct characteristic *chrc = data;
+ gboolean ret;
+
+ gatt_db_attribute_read(chrc->attr, 0, 0, NULL, read_check_cb, &ret);
- return chrc->value_known ? TRUE : FALSE;
+ return TRUE;
}
static gboolean characteristic_get_notifying(const GDBusPropertyTable *property,
return TRUE;
}
+static void write_characteristic_cb(struct gatt_db_attribute *attr, int err,
+ void *user_data)
+{
+ struct characteristic *chrc = user_data;
+
+ if (err)
+ return;
+
+ g_dbus_emit_property_changed(btd_get_dbus_connection(), chrc->path,
+ GATT_CHARACTERISTIC_IFACE, "Value");
+}
+
static void chrc_read_long_cb(bool success, uint8_t att_ecode,
const uint8_t *value, uint16_t length,
void *user_data)
goto done;
}
- update_value_property(value, length, &chrc->value, &chrc->value_len,
- &chrc->value_known, chrc->path,
- GATT_CHARACTERISTIC_IFACE);
+ gatt_db_attribute_write(chrc->attr, 0, value, length, 0, NULL,
+ write_characteristic_cb, chrc);
reply = g_dbus_create_reply(op->msg, DBUS_TYPE_INVALID);
if (!reply) {
struct characteristic *chrc = data;
queue_destroy(chrc->descs, NULL); /* List should be empty here */
- free(chrc->value);
g_free(chrc->path);
free(chrc);
}
gatt_db_attribute_get_char_data(attr, &chrc->handle,
&chrc->value_handle,
&chrc->props, &uuid);
+ chrc->attr = gatt_db_get_attribute(service->client->db,
+ chrc->value_handle);
bt_uuid_to_uuid128(&uuid, &chrc->uuid);
chrc->path = g_strdup_printf("%s/char%04x", service->path,