static void handle_characteristic(struct gatt_db_attribute *attr, void *user_data) { struct gas *gas = user_data; uint16_t value_handle; bt_uuid_t uuid; if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL, NULL, &uuid)) { error("Failed to obtain characteristic data"); return; } if (uuid_cmp(GATT_CHARAC_DEVICE_NAME, &uuid)) handle_device_name(gas, value_handle); else if (uuid_cmp(GATT_CHARAC_APPEARANCE, &uuid)) handle_appearance(gas, value_handle); else { char uuid_str[MAX_LEN_UUID_STR]; /* TODO: Support peripheral privacy feature */ bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); DBG("Unsupported characteristic: %s", uuid_str); } }
static struct characteristic *characteristic_create( struct gatt_db_attribute *attr, struct service *service) { struct characteristic *chrc; bt_uuid_t uuid; chrc = new0(struct characteristic, 1); if (!chrc) return NULL; chrc->descs = queue_new(); if (!chrc->descs) { free(chrc); return NULL; } chrc->notify_clients = queue_new(); if (!chrc->notify_clients) { queue_destroy(chrc->descs, NULL); free(chrc); return NULL; } chrc->service = service; 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); if (!chrc->attr) { error("Attribute 0x%04x not found", chrc->value_handle); characteristic_free(chrc); return NULL; } bt_uuid_to_uuid128(&uuid, &chrc->uuid); chrc->path = g_strdup_printf("%s/char%04x", service->path, chrc->handle); if (!g_dbus_register_interface(btd_get_dbus_connection(), chrc->path, GATT_CHARACTERISTIC_IFACE, characteristic_methods, NULL, characteristic_properties, chrc, characteristic_free)) { error("Unable to register GATT characteristic with handle " "0x%04x", chrc->handle); characteristic_free(chrc); return NULL; } DBG("Exported GATT characteristic: %s", chrc->path); return chrc; }
static bool is_reliable_write_supported(const struct bt_gatt_server *server, uint16_t handle) { struct gatt_db_attribute *attr; uint16_t ext_prop; attr = gatt_db_get_attribute(server->db, handle); if (!attr) return false; if (!gatt_db_attribute_get_char_data(attr, NULL, NULL, NULL, &ext_prop, NULL)) return false; return (ext_prop & BT_GATT_CHRC_EXT_PROP_RELIABLE_WRITE); }
static void print_chrc(struct gatt_db_attribute *attr, void *user_data) { uint16_t handle, value_handle; uint8_t properties; bt_uuid_t uuid; if (!gatt_db_attribute_get_char_data(attr, &handle, &value_handle, &properties, &uuid)) return; printf("\t " COLOR_YELLOW "charac" COLOR_OFF " - start: 0x%04x, value: 0x%04x, " "props: 0x%02x, uuid: ", handle, value_handle, properties); print_uuid(&uuid); gatt_db_service_foreach_desc(attr, print_desc, NULL); }
static void handle_characteristic(struct gatt_db_attribute *attr, void *user_data) { struct btd_device *device = user_data; uint16_t value_handle; bt_uuid_t uuid, pnpid_uuid; bt_string_to_uuid(&pnpid_uuid, PNPID_UUID); if (!gatt_db_attribute_get_char_data(attr, NULL, &value_handle, NULL, NULL, &uuid)) { error("Failed to obtain characteristic data"); return; } if (bt_uuid_cmp(&pnpid_uuid, &uuid) == 0) handle_pnpid(device, value_handle); else { char uuid_str[MAX_LEN_UUID_STR]; bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); DBG("Unsupported characteristic: %s", uuid_str); } }