static DBusMessage *characteristic_read_value(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct characteristic *chrc = user_data; struct bt_gatt_client *gatt = chrc->service->client->gatt; struct async_dbus_op *op; if (chrc->read_id) return btd_error_in_progress(msg); op = new0(struct async_dbus_op, 1); if (!op) return btd_error_failed(msg, "Failed to initialize request"); op->msg = dbus_message_ref(msg); op->data = chrc; chrc->read_id = bt_gatt_client_read_value(gatt, chrc->value_handle, chrc_read_cb, async_dbus_op_ref(op), async_dbus_op_unref); if (chrc->read_id) return NULL; async_dbus_op_free(op); return btd_error_failed(msg, "Failed to send read request"); }
static DBusMessage *descriptor_read_value(DBusConnection *conn, DBusMessage *msg, void *user_data) { struct descriptor *desc = user_data; struct bt_gatt_client *gatt = desc->chrc->service->client->gatt; struct async_dbus_op *op; if (!gatt) return btd_error_failed(msg, "Not connected"); if (desc->read_id) return btd_error_in_progress(msg); op = new0(struct async_dbus_op, 1); op->msg = dbus_message_ref(msg); op->data = desc; desc->read_id = bt_gatt_client_read_value(gatt, desc->handle, desc_read_cb, async_dbus_op_ref(op), async_dbus_op_unref); if (desc->read_id) return NULL; async_dbus_op_free(op); return btd_error_failed(msg, "Failed to send read request"); }
static void desc_read_cb(bool success, uint8_t att_ecode, const uint8_t *value, uint16_t length, void *user_data) { struct async_dbus_op *op = user_data; struct descriptor *desc = op->data; struct service *service = desc->chrc->service; DBusMessage *reply; if (!success) goto fail; if (!op->offset) gatt_db_attribute_reset(desc->attr); if (!gatt_db_attribute_write(desc->attr, op->offset, value, length, 0, NULL, write_descriptor_cb, desc)) { error("Failed to store attribute"); goto fail; } /* * If the value length is exactly MTU-1, then we may not have read the * entire value. Perform a long read to obtain the rest, otherwise, * we're done. */ if (length == bt_gatt_client_get_mtu(service->client->gatt) - 1) { op->offset += length; desc->read_id = bt_gatt_client_read_long_value( service->client->gatt, desc->handle, op->offset, desc_read_cb, async_dbus_op_ref(op), async_dbus_op_unref); if (desc->read_id) return; } /* Read the stored data from db */ if (!gatt_db_attribute_read(desc->attr, 0, 0, NULL, read_op_cb, op)) { error("Failed to read database"); goto fail; } desc->read_id = 0; return; fail: reply = create_gatt_dbus_error(op->msg, att_ecode); desc->read_id = 0; g_dbus_send_message(btd_get_dbus_connection(), reply); return; }
static void chrc_read_cb(bool success, uint8_t att_ecode, const uint8_t *value, uint16_t length, void *user_data) { struct async_dbus_op *op = user_data; struct characteristic *chrc = op->data; struct service *service = chrc->service; if (!success) { DBusMessage *reply = create_gatt_dbus_error(op->msg, att_ecode); chrc->read_id = 0; g_dbus_send_message(btd_get_dbus_connection(), reply); return ; } if (!op->offset) gatt_db_attribute_reset(chrc->attr); gatt_db_attribute_write(chrc->attr, op->offset, value, length, 0, NULL, write_characteristic_cb, chrc); /* * If the value length is exactly MTU-1, then we may not have read the * entire value. Perform a long read to obtain the rest, otherwise, * we're done. */ if (length == bt_gatt_client_get_mtu(service->client->gatt) - 1) { op->offset += length; chrc->read_id = bt_gatt_client_read_long_value( service->client->gatt, chrc->value_handle, op->offset, chrc_read_cb, async_dbus_op_ref(op), async_dbus_op_unref); if (chrc->read_id) return; } chrc->read_id = 0; /* Read the stored data from db */ gatt_db_attribute_read(chrc->attr, 0, 0, NULL, read_op_cb, op); }