From patchwork Fri May 20 04:16:55 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12856287 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 4399CC433FE for ; Fri, 20 May 2022 04:17:11 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234210AbiETERK (ORCPT ); Fri, 20 May 2022 00:17:10 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38154 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233029AbiETERG (ORCPT ); Fri, 20 May 2022 00:17:06 -0400 Received: from mail-pl1-x62d.google.com (mail-pl1-x62d.google.com [IPv6:2607:f8b0:4864:20::62d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 02EFD6B670 for ; Thu, 19 May 2022 21:17:04 -0700 (PDT) Received: by mail-pl1-x62d.google.com with SMTP id s14so6403292plk.8 for ; Thu, 19 May 2022 21:17:03 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=80Rc8wrOrqHpcMINX27MgcDRfkMFIB557PHl9IiT88g=; b=P1tXFUWvMRfR7i/J2LswdvzHlThIOBskbLKdIwQerYugTL4SQuSF0lXmZ2YOT1xMyJ Z6bGOozMvwHyE/EWSt/0ZtOCjxbBcc+C5UE6T6Sk5LJjnDtE/h77Lx9ZaBtI+a2i0B4K e+Qem+4TR77/lC5/e3oGhSvPiyD0LSnwp5b9q/+B4jzEUyEE4v1IsvlV+MB66f/UoCos 1kiyLVSmuAk6dbxJGR4CO2bESzBAq+JkADe2Vt5INApIeT7yzvYvUoTyzpxlnHuf9H9m SgpICeH5Xh3tzO3n2FuFYkHM/no2jUto3+dGF/1MBs8bbdFD6EnvkRLOgnMmLXzro054 +jlA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:mime-version :content-transfer-encoding; bh=80Rc8wrOrqHpcMINX27MgcDRfkMFIB557PHl9IiT88g=; b=xnANHfZ9UCcJEAqIw59dhu7z+oK0KtWbVZmQ00Xlg35qaUhQCPPoDxBFhGkLXo+1lz I4VOBjNjhiG8ZtG0V+kq23WnTQB57zAxSj290jj7X0NuU4iMLADlZfj0rsInN5cx5dbj nvP5j6CcqxGRxIlOcdCiZuVT24+b2uWQ+caieqg0juXjYXNDKu6xQOt9L0Oz70XSBkeh zZZ63LTRHoMqJ+H9ChvFT/h5ovQlUTp8r4wAGOAPvmAyz98sgQguSpar5WDgQU4mU8QR H/81o+25tzbDKcG9GFcuIsv5409tRu0qP1SKRSE2i5p7CSt6qBExoCJj1I7kIg4HBrU+ oSzw== X-Gm-Message-State: AOAM533rseKyNT10/SauCGnCVZ3lipH6JRW+hGeJ7lSVXBEzVdyfFrgq ydjMyDyfJuWlzT/LIwDfs5B10b0IcIM= X-Google-Smtp-Source: ABdhPJxCdaClm0OhU5EGKbs82dwZ3aRbPnwk/xQqUkBy4lFkZGIcrbuRAbecsUd/6R+dyfHkWwfLLw== X-Received: by 2002:a17:90b:314c:b0:1dc:767d:a7d9 with SMTP id ip12-20020a17090b314c00b001dc767da7d9mr8640504pjb.99.1653020222685; Thu, 19 May 2022 21:17:02 -0700 (PDT) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id u13-20020a17090a450d00b001df955c28f6sm381405pjg.37.2022.05.19.21.17.01 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 21:17:01 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 1/7] settings: Add btd_settings_gatt_db_{store,load} Date: Thu, 19 May 2022 21:16:55 -0700 Message-Id: <20220520041701.2572197-1-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.35.1 MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This adds helper functions to store and load from/to file so they can get reused by the likes of gatt-database.c and btmon. --- Makefile.am | 3 +- src/device.c | 499 ++--------------------------------------------- src/settings.c | 510 +++++++++++++++++++++++++++++++++++++++++++++++++ src/settings.h | 11 ++ 4 files changed, 534 insertions(+), 489 deletions(-) create mode 100644 src/settings.c create mode 100644 src/settings.h diff --git a/Makefile.am b/Makefile.am index 82125c482..0074ea3ac 100644 --- a/Makefile.am +++ b/Makefile.am @@ -322,7 +322,8 @@ src_bluetoothd_SOURCES = $(builtin_sources) \ src/dbus-common.c src/dbus-common.h \ src/eir.h src/eir.c \ src/adv_monitor.h src/adv_monitor.c \ - src/battery.h src/battery.c + src/battery.h src/battery.c \ + src/settings.h src/settings.c src_bluetoothd_LDADD = lib/libbluetooth-internal.la \ gdbus/libgdbus-internal.la \ src/libshared-glib.la \ diff --git a/src/device.c b/src/device.c index 638bad061..0d7c62c9c 100644 --- a/src/device.c +++ b/src/device.c @@ -63,6 +63,7 @@ #include "textfile.h" #include "storage.h" #include "eir.h" +#include "settings.h" #define DISCONNECT_TIMER 2 #define DISCOVERY_TIMER 1 @@ -74,11 +75,6 @@ #define RSSI_THRESHOLD 8 -#define GATT_PRIM_SVC_UUID_STR "2800" -#define GATT_SND_SVC_UUID_STR "2801" -#define GATT_INCLUDE_UUID_STR "2802" -#define GATT_CHARAC_UUID_STR "2803" - static DBusConnection *dbus_conn = NULL; static unsigned service_state_cb_id; @@ -2517,171 +2513,10 @@ static void store_services(struct btd_device *device) g_key_file_free(key_file); } -struct gatt_saver { - struct btd_device *device; - uint16_t ext_props; - GKeyFile *key_file; -}; - -static void db_hash_read_value_cb(struct gatt_db_attribute *attrib, - int err, const uint8_t *value, - size_t length, void *user_data) -{ - const uint8_t **hash = user_data; - - if (err || (length != 16)) - return; - - *hash = value; -} - -static void store_desc(struct gatt_db_attribute *attr, void *user_data) -{ - struct gatt_saver *saver = user_data; - GKeyFile *key_file = saver->key_file; - char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR]; - const bt_uuid_t *uuid; - bt_uuid_t ext_uuid; - uint16_t handle_num; - - handle_num = gatt_db_attribute_get_handle(attr); - sprintf(handle, "%04hx", handle_num); - - uuid = gatt_db_attribute_get_type(attr); - bt_uuid_to_string(uuid, uuid_str, sizeof(uuid_str)); - - bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID); - if (!bt_uuid_cmp(uuid, &ext_uuid) && saver->ext_props) - sprintf(value, "%04hx:%s", saver->ext_props, uuid_str); - else - sprintf(value, "%s", uuid_str); - - g_key_file_set_string(key_file, "Attributes", handle, value); -} - -static void store_chrc(struct gatt_db_attribute *attr, void *user_data) -{ - struct gatt_saver *saver = user_data; - GKeyFile *key_file = saver->key_file; - char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR]; - uint16_t handle_num, value_handle; - uint8_t properties; - bt_uuid_t uuid, hash_uuid; - - if (!gatt_db_attribute_get_char_data(attr, &handle_num, &value_handle, - &properties, &saver->ext_props, - &uuid)) { - warn("Error storing characteristic - can't get data"); - return; - } - - sprintf(handle, "%04hx", handle_num); - bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); - - /* Store Database Hash value if available */ - bt_uuid16_create(&hash_uuid, GATT_CHARAC_DB_HASH); - if (!bt_uuid_cmp(&uuid, &hash_uuid)) { - const uint8_t *hash = NULL; - - attr = gatt_db_get_attribute(saver->device->db, value_handle); - - gatt_db_attribute_read(attr, 0, BT_ATT_OP_READ_REQ, NULL, - db_hash_read_value_cb, &hash); - if (hash) - sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:" - "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" - "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" - "%02hhx%02hhx:%s", value_handle, properties, - hash[0], hash[1], hash[2], hash[3], - hash[4], hash[5], hash[6], hash[7], - hash[8], hash[9], hash[10], hash[11], - hash[12], hash[13], hash[14], hash[15], - uuid_str); - else - sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s", - value_handle, properties, uuid_str); - - } else - sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s", - value_handle, properties, uuid_str); - - g_key_file_set_string(key_file, "Attributes", handle, value); - - gatt_db_service_foreach_desc(attr, store_desc, saver); -} - -static void store_incl(struct gatt_db_attribute *attr, void *user_data) -{ - struct gatt_saver *saver = user_data; - GKeyFile *key_file = saver->key_file; - struct gatt_db_attribute *service; - char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR]; - uint16_t handle_num, start, end; - bt_uuid_t uuid; - - if (!gatt_db_attribute_get_incl_data(attr, &handle_num, &start, &end)) { - warn("Error storing included service - can't get data"); - return; - } - - service = gatt_db_get_attribute(saver->device->db, start); - if (!service) { - warn("Error storing included service - can't find it"); - return; - } - - sprintf(handle, "%04hx", handle_num); - - gatt_db_attribute_get_service_uuid(service, &uuid); - bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); - sprintf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", start, - end, uuid_str); - - g_key_file_set_string(key_file, "Attributes", handle, value); -} - -static void store_service(struct gatt_db_attribute *attr, void *user_data) -{ - struct gatt_saver *saver = user_data; - GKeyFile *key_file = saver->key_file; - char uuid_str[MAX_LEN_UUID_STR], handle[6], value[256]; - uint16_t start, end; - bt_uuid_t uuid; - bool primary; - char *type; - - if (!gatt_db_attribute_get_service_data(attr, &start, &end, &primary, - &uuid)) { - warn("Error storing service - can't get data"); - return; - } - - sprintf(handle, "%04hx", start); - - bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); - - if (primary) - type = GATT_PRIM_SVC_UUID_STR; - else - type = GATT_SND_SVC_UUID_STR; - - sprintf(value, "%s:%04hx:%s", type, end, uuid_str); - - g_key_file_set_string(key_file, "Attributes", handle, value); - - gatt_db_service_foreach_incl(attr, store_incl, saver); - gatt_db_service_foreach_char(attr, store_chrc, saver); -} - static void store_gatt_db(struct btd_device *device) { char filename[PATH_MAX]; char dst_addr[18]; - GKeyFile *key_file; - GError *gerr = NULL; - char *data; - gsize length = 0; - struct gatt_saver saver; if (device_address_is_private(device)) { DBG("Can't store GATT db for private addressed device %s", @@ -2699,33 +2534,9 @@ static void store_gatt_db(struct btd_device *device) dst_addr); create_file(filename, 0600); - key_file = g_key_file_new(); - if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) { - error("Unable to load key file from %s: (%s)", filename, - gerr->message); - g_clear_error(&gerr); - } - - /* Remove current attributes since it might have changed */ - g_key_file_remove_group(key_file, "Attributes", NULL); - - saver.key_file = key_file; - saver.device = device; - - gatt_db_foreach_service(device->db, NULL, store_service, &saver); - - data = g_key_file_to_data(key_file, &length, NULL); - if (!g_file_set_contents(filename, data, length, &gerr)) { - error("Unable set contents for %s: (%s)", filename, - gerr->message); - g_error_free(gerr); - } - - g_free(data); - g_key_file_free(key_file); + btd_settings_gatt_db_store(device->db, filename); } - static void browse_request_complete(struct browse_req *req, uint8_t type, uint8_t bdaddr_type, int err) { @@ -3797,288 +3608,11 @@ static void add_primary(struct gatt_db_attribute *attr, void *user_data) *new_services = g_slist_append(*new_services, prim); } -static void load_desc_value(struct gatt_db_attribute *attrib, - int err, void *user_data) -{ - if (err) - warn("loading descriptor value to db failed"); -} - -static ssize_t str2val(const char *str, uint8_t *val, size_t len) -{ - const char *pos = str; - size_t i; - - for (i = 0; i < len; i++) { - if (sscanf(pos, "%2hhx", &val[i]) != 1) - break; - pos += 2; - } - - return i; -} - -static int load_desc(char *handle, char *value, - struct gatt_db_attribute *service) -{ - char uuid_str[MAX_LEN_UUID_STR]; - struct gatt_db_attribute *att; - uint16_t handle_int; - uint16_t val; - bt_uuid_t uuid, ext_uuid; - - if (sscanf(handle, "%04hx", &handle_int) != 1) - return -EIO; - - /* Check if there is any value stored, otherwise it is just the UUID */ - if (sscanf(value, "%04hx:%36s", &val, uuid_str) != 2) { - if (sscanf(value, "%36s", uuid_str) != 1) - return -EIO; - val = 0; - } - - DBG("loading descriptor handle: 0x%04x, value: 0x%04x, value uuid: %s", - handle_int, val, uuid_str); - - bt_string_to_uuid(&uuid, uuid_str); - bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID); - - /* If it is CEP then it must contain the value */ - if (!bt_uuid_cmp(&uuid, &ext_uuid) && !val) { - warn("cannot load CEP descriptor without value"); - return -EIO; - } - - att = gatt_db_service_insert_descriptor(service, handle_int, &uuid, - 0, NULL, NULL, NULL); - if (!att || gatt_db_attribute_get_handle(att) != handle_int) { - warn("loading descriptor to db failed"); - return -EIO; - } - - if (val) { - if (!gatt_db_attribute_write(att, 0, (uint8_t *)&val, - sizeof(val), 0, NULL, - load_desc_value, NULL)) - return -EIO; - } - - return 0; -} - -static int load_chrc(char *handle, char *value, - struct gatt_db_attribute *service) -{ - uint16_t properties, value_handle, handle_int; - char uuid_str[MAX_LEN_UUID_STR]; - struct gatt_db_attribute *att; - char val_str[33]; - uint8_t val[16]; - size_t val_len; - bt_uuid_t uuid; - - if (sscanf(handle, "%04hx", &handle_int) != 1) - return -EIO; - - /* Check if there is any value stored */ - if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%32s:%36s", - &value_handle, &properties, val_str, uuid_str) != 4) { - if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%36s", - &value_handle, &properties, uuid_str) != 3) - return -EIO; - val_len = 0; - } else - val_len = str2val(val_str, val, sizeof(val)); - - bt_string_to_uuid(&uuid, uuid_str); - - /* Log debug message. */ - DBG("loading characteristic handle: 0x%04x, value handle: 0x%04x," - " properties 0x%04x value: %s uuid: %s", - handle_int, value_handle, properties, - val_len ? val_str : "", uuid_str); - - att = gatt_db_service_insert_characteristic(service, value_handle, - &uuid, 0, properties, - NULL, NULL, NULL); - if (!att || gatt_db_attribute_get_handle(att) != value_handle) { - warn("loading characteristic to db failed"); - return -EIO; - } - - if (val_len) { - if (!gatt_db_attribute_write(att, 0, val, val_len, 0, NULL, - load_desc_value, NULL)) - return -EIO; - } - - return 0; -} - -static int load_incl(struct gatt_db *db, char *handle, char *value, - struct gatt_db_attribute *service) -{ - char uuid_str[MAX_LEN_UUID_STR]; - struct gatt_db_attribute *att; - uint16_t start, end; - - if (sscanf(handle, "%04hx", &start) != 1) - return -EIO; - - if (sscanf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%36s", &start, - &end, uuid_str) != 3) - return -EIO; - - /* Log debug message. */ - DBG("loading included service: 0x%04x, end: 0x%04x, uuid: %s", start, - end, uuid_str); - - att = gatt_db_get_attribute(db, start); - if (!att) { - warn("loading included service to db failed - no such service"); - return -EIO; - } - - att = gatt_db_service_add_included(service, att); - if (!att) { - warn("loading included service to db failed"); - return -EIO; - } - - return 0; -} - -static int load_service(struct gatt_db *db, char *handle, char *value) -{ - struct gatt_db_attribute *att; - uint16_t start, end; - char type[MAX_LEN_UUID_STR], uuid_str[MAX_LEN_UUID_STR]; - bt_uuid_t uuid; - bool primary; - - if (sscanf(handle, "%04hx", &start) != 1) - return -EIO; - - if (sscanf(value, "%[^:]:%04hx:%36s", type, &end, uuid_str) != 3) - return -EIO; - - if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR)) - primary = true; - else if (g_str_equal(type, GATT_SND_SVC_UUID_STR)) - primary = false; - else - return -EIO; - - bt_string_to_uuid(&uuid, uuid_str); - - /* Log debug message. */ - DBG("loading service: 0x%04x, end: 0x%04x, uuid: %s", - start, end, uuid_str); - - att = gatt_db_insert_service(db, start, &uuid, primary, - end - start + 1); - if (!att) { - error("Unable load service into db!"); - return -EIO; - } - - return 0; -} - -static int load_gatt_db_impl(GKeyFile *key_file, char **keys, - struct gatt_db *db) -{ - struct gatt_db_attribute *current_service; - char **handle, *value, type[MAX_LEN_UUID_STR]; - int ret; - - /* first load service definitions */ - for (handle = keys; *handle; handle++) { - value = g_key_file_get_string(key_file, "Attributes", *handle, - NULL); - - if (sscanf(value, "%[^:]:", type) != 1) { - warn("Missing Type in attribute definition"); - g_free(value); - return -EIO; - } - - if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) || - g_str_equal(type, GATT_SND_SVC_UUID_STR)) { - ret = load_service(db, *handle, value); - if (ret) { - g_free(value); - return ret; - } - } - - g_free(value); - } - - current_service = NULL; - /* then fill them with data*/ - for (handle = keys; *handle; handle++) { - value = g_key_file_get_string(key_file, "Attributes", *handle, - NULL); - - if (sscanf(value, "%[^:]:", type) != 1) { - warn("Missing Type in attribute definition"); - g_free(value); - return -EIO; - } - - if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) || - g_str_equal(type, GATT_SND_SVC_UUID_STR)) { - uint16_t tmp; - uint16_t start, end; - bool primary; - bt_uuid_t uuid; - char uuid_str[MAX_LEN_UUID_STR]; - - if (sscanf(*handle, "%04hx", &tmp) != 1) { - warn("Unable to parse attribute handle"); - g_free(value); - return -EIO; - } - - if (current_service) - gatt_db_service_set_active(current_service, - true); - - current_service = gatt_db_get_attribute(db, tmp); - - gatt_db_attribute_get_service_data(current_service, - &start, &end, - &primary, &uuid); - - bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); - } else if (g_str_equal(type, GATT_INCLUDE_UUID_STR)) { - ret = load_incl(db, *handle, value, current_service); - } else if (g_str_equal(type, GATT_CHARAC_UUID_STR)) { - ret = load_chrc(*handle, value, current_service); - } else { - ret = load_desc(*handle, value, current_service); - } - - g_free(value); - if (ret) { - gatt_db_clear(db); - return ret; - } - } - - if (current_service) - gatt_db_service_set_active(current_service, true); - - return 0; -} - static void load_gatt_db(struct btd_device *device, const char *local, const char *peer) { - char **keys, filename[PATH_MAX]; - GKeyFile *key_file; - GError *gerr = NULL; + char filename[PATH_MAX]; + int err; if (!gatt_cache_is_enabled(device)) return; @@ -4087,25 +3621,14 @@ static void load_gatt_db(struct btd_device *device, const char *local, create_filename(filename, PATH_MAX, "/%s/cache/%s", local, peer); - key_file = g_key_file_new(); - if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) { - error("Unable to load key file from %s: (%s)", filename, - gerr->message); - g_error_free(gerr); + err = btd_settings_gatt_db_load(device->db, filename); + if (err < 0) { + if (err == -ENOENT) + return; + + warn("Error loading db from cache for %s: %s (%d)", peer, + strerror(-err), err); } - keys = g_key_file_get_keys(key_file, "Attributes", NULL, NULL); - - if (!keys) { - warn("No cache for %s", peer); - g_key_file_free(key_file); - return; - } - - if (load_gatt_db_impl(key_file, keys, device->db)) - warn("Unable to load gatt db from file for %s", peer); - - g_strfreev(keys); - g_key_file_free(key_file); g_slist_free_full(device->primaries, g_free); device->primaries = NULL; diff --git a/src/settings.c b/src/settings.c new file mode 100644 index 000000000..0f0530006 --- /dev/null +++ b/src/settings.c @@ -0,0 +1,510 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2022 Intel Corporation. + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#include +#include + +#include + +#include "lib/bluetooth.h" +#include "lib/uuid.h" + +#include "log.h" +#include "src/shared/queue.h" +#include "src/shared/att.h" +#include "src/shared/gatt-db.h" +#include "settings.h" + +#define GATT_PRIM_SVC_UUID_STR "2800" +#define GATT_SND_SVC_UUID_STR "2801" +#define GATT_INCLUDE_UUID_STR "2802" +#define GATT_CHARAC_UUID_STR "2803" + +static ssize_t str2val(const char *str, uint8_t *val, size_t len) +{ + const char *pos = str; + size_t i; + + for (i = 0; i < len; i++) { + if (sscanf(pos, "%2hhx", &val[i]) != 1) + break; + pos += 2; + } + + return i; +} + +static void load_desc_value(struct gatt_db_attribute *attrib, int err, + void *user_data) +{ +} + +static int load_desc(struct gatt_db *db, char *handle, char *value, + struct gatt_db_attribute *service) +{ + char uuid_str[MAX_LEN_UUID_STR]; + struct gatt_db_attribute *att; + uint16_t handle_int; + uint16_t val; + bt_uuid_t uuid, ext_uuid; + + if (sscanf(handle, "%04hx", &handle_int) != 1) + return -EIO; + + /* Check if there is any value stored, otherwise it is just the UUID */ + if (sscanf(value, "%04hx:%36s", &val, uuid_str) != 2) { + if (sscanf(value, "%36s", uuid_str) != 1) + return -EIO; + val = 0; + } + + DBG("loading descriptor handle: 0x%04x, value: 0x%04x, value uuid: %s", + handle_int, val, uuid_str); + + bt_string_to_uuid(&uuid, uuid_str); + bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID); + + /* If it is CEP then it must contain the value */ + if (!bt_uuid_cmp(&uuid, &ext_uuid) && !val) + return -EIO; + + att = gatt_db_service_insert_descriptor(service, handle_int, &uuid, + 0, NULL, NULL, NULL); + if (!att || gatt_db_attribute_get_handle(att) != handle_int) + return -EIO; + + if (val) { + if (!gatt_db_attribute_write(att, 0, (uint8_t *)&val, + sizeof(val), 0, NULL, + load_desc_value, NULL)) + return -EIO; + } + + return 0; +} + +static int load_chrc(struct gatt_db *db, char *handle, char *value, + struct gatt_db_attribute *service) +{ + uint16_t properties, value_handle, handle_int; + char uuid_str[MAX_LEN_UUID_STR]; + struct gatt_db_attribute *att; + char val_str[33]; + uint8_t val[16]; + size_t val_len; + bt_uuid_t uuid; + + if (sscanf(handle, "%04hx", &handle_int) != 1) + return -EIO; + + /* Check if there is any value stored */ + if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%32s:%36s", + &value_handle, &properties, val_str, uuid_str) != 4) { + if (sscanf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hx:%36s", + &value_handle, &properties, uuid_str) != 3) + return -EIO; + val_len = 0; + } else + val_len = str2val(val_str, val, sizeof(val)); + + bt_string_to_uuid(&uuid, uuid_str); + + /* Log debug message. */ + DBG("loading characteristic handle: 0x%04x, value handle: 0x%04x, " + "properties 0x%04x value: %s uuid: %s", + handle_int, value_handle, + properties, val_len ? val_str : "", uuid_str); + + att = gatt_db_service_insert_characteristic(service, value_handle, + &uuid, 0, properties, + NULL, NULL, NULL); + if (!att || gatt_db_attribute_get_handle(att) != value_handle) + return -EIO; + + if (val_len) { + if (!gatt_db_attribute_write(att, 0, val, val_len, 0, NULL, + load_desc_value, NULL)) + return -EIO; + } + + return 0; +} + +static int load_incl(struct gatt_db *db, char *handle, char *value, + struct gatt_db_attribute *service) +{ + char uuid_str[MAX_LEN_UUID_STR]; + struct gatt_db_attribute *att; + uint16_t start, end; + + if (sscanf(handle, "%04hx", &start) != 1) + return -EIO; + + if (sscanf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%36s", &start, + &end, uuid_str) != 3) + return -EIO; + + /* Log debug message. */ + DBG("loading included service: 0x%04x, end: 0x%04x, uuid: %s", + start, end, uuid_str); + + att = gatt_db_get_attribute(db, start); + if (!att) + return -EIO; + + att = gatt_db_service_add_included(service, att); + if (!att) + return -EIO; + + return 0; +} + +static int load_service(struct gatt_db *db, char *handle, char *value) +{ + struct gatt_db_attribute *att; + uint16_t start, end; + char type[MAX_LEN_UUID_STR], uuid_str[MAX_LEN_UUID_STR]; + bt_uuid_t uuid; + bool primary; + + if (sscanf(handle, "%04hx", &start) != 1) + return -EIO; + + if (sscanf(value, "%[^:]:%04hx:%36s", type, &end, uuid_str) != 3) + return -EIO; + + if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR)) + primary = true; + else if (g_str_equal(type, GATT_SND_SVC_UUID_STR)) + primary = false; + else + return -EIO; + + bt_string_to_uuid(&uuid, uuid_str); + + /* Log debug message. */ + DBG("loading service: 0x%04x, end: 0x%04x, uuid: %s", start, end, + uuid_str); + + att = gatt_db_insert_service(db, start, &uuid, primary, + end - start + 1); + if (!att) { + DBG("Unable load service into db!"); + return -EIO; + } + + return 0; +} + +static int gatt_db_load(struct gatt_db *db, GKeyFile *key_file, char **keys) +{ + struct gatt_db_attribute *current_service; + char **handle, *value, type[MAX_LEN_UUID_STR]; + int ret; + + /* first load service definitions */ + for (handle = keys; *handle; handle++) { + value = g_key_file_get_string(key_file, "Attributes", *handle, + NULL); + + if (sscanf(value, "%[^:]:", type) != 1) { + g_free(value); + return -EIO; + } + + if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) || + g_str_equal(type, GATT_SND_SVC_UUID_STR)) { + ret = load_service(db, *handle, value); + if (ret) { + g_free(value); + return ret; + } + } + + g_free(value); + } + + current_service = NULL; + /* then fill them with data*/ + for (handle = keys; *handle; handle++) { + value = g_key_file_get_string(key_file, "Attributes", *handle, + NULL); + + if (sscanf(value, "%[^:]:", type) != 1) { + g_free(value); + return -EIO; + } + + if (g_str_equal(type, GATT_PRIM_SVC_UUID_STR) || + g_str_equal(type, GATT_SND_SVC_UUID_STR)) { + uint16_t tmp; + uint16_t start, end; + bool primary; + bt_uuid_t uuid; + char uuid_str[MAX_LEN_UUID_STR]; + + if (sscanf(*handle, "%04hx", &tmp) != 1) { + g_free(value); + return -EIO; + } + + if (current_service) + gatt_db_service_set_active(current_service, + true); + + current_service = gatt_db_get_attribute(db, tmp); + + gatt_db_attribute_get_service_data(current_service, + &start, &end, + &primary, &uuid); + + bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); + } else if (g_str_equal(type, GATT_INCLUDE_UUID_STR)) { + ret = load_incl(db, *handle, value, current_service); + } else if (g_str_equal(type, GATT_CHARAC_UUID_STR)) { + ret = load_chrc(db, *handle, value, current_service); + } else { + ret = load_desc(db, *handle, value, current_service); + } + + g_free(value); + if (ret) { + gatt_db_clear(db); + return ret; + } + } + + if (current_service) + gatt_db_service_set_active(current_service, true); + + return 0; +} + +int btd_settings_gatt_db_load(struct gatt_db *db, const char *filename) +{ + char **keys; + GKeyFile *key_file; + GError *gerr = NULL; + int err; + + key_file = g_key_file_new(); + if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) { + DBG("Unable to load key file from %s: (%s)", filename, + gerr->message); + g_clear_error(&gerr); + } + + keys = g_key_file_get_keys(key_file, "Attributes", NULL, NULL); + + if (!keys) { + g_key_file_free(key_file); + return -ENOENT; + } + + err = gatt_db_load(db, key_file, keys); + + g_strfreev(keys); + g_key_file_free(key_file); + + return err; +} + +struct gatt_saver { + struct gatt_db *db; + uint16_t ext_props; + GKeyFile *key_file; +}; + +static void db_hash_read_value_cb(struct gatt_db_attribute *attrib, + int err, const uint8_t *value, + size_t length, void *user_data) +{ + const uint8_t **hash = user_data; + + if (err || (length != 16)) + return; + + *hash = value; +} + +static void store_desc(struct gatt_db_attribute *attr, void *user_data) +{ + struct gatt_saver *saver = user_data; + GKeyFile *key_file = saver->key_file; + char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR]; + const bt_uuid_t *uuid; + bt_uuid_t ext_uuid; + uint16_t handle_num; + + handle_num = gatt_db_attribute_get_handle(attr); + sprintf(handle, "%04hx", handle_num); + + uuid = gatt_db_attribute_get_type(attr); + bt_uuid_to_string(uuid, uuid_str, sizeof(uuid_str)); + + bt_uuid16_create(&ext_uuid, GATT_CHARAC_EXT_PROPER_UUID); + if (!bt_uuid_cmp(uuid, &ext_uuid) && saver->ext_props) + sprintf(value, "%04hx:%s", saver->ext_props, uuid_str); + else + sprintf(value, "%s", uuid_str); + + g_key_file_set_string(key_file, "Attributes", handle, value); +} + +static void store_chrc(struct gatt_db_attribute *attr, void *user_data) +{ + struct gatt_saver *saver = user_data; + GKeyFile *key_file = saver->key_file; + char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR]; + uint16_t handle_num, value_handle; + uint8_t properties; + bt_uuid_t uuid, hash_uuid; + + if (!gatt_db_attribute_get_char_data(attr, &handle_num, &value_handle, + &properties, &saver->ext_props, + &uuid)) { + DBG("Unable to locate Characteristic data"); + return; + } + + sprintf(handle, "%04hx", handle_num); + bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); + + /* Store Database Hash value if available */ + bt_uuid16_create(&hash_uuid, GATT_CHARAC_DB_HASH); + if (!bt_uuid_cmp(&uuid, &hash_uuid)) { + const uint8_t *hash = NULL; + + attr = gatt_db_get_attribute(saver->db, value_handle); + + gatt_db_attribute_read(attr, 0, BT_ATT_OP_READ_REQ, NULL, + db_hash_read_value_cb, &hash); + if (hash) + sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:" + "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" + "%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx%02hhx" + "%02hhx%02hhx:%s", value_handle, properties, + hash[0], hash[1], hash[2], hash[3], + hash[4], hash[5], hash[6], hash[7], + hash[8], hash[9], hash[10], hash[11], + hash[12], hash[13], hash[14], hash[15], + uuid_str); + else + sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s", + value_handle, properties, uuid_str); + + } else + sprintf(value, GATT_CHARAC_UUID_STR ":%04hx:%02hhx:%s", + value_handle, properties, uuid_str); + + g_key_file_set_string(key_file, "Attributes", handle, value); + + gatt_db_service_foreach_desc(attr, store_desc, saver); +} + +static void store_incl(struct gatt_db_attribute *attr, void *user_data) +{ + struct gatt_saver *saver = user_data; + GKeyFile *key_file = saver->key_file; + struct gatt_db_attribute *service; + char handle[6], value[100], uuid_str[MAX_LEN_UUID_STR]; + uint16_t handle_num, start, end; + bt_uuid_t uuid; + + if (!gatt_db_attribute_get_incl_data(attr, &handle_num, &start, &end)) { + DBG("Unable to locate Included data"); + return; + } + + service = gatt_db_get_attribute(saver->db, start); + if (!service) { + DBG("Unable to locate Included Service"); + return; + } + + sprintf(handle, "%04hx", handle_num); + + gatt_db_attribute_get_service_uuid(service, &uuid); + bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); + sprintf(value, GATT_INCLUDE_UUID_STR ":%04hx:%04hx:%s", start, + end, uuid_str); + + g_key_file_set_string(key_file, "Attributes", handle, value); +} + +static void store_service(struct gatt_db_attribute *attr, void *user_data) +{ + struct gatt_saver *saver = user_data; + GKeyFile *key_file = saver->key_file; + char uuid_str[MAX_LEN_UUID_STR], handle[6], value[256]; + uint16_t start, end; + bt_uuid_t uuid; + bool primary; + char *type; + + if (!gatt_db_attribute_get_service_data(attr, &start, &end, &primary, + &uuid)) { + DBG("Unable to locate Service data"); + return; + } + + sprintf(handle, "%04hx", start); + + bt_uuid_to_string(&uuid, uuid_str, sizeof(uuid_str)); + + if (primary) + type = GATT_PRIM_SVC_UUID_STR; + else + type = GATT_SND_SVC_UUID_STR; + + sprintf(value, "%s:%04hx:%s", type, end, uuid_str); + + g_key_file_set_string(key_file, "Attributes", handle, value); + + gatt_db_service_foreach_incl(attr, store_incl, saver); + gatt_db_service_foreach_char(attr, store_chrc, saver); +} + +void btd_settings_gatt_db_store(struct gatt_db *db, const char *filename) +{ + GKeyFile *key_file; + GError *gerr = NULL; + char *data; + gsize length = 0; + struct gatt_saver saver; + + key_file = g_key_file_new(); + if (!g_key_file_load_from_file(key_file, filename, 0, &gerr)) { + DBG("Unable to load key file from %s: (%s)", filename, + gerr->message); + g_clear_error(&gerr); + } + + /* Remove current attributes since it might have changed */ + g_key_file_remove_group(key_file, "Attributes", NULL); + + saver.key_file = key_file; + saver.db = db; + + gatt_db_foreach_service(db, NULL, store_service, &saver); + + data = g_key_file_to_data(key_file, &length, NULL); + if (!g_file_set_contents(filename, data, length, &gerr)) { + DBG("Unable set contents for %s: (%s)", filename, + gerr->message); + g_error_free(gerr); + } + + g_free(data); + g_key_file_free(key_file); +} diff --git a/src/settings.h b/src/settings.h new file mode 100644 index 000000000..675f643a6 --- /dev/null +++ b/src/settings.h @@ -0,0 +1,11 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2022 Intel Corporation. + * + */ + +int btd_settings_gatt_db_load(struct gatt_db *db, const char *filename); +void btd_settings_gatt_db_store(struct gatt_db *db, const char *filename); From patchwork Fri May 20 04:16:56 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12856285 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 05D12C433F5 for ; Fri, 20 May 2022 04:17:07 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S233851AbiETERF (ORCPT ); Fri, 20 May 2022 00:17:05 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38034 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233029AbiETERF (ORCPT ); Fri, 20 May 2022 00:17:05 -0400 Received: from mail-pg1-x52d.google.com (mail-pg1-x52d.google.com [IPv6:2607:f8b0:4864:20::52d]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 534426B671 for ; Thu, 19 May 2022 21:17:04 -0700 (PDT) Received: by mail-pg1-x52d.google.com with SMTP id a19so6742439pgw.6 for ; Thu, 19 May 2022 21:17:04 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=X1tWqgEEva7mkuzTKbVhg+7xlep5rVnxIn+4oJ8Ey4k=; b=ORzOywuLtxLy8TNUaOO1kJq2fokVfdNHZonenAOzur8tHwDsXZlfNn9TTxpT03SXWd h+OCmPxeqxb13PNvgEVs3ZVUYQ/87A2jZ9d9vB7lbztuiwIrAF+DesszgPIgJ5fPRgdx YqpVpfz2Ml1ai4WpVxjYZbbG1Chc1wF5QrpHjltM8oIJf2heZjyefM8Hqvqc9Y2xyfnm dkSzq1SaUh+D/a5mcLUs7sNLxbLM9UHtqiG/xgqNIcWnlzqyZ82ASpi09JUHFCrYER9Z eC+IxG7xCWgFKOryt1v3EOZBQD0PtmTkQPF8U3w8aTTsuw/Yn86H0EPr5T96Q6Yjtytm KoLQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=X1tWqgEEva7mkuzTKbVhg+7xlep5rVnxIn+4oJ8Ey4k=; b=RaIpyeozntu83EkBAiwLkFnLTEAp4eomz7FzMkcxZdro0S7o4B5x4SPirxdSPugAuB fssVmZGwJJ8Z7lAJt0BerzkpFc2bfS0fO8viuJKyImPeDevca8V2UzbaeBkpaqdo3D8H ZyCqXQ6ZmVIRwDwytKk2p4S1JXkSkudPxXXaSfkFni3dDtvW1/FvfJtY32qMU+YylEpF msxcofE7R1fUknTzTf3dukZDKzAqGJAzlIUAsX1XE66hXxg+WUb9+i7I4YS5wcNz6sDT tGMoKCyTOw46Flu8T8rqX23Pxs+scLEu4VvjX/hnGPMFpr8QTEqXvbn6k6JikOkUvZgq PJTw== X-Gm-Message-State: AOAM532k4Ti6LDAnwNJqpOcdS54vvhjRj5T/xE1BcO4x6GvTIgJjvZKR aJA73dacOFkwDsX/cpXONjeCSVPEjjY= X-Google-Smtp-Source: ABdhPJzGig529p1NIITWRduaWFR7zJ3DUxGXMCjKe9jNvgjOhkXhHEgzsiRitPXMS0+rojrau8HgNg== X-Received: by 2002:a63:5357:0:b0:3f2:6210:f8e9 with SMTP id t23-20020a635357000000b003f26210f8e9mr6670136pgl.158.1653020223536; Thu, 19 May 2022 21:17:03 -0700 (PDT) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id u13-20020a17090a450d00b001df955c28f6sm381405pjg.37.2022.05.19.21.17.02 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 21:17:02 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 2/7] gatt: Store local GATT database Date: Thu, 19 May 2022 21:16:56 -0700 Message-Id: <20220520041701.2572197-2-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220520041701.2572197-1-luiz.dentz@gmail.com> References: <20220520041701.2572197-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This enables storing the local (adapter) GATT database which later will be used by btmon to decode GATT handles. --- src/gatt-database.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/src/gatt-database.c b/src/gatt-database.c index d32f616a9..cf651b5f5 100644 --- a/src/gatt-database.c +++ b/src/gatt-database.c @@ -38,6 +38,8 @@ #include "dbus-common.h" #include "profile.h" #include "service.h" +#include "textfile.h" +#include "settings.h" #define GATT_MANAGER_IFACE "org.bluez.GattManager1" #define GATT_PROFILE_IFACE "org.bluez.GattProfile1" @@ -1528,6 +1530,17 @@ static void send_service_changed(struct btd_gatt_database *database, error("Failed to notify Service Changed"); } +static void database_store(struct btd_gatt_database *database) +{ + char filename[PATH_MAX]; + + create_filename(filename, PATH_MAX, "/%s/attributes", + btd_adapter_get_storage_dir(database->adapter)); + create_file(filename, 0600); + + btd_settings_gatt_db_store(database->db, filename); +} + static void gatt_db_service_added(struct gatt_db_attribute *attrib, void *user_data) { @@ -1538,6 +1551,8 @@ static void gatt_db_service_added(struct gatt_db_attribute *attrib, database_add_record(database, attrib); send_service_changed(database, attrib); + + database_store(database); } static bool ccc_match_service(const void *data, const void *match_data) From patchwork Fri May 20 04:16:57 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12856286 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id B7EF8C433EF for ; Fri, 20 May 2022 04:17:10 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234128AbiETERJ (ORCPT ); Fri, 20 May 2022 00:17:09 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38122 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234070AbiETERG (ORCPT ); Fri, 20 May 2022 00:17:06 -0400 Received: from mail-pg1-x536.google.com (mail-pg1-x536.google.com [IPv6:2607:f8b0:4864:20::536]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 578C86B671 for ; Thu, 19 May 2022 21:17:05 -0700 (PDT) Received: by mail-pg1-x536.google.com with SMTP id h186so6749737pgc.3 for ; Thu, 19 May 2022 21:17:05 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=H846IO+fjJ5R46JqSkbj1tpySM3tu5H6t+OYD86b50Q=; b=HMJFGHxi7/CSmtHb+ntD0dJK5IZCryBRflgf2uqBVWox65ZsqOYsyHBAluHx6pVRtK ZqSyVNXtZEGHakkR0LxRTgkXdSIheWGW2AHmxrwecd8WVFuc8BpgFtPUUDvHitz/KCg1 dd20QFLBvqsmcY+Y9qTiJonX4wDBPxHzpOAsha43s5lzeWG0oNoCt1vVgrAVwOOUWITv 4P6Zf5a0oFawG45baTSgG8pcBHKuZJ8iB3Yp4wqkzXn+o/M3gDBCf2TfBWLka6ETlG06 eikHxNXsMVdRDbbn7SO/8BfqFPE9gwvb5rYbAmtH/vtZhi3t1vkFf4vCWTyhFT64fmqZ rWHg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=H846IO+fjJ5R46JqSkbj1tpySM3tu5H6t+OYD86b50Q=; b=Owc+bTCgdnDW1cL4T4quskqzEM0erPYhWJskWhfUOnt7+0g3THWOG7iwI2iHlcKUwO tljDz+gzDu8jE//LHkywLXV3Gp3ED3yIXd+lwVSCn/AWl/rZwFHVc9+piw/cylb4f5Zt P4at4cTb6X04HCpfcsThOvorWZiA/aVgTN5J6mSceGVa9orecq1SyXVmmXTtHCbXPkHM aVbxXhVw1ZM2MtRtYMV4b65qzpb4jQ5hGrBLyAVDHAo5yb2vRp/9N9+7rRAQdwWsjwmq SLKLyab1eytFAcf87ZcDO+EW4G/MhMRqtp/iE8tIsdPgSu9tzryU7Iwq2d1r2Njqoahx BwTw== X-Gm-Message-State: AOAM530bCgz8j7ThmrbMBNUe1WJK8KP4L4/3sSjEgOzgsVN9tW6Tfeor 8mdnvSWAKkqLBApbv8wCVZnzedOxeCc= X-Google-Smtp-Source: ABdhPJyVmZ5y9DBIUgOEj1ZoZHxUhGyc+w9Y6lSmYRnwjifEvLzsgVAyeMYo8E7kJDEcVBcr57yRfQ== X-Received: by 2002:a65:6e88:0:b0:382:3851:50c8 with SMTP id bm8-20020a656e88000000b00382385150c8mr6948098pgb.270.1653020224528; Thu, 19 May 2022 21:17:04 -0700 (PDT) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id u13-20020a17090a450d00b001df955c28f6sm381405pjg.37.2022.05.19.21.17.03 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 21:17:03 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 3/7] monitor: Move print_hex_field to display.h Date: Thu, 19 May 2022 21:16:57 -0700 Message-Id: <20220520041701.2572197-3-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220520041701.2572197-1-luiz.dentz@gmail.com> References: <20220520041701.2572197-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This moves print_hex_field to display.h and removes the duplicated code from packet.c and l2cap.c. --- monitor/display.h | 14 ++++++++++++++ monitor/l2cap.c | 14 -------------- monitor/packet.c | 14 -------------- 3 files changed, 14 insertions(+), 28 deletions(-) diff --git a/monitor/display.h b/monitor/display.h index be5739833..5a82f8e6f 100644 --- a/monitor/display.h +++ b/monitor/display.h @@ -76,6 +76,20 @@ static inline uint64_t print_bitfield(int indent, uint64_t val, return mask; } +static inline void print_hex_field(const char *label, const uint8_t *data, + uint8_t len) +{ + char str[len * 2 + 1]; + uint8_t i; + + str[0] = '\0'; + + for (i = 0; i < len; i++) + sprintf(str + (i * 2), "%2.2x", data[i]); + + print_field("%s: %s", label, str); +} + void set_default_pager_num_columns(int num_columns); int num_columns(void); diff --git a/monitor/l2cap.c b/monitor/l2cap.c index 01825ce0a..192b6c920 100644 --- a/monitor/l2cap.c +++ b/monitor/l2cap.c @@ -2123,20 +2123,6 @@ static void amp_packet(uint16_t index, bool in, uint16_t handle, opcode_data->func(&frame); } -static void print_hex_field(const char *label, const uint8_t *data, - uint8_t len) -{ - char str[len * 2 + 1]; - uint8_t i; - - str[0] = '\0'; - - for (i = 0; i < len; i++) - sprintf(str + (i * 2), "%2.2x", data[i]); - - print_field("%s: %s", label, str); -} - static void print_uuid(const char *label, const void *data, uint16_t size) { const char *str; diff --git a/monitor/packet.c b/monitor/packet.c index d80735a06..2e02b3923 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -1755,20 +1755,6 @@ static void print_key_size(uint8_t key_size) print_field("Key size: %d", key_size); } -static void print_hex_field(const char *label, const uint8_t *data, - uint8_t len) -{ - char str[len * 2 + 1]; - uint8_t i; - - str[0] = '\0'; - - for (i = 0; i < len; i++) - sprintf(str + (i * 2), "%2.2x", data[i]); - - print_field("%s: %s", label, str); -} - static void print_key(const char *label, const uint8_t *link_key) { print_hex_field(label, link_key, 16); From patchwork Fri May 20 04:16:58 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12856291 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id CDC0AC433EF for ; Fri, 20 May 2022 04:17:32 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S235761AbiETERa (ORCPT ); Fri, 20 May 2022 00:17:30 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:39156 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234687AbiETERU (ORCPT ); Fri, 20 May 2022 00:17:20 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id B68FD703E8 for ; Thu, 19 May 2022 21:17:17 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id pq9-20020a17090b3d8900b001df622bf81dso6897262pjb.3 for ; Thu, 19 May 2022 21:17:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=+tTlP/tjwm51gk5ioQz3E377YsDesZVEuKkVCbz2gtI=; b=l47vgddIRIC7RQsj4tUNZG6rrHZYgH3QKV6wil3v7flTW2pP45qIoFaJnDfS3dbdQc GhZzZ65HX/kXQ6QgAGGPl7MIUkG1NGrjn77GclK2obrTasu9Mmhg5ZMTyBbnefjz4N6n c+86z9mKJoq3+SQOg+B9N2NNF+j4G5Xr3wwOXFhTgVfVgsqqCmdi3ZqRTdZRBzVEhUlC GYL7Md+erI2SckcXsBMRUDZWF8H1rqDi0j/2vkwGW+hDsfmQ8kZPK8PSZoFPlmSbJXSm YiQtfQZ5EZnm/lBV1WZmmh4Y/855c3qsLWGuX0+PlbOBCdTlVdO1NPhX6KeKf/eXgODa TDBA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=+tTlP/tjwm51gk5ioQz3E377YsDesZVEuKkVCbz2gtI=; b=EcGmKCZ6Zie3CNrb4/vrVmSn81nUuQrFVyfGjOL4TfWC5QV+nrlULEnnckbP3LvQB6 shwT0+Q/DyWiGbbzcS+3F5eETTkFhQ6QnIFyTBe5C6X1GI1UGqTdI3Ub2aSdew9Og+wU zNTuzy2ATloSTvp60crf8nv/JabYTCgKod/VBqbMNiLkRGjaLVk8RzDIdlaykmjr5m0r Z1MTR9ycPzc5+gNIVJtWPwtB6xI7NjhZ5/n/TP84kJXBj1EJqvCqnL2OmlwMpMVigr7m v421DK+pGKtC14CbzGy45bHlXnMB0lioIxdlPJxPNrYlGm7jWA8bErnh7L7d9GRS4dVe u/lA== X-Gm-Message-State: AOAM5338GHIUf5YnBdMvkJFBHiScBrbkM6mRLquCXeWDwwaEerKDAW7j yuRohxZIgtUn02/JaCYaFDKtezSnp5s= X-Google-Smtp-Source: ABdhPJxOl+N9xayJ9kmurLmA90K81nc70g+9Db1e4jj4Z1HKK2LkupG1AgNcRIwVNnViH8dr5c3h0Q== X-Received: by 2002:a17:902:e0d3:b0:161:f0c7:b810 with SMTP id e19-20020a170902e0d300b00161f0c7b810mr1946561pla.138.1653020225524; Thu, 19 May 2022 21:17:05 -0700 (PDT) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id u13-20020a17090a450d00b001df955c28f6sm381405pjg.37.2022.05.19.21.17.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 21:17:04 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 4/7] monitor: Move ATT decoding function into its own file Date: Thu, 19 May 2022 21:16:58 -0700 Message-Id: <20220520041701.2572197-4-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220520041701.2572197-1-luiz.dentz@gmail.com> References: <20220520041701.2572197-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This moves ATT decoding function from l2cap.c to att.c. --- Makefile.tools | 6 +- monitor/att.c | 642 ++++++++++++++++++++++++++++++++++++++++++++++++ monitor/att.h | 16 ++ monitor/l2cap.c | 616 +--------------------------------------------- monitor/l2cap.h | 5 + 5 files changed, 669 insertions(+), 616 deletions(-) create mode 100644 monitor/att.c create mode 100644 monitor/att.h diff --git a/Makefile.tools b/Makefile.tools index b7d893248..a152dad6f 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -48,9 +48,11 @@ monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \ monitor/broadcom.h monitor/broadcom.c \ monitor/msft.h monitor/msft.c \ monitor/jlink.h monitor/jlink.c \ - monitor/tty.h monitor/emulator.h + monitor/tty.h monitor/emulator.h \ + monitor/att.h monitor/att.c monitor_btmon_LDADD = lib/libbluetooth-internal.la \ - src/libshared-mainloop.la $(UDEV_LIBS) -ldl + src/libshared-mainloop.la \ + $(GLIB_LIBS) $(UDEV_LIBS) -ldl if MANPAGES man_MANS += monitor/btmon.1 diff --git a/monitor/att.c b/monitor/att.c new file mode 100644 index 000000000..5ad8244db --- /dev/null +++ b/monitor/att.c @@ -0,0 +1,642 @@ +// SPDX-License-Identifier: LGPL-2.1-or-later +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011-2014 Intel Corporation + * Copyright (C) 2002-2010 Marcel Holtmann + * + * + */ + +#ifdef HAVE_CONFIG_H +#include +#endif + +#define _GNU_SOURCE +#include +#include +#include +#include + +#include "lib/bluetooth.h" +#include "lib/uuid.h" + +#include "src/shared/util.h" +#include "bt.h" +#include "packet.h" +#include "display.h" +#include "l2cap.h" +#include "att.h" + +static void print_uuid(const char *label, const void *data, uint16_t size) +{ + const char *str; + char uuidstr[MAX_LEN_UUID_STR]; + + switch (size) { + case 2: + str = bt_uuid16_to_str(get_le16(data)); + print_field("%s: %s (0x%4.4x)", label, str, get_le16(data)); + break; + case 4: + str = bt_uuid32_to_str(get_le32(data)); + print_field("%s: %s (0x%8.8x)", label, str, get_le32(data)); + break; + case 16: + sprintf(uuidstr, "%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x", + get_le32(data + 12), get_le16(data + 10), + get_le16(data + 8), get_le16(data + 6), + get_le32(data + 2), get_le16(data + 0)); + str = bt_uuidstr_to_str(uuidstr); + print_field("%s: %s (%s)", label, str, uuidstr); + break; + default: + packet_hexdump(data, size); + break; + } +} + +static void print_handle_range(const char *label, const void *data) +{ + print_field("%s: 0x%4.4x-0x%4.4x", label, + get_le16(data), get_le16(data + 2)); +} + +static void print_data_list(const char *label, uint8_t length, + const void *data, uint16_t size) +{ + uint8_t count; + + if (length == 0) + return; + + count = size / length; + + print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies"); + + while (size >= length) { + print_field("Handle: 0x%4.4x", get_le16(data)); + print_hex_field("Value", data + 2, length - 2); + + data += length; + size -= length; + } + + packet_hexdump(data, size); +} + +static void print_attribute_info(uint16_t type, const void *data, uint16_t len) +{ + const char *str = bt_uuid16_to_str(type); + + print_field("%s: %s (0x%4.4x)", "Attribute type", str, type); + + switch (type) { + case 0x2800: /* Primary Service */ + case 0x2801: /* Secondary Service */ + print_uuid(" UUID", data, len); + break; + case 0x2802: /* Include */ + if (len < 4) { + print_hex_field(" Value", data, len); + break; + } + print_handle_range(" Handle range", data); + print_uuid(" UUID", data + 4, len - 4); + break; + case 0x2803: /* Characteristic */ + if (len < 3) { + print_hex_field(" Value", data, len); + break; + } + print_field(" Properties: 0x%2.2x", *((uint8_t *) data)); + print_field(" Handle: 0x%2.2x", get_le16(data + 1)); + print_uuid(" UUID", data + 3, len - 3); + break; + default: + print_hex_field("Value", data, len); + break; + } +} + +static const char *att_opcode_to_str(uint8_t opcode); + +static void att_error_response(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_error_response *pdu = frame->data; + const char *str; + + switch (pdu->error) { + case 0x01: + str = "Invalid Handle"; + break; + case 0x02: + str = "Read Not Permitted"; + break; + case 0x03: + str = "Write Not Permitted"; + break; + case 0x04: + str = "Invalid PDU"; + break; + case 0x05: + str = "Insufficient Authentication"; + break; + case 0x06: + str = "Request Not Supported"; + break; + case 0x07: + str = "Invalid Offset"; + break; + case 0x08: + str = "Insufficient Authorization"; + break; + case 0x09: + str = "Prepare Queue Full"; + break; + case 0x0a: + str = "Attribute Not Found"; + break; + case 0x0b: + str = "Attribute Not Long"; + break; + case 0x0c: + str = "Insufficient Encryption Key Size"; + break; + case 0x0d: + str = "Invalid Attribute Value Length"; + break; + case 0x0e: + str = "Unlikely Error"; + break; + case 0x0f: + str = "Insufficient Encryption"; + break; + case 0x10: + str = "Unsupported Group Type"; + break; + case 0x11: + str = "Insufficient Resources"; + break; + case 0x12: + str = "Database Out of Sync"; + break; + case 0x13: + str = "Value Not Allowed"; + break; + case 0xfd: + str = "CCC Improperly Configured"; + break; + case 0xfe: + str = "Procedure Already in Progress"; + break; + case 0xff: + str = "Out of Range"; + break; + default: + str = "Reserved"; + break; + } + + print_field("%s (0x%2.2x)", att_opcode_to_str(pdu->request), + pdu->request); + print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); + print_field("Error: %s (0x%2.2x)", str, pdu->error); +} + +static void att_exchange_mtu_req(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_exchange_mtu_req *pdu = frame->data; + + print_field("Client RX MTU: %d", le16_to_cpu(pdu->mtu)); +} + +static void att_exchange_mtu_rsp(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_exchange_mtu_rsp *pdu = frame->data; + + print_field("Server RX MTU: %d", le16_to_cpu(pdu->mtu)); +} + +static void att_find_info_req(const struct l2cap_frame *frame) +{ + print_handle_range("Handle range", frame->data); +} + +static const char *att_format_str(uint8_t format) +{ + switch (format) { + case 0x01: + return "UUID-16"; + case 0x02: + return "UUID-128"; + default: + return "unknown"; + } +} + +static uint16_t print_info_data_16(const void *data, uint16_t len) +{ + while (len >= 4) { + print_field("Handle: 0x%4.4x", get_le16(data)); + print_uuid("UUID", data + 2, 2); + data += 4; + len -= 4; + } + + return len; +} + +static uint16_t print_info_data_128(const void *data, uint16_t len) +{ + while (len >= 18) { + print_field("Handle: 0x%4.4x", get_le16(data)); + print_uuid("UUID", data + 2, 16); + data += 18; + len -= 18; + } + + return len; +} + +static void att_find_info_rsp(const struct l2cap_frame *frame) +{ + const uint8_t *format = frame->data; + uint16_t len; + + print_field("Format: %s (0x%2.2x)", att_format_str(*format), *format); + + if (*format == 0x01) + len = print_info_data_16(frame->data + 1, frame->size - 1); + else if (*format == 0x02) + len = print_info_data_128(frame->data + 1, frame->size - 1); + else + len = frame->size - 1; + + packet_hexdump(frame->data + (frame->size - len), len); +} + +static void att_find_by_type_val_req(const struct l2cap_frame *frame) +{ + uint16_t type; + + print_handle_range("Handle range", frame->data); + + type = get_le16(frame->data + 4); + print_attribute_info(type, frame->data + 6, frame->size - 6); +} + +static void att_find_by_type_val_rsp(const struct l2cap_frame *frame) +{ + const uint8_t *ptr = frame->data; + uint16_t len = frame->size; + + while (len >= 4) { + print_handle_range("Handle range", ptr); + ptr += 4; + len -= 4; + } + + packet_hexdump(ptr, len); +} + +static void att_read_type_req(const struct l2cap_frame *frame) +{ + print_handle_range("Handle range", frame->data); + print_uuid("Attribute type", frame->data + 4, frame->size - 4); +} + +static void att_read_type_rsp(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data; + + print_field("Attribute data length: %d", pdu->length); + print_data_list("Attribute data list", pdu->length, + frame->data + 1, frame->size - 1); +} + +static void att_read_req(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_read_req *pdu = frame->data; + + print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); +} + +static void att_read_rsp(const struct l2cap_frame *frame) +{ + print_hex_field("Value", frame->data, frame->size); +} + +static void att_read_blob_req(const struct l2cap_frame *frame) +{ + print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); +} + +static void att_read_blob_rsp(const struct l2cap_frame *frame) +{ + packet_hexdump(frame->data, frame->size); +} + +static void att_read_multiple_req(const struct l2cap_frame *frame) +{ + int i, count; + + count = frame->size / 2; + + for (i = 0; i < count; i++) + print_field("Handle: 0x%4.4x", + get_le16(frame->data + (i * 2))); +} + +static void att_read_group_type_req(const struct l2cap_frame *frame) +{ + print_handle_range("Handle range", frame->data); + print_uuid("Attribute group type", frame->data + 4, frame->size - 4); +} + +static void print_group_list(const char *label, uint8_t length, + const void *data, uint16_t size) +{ + uint8_t count; + + if (length == 0) + return; + + count = size / length; + + print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies"); + + while (size >= length) { + print_handle_range("Handle range", data); + print_uuid("UUID", data + 4, length - 4); + + data += length; + size -= length; + } + + packet_hexdump(data, size); +} + +static void att_read_group_type_rsp(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data; + + print_field("Attribute data length: %d", pdu->length); + print_group_list("Attribute group list", pdu->length, + frame->data + 1, frame->size - 1); +} + +static void att_write_req(const struct l2cap_frame *frame) +{ + print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_hex_field(" Data", frame->data + 2, frame->size - 2); +} + +static void att_write_rsp(const struct l2cap_frame *frame) +{ +} + +static void att_prepare_write_req(const struct l2cap_frame *frame) +{ + print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); + print_hex_field(" Data", frame->data + 4, frame->size - 4); +} + +static void att_prepare_write_rsp(const struct l2cap_frame *frame) +{ + print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); + print_hex_field(" Data", frame->data + 4, frame->size - 4); +} + +static void att_execute_write_req(const struct l2cap_frame *frame) +{ + uint8_t flags = *(uint8_t *) frame->data; + const char *flags_str; + + switch (flags) { + case 0x00: + flags_str = "Cancel all prepared writes"; + break; + case 0x01: + flags_str = "Immediately write all pending values"; + break; + default: + flags_str = "Unknown"; + break; + } + + print_field("Flags: %s (0x%02x)", flags_str, flags); +} + +static void att_handle_value_notify(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_handle_value_notify *pdu = frame->data; + + print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); + print_hex_field(" Data", frame->data + 2, frame->size - 2); +} + +static void att_handle_value_ind(const struct l2cap_frame *frame) +{ + const struct bt_l2cap_att_handle_value_ind *pdu = frame->data; + + print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); + print_hex_field(" Data", frame->data + 2, frame->size - 2); +} + +static void att_handle_value_conf(const struct l2cap_frame *frame) +{ +} + +static void att_multiple_vl_rsp(const struct l2cap_frame *frame) +{ + struct l2cap_frame *f = (void *) frame; + + while (frame->size) { + uint16_t handle; + uint16_t len; + + if (!l2cap_frame_get_le16(f, &handle)) + return; + + print_field("Handle: 0x%4.4x", handle); + + if (!l2cap_frame_get_le16(f, &len)) + return; + + print_field("Length: 0x%4.4x", len); + + print_hex_field(" Data", f->data, + len < f->size ? len : f->size); + + if (len > f->size) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + l2cap_frame_pull(f, f, len); + } +} + +static void att_write_command(const struct l2cap_frame *frame) +{ + print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_hex_field(" Data", frame->data + 2, frame->size - 2); +} + +static void att_signed_write_command(const struct l2cap_frame *frame) +{ + print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_hex_field(" Data", frame->data + 2, frame->size - 2 - 12); + print_hex_field(" Signature", frame->data + frame->size - 12, 12); +} + +struct att_opcode_data { + uint8_t opcode; + const char *str; + void (*func) (const struct l2cap_frame *frame); + uint8_t size; + bool fixed; +}; + +static const struct att_opcode_data att_opcode_table[] = { + { 0x01, "Error Response", + att_error_response, 4, true }, + { 0x02, "Exchange MTU Request", + att_exchange_mtu_req, 2, true }, + { 0x03, "Exchange MTU Response", + att_exchange_mtu_rsp, 2, true }, + { 0x04, "Find Information Request", + att_find_info_req, 4, true }, + { 0x05, "Find Information Response", + att_find_info_rsp, 5, false }, + { 0x06, "Find By Type Value Request", + att_find_by_type_val_req, 6, false }, + { 0x07, "Find By Type Value Response", + att_find_by_type_val_rsp, 4, false }, + { 0x08, "Read By Type Request", + att_read_type_req, 6, false }, + { 0x09, "Read By Type Response", + att_read_type_rsp, 3, false }, + { 0x0a, "Read Request", + att_read_req, 2, true }, + { 0x0b, "Read Response", + att_read_rsp, 0, false }, + { 0x0c, "Read Blob Request", + att_read_blob_req, 4, true }, + { 0x0d, "Read Blob Response", + att_read_blob_rsp, 0, false }, + { 0x0e, "Read Multiple Request", + att_read_multiple_req, 4, false }, + { 0x0f, "Read Multiple Response" }, + { 0x10, "Read By Group Type Request", + att_read_group_type_req, 6, false }, + { 0x11, "Read By Group Type Response", + att_read_group_type_rsp, 4, false }, + { 0x12, "Write Request" , + att_write_req, 2, false }, + { 0x13, "Write Response", + att_write_rsp, 0, true }, + { 0x16, "Prepare Write Request", + att_prepare_write_req, 4, false }, + { 0x17, "Prepare Write Response", + att_prepare_write_rsp, 4, false }, + { 0x18, "Execute Write Request", + att_execute_write_req, 1, true }, + { 0x19, "Execute Write Response" }, + { 0x1b, "Handle Value Notification", + att_handle_value_notify, 2, false }, + { 0x1d, "Handle Value Indication", + att_handle_value_ind, 2, false }, + { 0x1e, "Handle Value Confirmation", + att_handle_value_conf, 0, true }, + { 0x20, "Read Multiple Request Variable Length", + att_read_multiple_req, 4, false }, + { 0x21, "Read Multiple Response Variable Length", + att_multiple_vl_rsp, 4, false }, + { 0x23, "Handle Multiple Value Notification", + att_multiple_vl_rsp, 4, false }, + { 0x52, "Write Command", + att_write_command, 2, false }, + { 0xd2, "Signed Write Command", att_signed_write_command, 14, false }, + { } +}; + +static const char *att_opcode_to_str(uint8_t opcode) +{ + int i; + + for (i = 0; att_opcode_table[i].str; i++) { + if (att_opcode_table[i].opcode == opcode) + return att_opcode_table[i].str; + } + + return "Unknown"; +} + +void att_packet(uint16_t index, bool in, uint16_t handle, uint16_t cid, + const void *data, uint16_t size) +{ + struct l2cap_frame frame; + uint8_t opcode = *((const uint8_t *) data); + const struct att_opcode_data *opcode_data = NULL; + const char *opcode_color, *opcode_str; + int i; + + if (size < 1) { + print_text(COLOR_ERROR, "malformed attribute packet"); + packet_hexdump(data, size); + return; + } + + for (i = 0; att_opcode_table[i].str; i++) { + if (att_opcode_table[i].opcode == opcode) { + opcode_data = &att_opcode_table[i]; + break; + } + } + + if (opcode_data) { + if (opcode_data->func) { + if (in) + opcode_color = COLOR_MAGENTA; + else + opcode_color = COLOR_BLUE; + } else + opcode_color = COLOR_WHITE_BG; + opcode_str = opcode_data->str; + } else { + opcode_color = COLOR_WHITE_BG; + opcode_str = "Unknown"; + } + + print_indent(6, opcode_color, "ATT: ", opcode_str, COLOR_OFF, + " (0x%2.2x) len %d", opcode, size - 1); + + if (!opcode_data || !opcode_data->func) { + packet_hexdump(data + 1, size - 1); + return; + } + + if (opcode_data->fixed) { + if (size - 1 != opcode_data->size) { + print_text(COLOR_ERROR, "invalid size"); + packet_hexdump(data + 1, size - 1); + return; + } + } else { + if (size - 1 < opcode_data->size) { + print_text(COLOR_ERROR, "too short packet"); + packet_hexdump(data + 1, size - 1); + return; + } + } + + l2cap_frame_init(&frame, index, in, handle, 0, cid, 0, + data + 1, size - 1); + opcode_data->func(&frame); +} diff --git a/monitor/att.h b/monitor/att.h new file mode 100644 index 000000000..07951b200 --- /dev/null +++ b/monitor/att.h @@ -0,0 +1,16 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +/* + * + * BlueZ - Bluetooth protocol stack for Linux + * + * Copyright (C) 2011-2014 Intel Corporation + * Copyright (C) 2002-2010 Marcel Holtmann + * + * + */ + +#include +#include + +void att_packet(uint16_t index, bool in, uint16_t handle, uint16_t cid, + const void *data, uint16_t size); diff --git a/monitor/l2cap.c b/monitor/l2cap.c index 192b6c920..3f5554e5e 100644 --- a/monitor/l2cap.c +++ b/monitor/l2cap.c @@ -33,7 +33,7 @@ #include "avdtp.h" #include "rfcomm.h" #include "bnep.h" - +#include "att.h" #define L2CAP_MODE_BASIC 0x00 #define L2CAP_MODE_RETRANS 0x01 @@ -1538,7 +1538,7 @@ static const struct sig_opcode_data le_sig_opcode_table[] = { { }, }; -static void l2cap_frame_init(struct l2cap_frame *frame, uint16_t index, bool in, +void l2cap_frame_init(struct l2cap_frame *frame, uint16_t index, bool in, uint16_t handle, uint8_t ident, uint16_t cid, uint16_t psm, const void *data, uint16_t size) @@ -2123,618 +2123,6 @@ static void amp_packet(uint16_t index, bool in, uint16_t handle, opcode_data->func(&frame); } -static void print_uuid(const char *label, const void *data, uint16_t size) -{ - const char *str; - char uuidstr[MAX_LEN_UUID_STR]; - - switch (size) { - case 2: - str = bt_uuid16_to_str(get_le16(data)); - print_field("%s: %s (0x%4.4x)", label, str, get_le16(data)); - break; - case 4: - str = bt_uuid32_to_str(get_le32(data)); - print_field("%s: %s (0x%8.8x)", label, str, get_le32(data)); - break; - case 16: - sprintf(uuidstr, "%8.8x-%4.4x-%4.4x-%4.4x-%8.8x%4.4x", - get_le32(data + 12), get_le16(data + 10), - get_le16(data + 8), get_le16(data + 6), - get_le32(data + 2), get_le16(data + 0)); - str = bt_uuidstr_to_str(uuidstr); - print_field("%s: %s (%s)", label, str, uuidstr); - break; - default: - packet_hexdump(data, size); - break; - } -} - -static void print_handle_range(const char *label, const void *data) -{ - print_field("%s: 0x%4.4x-0x%4.4x", label, - get_le16(data), get_le16(data + 2)); -} - -static void print_data_list(const char *label, uint8_t length, - const void *data, uint16_t size) -{ - uint8_t count; - - if (length == 0) - return; - - count = size / length; - - print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies"); - - while (size >= length) { - print_field("Handle: 0x%4.4x", get_le16(data)); - print_hex_field("Value", data + 2, length - 2); - - data += length; - size -= length; - } - - packet_hexdump(data, size); -} - -static void print_attribute_info(uint16_t type, const void *data, uint16_t len) -{ - const char *str = bt_uuid16_to_str(type); - - print_field("%s: %s (0x%4.4x)", "Attribute type", str, type); - - switch (type) { - case 0x2800: /* Primary Service */ - case 0x2801: /* Secondary Service */ - print_uuid(" UUID", data, len); - break; - case 0x2802: /* Include */ - if (len < 4) { - print_hex_field(" Value", data, len); - break; - } - print_handle_range(" Handle range", data); - print_uuid(" UUID", data + 4, len - 4); - break; - case 0x2803: /* Characteristic */ - if (len < 3) { - print_hex_field(" Value", data, len); - break; - } - print_field(" Properties: 0x%2.2x", *((uint8_t *) data)); - print_field(" Handle: 0x%2.2x", get_le16(data + 1)); - print_uuid(" UUID", data + 3, len - 3); - break; - default: - print_hex_field("Value", data, len); - break; - } -} - -static const char *att_opcode_to_str(uint8_t opcode); - -static void att_error_response(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_error_response *pdu = frame->data; - const char *str; - - switch (pdu->error) { - case 0x01: - str = "Invalid Handle"; - break; - case 0x02: - str = "Read Not Permitted"; - break; - case 0x03: - str = "Write Not Permitted"; - break; - case 0x04: - str = "Invalid PDU"; - break; - case 0x05: - str = "Insufficient Authentication"; - break; - case 0x06: - str = "Request Not Supported"; - break; - case 0x07: - str = "Invalid Offset"; - break; - case 0x08: - str = "Insufficient Authorization"; - break; - case 0x09: - str = "Prepare Queue Full"; - break; - case 0x0a: - str = "Attribute Not Found"; - break; - case 0x0b: - str = "Attribute Not Long"; - break; - case 0x0c: - str = "Insufficient Encryption Key Size"; - break; - case 0x0d: - str = "Invalid Attribute Value Length"; - break; - case 0x0e: - str = "Unlikely Error"; - break; - case 0x0f: - str = "Insufficient Encryption"; - break; - case 0x10: - str = "Unsupported Group Type"; - break; - case 0x11: - str = "Insufficient Resources"; - break; - case 0x12: - str = "Database Out of Sync"; - break; - case 0x13: - str = "Value Not Allowed"; - break; - case 0xfd: - str = "CCC Improperly Configured"; - break; - case 0xfe: - str = "Procedure Already in Progress"; - break; - case 0xff: - str = "Out of Range"; - break; - default: - str = "Reserved"; - break; - } - - print_field("%s (0x%2.2x)", att_opcode_to_str(pdu->request), - pdu->request); - print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); - print_field("Error: %s (0x%2.2x)", str, pdu->error); -} - -static void att_exchange_mtu_req(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_exchange_mtu_req *pdu = frame->data; - - print_field("Client RX MTU: %d", le16_to_cpu(pdu->mtu)); -} - -static void att_exchange_mtu_rsp(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_exchange_mtu_rsp *pdu = frame->data; - - print_field("Server RX MTU: %d", le16_to_cpu(pdu->mtu)); -} - -static void att_find_info_req(const struct l2cap_frame *frame) -{ - print_handle_range("Handle range", frame->data); -} - -static const char *att_format_str(uint8_t format) -{ - switch (format) { - case 0x01: - return "UUID-16"; - case 0x02: - return "UUID-128"; - default: - return "unknown"; - } -} - -static uint16_t print_info_data_16(const void *data, uint16_t len) -{ - while (len >= 4) { - print_field("Handle: 0x%4.4x", get_le16(data)); - print_uuid("UUID", data + 2, 2); - data += 4; - len -= 4; - } - - return len; -} - -static uint16_t print_info_data_128(const void *data, uint16_t len) -{ - while (len >= 18) { - print_field("Handle: 0x%4.4x", get_le16(data)); - print_uuid("UUID", data + 2, 16); - data += 18; - len -= 18; - } - - return len; -} - -static void att_find_info_rsp(const struct l2cap_frame *frame) -{ - const uint8_t *format = frame->data; - uint16_t len; - - print_field("Format: %s (0x%2.2x)", att_format_str(*format), *format); - - if (*format == 0x01) - len = print_info_data_16(frame->data + 1, frame->size - 1); - else if (*format == 0x02) - len = print_info_data_128(frame->data + 1, frame->size - 1); - else - len = frame->size - 1; - - packet_hexdump(frame->data + (frame->size - len), len); -} - -static void att_find_by_type_val_req(const struct l2cap_frame *frame) -{ - uint16_t type; - - print_handle_range("Handle range", frame->data); - - type = get_le16(frame->data + 4); - print_attribute_info(type, frame->data + 6, frame->size - 6); -} - -static void att_find_by_type_val_rsp(const struct l2cap_frame *frame) -{ - const uint8_t *ptr = frame->data; - uint16_t len = frame->size; - - while (len >= 4) { - print_handle_range("Handle range", ptr); - ptr += 4; - len -= 4; - } - - packet_hexdump(ptr, len); -} - -static void att_read_type_req(const struct l2cap_frame *frame) -{ - print_handle_range("Handle range", frame->data); - print_uuid("Attribute type", frame->data + 4, frame->size - 4); -} - -static void att_read_type_rsp(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data; - - print_field("Attribute data length: %d", pdu->length); - print_data_list("Attribute data list", pdu->length, - frame->data + 1, frame->size - 1); -} - -static void att_read_req(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_read_req *pdu = frame->data; - - print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); -} - -static void att_read_rsp(const struct l2cap_frame *frame) -{ - print_hex_field("Value", frame->data, frame->size); -} - -static void att_read_blob_req(const struct l2cap_frame *frame) -{ - print_field("Handle: 0x%4.4x", get_le16(frame->data)); - print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); -} - -static void att_read_blob_rsp(const struct l2cap_frame *frame) -{ - packet_hexdump(frame->data, frame->size); -} - -static void att_read_multiple_req(const struct l2cap_frame *frame) -{ - int i, count; - - count = frame->size / 2; - - for (i = 0; i < count; i++) - print_field("Handle: 0x%4.4x", - get_le16(frame->data + (i * 2))); -} - -static void att_read_group_type_req(const struct l2cap_frame *frame) -{ - print_handle_range("Handle range", frame->data); - print_uuid("Attribute group type", frame->data + 4, frame->size - 4); -} - -static void print_group_list(const char *label, uint8_t length, - const void *data, uint16_t size) -{ - uint8_t count; - - if (length == 0) - return; - - count = size / length; - - print_field("%s: %u entr%s", label, count, count == 1 ? "y" : "ies"); - - while (size >= length) { - print_handle_range("Handle range", data); - print_uuid("UUID", data + 4, length - 4); - - data += length; - size -= length; - } - - packet_hexdump(data, size); -} - -static void att_read_group_type_rsp(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_read_group_type_rsp *pdu = frame->data; - - print_field("Attribute data length: %d", pdu->length); - print_group_list("Attribute group list", pdu->length, - frame->data + 1, frame->size - 1); -} - -static void att_write_req(const struct l2cap_frame *frame) -{ - print_field("Handle: 0x%4.4x", get_le16(frame->data)); - print_hex_field(" Data", frame->data + 2, frame->size - 2); -} - -static void att_write_rsp(const struct l2cap_frame *frame) -{ -} - -static void att_prepare_write_req(const struct l2cap_frame *frame) -{ - print_field("Handle: 0x%4.4x", get_le16(frame->data)); - print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); - print_hex_field(" Data", frame->data + 4, frame->size - 4); -} - -static void att_prepare_write_rsp(const struct l2cap_frame *frame) -{ - print_field("Handle: 0x%4.4x", get_le16(frame->data)); - print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); - print_hex_field(" Data", frame->data + 4, frame->size - 4); -} - -static void att_execute_write_req(const struct l2cap_frame *frame) -{ - uint8_t flags = *(uint8_t *) frame->data; - const char *flags_str; - - switch (flags) { - case 0x00: - flags_str = "Cancel all prepared writes"; - break; - case 0x01: - flags_str = "Immediately write all pending values"; - break; - default: - flags_str = "Unknown"; - break; - } - - print_field("Flags: %s (0x%02x)", flags_str, flags); -} - -static void att_handle_value_notify(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_handle_value_notify *pdu = frame->data; - - print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); - print_hex_field(" Data", frame->data + 2, frame->size - 2); -} - -static void att_handle_value_ind(const struct l2cap_frame *frame) -{ - const struct bt_l2cap_att_handle_value_ind *pdu = frame->data; - - print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); - print_hex_field(" Data", frame->data + 2, frame->size - 2); -} - -static void att_handle_value_conf(const struct l2cap_frame *frame) -{ -} - -static void att_multiple_vl_rsp(const struct l2cap_frame *frame) -{ - struct l2cap_frame *f = (void *) frame; - - while (frame->size) { - uint16_t handle; - uint16_t len; - - if (!l2cap_frame_get_le16(f, &handle)) - return; - - print_field("Handle: 0x%4.4x", handle); - - if (!l2cap_frame_get_le16(f, &len)) - return; - - print_field("Length: 0x%4.4x", len); - - print_hex_field(" Data", f->data, - len < f->size ? len : f->size); - - if (len > f->size) { - print_text(COLOR_ERROR, "invalid size"); - return; - } - - l2cap_frame_pull(f, f, len); - } -} - -static void att_write_command(const struct l2cap_frame *frame) -{ - print_field("Handle: 0x%4.4x", get_le16(frame->data)); - print_hex_field(" Data", frame->data + 2, frame->size - 2); -} - -static void att_signed_write_command(const struct l2cap_frame *frame) -{ - print_field("Handle: 0x%4.4x", get_le16(frame->data)); - print_hex_field(" Data", frame->data + 2, frame->size - 2 - 12); - print_hex_field(" Signature", frame->data + frame->size - 12, 12); -} - -struct att_opcode_data { - uint8_t opcode; - const char *str; - void (*func) (const struct l2cap_frame *frame); - uint8_t size; - bool fixed; -}; - -static const struct att_opcode_data att_opcode_table[] = { - { 0x01, "Error Response", - att_error_response, 4, true }, - { 0x02, "Exchange MTU Request", - att_exchange_mtu_req, 2, true }, - { 0x03, "Exchange MTU Response", - att_exchange_mtu_rsp, 2, true }, - { 0x04, "Find Information Request", - att_find_info_req, 4, true }, - { 0x05, "Find Information Response", - att_find_info_rsp, 5, false }, - { 0x06, "Find By Type Value Request", - att_find_by_type_val_req, 6, false }, - { 0x07, "Find By Type Value Response", - att_find_by_type_val_rsp, 4, false }, - { 0x08, "Read By Type Request", - att_read_type_req, 6, false }, - { 0x09, "Read By Type Response", - att_read_type_rsp, 3, false }, - { 0x0a, "Read Request", - att_read_req, 2, true }, - { 0x0b, "Read Response", - att_read_rsp, 0, false }, - { 0x0c, "Read Blob Request", - att_read_blob_req, 4, true }, - { 0x0d, "Read Blob Response", - att_read_blob_rsp, 0, false }, - { 0x0e, "Read Multiple Request", - att_read_multiple_req, 4, false }, - { 0x0f, "Read Multiple Response" }, - { 0x10, "Read By Group Type Request", - att_read_group_type_req, 6, false }, - { 0x11, "Read By Group Type Response", - att_read_group_type_rsp, 4, false }, - { 0x12, "Write Request" , - att_write_req, 2, false }, - { 0x13, "Write Response", - att_write_rsp, 0, true }, - { 0x16, "Prepare Write Request", - att_prepare_write_req, 4, false }, - { 0x17, "Prepare Write Response", - att_prepare_write_rsp, 4, false }, - { 0x18, "Execute Write Request", - att_execute_write_req, 1, true }, - { 0x19, "Execute Write Response" }, - { 0x1b, "Handle Value Notification", - att_handle_value_notify, 2, false }, - { 0x1d, "Handle Value Indication", - att_handle_value_ind, 2, false }, - { 0x1e, "Handle Value Confirmation", - att_handle_value_conf, 0, true }, - { 0x20, "Read Multiple Request Variable Length", - att_read_multiple_req, 4, false }, - { 0x21, "Read Multiple Response Variable Length", - att_multiple_vl_rsp, 4, false }, - { 0x23, "Handle Multiple Value Notification", - att_multiple_vl_rsp, 4, false }, - { 0x52, "Write Command", - att_write_command, 2, false }, - { 0xd2, "Signed Write Command", att_signed_write_command, 14, false }, - { } -}; - -static const char *att_opcode_to_str(uint8_t opcode) -{ - int i; - - for (i = 0; att_opcode_table[i].str; i++) { - if (att_opcode_table[i].opcode == opcode) - return att_opcode_table[i].str; - } - - return "Unknown"; -} - -static void att_packet(uint16_t index, bool in, uint16_t handle, - uint16_t cid, const void *data, uint16_t size) -{ - struct l2cap_frame frame; - uint8_t opcode = *((const uint8_t *) data); - const struct att_opcode_data *opcode_data = NULL; - const char *opcode_color, *opcode_str; - int i; - - if (size < 1) { - print_text(COLOR_ERROR, "malformed attribute packet"); - packet_hexdump(data, size); - return; - } - - for (i = 0; att_opcode_table[i].str; i++) { - if (att_opcode_table[i].opcode == opcode) { - opcode_data = &att_opcode_table[i]; - break; - } - } - - if (opcode_data) { - if (opcode_data->func) { - if (in) - opcode_color = COLOR_MAGENTA; - else - opcode_color = COLOR_BLUE; - } else - opcode_color = COLOR_WHITE_BG; - opcode_str = opcode_data->str; - } else { - opcode_color = COLOR_WHITE_BG; - opcode_str = "Unknown"; - } - - print_indent(6, opcode_color, "ATT: ", opcode_str, COLOR_OFF, - " (0x%2.2x) len %d", opcode, size - 1); - - if (!opcode_data || !opcode_data->func) { - packet_hexdump(data + 1, size - 1); - return; - } - - if (opcode_data->fixed) { - if (size - 1 != opcode_data->size) { - print_text(COLOR_ERROR, "invalid size"); - packet_hexdump(data + 1, size - 1); - return; - } - } else { - if (size - 1 < opcode_data->size) { - print_text(COLOR_ERROR, "too short packet"); - packet_hexdump(data + 1, size - 1); - return; - } - } - - l2cap_frame_init(&frame, index, in, handle, 0, cid, 0, - data + 1, size - 1); - opcode_data->func(&frame); -} - static void print_smp_io_capa(uint8_t io_capa) { const char *str; diff --git a/monitor/l2cap.h b/monitor/l2cap.h index e46042db4..951b411e0 100644 --- a/monitor/l2cap.h +++ b/monitor/l2cap.h @@ -26,6 +26,11 @@ struct l2cap_frame { uint16_t size; }; +void l2cap_frame_init(struct l2cap_frame *frame, uint16_t index, bool in, + uint16_t handle, uint8_t ident, + uint16_t cid, uint16_t psm, + const void *data, uint16_t size); + static inline void l2cap_frame_pull(struct l2cap_frame *frame, const struct l2cap_frame *source, uint16_t len) { From patchwork Fri May 20 04:16:59 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12856290 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 39427C433EF for ; Fri, 20 May 2022 04:17:17 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234784AbiETERP (ORCPT ); Fri, 20 May 2022 00:17:15 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38560 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234146AbiETERM (ORCPT ); Fri, 20 May 2022 00:17:12 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 063766B7F5 for ; Thu, 19 May 2022 21:17:08 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id pq9-20020a17090b3d8900b001df622bf81dso6897262pjb.3 for ; Thu, 19 May 2022 21:17:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=bpudxNkCKlflupd9luclYs5EjHBTCWE7knXxHrs15Cg=; b=flxzUkcXTL6rAJmdZTfrMrGVGcHrDqzZMRkVjGYZY6cwEqDnSNrcDctDesNvt/GAve iQRgQ1cvXyTSYC+slGqWBoM0VaXPXWzv74wxPGnrgCfExSMwHgF5Kp+NJxXGSGRc9cay DaDjOsgr6wC6xk5F23SCHvHrh4hyDtKNlouthIKAYfUa1AfKwwESy+B63IklIPMKZ3jj Hwmns4dsSf98ybKyAHMaIvB9ojEBu1BP1Fph662xUwJMim+mwE2iys5frEf3F0PK3VPv UIpeKXEedfYLvNnpw9Y6WPT3ehV+TpRjbKnUaI/pVXmpAkEepA+SCVJ0ylXiNBK9UxFF URFA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=bpudxNkCKlflupd9luclYs5EjHBTCWE7knXxHrs15Cg=; b=RNU3CAeTUohk4avvn4BoBDTrZkqkG06zqdgVJQebZOEfXqdvbw2mpD1PSr6ovUIIsv tuRCeiUUDqgI/ap+cWh31CrL9qCGALGOEDsA/CeO5bCQXnPoLD1xx64k+Cf2WhkYTmBv MyWN7mOy7F8HGy8VnVc3g2qAzQWnP1vHWxelDjMAvphOAZSCAnfHSSj0Ksb6YEefn4Dv MagQ3UDb1d6BE9mc8hq4S82m4kHdmcPEIiION+twLXhxE8em31MzIl/2o92SOsyLa8+D r2zjKo0ut0linSYtE++vU39DB8bcPY8pMIphllcbtUEC62ycCvQLaHcrCWPsYKimeJzD uv+A== X-Gm-Message-State: AOAM531z7N84x6KmiexxA9gV/zitGltuVNj0SKxT6M8M8/0O+M29OAhY A1RAlrAiPH522VvOXVuAYhNXIAQuvLo= X-Google-Smtp-Source: ABdhPJwOuyBctbU/D4I1p6+oxLaJLrGVXAhFgjBL5Q801UkM84w5PQujcUxIvbxFlDtESoKS7IU3sA== X-Received: by 2002:a17:902:d191:b0:161:5c4f:ce9e with SMTP id m17-20020a170902d19100b001615c4fce9emr8062462plb.159.1653020226727; Thu, 19 May 2022 21:17:06 -0700 (PDT) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id u13-20020a17090a450d00b001df955c28f6sm381405pjg.37.2022.05.19.21.17.05 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 21:17:06 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 5/7] monitor: Cache connection information Date: Thu, 19 May 2022 21:16:59 -0700 Message-Id: <20220520041701.2572197-5-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220520041701.2572197-1-luiz.dentz@gmail.com> References: <20220520041701.2572197-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This caches connection information including the device addres so it can be printed alongside the handle: > HCI Event: Disconnect Complete (0x05) plen 4 Status: Success (0x00) Handle: 3585 Address: 68:79:12:XX:XX:XX (OUI 68-79-12) Reason: Connection Terminated By Local Host (0x16) --- monitor/broadcom.c | 60 ++- monitor/intel.c | 79 +-- monitor/msft.c | 6 +- monitor/packet.c | 1288 ++++++++++++++++++++++++++++---------------- monitor/packet.h | 12 + monitor/vendor.h | 6 +- 6 files changed, 918 insertions(+), 533 deletions(-) diff --git a/monitor/broadcom.c b/monitor/broadcom.c index 21a86461b..72da56da2 100644 --- a/monitor/broadcom.c +++ b/monitor/broadcom.c @@ -220,23 +220,24 @@ static void print_clock_setting(uint8_t clock) print_field("UART clock: %s (0x%2.2x)", str, clock); } -static void null_cmd(const void *data, uint8_t size) +static void null_cmd(uint16_t index, const void *data, uint8_t size) { } -static void status_rsp(const void *data, uint8_t size) +static void status_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); print_status(status); } -static void write_bd_addr_cmd(const void *data, uint8_t size) +static void write_bd_addr_cmd(uint16_t index, const void *data, uint8_t size) { packet_print_addr("Address", data, 0x00); } -static void update_uart_baud_rate_cmd(const void *data, uint8_t size) +static void update_uart_baud_rate_cmd(uint16_t index, const void *data, + uint8_t size) { uint16_t enc_rate = get_le16(data); uint32_t exp_rate = get_le32(data + 2); @@ -249,7 +250,8 @@ static void update_uart_baud_rate_cmd(const void *data, uint8_t size) print_field("Explicit baud rate: %u Mbps", exp_rate); } -static void write_sco_pcm_int_param_cmd(const void *data, uint8_t size) +static void write_sco_pcm_int_param_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t routing = get_u8(data); uint8_t rate = get_u8(data + 1); @@ -264,7 +266,8 @@ static void write_sco_pcm_int_param_cmd(const void *data, uint8_t size) print_clock_mode(clock_mode); } -static void read_sco_pcm_int_param_rsp(const void *data, uint8_t size) +static void read_sco_pcm_int_param_rsp(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); uint8_t routing = get_u8(data + 1); @@ -281,7 +284,8 @@ static void read_sco_pcm_int_param_rsp(const void *data, uint8_t size) print_clock_mode(clock_mode); } -static void set_sleepmode_param_cmd(const void *data, uint8_t size) +static void set_sleepmode_param_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t mode = get_u8(data); @@ -290,7 +294,8 @@ static void set_sleepmode_param_cmd(const void *data, uint8_t size) packet_hexdump(data + 1, size - 1); } -static void read_sleepmode_param_rsp(const void *data, uint8_t size) +static void read_sleepmode_param_rsp(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); uint8_t mode = get_u8(data + 1); @@ -301,7 +306,8 @@ static void read_sleepmode_param_rsp(const void *data, uint8_t size) packet_hexdump(data + 2, size - 2); } -static void enable_radio_cmd(const void *data, uint8_t size) +static void enable_radio_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t mode = get_u8(data); const char *str; @@ -321,7 +327,8 @@ static void enable_radio_cmd(const void *data, uint8_t size) print_field("Mode: %s (0x%2.2x)", str, mode); } -static void enable_usb_hid_emulation_cmd(const void *data, uint8_t size) +static void enable_usb_hid_emulation_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t enable = get_u8(data); const char *str; @@ -341,7 +348,8 @@ static void enable_usb_hid_emulation_cmd(const void *data, uint8_t size) print_field("Enable: %s (0x%2.2x)", str, enable); } -static void read_uart_clock_setting_rsp(const void *data, uint8_t size) +static void read_uart_clock_setting_rsp(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); uint8_t clock = get_u8(data + 1); @@ -350,21 +358,22 @@ static void read_uart_clock_setting_rsp(const void *data, uint8_t size) print_clock_setting(clock); } -static void write_uart_clock_setting_cmd(const void *data, uint8_t size) +static void write_uart_clock_setting_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t clock = get_u8(data); print_clock_setting(clock); } -static void read_raw_rssi_cmd(const void *data, uint8_t size) +static void read_raw_rssi_cmd(uint16_t index, const void *data, uint8_t size) { uint16_t handle = get_le16(data); print_handle(handle); } -static void read_raw_rssi_rsp(const void *data, uint8_t size) +static void read_raw_rssi_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); uint16_t handle = get_le16(data + 1); @@ -375,7 +384,7 @@ static void read_raw_rssi_rsp(const void *data, uint8_t size) print_rssi(rssi); } -static void write_ram_cmd(const void *data, uint8_t size) +static void write_ram_cmd(uint16_t index, const void *data, uint8_t size) { uint32_t addr = get_le32(data); @@ -384,7 +393,7 @@ static void write_ram_cmd(const void *data, uint8_t size) packet_hexdump(data + 4, size - 4); } -static void read_ram_cmd(const void *data, uint8_t size) +static void read_ram_cmd(uint16_t index, const void *data, uint8_t size) { uint32_t addr = get_le32(data); uint8_t length = get_u8(data + 4); @@ -393,7 +402,7 @@ static void read_ram_cmd(const void *data, uint8_t size) print_field("Length: %u", length); } -static void read_ram_rsp(const void *data, uint8_t size) +static void read_ram_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); @@ -402,14 +411,14 @@ static void read_ram_rsp(const void *data, uint8_t size) packet_hexdump(data + 1, size - 1); } -static void launch_ram_cmd(const void *data, uint8_t size) +static void launch_ram_cmd(uint16_t index, const void *data, uint8_t size) { uint32_t addr = get_le32(data); print_field("Address: 0x%8.8x", addr); } -static void read_vid_pid_rsp(const void *data, uint8_t size) +static void read_vid_pid_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); uint16_t vid = get_le16(data + 1); @@ -419,7 +428,8 @@ static void read_vid_pid_rsp(const void *data, uint8_t size) print_field("Product: %4.4x:%4.4x", vid, pid); } -static void write_high_priority_connection_cmd(const void *data, uint8_t size) +static void write_high_priority_connection_cmd(uint16_t index, const void *data, + uint8_t size) { uint16_t handle = get_le16(data); uint8_t priority = get_u8(data + 2); @@ -480,7 +490,8 @@ static void print_features(const uint8_t *features_array) "(0x%16.16" PRIx64 ")", mask); } -static void read_controller_features_rsp(const void *data, uint8_t size) +static void read_controller_features_rsp(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); @@ -488,7 +499,8 @@ static void read_controller_features_rsp(const void *data, uint8_t size) print_features(data + 1); } -static void read_verbose_version_info_rsp(const void *data, uint8_t size) +static void read_verbose_version_info_rsp(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); uint8_t chip_id = get_u8(data + 1); @@ -517,7 +529,7 @@ static void read_verbose_version_info_rsp(const void *data, uint8_t size) print_field("Build number: %u (0x%4.4x)", build_num, build_num); } -static void enable_wbs_cmd(const void *data, uint8_t size) +static void enable_wbs_cmd(uint16_t index, const void *data, uint8_t size) { uint8_t mode = get_u8(data); uint16_t codec = get_le16(data + 1); @@ -694,7 +706,7 @@ void broadcom_lm_diag(const void *data, uint8_t size) } } -static void lm_diag_evt(const void *data, uint8_t size) +static void lm_diag_evt(uint16_t index, const void *data, uint8_t size) { broadcom_lm_diag(data, 63); } diff --git a/monitor/intel.c b/monitor/intel.c index 728bff587..f5e9f5932 100644 --- a/monitor/intel.c +++ b/monitor/intel.c @@ -86,18 +86,18 @@ static void print_module(uint8_t module) print_field("Module: %s (0x%2.2x)", str, module); } -static void null_cmd(const void *data, uint8_t size) +static void null_cmd(uint16_t index, const void *data, uint8_t size) { } -static void status_rsp(const void *data, uint8_t size) +static void status_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); print_status(status); } -static void reset_cmd(const void *data, uint8_t size) +static void reset_cmd(uint16_t index, const void *data, uint8_t size) { uint8_t reset_type = get_u8(data); uint8_t patch_enable = get_u8(data + 1); @@ -326,7 +326,7 @@ static void read_version_tlv_rsp(const void *data, uint8_t size) } } -static void read_version_rsp(const void *data, uint8_t size) +static void read_version_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); uint8_t hw_platform = get_u8(data + 1); @@ -363,7 +363,7 @@ static void read_version_rsp(const void *data, uint8_t size) print_field("Firmware patch: %u", fw_patch); } -static void read_version_cmd(const void *data, uint8_t size) +static void read_version_cmd(uint16_t index, const void *data, uint8_t size) { char *str; uint8_t type; @@ -406,7 +406,8 @@ static void read_version_cmd(const void *data, uint8_t size) } } -static void set_uart_baudrate_cmd(const void *data, uint8_t size) +static void set_uart_baudrate_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t baudrate = get_u8(data); const char *str; @@ -465,7 +466,7 @@ static void set_uart_baudrate_cmd(const void *data, uint8_t size) print_field("Baudrate: %s (0x%2.2x)", str, baudrate); } -static void secure_send_cmd(const void *data, uint8_t size) +static void secure_send_cmd(uint16_t index, const void *data, uint8_t size) { uint8_t type = get_u8(data); const char *str; @@ -493,7 +494,8 @@ static void secure_send_cmd(const void *data, uint8_t size) packet_hexdump(data + 1, size - 1); } -static void manufacturer_mode_cmd(const void *data, uint8_t size) +static void manufacturer_mode_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t mode = get_u8(data); uint8_t reset = get_u8(data + 1); @@ -531,7 +533,7 @@ static void manufacturer_mode_cmd(const void *data, uint8_t size) print_field("Reset behavior: %s (0x%2.2x)", str, reset); } -static void write_bd_data_cmd(const void *data, uint8_t size) +static void write_bd_data_cmd(uint16_t index, const void *data, uint8_t size) { uint8_t features[8]; @@ -548,7 +550,7 @@ static void write_bd_data_cmd(const void *data, uint8_t size) packet_hexdump(data + 21, size - 21); } -static void read_bd_data_rsp(const void *data, uint8_t size) +static void read_bd_data_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); @@ -557,12 +559,12 @@ static void read_bd_data_rsp(const void *data, uint8_t size) packet_hexdump(data + 7, size - 7); } -static void write_bd_address_cmd(const void *data, uint8_t size) +static void write_bd_address_cmd(uint16_t index, const void *data, uint8_t size) { packet_print_addr("Address", data, 0x00); } -static void act_deact_traces_cmd(const void *data, uint8_t size) +static void act_deact_traces_cmd(uint16_t index, const void *data, uint8_t size) { uint8_t tx = get_u8(data); uint8_t tx_arq = get_u8(data + 1); @@ -573,7 +575,8 @@ static void act_deact_traces_cmd(const void *data, uint8_t size) print_field("Receive traces: 0x%2.2x", rx); } -static void stimulate_exception_cmd(const void *data, uint8_t size) +static void stimulate_exception_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t type = get_u8(data); const char *str; @@ -609,7 +612,7 @@ static const struct { { } }; -static void set_event_mask_cmd(const void *data, uint8_t size) +static void set_event_mask_cmd(uint16_t index, const void *data, uint8_t size) { const uint8_t *events_array = data; uint64_t mask, events = 0; @@ -634,7 +637,7 @@ static void set_event_mask_cmd(const void *data, uint8_t size) "(0x%16.16" PRIx64 ")", mask); } -static void ddc_config_write_cmd(const void *data, uint8_t size) +static void ddc_config_write_cmd(uint16_t index, const void *data, uint8_t size) { while (size > 0) { uint8_t param_len = get_u8(data); @@ -648,7 +651,7 @@ static void ddc_config_write_cmd(const void *data, uint8_t size) } } -static void ddc_config_write_rsp(const void *data, uint8_t size) +static void ddc_config_write_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); uint16_t param_id = get_le16(data + 1); @@ -657,7 +660,7 @@ static void ddc_config_write_rsp(const void *data, uint8_t size) print_field("Identifier: 0x%4.4x", param_id); } -static void memory_write_cmd(const void *data, uint8_t size) +static void memory_write_cmd(uint16_t index, const void *data, uint8_t size) { uint32_t addr = get_le32(data); uint8_t mode = get_u8(data + 4); @@ -687,14 +690,16 @@ static void memory_write_cmd(const void *data, uint8_t size) packet_hexdump(data + 6, size - 6); } -static void read_supported_features_cmd(const void *data, uint8_t size) +static void read_supported_features_cmd(uint16_t index, const void *data, + uint8_t size) { uint8_t page = get_u8(data); print_field("Page: 0x%2.2x", page); } -static void read_supported_features_rsp(const void *data, uint8_t size) +static void read_supported_features_rsp(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); uint8_t page = get_u8(data + 1); @@ -788,11 +793,11 @@ const struct vendor_ocf *intel_vendor_ocf(uint16_t ocf) return NULL; } -static void startup_evt(const void *data, uint8_t size) +static void startup_evt(uint16_t index, const void *data, uint8_t size) { } -static void fatal_exception_evt(const void *data, uint8_t size) +static void fatal_exception_evt(uint16_t index, const void *data, uint8_t size) { uint16_t line = get_le16(data); uint8_t module = get_u8(data + 2); @@ -803,7 +808,7 @@ static void fatal_exception_evt(const void *data, uint8_t size) print_field("Reason: 0x%2.2x", reason); } -static void bootup_evt(const void *data, uint8_t size) +static void bootup_evt(uint16_t index, const void *data, uint8_t size) { uint8_t zero = get_u8(data); uint8_t num_packets = get_u8(data + 1); @@ -906,7 +911,7 @@ static void bootup_evt(const void *data, uint8_t size) print_field("DDC status: %s (0x%2.2x)", str, ddc_status); } -static void default_bd_data_evt(const void *data, uint8_t size) +static void default_bd_data_evt(uint16_t index, const void *data, uint8_t size) { uint8_t mem_status = get_u8(data); const char *str; @@ -923,7 +928,8 @@ static void default_bd_data_evt(const void *data, uint8_t size) print_field("Memory status: %s (0x%2.2x)", str, mem_status); } -static void secure_send_commands_result_evt(const void *data, uint8_t size) +static void secure_send_commands_result_evt(uint16_t index, const void *data, + uint8_t size) { uint8_t result = get_u8(data); uint16_t opcode = get_le16(data + 1); @@ -967,7 +973,7 @@ static void secure_send_commands_result_evt(const void *data, uint8_t size) print_status(status); } -static void debug_exception_evt(const void *data, uint8_t size) +static void debug_exception_evt(uint16_t index, const void *data, uint8_t size) { uint16_t line = get_le16(data); uint8_t module = get_u8(data + 2); @@ -978,7 +984,8 @@ static void debug_exception_evt(const void *data, uint8_t size) print_field("Reason: 0x%2.2x", reason); } -static void le_link_established_evt(const void *data, uint8_t size) +static void le_link_established_evt(uint16_t index, const void *data, + uint8_t size) { uint16_t handle = get_le16(data); uint32_t access_addr = get_le32(data + 10); @@ -992,7 +999,7 @@ static void le_link_established_evt(const void *data, uint8_t size) packet_hexdump(data + 14, size - 14); } -static void scan_status_evt(const void *data, uint8_t size) +static void scan_status_evt(uint16_t index, const void *data, uint8_t size) { uint8_t enable = get_u8(data); @@ -1007,14 +1014,15 @@ static void scan_status_evt(const void *data, uint8_t size) } -static void act_deact_traces_complete_evt(const void *data, uint8_t size) +static void act_deact_traces_complete_evt(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); print_status(status); } -static void lmp_pdu_trace_evt(const void *data, uint8_t size) +static void lmp_pdu_trace_evt(uint16_t index, const void *data, uint8_t size) { uint8_t type, len, id; uint16_t handle, count; @@ -1108,14 +1116,16 @@ static void lmp_pdu_trace_evt(const void *data, uint8_t size) } } -static void write_bd_data_complete_evt(const void *data, uint8_t size) +static void write_bd_data_complete_evt(uint16_t index, const void *data, + uint8_t size) { uint8_t status = get_u8(data); print_status(status); } -static void sco_rejected_via_lmp_evt(const void *data, uint8_t size) +static void sco_rejected_via_lmp_evt(uint16_t index, const void *data, + uint8_t size) { uint8_t reason = get_u8(data + 6); @@ -1123,7 +1133,8 @@ static void sco_rejected_via_lmp_evt(const void *data, uint8_t size) packet_print_error("Reason", reason); } -static void ptt_switch_notification_evt(const void *data, uint8_t size) +static void ptt_switch_notification_evt(uint16_t index, const void *data, + uint8_t size) { uint16_t handle = get_le16(data); uint8_t table = get_u8(data + 2); @@ -1146,7 +1157,7 @@ static void ptt_switch_notification_evt(const void *data, uint8_t size) print_field("Packet type table: %s (0x%2.2x)", str, table); } -static void system_exception_evt(const void *data, uint8_t size) +static void system_exception_evt(uint16_t index, const void *data, uint8_t size) { uint8_t type = get_u8(data); const char *str; @@ -1614,7 +1625,7 @@ static const struct intel_tlv *process_ext_subevent(const struct intel_tlv *tlv, return next_tlv; } -static void intel_vendor_ext_evt(const void *data, uint8_t size) +static void intel_vendor_ext_evt(uint16_t index, const void *data, uint8_t size) { /* The data pointer points to a number of tlv.*/ const struct intel_tlv *tlv = data; diff --git a/monitor/msft.c b/monitor/msft.c index 6de03f3f5..38af6722e 100644 --- a/monitor/msft.c +++ b/monitor/msft.c @@ -219,7 +219,7 @@ static const struct { { } }; -static void msft_cmd(const void *data, uint8_t size) +static void msft_cmd(uint16_t index, const void *data, uint8_t size) { uint8_t code = get_u8(data); const char *code_color, *code_str = NULL; @@ -253,7 +253,7 @@ static void msft_cmd(const void *data, uint8_t size) packet_hexdump(data + 1, size - 1); } -static void msft_rsp(const void *data, uint8_t size) +static void msft_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = get_u8(data); uint8_t code = get_u8(data + 1); @@ -299,7 +299,7 @@ const struct vendor_ocf *msft_vendor_ocf(void) return &vendor_ocf_entry; } -static void msft_evt(const void *data, uint8_t size) +static void msft_evt(uint16_t index, const void *data, uint8_t size) { packet_hexdump(data, size); } diff --git a/monitor/packet.c b/monitor/packet.c index 2e02b3923..8608cf2ef 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -169,21 +169,24 @@ static uint16_t get_format(uint32_t cookie) #define MAX_CONN 16 -struct conn_data { - uint16_t handle; - uint8_t type; -}; +static struct packet_conn_data conn_list[MAX_CONN]; -static struct conn_data conn_list[MAX_CONN]; - -static void assign_handle(uint16_t handle, uint8_t type) +static void assign_handle(uint16_t index, uint16_t handle, uint8_t type, + uint8_t *dst, uint8_t dst_type) { int i; for (i = 0; i < MAX_CONN; i++) { if (conn_list[i].handle == 0x0000) { + conn_list[i].index = index; conn_list[i].handle = handle; conn_list[i].type = type; + + if (!dst) + break; + + memcpy(conn_list[i].dst, dst, sizeof(conn_list[i].dst)); + conn_list[i].dst_type = dst_type; break; } } @@ -195,23 +198,36 @@ static void release_handle(uint16_t handle) for (i = 0; i < MAX_CONN; i++) { if (conn_list[i].handle == handle) { - conn_list[i].handle = 0x0000; - conn_list[i].type = 0x00; + if (conn_list[i].destroy) + conn_list[i].destroy(conn_list[i].data); + + memset(&conn_list[i], 0, sizeof(conn_list[i])); break; } } } -static uint8_t get_type(uint16_t handle) +struct packet_conn_data *packet_get_conn_data(uint16_t handle) { int i; for (i = 0; i < MAX_CONN; i++) { if (conn_list[i].handle == handle) - return conn_list[i].type; + return &conn_list[i]; } - return 0xff; + return NULL; +} + +static uint8_t get_type(uint16_t handle) +{ + struct packet_conn_data *conn; + + conn = packet_get_conn_data(handle); + if (!conn) + return 0xff; + + return conn->type; } bool packet_has_filter(unsigned long filter) @@ -739,7 +755,17 @@ static void print_lt_addr(uint8_t lt_addr) static void print_handle_native(uint16_t handle) { - print_field("Handle: %d", handle); + struct packet_conn_data *conn; + char label[25]; + + conn = packet_get_conn_data(handle); + if (!conn) { + print_field("Handle: %d", handle); + return; + } + + sprintf(label, "Handle: %d Address", handle); + print_addr(" Address", conn->dst, conn->dst_type); } static void print_handle(uint16_t handle) @@ -4267,18 +4293,18 @@ void packet_simulator(struct timeval *tv, uint16_t frequency, ll_packet(frequency, data, size, false); } -static void null_cmd(const void *data, uint8_t size) +static void null_cmd(uint16_t index, const void *data, uint8_t size) { } -static void status_rsp(const void *data, uint8_t size) +static void status_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = *((const uint8_t *) data); print_status(status); } -static void status_handle_rsp(const void *data, uint8_t size) +static void status_handle_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = *((const uint8_t *) data); @@ -4286,7 +4312,7 @@ static void status_handle_rsp(const void *data, uint8_t size) print_field("Connection handle: %d", get_u8(data + 1)); } -static void status_bdaddr_rsp(const void *data, uint8_t size) +static void status_bdaddr_rsp(uint16_t index, const void *data, uint8_t size) { uint8_t status = *((const uint8_t *) data); @@ -4294,7 +4320,7 @@ static void status_bdaddr_rsp(const void *data, uint8_t size) print_bdaddr(data + 1); } -static void inquiry_cmd(const void *data, uint8_t size) +static void inquiry_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_inquiry *cmd = data; @@ -4304,7 +4330,7 @@ static void inquiry_cmd(const void *data, uint8_t size) print_num_resp(cmd->num_resp); } -static void periodic_inquiry_cmd(const void *data, uint8_t size) +static void periodic_inquiry_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_periodic_inquiry *cmd = data; @@ -4318,7 +4344,7 @@ static void periodic_inquiry_cmd(const void *data, uint8_t size) print_num_resp(cmd->num_resp); } -static void create_conn_cmd(const void *data, uint8_t size) +static void create_conn_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_create_conn *cmd = data; const char *str; @@ -4344,7 +4370,7 @@ static void create_conn_cmd(const void *data, uint8_t size) print_field("Role switch: %s (0x%2.2x)", str, cmd->role_switch); } -static void disconnect_cmd(const void *data, uint8_t size) +static void disconnect_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_disconnect *cmd = data; @@ -4352,7 +4378,7 @@ static void disconnect_cmd(const void *data, uint8_t size) print_reason(cmd->reason); } -static void add_sco_conn_cmd(const void *data, uint8_t size) +static void add_sco_conn_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_add_sco_conn *cmd = data; @@ -4360,14 +4386,16 @@ static void add_sco_conn_cmd(const void *data, uint8_t size) print_pkt_type_sco(cmd->pkt_type); } -static void create_conn_cancel_cmd(const void *data, uint8_t size) +static void create_conn_cancel_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_create_conn_cancel *cmd = data; print_bdaddr(cmd->bdaddr); } -static void accept_conn_request_cmd(const void *data, uint8_t size) +static void accept_conn_request_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_accept_conn_request *cmd = data; @@ -4375,7 +4403,8 @@ static void accept_conn_request_cmd(const void *data, uint8_t size) print_role(cmd->role); } -static void reject_conn_request_cmd(const void *data, uint8_t size) +static void reject_conn_request_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_reject_conn_request *cmd = data; @@ -4383,7 +4412,8 @@ static void reject_conn_request_cmd(const void *data, uint8_t size) print_reason(cmd->reason); } -static void link_key_request_reply_cmd(const void *data, uint8_t size) +static void link_key_request_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_link_key_request_reply *cmd = data; @@ -4391,14 +4421,16 @@ static void link_key_request_reply_cmd(const void *data, uint8_t size) print_link_key(cmd->link_key); } -static void link_key_request_neg_reply_cmd(const void *data, uint8_t size) +static void link_key_request_neg_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_link_key_request_neg_reply *cmd = data; print_bdaddr(cmd->bdaddr); } -static void pin_code_request_reply_cmd(const void *data, uint8_t size) +static void pin_code_request_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_pin_code_request_reply *cmd = data; @@ -4407,14 +4439,16 @@ static void pin_code_request_reply_cmd(const void *data, uint8_t size) print_pin_code(cmd->pin_code, cmd->pin_len); } -static void pin_code_request_neg_reply_cmd(const void *data, uint8_t size) +static void pin_code_request_neg_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_pin_code_request_neg_reply *cmd = data; print_bdaddr(cmd->bdaddr); } -static void change_conn_pkt_type_cmd(const void *data, uint8_t size) +static void change_conn_pkt_type_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_change_conn_pkt_type *cmd = data; @@ -4422,14 +4456,14 @@ static void change_conn_pkt_type_cmd(const void *data, uint8_t size) print_pkt_type(cmd->pkt_type); } -static void auth_requested_cmd(const void *data, uint8_t size) +static void auth_requested_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_auth_requested *cmd = data; print_handle(cmd->handle); } -static void set_conn_encrypt_cmd(const void *data, uint8_t size) +static void set_conn_encrypt_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_set_conn_encrypt *cmd = data; @@ -4437,21 +4471,24 @@ static void set_conn_encrypt_cmd(const void *data, uint8_t size) print_enable("Encryption", cmd->encr_mode); } -static void change_conn_link_key_cmd(const void *data, uint8_t size) +static void change_conn_link_key_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_change_conn_link_key *cmd = data; print_handle(cmd->handle); } -static void link_key_selection_cmd(const void *data, uint8_t size) +static void link_key_selection_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_link_key_selection *cmd = data; print_key_flag(cmd->key_flag); } -static void remote_name_request_cmd(const void *data, uint8_t size) +static void remote_name_request_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_remote_name_request *cmd = data; @@ -4461,21 +4498,24 @@ static void remote_name_request_cmd(const void *data, uint8_t size) print_clock_offset(cmd->clock_offset); } -static void remote_name_request_cancel_cmd(const void *data, uint8_t size) +static void remote_name_request_cancel_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_remote_name_request_cancel *cmd = data; print_bdaddr(cmd->bdaddr); } -static void read_remote_features_cmd(const void *data, uint8_t size) +static void read_remote_features_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_remote_features *cmd = data; print_handle(cmd->handle); } -static void read_remote_ext_features_cmd(const void *data, uint8_t size) +static void read_remote_ext_features_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_remote_ext_features *cmd = data; @@ -4483,28 +4523,30 @@ static void read_remote_ext_features_cmd(const void *data, uint8_t size) print_field("Page: %d", cmd->page); } -static void read_remote_version_cmd(const void *data, uint8_t size) +static void read_remote_version_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_remote_version *cmd = data; print_handle(cmd->handle); } -static void read_clock_offset_cmd(const void *data, uint8_t size) +static void read_clock_offset_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_clock_offset *cmd = data; print_handle(cmd->handle); } -static void read_lmp_handle_cmd(const void *data, uint8_t size) +static void read_lmp_handle_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_read_lmp_handle *cmd = data; print_handle(cmd->handle); } -static void read_lmp_handle_rsp(const void *data, uint8_t size) +static void read_lmp_handle_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_lmp_handle *rsp = data; @@ -4514,7 +4556,7 @@ static void read_lmp_handle_rsp(const void *data, uint8_t size) print_field("Reserved: %d", le32_to_cpu(rsp->reserved)); } -static void setup_sync_conn_cmd(const void *data, uint8_t size) +static void setup_sync_conn_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_setup_sync_conn *cmd = data; @@ -4527,7 +4569,8 @@ static void setup_sync_conn_cmd(const void *data, uint8_t size) print_pkt_type_sco(cmd->pkt_type); } -static void accept_sync_conn_request_cmd(const void *data, uint8_t size) +static void accept_sync_conn_request_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_accept_sync_conn_request *cmd = data; @@ -4540,7 +4583,8 @@ static void accept_sync_conn_request_cmd(const void *data, uint8_t size) print_pkt_type_sco(cmd->pkt_type); } -static void reject_sync_conn_request_cmd(const void *data, uint8_t size) +static void reject_sync_conn_request_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_reject_sync_conn_request *cmd = data; @@ -4548,7 +4592,8 @@ static void reject_sync_conn_request_cmd(const void *data, uint8_t size) print_reason(cmd->reason); } -static void io_capability_request_reply_cmd(const void *data, uint8_t size) +static void io_capability_request_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_io_capability_request_reply *cmd = data; @@ -4558,21 +4603,24 @@ static void io_capability_request_reply_cmd(const void *data, uint8_t size) print_authentication(cmd->authentication); } -static void user_confirm_request_reply_cmd(const void *data, uint8_t size) +static void user_confirm_request_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_user_confirm_request_reply *cmd = data; print_bdaddr(cmd->bdaddr); } -static void user_confirm_request_neg_reply_cmd(const void *data, uint8_t size) +static void user_confirm_request_neg_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_user_confirm_request_neg_reply *cmd = data; print_bdaddr(cmd->bdaddr); } -static void user_passkey_request_reply_cmd(const void *data, uint8_t size) +static void user_passkey_request_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_user_passkey_request_reply *cmd = data; @@ -4580,14 +4628,16 @@ static void user_passkey_request_reply_cmd(const void *data, uint8_t size) print_passkey(cmd->passkey); } -static void user_passkey_request_neg_reply_cmd(const void *data, uint8_t size) +static void user_passkey_request_neg_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_user_passkey_request_neg_reply *cmd = data; print_bdaddr(cmd->bdaddr); } -static void remote_oob_data_request_reply_cmd(const void *data, uint8_t size) +static void remote_oob_data_request_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_remote_oob_data_request_reply *cmd = data; @@ -4596,14 +4646,16 @@ static void remote_oob_data_request_reply_cmd(const void *data, uint8_t size) print_randomizer_p192(cmd->randomizer); } -static void remote_oob_data_request_neg_reply_cmd(const void *data, uint8_t size) +static void remote_oob_data_request_neg_reply_cmd(uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_cmd_remote_oob_data_request_neg_reply *cmd = data; print_bdaddr(cmd->bdaddr); } -static void io_capability_request_neg_reply_cmd(const void *data, uint8_t size) +static void io_capability_request_neg_reply_cmd(uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_cmd_io_capability_request_neg_reply *cmd = data; @@ -4611,7 +4663,7 @@ static void io_capability_request_neg_reply_cmd(const void *data, uint8_t size) print_reason(cmd->reason); } -static void create_phy_link_cmd(const void *data, uint8_t size) +static void create_phy_link_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_create_phy_link *cmd = data; @@ -4622,7 +4674,7 @@ static void create_phy_link_cmd(const void *data, uint8_t size) packet_hexdump(data + 3, size - 3); } -static void accept_phy_link_cmd(const void *data, uint8_t size) +static void accept_phy_link_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_accept_phy_link *cmd = data; @@ -4633,7 +4685,7 @@ static void accept_phy_link_cmd(const void *data, uint8_t size) packet_hexdump(data + 3, size - 3); } -static void disconn_phy_link_cmd(const void *data, uint8_t size) +static void disconn_phy_link_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_disconn_phy_link *cmd = data; @@ -4641,7 +4693,8 @@ static void disconn_phy_link_cmd(const void *data, uint8_t size) print_reason(cmd->reason); } -static void create_logic_link_cmd(const void *data, uint8_t size) +static void create_logic_link_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_create_logic_link *cmd = data; @@ -4650,7 +4703,8 @@ static void create_logic_link_cmd(const void *data, uint8_t size) print_flow_spec("RX", cmd->rx_flow_spec); } -static void accept_logic_link_cmd(const void *data, uint8_t size) +static void accept_logic_link_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_accept_logic_link *cmd = data; @@ -4659,14 +4713,16 @@ static void accept_logic_link_cmd(const void *data, uint8_t size) print_flow_spec("RX", cmd->rx_flow_spec); } -static void disconn_logic_link_cmd(const void *data, uint8_t size) +static void disconn_logic_link_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_disconn_logic_link *cmd = data; print_handle(cmd->handle); } -static void logic_link_cancel_cmd(const void *data, uint8_t size) +static void logic_link_cancel_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_logic_link_cancel *cmd = data; @@ -4674,7 +4730,8 @@ static void logic_link_cancel_cmd(const void *data, uint8_t size) print_field("TX flow spec: 0x%2.2x", cmd->flow_spec); } -static void logic_link_cancel_rsp(const void *data, uint8_t size) +static void logic_link_cancel_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_logic_link_cancel *rsp = data; @@ -4683,7 +4740,7 @@ static void logic_link_cancel_rsp(const void *data, uint8_t size) print_field("TX flow spec: 0x%2.2x", rsp->flow_spec); } -static void flow_spec_modify_cmd(const void *data, uint8_t size) +static void flow_spec_modify_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_flow_spec_modify *cmd = data; @@ -4692,7 +4749,8 @@ static void flow_spec_modify_cmd(const void *data, uint8_t size) print_flow_spec("RX", cmd->rx_flow_spec); } -static void enhanced_setup_sync_conn_cmd(const void *data, uint8_t size) +static void enhanced_setup_sync_conn_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_enhanced_setup_sync_conn *cmd = data; @@ -4707,7 +4765,9 @@ static void enhanced_setup_sync_conn_cmd(const void *data, uint8_t size) print_retransmission_effort(cmd->retrans_effort); } -static void enhanced_accept_sync_conn_request_cmd(const void *data, uint8_t size) +static void enhanced_accept_sync_conn_request_cmd(uint16_t index, + const void *data, + uint8_t size) { const struct bt_hci_cmd_enhanced_accept_sync_conn_request *cmd = data; @@ -4722,7 +4782,7 @@ static void enhanced_accept_sync_conn_request_cmd(const void *data, uint8_t size print_retransmission_effort(cmd->retrans_effort); } -static void truncated_page_cmd(const void *data, uint8_t size) +static void truncated_page_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_truncated_page *cmd = data; @@ -4731,14 +4791,16 @@ static void truncated_page_cmd(const void *data, uint8_t size) print_clock_offset(cmd->clock_offset); } -static void truncated_page_cancel_cmd(const void *data, uint8_t size) +static void truncated_page_cancel_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_truncated_page_cancel *cmd = data; print_bdaddr(cmd->bdaddr); } -static void set_peripheral_broadcast_cmd(const void *data, uint8_t size) +static void set_peripheral_broadcast_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_set_peripheral_broadcast *cmd = data; @@ -4751,7 +4813,8 @@ static void set_peripheral_broadcast_cmd(const void *data, uint8_t size) print_slot_625("Supervision timeout", cmd->timeout); } -static void set_peripheral_broadcast_rsp(const void *data, uint8_t size) +static void set_peripheral_broadcast_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_set_peripheral_broadcast *rsp = data; @@ -4760,7 +4823,8 @@ static void set_peripheral_broadcast_rsp(const void *data, uint8_t size) print_interval(rsp->interval); } -static void set_peripheral_broadcast_receive_cmd(const void *data, uint8_t size) +static void set_peripheral_broadcast_receive_cmd(uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_cmd_set_peripheral_broadcast_receive *cmd = data; @@ -4778,7 +4842,8 @@ static void set_peripheral_broadcast_receive_cmd(const void *data, uint8_t size) print_channel_map(cmd->map); } -static void set_peripheral_broadcast_receive_rsp(const void *data, uint8_t size) +static void set_peripheral_broadcast_receive_rsp(uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_rsp_set_peripheral_broadcast_receive *rsp = data; @@ -4787,7 +4852,8 @@ static void set_peripheral_broadcast_receive_rsp(const void *data, uint8_t size) print_lt_addr(rsp->lt_addr); } -static void receive_sync_train_cmd(const void *data, uint8_t size) +static void receive_sync_train_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_receive_sync_train *cmd = data; @@ -4797,7 +4863,8 @@ static void receive_sync_train_cmd(const void *data, uint8_t size) print_interval(cmd->interval); } -static void remote_oob_ext_data_request_reply_cmd(const void *data, uint8_t size) +static void remote_oob_ext_data_request_reply_cmd(uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_cmd_remote_oob_ext_data_request_reply *cmd = data; @@ -4808,7 +4875,7 @@ static void remote_oob_ext_data_request_reply_cmd(const void *data, uint8_t size print_randomizer_p256(cmd->randomizer256); } -static void hold_mode_cmd(const void *data, uint8_t size) +static void hold_mode_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_hold_mode *cmd = data; @@ -4817,7 +4884,7 @@ static void hold_mode_cmd(const void *data, uint8_t size) print_slot_625("Hold min interval", cmd->min_interval); } -static void sniff_mode_cmd(const void *data, uint8_t size) +static void sniff_mode_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_sniff_mode *cmd = data; @@ -4828,14 +4895,14 @@ static void sniff_mode_cmd(const void *data, uint8_t size) print_slot_125("Sniff timeout", cmd->timeout); } -static void exit_sniff_mode_cmd(const void *data, uint8_t size) +static void exit_sniff_mode_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_exit_sniff_mode *cmd = data; print_handle(cmd->handle); } -static void park_state_cmd(const void *data, uint8_t size) +static void park_state_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_park_state *cmd = data; @@ -4844,14 +4911,14 @@ static void park_state_cmd(const void *data, uint8_t size) print_slot_625("Beacon min interval", cmd->min_interval); } -static void exit_park_state_cmd(const void *data, uint8_t size) +static void exit_park_state_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_exit_park_state *cmd = data; print_handle(cmd->handle); } -static void qos_setup_cmd(const void *data, uint8_t size) +static void qos_setup_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_qos_setup *cmd = data; @@ -4866,14 +4933,14 @@ static void qos_setup_cmd(const void *data, uint8_t size) print_field("Delay variation: %d", le32_to_cpu(cmd->delay_variation)); } -static void role_discovery_cmd(const void *data, uint8_t size) +static void role_discovery_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_role_discovery *cmd = data; print_handle(cmd->handle); } -static void role_discovery_rsp(const void *data, uint8_t size) +static void role_discovery_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_role_discovery *rsp = data; @@ -4882,7 +4949,7 @@ static void role_discovery_rsp(const void *data, uint8_t size) print_role(rsp->role); } -static void switch_role_cmd(const void *data, uint8_t size) +static void switch_role_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_switch_role *cmd = data; @@ -4890,14 +4957,14 @@ static void switch_role_cmd(const void *data, uint8_t size) print_role(cmd->role); } -static void read_link_policy_cmd(const void *data, uint8_t size) +static void read_link_policy_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_read_link_policy *cmd = data; print_handle(cmd->handle); } -static void read_link_policy_rsp(const void *data, uint8_t size) +static void read_link_policy_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_link_policy *rsp = data; @@ -4906,7 +4973,8 @@ static void read_link_policy_rsp(const void *data, uint8_t size) print_link_policy(rsp->policy); } -static void write_link_policy_cmd(const void *data, uint8_t size) +static void write_link_policy_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_link_policy *cmd = data; @@ -4914,7 +4982,8 @@ static void write_link_policy_cmd(const void *data, uint8_t size) print_link_policy(cmd->policy); } -static void write_link_policy_rsp(const void *data, uint8_t size) +static void write_link_policy_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_write_link_policy *rsp = data; @@ -4922,7 +4991,8 @@ static void write_link_policy_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void read_default_link_policy_rsp(const void *data, uint8_t size) +static void read_default_link_policy_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_default_link_policy *rsp = data; @@ -4930,14 +5000,15 @@ static void read_default_link_policy_rsp(const void *data, uint8_t size) print_link_policy(rsp->policy); } -static void write_default_link_policy_cmd(const void *data, uint8_t size) +static void write_default_link_policy_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_default_link_policy *cmd = data; print_link_policy(cmd->policy); } -static void flow_spec_cmd(const void *data, uint8_t size) +static void flow_spec_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_flow_spec *cmd = data; @@ -4954,7 +5025,7 @@ static void flow_spec_cmd(const void *data, uint8_t size) print_field("Access latency: %d", le32_to_cpu(cmd->access_latency)); } -static void sniff_subrating_cmd(const void *data, uint8_t size) +static void sniff_subrating_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_sniff_subrating *cmd = data; @@ -4964,7 +5035,7 @@ static void sniff_subrating_cmd(const void *data, uint8_t size) print_slot_625("Min local timeout", cmd->min_local_timeout); } -static void sniff_subrating_rsp(const void *data, uint8_t size) +static void sniff_subrating_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_sniff_subrating *rsp = data; @@ -4972,14 +5043,14 @@ static void sniff_subrating_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void set_event_mask_cmd(const void *data, uint8_t size) +static void set_event_mask_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_set_event_mask *cmd = data; print_event_mask(cmd->mask, events_table); } -static void set_event_filter_cmd(const void *data, uint8_t size) +static void set_event_filter_cmd(uint16_t index, const void *data, uint8_t size) { uint8_t type = *((const uint8_t *) data); uint8_t filter; @@ -5077,14 +5148,14 @@ static void set_event_filter_cmd(const void *data, uint8_t size) } } -static void flush_cmd(const void *data, uint8_t size) +static void flush_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_flush *cmd = data; print_handle(cmd->handle); } -static void flush_rsp(const void *data, uint8_t size) +static void flush_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_flush *rsp = data; @@ -5092,7 +5163,7 @@ static void flush_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void read_pin_type_rsp(const void *data, uint8_t size) +static void read_pin_type_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_pin_type *rsp = data; @@ -5100,14 +5171,15 @@ static void read_pin_type_rsp(const void *data, uint8_t size) print_pin_type(rsp->pin_type); } -static void write_pin_type_cmd(const void *data, uint8_t size) +static void write_pin_type_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_write_pin_type *cmd = data; print_pin_type(cmd->pin_type); } -static void read_stored_link_key_cmd(const void *data, uint8_t size) +static void read_stored_link_key_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_stored_link_key *cmd = data; @@ -5115,7 +5187,8 @@ static void read_stored_link_key_cmd(const void *data, uint8_t size) print_field("Read all: 0x%2.2x", cmd->read_all); } -static void read_stored_link_key_rsp(const void *data, uint8_t size) +static void read_stored_link_key_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_stored_link_key *rsp = data; @@ -5124,7 +5197,8 @@ static void read_stored_link_key_rsp(const void *data, uint8_t size) print_field("Num keys: %d", le16_to_cpu(rsp->num_keys)); } -static void write_stored_link_key_cmd(const void *data, uint8_t size) +static void write_stored_link_key_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_stored_link_key *cmd = data; @@ -5133,7 +5207,8 @@ static void write_stored_link_key_cmd(const void *data, uint8_t size) packet_hexdump(data + 1, size - 1); } -static void write_stored_link_key_rsp(const void *data, uint8_t size) +static void write_stored_link_key_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_write_stored_link_key *rsp = data; @@ -5141,7 +5216,8 @@ static void write_stored_link_key_rsp(const void *data, uint8_t size) print_field("Num keys: %d", rsp->num_keys); } -static void delete_stored_link_key_cmd(const void *data, uint8_t size) +static void delete_stored_link_key_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_delete_stored_link_key *cmd = data; @@ -5149,7 +5225,8 @@ static void delete_stored_link_key_cmd(const void *data, uint8_t size) print_field("Delete all: 0x%2.2x", cmd->delete_all); } -static void delete_stored_link_key_rsp(const void *data, uint8_t size) +static void delete_stored_link_key_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_delete_stored_link_key *rsp = data; @@ -5157,14 +5234,14 @@ static void delete_stored_link_key_rsp(const void *data, uint8_t size) print_field("Num keys: %d", le16_to_cpu(rsp->num_keys)); } -static void write_local_name_cmd(const void *data, uint8_t size) +static void write_local_name_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_write_local_name *cmd = data; print_name(cmd->name); } -static void read_local_name_rsp(const void *data, uint8_t size) +static void read_local_name_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_local_name *rsp = data; @@ -5172,7 +5249,8 @@ static void read_local_name_rsp(const void *data, uint8_t size) print_name(rsp->name); } -static void read_conn_accept_timeout_rsp(const void *data, uint8_t size) +static void read_conn_accept_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_conn_accept_timeout *rsp = data; @@ -5180,14 +5258,16 @@ static void read_conn_accept_timeout_rsp(const void *data, uint8_t size) print_timeout(rsp->timeout); } -static void write_conn_accept_timeout_cmd(const void *data, uint8_t size) +static void write_conn_accept_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_conn_accept_timeout *cmd = data; print_timeout(cmd->timeout); } -static void read_page_timeout_rsp(const void *data, uint8_t size) +static void read_page_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_page_timeout *rsp = data; @@ -5195,14 +5275,15 @@ static void read_page_timeout_rsp(const void *data, uint8_t size) print_timeout(rsp->timeout); } -static void write_page_timeout_cmd(const void *data, uint8_t size) +static void write_page_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_page_timeout *cmd = data; print_timeout(cmd->timeout); } -static void read_scan_enable_rsp(const void *data, uint8_t size) +static void read_scan_enable_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_scan_enable *rsp = data; @@ -5210,14 +5291,16 @@ static void read_scan_enable_rsp(const void *data, uint8_t size) print_scan_enable(rsp->enable); } -static void write_scan_enable_cmd(const void *data, uint8_t size) +static void write_scan_enable_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_scan_enable *cmd = data; print_scan_enable(cmd->enable); } -static void read_page_scan_activity_rsp(const void *data, uint8_t size) +static void read_page_scan_activity_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_page_scan_activity *rsp = data; @@ -5226,7 +5309,8 @@ static void read_page_scan_activity_rsp(const void *data, uint8_t size) print_window(rsp->window); } -static void write_page_scan_activity_cmd(const void *data, uint8_t size) +static void write_page_scan_activity_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_page_scan_activity *cmd = data; @@ -5234,7 +5318,8 @@ static void write_page_scan_activity_cmd(const void *data, uint8_t size) print_window(cmd->window); } -static void read_inquiry_scan_activity_rsp(const void *data, uint8_t size) +static void read_inquiry_scan_activity_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_inquiry_scan_activity *rsp = data; @@ -5243,7 +5328,8 @@ static void read_inquiry_scan_activity_rsp(const void *data, uint8_t size) print_window(rsp->window); } -static void write_inquiry_scan_activity_cmd(const void *data, uint8_t size) +static void write_inquiry_scan_activity_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_inquiry_scan_activity *cmd = data; @@ -5251,7 +5337,7 @@ static void write_inquiry_scan_activity_cmd(const void *data, uint8_t size) print_window(cmd->window); } -static void read_auth_enable_rsp(const void *data, uint8_t size) +static void read_auth_enable_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_auth_enable *rsp = data; @@ -5259,14 +5345,16 @@ static void read_auth_enable_rsp(const void *data, uint8_t size) print_auth_enable(rsp->enable); } -static void write_auth_enable_cmd(const void *data, uint8_t size) +static void write_auth_enable_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_auth_enable *cmd = data; print_auth_enable(cmd->enable); } -static void read_encrypt_mode_rsp(const void *data, uint8_t size) +static void read_encrypt_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_encrypt_mode *rsp = data; @@ -5274,14 +5362,16 @@ static void read_encrypt_mode_rsp(const void *data, uint8_t size) print_encrypt_mode(rsp->mode); } -static void write_encrypt_mode_cmd(const void *data, uint8_t size) +static void write_encrypt_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_encrypt_mode *cmd = data; print_encrypt_mode(cmd->mode); } -static void read_class_of_dev_rsp(const void *data, uint8_t size) +static void read_class_of_dev_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_class_of_dev *rsp = data; @@ -5289,14 +5379,16 @@ static void read_class_of_dev_rsp(const void *data, uint8_t size) print_dev_class(rsp->dev_class); } -static void write_class_of_dev_cmd(const void *data, uint8_t size) +static void write_class_of_dev_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_class_of_dev *cmd = data; print_dev_class(cmd->dev_class); } -static void read_voice_setting_rsp(const void *data, uint8_t size) +static void read_voice_setting_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_voice_setting *rsp = data; @@ -5304,21 +5396,24 @@ static void read_voice_setting_rsp(const void *data, uint8_t size) print_voice_setting(rsp->setting); } -static void write_voice_setting_cmd(const void *data, uint8_t size) +static void write_voice_setting_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_voice_setting *cmd = data; print_voice_setting(cmd->setting); } -static void read_auto_flush_timeout_cmd(const void *data, uint8_t size) +static void read_auto_flush_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_auto_flush_timeout *cmd = data; print_handle(cmd->handle); } -static void read_auto_flush_timeout_rsp(const void *data, uint8_t size) +static void read_auto_flush_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_auto_flush_timeout *rsp = data; @@ -5327,7 +5422,8 @@ static void read_auto_flush_timeout_rsp(const void *data, uint8_t size) print_flush_timeout(rsp->timeout); } -static void write_auto_flush_timeout_cmd(const void *data, uint8_t size) +static void write_auto_flush_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_auto_flush_timeout *cmd = data; @@ -5335,7 +5431,8 @@ static void write_auto_flush_timeout_cmd(const void *data, uint8_t size) print_flush_timeout(cmd->timeout); } -static void write_auto_flush_timeout_rsp(const void *data, uint8_t size) +static void write_auto_flush_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_write_auto_flush_timeout *rsp = data; @@ -5343,7 +5440,8 @@ static void write_auto_flush_timeout_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void read_num_broadcast_retrans_rsp(const void *data, uint8_t size) +static void read_num_broadcast_retrans_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_num_broadcast_retrans *rsp = data; @@ -5351,14 +5449,16 @@ static void read_num_broadcast_retrans_rsp(const void *data, uint8_t size) print_num_broadcast_retrans(rsp->num_retrans); } -static void write_num_broadcast_retrans_cmd(const void *data, uint8_t size) +static void write_num_broadcast_retrans_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_num_broadcast_retrans *cmd = data; print_num_broadcast_retrans(cmd->num_retrans); } -static void read_hold_mode_activity_rsp(const void *data, uint8_t size) +static void read_hold_mode_activity_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_hold_mode_activity *rsp = data; @@ -5366,14 +5466,15 @@ static void read_hold_mode_activity_rsp(const void *data, uint8_t size) print_hold_mode_activity(rsp->activity); } -static void write_hold_mode_activity_cmd(const void *data, uint8_t size) +static void write_hold_mode_activity_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_hold_mode_activity *cmd = data; print_hold_mode_activity(cmd->activity); } -static void read_tx_power_cmd(const void *data, uint8_t size) +static void read_tx_power_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_read_tx_power *cmd = data; @@ -5381,7 +5482,7 @@ static void read_tx_power_cmd(const void *data, uint8_t size) print_power_type(cmd->type); } -static void read_tx_power_rsp(const void *data, uint8_t size) +static void read_tx_power_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_tx_power *rsp = data; @@ -5390,7 +5491,8 @@ static void read_tx_power_rsp(const void *data, uint8_t size) print_power_level(rsp->level, NULL); } -static void read_sync_flow_control_rsp(const void *data, uint8_t size) +static void read_sync_flow_control_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_sync_flow_control *rsp = data; @@ -5398,21 +5500,23 @@ static void read_sync_flow_control_rsp(const void *data, uint8_t size) print_enable("Flow control", rsp->enable); } -static void write_sync_flow_control_cmd(const void *data, uint8_t size) +static void write_sync_flow_control_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_sync_flow_control *cmd = data; print_enable("Flow control", cmd->enable); } -static void set_host_flow_control_cmd(const void *data, uint8_t size) +static void set_host_flow_control_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_set_host_flow_control *cmd = data; print_host_flow_control(cmd->enable); } -static void host_buffer_size_cmd(const void *data, uint8_t size) +static void host_buffer_size_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_host_buffer_size *cmd = data; @@ -5424,7 +5528,8 @@ static void host_buffer_size_cmd(const void *data, uint8_t size) le16_to_cpu(cmd->sco_max_pkt)); } -static void host_num_completed_packets_cmd(const void *data, uint8_t size) +static void host_num_completed_packets_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_host_num_completed_packets *cmd = data; @@ -5436,14 +5541,16 @@ static void host_num_completed_packets_cmd(const void *data, uint8_t size) packet_hexdump(data + sizeof(*cmd), size - sizeof(*cmd)); } -static void read_link_supv_timeout_cmd(const void *data, uint8_t size) +static void read_link_supv_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_link_supv_timeout *cmd = data; print_handle(cmd->handle); } -static void read_link_supv_timeout_rsp(const void *data, uint8_t size) +static void read_link_supv_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_link_supv_timeout *rsp = data; @@ -5452,7 +5559,8 @@ static void read_link_supv_timeout_rsp(const void *data, uint8_t size) print_timeout(rsp->timeout); } -static void write_link_supv_timeout_cmd(const void *data, uint8_t size) +static void write_link_supv_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_link_supv_timeout *cmd = data; @@ -5460,7 +5568,8 @@ static void write_link_supv_timeout_cmd(const void *data, uint8_t size) print_timeout(cmd->timeout); } -static void write_link_supv_timeout_rsp(const void *data, uint8_t size) +static void write_link_supv_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_write_link_supv_timeout *rsp = data; @@ -5468,7 +5577,8 @@ static void write_link_supv_timeout_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void read_num_supported_iac_rsp(const void *data, uint8_t size) +static void read_num_supported_iac_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_num_supported_iac *rsp = data; @@ -5476,7 +5586,8 @@ static void read_num_supported_iac_rsp(const void *data, uint8_t size) print_field("Number of IAC: %d", rsp->num_iac); } -static void read_current_iac_lap_rsp(const void *data, uint8_t size) +static void read_current_iac_lap_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_current_iac_lap *rsp = data; uint8_t i; @@ -5488,7 +5599,8 @@ static void read_current_iac_lap_rsp(const void *data, uint8_t size) print_iac(rsp->iac_lap + (i * 3)); } -static void write_current_iac_lap_cmd(const void *data, uint8_t size) +static void write_current_iac_lap_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_current_iac_lap *cmd = data; uint8_t i; @@ -5499,7 +5611,8 @@ static void write_current_iac_lap_cmd(const void *data, uint8_t size) print_iac(cmd->iac_lap + (i * 3)); } -static void read_page_scan_period_mode_rsp(const void *data, uint8_t size) +static void read_page_scan_period_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_page_scan_period_mode *rsp = data; @@ -5507,14 +5620,16 @@ static void read_page_scan_period_mode_rsp(const void *data, uint8_t size) print_pscan_period_mode(rsp->mode); } -static void write_page_scan_period_mode_cmd(const void *data, uint8_t size) +static void write_page_scan_period_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_page_scan_period_mode *cmd = data; print_pscan_period_mode(cmd->mode); } -static void read_page_scan_mode_rsp(const void *data, uint8_t size) +static void read_page_scan_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_page_scan_mode *rsp = data; @@ -5522,21 +5637,24 @@ static void read_page_scan_mode_rsp(const void *data, uint8_t size) print_pscan_mode(rsp->mode); } -static void write_page_scan_mode_cmd(const void *data, uint8_t size) +static void write_page_scan_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_page_scan_mode *cmd = data; print_pscan_mode(cmd->mode); } -static void set_afh_host_classification_cmd(const void *data, uint8_t size) +static void set_afh_host_classification_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_set_afh_host_classification *cmd = data; print_channel_map(cmd->map); } -static void read_inquiry_scan_type_rsp(const void *data, uint8_t size) +static void read_inquiry_scan_type_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_inquiry_scan_type *rsp = data; @@ -5544,14 +5662,16 @@ static void read_inquiry_scan_type_rsp(const void *data, uint8_t size) print_inquiry_scan_type(rsp->type); } -static void write_inquiry_scan_type_cmd(const void *data, uint8_t size) +static void write_inquiry_scan_type_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_inquiry_scan_type *cmd = data; print_inquiry_scan_type(cmd->type); } -static void read_inquiry_mode_rsp(const void *data, uint8_t size) +static void read_inquiry_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_inquiry_mode *rsp = data; @@ -5559,14 +5679,16 @@ static void read_inquiry_mode_rsp(const void *data, uint8_t size) print_inquiry_mode(rsp->mode); } -static void write_inquiry_mode_cmd(const void *data, uint8_t size) +static void write_inquiry_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_inquiry_mode *cmd = data; print_inquiry_mode(cmd->mode); } -static void read_page_scan_type_rsp(const void *data, uint8_t size) +static void read_page_scan_type_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_page_scan_type *rsp = data; @@ -5574,14 +5696,16 @@ static void read_page_scan_type_rsp(const void *data, uint8_t size) print_pscan_type(rsp->type); } -static void write_page_scan_type_cmd(const void *data, uint8_t size) +static void write_page_scan_type_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_page_scan_type *cmd = data; print_pscan_type(cmd->type); } -static void read_afh_assessment_mode_rsp(const void *data, uint8_t size) +static void read_afh_assessment_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_afh_assessment_mode *rsp = data; @@ -5589,14 +5713,16 @@ static void read_afh_assessment_mode_rsp(const void *data, uint8_t size) print_enable("Mode", rsp->mode); } -static void write_afh_assessment_mode_cmd(const void *data, uint8_t size) +static void write_afh_assessment_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_afh_assessment_mode *cmd = data; print_enable("Mode", cmd->mode); } -static void read_ext_inquiry_response_rsp(const void *data, uint8_t size) +static void read_ext_inquiry_response_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_ext_inquiry_response *rsp = data; @@ -5605,7 +5731,8 @@ static void read_ext_inquiry_response_rsp(const void *data, uint8_t size) print_eir(rsp->data, sizeof(rsp->data), false); } -static void write_ext_inquiry_response_cmd(const void *data, uint8_t size) +static void write_ext_inquiry_response_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_ext_inquiry_response *cmd = data; @@ -5613,14 +5740,16 @@ static void write_ext_inquiry_response_cmd(const void *data, uint8_t size) print_eir(cmd->data, sizeof(cmd->data), false); } -static void refresh_encrypt_key_cmd(const void *data, uint8_t size) +static void refresh_encrypt_key_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_refresh_encrypt_key *cmd = data; print_handle(cmd->handle); } -static void read_simple_pairing_mode_rsp(const void *data, uint8_t size) +static void read_simple_pairing_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_simple_pairing_mode *rsp = data; @@ -5628,14 +5757,16 @@ static void read_simple_pairing_mode_rsp(const void *data, uint8_t size) print_enable("Mode", rsp->mode); } -static void write_simple_pairing_mode_cmd(const void *data, uint8_t size) +static void write_simple_pairing_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_simple_pairing_mode *cmd = data; print_enable("Mode", cmd->mode); } -static void read_local_oob_data_rsp(const void *data, uint8_t size) +static void read_local_oob_data_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_oob_data *rsp = data; @@ -5644,7 +5775,8 @@ static void read_local_oob_data_rsp(const void *data, uint8_t size) print_randomizer_p192(rsp->randomizer); } -static void read_inquiry_resp_tx_power_rsp(const void *data, uint8_t size) +static void read_inquiry_resp_tx_power_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_inquiry_resp_tx_power *rsp = data; @@ -5652,14 +5784,16 @@ static void read_inquiry_resp_tx_power_rsp(const void *data, uint8_t size) print_power_level(rsp->level, NULL); } -static void write_inquiry_tx_power_cmd(const void *data, uint8_t size) +static void write_inquiry_tx_power_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_inquiry_tx_power *cmd = data; print_power_level(cmd->level, NULL); } -static void read_erroneous_reporting_rsp(const void *data, uint8_t size) +static void read_erroneous_reporting_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_erroneous_reporting *rsp = data; @@ -5667,14 +5801,15 @@ static void read_erroneous_reporting_rsp(const void *data, uint8_t size) print_enable("Mode", rsp->mode); } -static void write_erroneous_reporting_cmd(const void *data, uint8_t size) +static void write_erroneous_reporting_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_erroneous_reporting *cmd = data; print_enable("Mode", cmd->mode); } -static void enhanced_flush_cmd(const void *data, uint8_t size) +static void enhanced_flush_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_enhanced_flush *cmd = data; const char *str; @@ -5693,7 +5828,8 @@ static void enhanced_flush_cmd(const void *data, uint8_t size) print_field("Type: %s (0x%2.2x)", str, cmd->type); } -static void send_keypress_notify_cmd(const void *data, uint8_t size) +static void send_keypress_notify_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_send_keypress_notify *cmd = data; const char *str; @@ -5724,7 +5860,8 @@ static void send_keypress_notify_cmd(const void *data, uint8_t size) print_field("Type: %s (0x%2.2x)", str, cmd->type); } -static void send_keypress_notify_rsp(const void *data, uint8_t size) +static void send_keypress_notify_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_send_keypress_notify *rsp = data; @@ -5732,14 +5869,16 @@ static void send_keypress_notify_rsp(const void *data, uint8_t size) print_bdaddr(rsp->bdaddr); } -static void set_event_mask_page2_cmd(const void *data, uint8_t size) +static void set_event_mask_page2_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_set_event_mask_page2 *cmd = data; print_event_mask(cmd->mask, events_page2_table); } -static void read_location_data_rsp(const void *data, uint8_t size) +static void read_location_data_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_location_data *rsp = data; @@ -5750,7 +5889,8 @@ static void read_location_data_rsp(const void *data, uint8_t size) print_location_options(rsp->options); } -static void write_location_data_cmd(const void *data, uint8_t size) +static void write_location_data_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_location_data *cmd = data; @@ -5760,7 +5900,8 @@ static void write_location_data_cmd(const void *data, uint8_t size) print_location_options(cmd->options); } -static void read_flow_control_mode_rsp(const void *data, uint8_t size) +static void read_flow_control_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_flow_control_mode *rsp = data; @@ -5768,14 +5909,16 @@ static void read_flow_control_mode_rsp(const void *data, uint8_t size) print_flow_control_mode(rsp->mode); } -static void write_flow_control_mode_cmd(const void *data, uint8_t size) +static void write_flow_control_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_flow_control_mode *cmd = data; print_flow_control_mode(cmd->mode); } -static void read_enhanced_tx_power_cmd(const void *data, uint8_t size) +static void read_enhanced_tx_power_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_enhanced_tx_power *cmd = data; @@ -5783,7 +5926,8 @@ static void read_enhanced_tx_power_cmd(const void *data, uint8_t size) print_power_type(cmd->type); } -static void read_enhanced_tx_power_rsp(const void *data, uint8_t size) +static void read_enhanced_tx_power_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_enhanced_tx_power *rsp = data; @@ -5794,7 +5938,7 @@ static void read_enhanced_tx_power_rsp(const void *data, uint8_t size) print_power_level(rsp->level_8dpsk, "8DPSK"); } -static void short_range_mode_cmd(const void *data, uint8_t size) +static void short_range_mode_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_short_range_mode *cmd = data; @@ -5802,7 +5946,8 @@ static void short_range_mode_cmd(const void *data, uint8_t size) print_enable("Short range mode", cmd->mode); } -static void read_le_host_supported_rsp(const void *data, uint8_t size) +static void read_le_host_supported_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_le_host_supported *rsp = data; @@ -5811,7 +5956,8 @@ static void read_le_host_supported_rsp(const void *data, uint8_t size) print_field("Simultaneous: 0x%2.2x", rsp->simultaneous); } -static void write_le_host_supported_cmd(const void *data, uint8_t size) +static void write_le_host_supported_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_le_host_supported *cmd = data; @@ -5819,14 +5965,16 @@ static void write_le_host_supported_cmd(const void *data, uint8_t size) print_field("Simultaneous: 0x%2.2x", cmd->simultaneous); } -static void set_reserved_lt_addr_cmd(const void *data, uint8_t size) +static void set_reserved_lt_addr_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_set_reserved_lt_addr *cmd = data; print_lt_addr(cmd->lt_addr); } -static void set_reserved_lt_addr_rsp(const void *data, uint8_t size) +static void set_reserved_lt_addr_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_set_reserved_lt_addr *rsp = data; @@ -5834,14 +5982,16 @@ static void set_reserved_lt_addr_rsp(const void *data, uint8_t size) print_lt_addr(rsp->lt_addr); } -static void delete_reserved_lt_addr_cmd(const void *data, uint8_t size) +static void delete_reserved_lt_addr_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_delete_reserved_lt_addr *cmd = data; print_lt_addr(cmd->lt_addr); } -static void delete_reserved_lt_addr_rsp(const void *data, uint8_t size) +static void delete_reserved_lt_addr_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_delete_reserved_lt_addr *rsp = data; @@ -5849,7 +5999,8 @@ static void delete_reserved_lt_addr_rsp(const void *data, uint8_t size) print_lt_addr(rsp->lt_addr); } -static void set_peripheral_broadcast_data_cmd(const void *data, uint8_t size) +static void set_peripheral_broadcast_data_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_set_peripheral_broadcast_data *cmd = data; @@ -5864,7 +6015,8 @@ static void set_peripheral_broadcast_data_cmd(const void *data, uint8_t size) packet_hexdump(data + 3, size - 3); } -static void set_peripheral_broadcast_data_rsp(const void *data, uint8_t size) +static void set_peripheral_broadcast_data_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_set_peripheral_broadcast_data *rsp = data; @@ -5872,7 +6024,8 @@ static void set_peripheral_broadcast_data_rsp(const void *data, uint8_t size) print_lt_addr(rsp->lt_addr); } -static void read_sync_train_params_rsp(const void *data, uint8_t size) +static void read_sync_train_params_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_sync_train_params *rsp = data; @@ -5884,7 +6037,8 @@ static void read_sync_train_params_rsp(const void *data, uint8_t size) print_field("Service data: 0x%2.2x", rsp->service_data); } -static void write_sync_train_params_cmd(const void *data, uint8_t size) +static void write_sync_train_params_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_sync_train_params *cmd = data; @@ -5896,7 +6050,8 @@ static void write_sync_train_params_cmd(const void *data, uint8_t size) print_field("Service data: 0x%2.2x", cmd->service_data); } -static void write_sync_train_params_rsp(const void *data, uint8_t size) +static void write_sync_train_params_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_write_sync_train_params *rsp = data; @@ -5904,7 +6059,8 @@ static void write_sync_train_params_rsp(const void *data, uint8_t size) print_interval(rsp->interval); } -static void read_secure_conn_support_rsp(const void *data, uint8_t size) +static void read_secure_conn_support_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_secure_conn_support *rsp = data; @@ -5912,21 +6068,24 @@ static void read_secure_conn_support_rsp(const void *data, uint8_t size) print_enable("Support", rsp->support); } -static void write_secure_conn_support_cmd(const void *data, uint8_t size) +static void write_secure_conn_support_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_secure_conn_support *cmd = data; print_enable("Support", cmd->support); } -static void read_auth_payload_timeout_cmd(const void *data, uint8_t size) +static void read_auth_payload_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_auth_payload_timeout *cmd = data; print_handle(cmd->handle); } -static void read_auth_payload_timeout_rsp(const void *data, uint8_t size) +static void read_auth_payload_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_auth_payload_timeout *rsp = data; @@ -5935,7 +6094,8 @@ static void read_auth_payload_timeout_rsp(const void *data, uint8_t size) print_auth_payload_timeout(rsp->timeout); } -static void write_auth_payload_timeout_cmd(const void *data, uint8_t size) +static void write_auth_payload_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_auth_payload_timeout *cmd = data; @@ -5943,7 +6103,8 @@ static void write_auth_payload_timeout_cmd(const void *data, uint8_t size) print_auth_payload_timeout(cmd->timeout); } -static void write_auth_payload_timeout_rsp(const void *data, uint8_t size) +static void write_auth_payload_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_write_auth_payload_timeout *rsp = data; @@ -5951,7 +6112,8 @@ static void write_auth_payload_timeout_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void read_local_oob_ext_data_rsp(const void *data, uint8_t size) +static void read_local_oob_ext_data_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_oob_ext_data *rsp = data; @@ -5962,7 +6124,8 @@ static void read_local_oob_ext_data_rsp(const void *data, uint8_t size) print_randomizer_p256(rsp->randomizer256); } -static void read_ext_page_timeout_rsp(const void *data, uint8_t size) +static void read_ext_page_timeout_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_ext_page_timeout *rsp = data; @@ -5970,14 +6133,16 @@ static void read_ext_page_timeout_rsp(const void *data, uint8_t size) print_timeout(rsp->timeout); } -static void write_ext_page_timeout_cmd(const void *data, uint8_t size) +static void write_ext_page_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_ext_page_timeout *cmd = data; print_timeout(cmd->timeout); } -static void read_ext_inquiry_length_rsp(const void *data, uint8_t size) +static void read_ext_inquiry_length_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_ext_inquiry_length *rsp = data; @@ -5985,14 +6150,16 @@ static void read_ext_inquiry_length_rsp(const void *data, uint8_t size) print_interval(rsp->interval); } -static void write_ext_inquiry_length_cmd(const void *data, uint8_t size) +static void write_ext_inquiry_length_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_ext_inquiry_length *cmd = data; print_interval(cmd->interval); } -static void read_local_version_rsp(const void *data, uint8_t size) +static void read_local_version_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_version *rsp = data; uint16_t manufacturer; @@ -6024,7 +6191,8 @@ static void read_local_version_rsp(const void *data, uint8_t size) } } -static void read_local_commands_rsp(const void *data, uint8_t size) +static void read_local_commands_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_commands *rsp = data; @@ -6032,7 +6200,8 @@ static void read_local_commands_rsp(const void *data, uint8_t size) print_commands(rsp->commands); } -static void read_local_features_rsp(const void *data, uint8_t size) +static void read_local_features_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_features *rsp = data; @@ -6040,14 +6209,16 @@ static void read_local_features_rsp(const void *data, uint8_t size) print_features(0, rsp->features, 0x00); } -static void read_local_ext_features_cmd(const void *data, uint8_t size) +static void read_local_ext_features_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_local_ext_features *cmd = data; print_field("Page: %d", cmd->page); } -static void read_local_ext_features_rsp(const void *data, uint8_t size) +static void read_local_ext_features_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_ext_features *rsp = data; @@ -6056,7 +6227,7 @@ static void read_local_ext_features_rsp(const void *data, uint8_t size) print_features(rsp->page, rsp->features, 0x00); } -static void read_buffer_size_rsp(const void *data, uint8_t size) +static void read_buffer_size_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_buffer_size *rsp = data; @@ -6069,7 +6240,8 @@ static void read_buffer_size_rsp(const void *data, uint8_t size) le16_to_cpu(rsp->sco_max_pkt)); } -static void read_country_code_rsp(const void *data, uint8_t size) +static void read_country_code_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_country_code *rsp = data; const char *str; @@ -6091,7 +6263,7 @@ static void read_country_code_rsp(const void *data, uint8_t size) print_field("Country code: %s (0x%2.2x)", str, rsp->code); } -static void read_bd_addr_rsp(const void *data, uint8_t size) +static void read_bd_addr_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_bd_addr *rsp = data; @@ -6102,7 +6274,8 @@ static void read_bd_addr_rsp(const void *data, uint8_t size) memcpy(index_list[index_current].bdaddr, rsp->bdaddr, 6); } -static void read_data_block_size_rsp(const void *data, uint8_t size) +static void read_data_block_size_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_data_block_size *rsp = data; @@ -6112,7 +6285,8 @@ static void read_data_block_size_rsp(const void *data, uint8_t size) print_field("Num blocks: %d", le16_to_cpu(rsp->num_blocks)); } -static void read_local_codecs_rsp(const void *data, uint8_t size) +static void read_local_codecs_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_codecs *rsp = data; uint8_t i, num_vnd_codecs; @@ -6162,7 +6336,8 @@ static void print_list(const void *data, uint8_t size, int num_items, print_hex_field("", data, size); } -static void read_local_codecs_rsp_v2(const void *data, uint8_t size) +static void read_local_codecs_rsp_v2(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_codecs_v2 *rsp = data; uint8_t num_vnd_codecs; @@ -6236,7 +6411,8 @@ static void print_vnd_codec(const char *label, " Unknown transport (0x%2.2x)", mask); } -static void read_local_codec_caps_cmd(const void *data, uint8_t size) +static void read_local_codec_caps_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_local_codec_caps *cmd = data; @@ -6244,7 +6420,8 @@ static void read_local_codec_caps_cmd(const void *data, uint8_t size) print_path_direction("Direction", cmd->dir); } -static void read_local_codec_caps_rsp(const void *data, uint8_t size) +static void read_local_codec_caps_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_codec_caps *rsp = data; uint8_t i; @@ -6272,7 +6449,8 @@ static void read_local_codec_caps_rsp(const void *data, uint8_t size) } } -static void read_local_ctrl_delay_cmd(const void *data, uint8_t size) +static void read_local_ctrl_delay_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_local_ctrl_delay *cmd = data; @@ -6281,7 +6459,7 @@ static void read_local_ctrl_delay_cmd(const void *data, uint8_t size) print_field("Length Codec Configuration: %u", cmd->codec_cfg_len); } -static void config_data_path_cmd(const void *data, uint8_t size) +static void config_data_path_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_config_data_path *cmd = data; @@ -6301,7 +6479,8 @@ static void print_usec_interval(const char *prefix, const uint8_t interval[3]) le32_to_cpu(u24)); } -static void read_local_ctrl_delay_rsp(const void *data, uint8_t size) +static void read_local_ctrl_delay_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_ctrl_delay *rsp = data; @@ -6310,7 +6489,8 @@ static void read_local_ctrl_delay_rsp(const void *data, uint8_t size) print_usec_interval("Maximum Controller delay", rsp->max_delay); } -static void read_local_pairing_options_rsp(const void *data, uint8_t size) +static void read_local_pairing_options_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_pairing_options *rsp = data; @@ -6319,14 +6499,16 @@ static void read_local_pairing_options_rsp(const void *data, uint8_t size) print_field("Max encryption key size: %u octets", rsp->max_key_size); } -static void read_failed_contact_counter_cmd(const void *data, uint8_t size) +static void read_failed_contact_counter_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_failed_contact_counter *cmd = data; print_handle(cmd->handle); } -static void read_failed_contact_counter_rsp(const void *data, uint8_t size) +static void read_failed_contact_counter_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_failed_contact_counter *rsp = data; @@ -6335,14 +6517,16 @@ static void read_failed_contact_counter_rsp(const void *data, uint8_t size) print_field("Counter: %u", le16_to_cpu(rsp->counter)); } -static void reset_failed_contact_counter_cmd(const void *data, uint8_t size) +static void reset_failed_contact_counter_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_reset_failed_contact_counter *cmd = data; print_handle(cmd->handle); } -static void reset_failed_contact_counter_rsp(const void *data, uint8_t size) +static void reset_failed_contact_counter_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_reset_failed_contact_counter *rsp = data; @@ -6350,14 +6534,16 @@ static void reset_failed_contact_counter_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void read_link_quality_cmd(const void *data, uint8_t size) +static void read_link_quality_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_link_quality *cmd = data; print_handle(cmd->handle); } -static void read_link_quality_rsp(const void *data, uint8_t size) +static void read_link_quality_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_link_quality *rsp = data; @@ -6366,14 +6552,14 @@ static void read_link_quality_rsp(const void *data, uint8_t size) print_field("Link quality: 0x%2.2x", rsp->link_quality); } -static void read_rssi_cmd(const void *data, uint8_t size) +static void read_rssi_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_read_rssi *cmd = data; print_handle(cmd->handle); } -static void read_rssi_rsp(const void *data, uint8_t size) +static void read_rssi_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_rssi *rsp = data; @@ -6382,14 +6568,16 @@ static void read_rssi_rsp(const void *data, uint8_t size) print_rssi(rsp->rssi); } -static void read_afh_channel_map_cmd(const void *data, uint8_t size) +static void read_afh_channel_map_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_afh_channel_map *cmd = data; print_handle(cmd->handle); } -static void read_afh_channel_map_rsp(const void *data, uint8_t size) +static void read_afh_channel_map_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_afh_channel_map *rsp = data; @@ -6399,7 +6587,7 @@ static void read_afh_channel_map_rsp(const void *data, uint8_t size) print_channel_map(rsp->map); } -static void read_clock_cmd(const void *data, uint8_t size) +static void read_clock_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_read_clock *cmd = data; @@ -6407,7 +6595,7 @@ static void read_clock_cmd(const void *data, uint8_t size) print_clock_type(cmd->type); } -static void read_clock_rsp(const void *data, uint8_t size) +static void read_clock_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_read_clock *rsp = data; @@ -6417,14 +6605,16 @@ static void read_clock_rsp(const void *data, uint8_t size) print_clock_accuracy(rsp->accuracy); } -static void read_encrypt_key_size_cmd(const void *data, uint8_t size) +static void read_encrypt_key_size_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_encrypt_key_size *cmd = data; print_handle(cmd->handle); } -static void read_encrypt_key_size_rsp(const void *data, uint8_t size) +static void read_encrypt_key_size_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_encrypt_key_size *rsp = data; @@ -6433,7 +6623,8 @@ static void read_encrypt_key_size_rsp(const void *data, uint8_t size) print_key_size(rsp->key_size); } -static void read_local_amp_info_rsp(const void *data, uint8_t size) +static void read_local_amp_info_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_amp_info *rsp = data; const char *str; @@ -6468,7 +6659,8 @@ static void read_local_amp_info_rsp(const void *data, uint8_t size) le32_to_cpu(rsp->be_flush_to)); } -static void read_local_amp_assoc_cmd(const void *data, uint8_t size) +static void read_local_amp_assoc_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_read_local_amp_assoc *cmd = data; @@ -6477,7 +6669,8 @@ static void read_local_amp_assoc_cmd(const void *data, uint8_t size) print_field("Max ASSOC length: %d", le16_to_cpu(cmd->max_assoc_len)); } -static void read_local_amp_assoc_rsp(const void *data, uint8_t size) +static void read_local_amp_assoc_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_local_amp_assoc *rsp = data; @@ -6489,7 +6682,8 @@ static void read_local_amp_assoc_rsp(const void *data, uint8_t size) packet_hexdump(data + 4, size - 4); } -static void write_remote_amp_assoc_cmd(const void *data, uint8_t size) +static void write_remote_amp_assoc_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_remote_amp_assoc *cmd = data; @@ -6501,7 +6695,8 @@ static void write_remote_amp_assoc_cmd(const void *data, uint8_t size) packet_hexdump(data + 5, size - 5); } -static void write_remote_amp_assoc_rsp(const void *data, uint8_t size) +static void write_remote_amp_assoc_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_write_remote_amp_assoc *rsp = data; @@ -6509,7 +6704,8 @@ static void write_remote_amp_assoc_rsp(const void *data, uint8_t size) print_phy_handle(rsp->phy_handle); } -static void get_mws_transport_config_rsp(const void *data, uint8_t size) +static void get_mws_transport_config_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_get_mws_transport_config *rsp = data; uint8_t sum_baud_rates = 0; @@ -6564,7 +6760,8 @@ static void get_mws_transport_config_rsp(const void *data, uint8_t size) size - 2 - rsp->num_transports * 2 - sum_baud_rates * 8); } -static void set_triggered_clock_capture_cmd(const void *data, uint8_t size) +static void set_triggered_clock_capture_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_set_triggered_clock_capture *cmd = data; @@ -6575,7 +6772,8 @@ static void set_triggered_clock_capture_cmd(const void *data, uint8_t size) print_field("Clock captures to filter: %u", cmd->num_filter); } -static void read_loopback_mode_rsp(const void *data, uint8_t size) +static void read_loopback_mode_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_read_loopback_mode *rsp = data; @@ -6583,28 +6781,32 @@ static void read_loopback_mode_rsp(const void *data, uint8_t size) print_loopback_mode(rsp->mode); } -static void write_loopback_mode_cmd(const void *data, uint8_t size) +static void write_loopback_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_loopback_mode *cmd = data; print_loopback_mode(cmd->mode); } -static void write_ssp_debug_mode_cmd(const void *data, uint8_t size) +static void write_ssp_debug_mode_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_write_ssp_debug_mode *cmd = data; print_enable("Debug Mode", cmd->mode); } -static void le_set_event_mask_cmd(const void *data, uint8_t size) +static void le_set_event_mask_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_event_mask *cmd = data; print_event_mask(cmd->mask, events_le_table); } -static void le_read_buffer_size_rsp(const void *data, uint8_t size) +static void le_read_buffer_size_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_buffer_size *rsp = data; @@ -6613,7 +6815,8 @@ static void le_read_buffer_size_rsp(const void *data, uint8_t size) print_field("Num data packets: %d", rsp->le_max_pkt); } -static void le_read_local_features_rsp(const void *data, uint8_t size) +static void le_read_local_features_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_local_features *rsp = data; @@ -6621,14 +6824,16 @@ static void le_read_local_features_rsp(const void *data, uint8_t size) print_features(0, rsp->features, 0x01); } -static void le_set_random_address_cmd(const void *data, uint8_t size) +static void le_set_random_address_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_random_address *cmd = data; print_addr("Address", cmd->addr, 0x01); } -static void le_set_adv_parameters_cmd(const void *data, uint8_t size) +static void le_set_adv_parameters_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_adv_parameters *cmd = data; const char *str; @@ -6666,7 +6871,8 @@ static void le_set_adv_parameters_cmd(const void *data, uint8_t size) print_adv_filter_policy("Filter policy", cmd->filter_policy); } -static void le_read_adv_tx_power_rsp(const void *data, uint8_t size) +static void le_read_adv_tx_power_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_adv_tx_power *rsp = data; @@ -6674,7 +6880,7 @@ static void le_read_adv_tx_power_rsp(const void *data, uint8_t size) print_power_level(rsp->level, NULL); } -static void le_set_adv_data_cmd(const void *data, uint8_t size) +static void le_set_adv_data_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_adv_data *cmd = data; @@ -6682,7 +6888,8 @@ static void le_set_adv_data_cmd(const void *data, uint8_t size) print_eir(cmd->data, cmd->len, true); } -static void le_set_scan_rsp_data_cmd(const void *data, uint8_t size) +static void le_set_scan_rsp_data_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_scan_rsp_data *cmd = data; @@ -6690,7 +6897,8 @@ static void le_set_scan_rsp_data_cmd(const void *data, uint8_t size) print_eir(cmd->data, cmd->len, true); } -static void le_set_adv_enable_cmd(const void *data, uint8_t size) +static void le_set_adv_enable_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_adv_enable *cmd = data; @@ -6741,7 +6949,8 @@ static void print_scan_filter_policy(uint8_t policy) print_field("Filter policy: %s (0x%2.2x)", str, policy); } -static void le_set_scan_parameters_cmd(const void *data, uint8_t size) +static void le_set_scan_parameters_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_scan_parameters *cmd = data; @@ -6752,7 +6961,8 @@ static void le_set_scan_parameters_cmd(const void *data, uint8_t size) print_scan_filter_policy(cmd->filter_policy); } -static void le_set_scan_enable_cmd(const void *data, uint8_t size) +static void le_set_scan_enable_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_scan_enable *cmd = data; @@ -6760,7 +6970,7 @@ static void le_set_scan_enable_cmd(const void *data, uint8_t size) print_enable("Filter duplicates", cmd->filter_dup); } -static void le_create_conn_cmd(const void *data, uint8_t size) +static void le_create_conn_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_create_conn *cmd = data; const char *str; @@ -6796,7 +7006,8 @@ static void le_create_conn_cmd(const void *data, uint8_t size) print_slot_625("Max connection length", cmd->max_length); } -static void le_read_accept_list_size_rsp(const void *data, uint8_t size) +static void le_read_accept_list_size_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_accept_list_size *rsp = data; @@ -6804,7 +7015,8 @@ static void le_read_accept_list_size_rsp(const void *data, uint8_t size) print_field("Size: %u", rsp->size); } -static void le_add_to_accept_list_cmd(const void *data, uint8_t size) +static void le_add_to_accept_list_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_add_to_accept_list *cmd = data; @@ -6812,7 +7024,8 @@ static void le_add_to_accept_list_cmd(const void *data, uint8_t size) print_addr("Address", cmd->addr, cmd->addr_type); } -static void le_remove_from_accept_list_cmd(const void *data, uint8_t size) +static void le_remove_from_accept_list_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_remove_from_accept_list *cmd = data; @@ -6820,7 +7033,7 @@ static void le_remove_from_accept_list_cmd(const void *data, uint8_t size) print_addr("Address", cmd->addr, cmd->addr_type); } -static void le_conn_update_cmd(const void *data, uint8_t size) +static void le_conn_update_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_conn_update *cmd = data; @@ -6835,21 +7048,24 @@ static void le_conn_update_cmd(const void *data, uint8_t size) print_slot_625("Max connection length", cmd->max_length); } -static void le_set_host_classification_cmd(const void *data, uint8_t size) +static void le_set_host_classification_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_host_classification *cmd = data; print_le_channel_map(cmd->map); } -static void le_read_channel_map_cmd(const void *data, uint8_t size) +static void le_read_channel_map_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_read_channel_map *cmd = data; print_handle(cmd->handle); } -static void le_read_channel_map_rsp(const void *data, uint8_t size) +static void le_read_channel_map_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_channel_map *rsp = data; @@ -6858,14 +7074,15 @@ static void le_read_channel_map_rsp(const void *data, uint8_t size) print_le_channel_map(rsp->map); } -static void le_read_remote_features_cmd(const void *data, uint8_t size) +static void le_read_remote_features_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_read_remote_features *cmd = data; print_handle(cmd->handle); } -static void le_encrypt_cmd(const void *data, uint8_t size) +static void le_encrypt_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_encrypt *cmd = data; @@ -6873,7 +7090,7 @@ static void le_encrypt_cmd(const void *data, uint8_t size) print_key("Plaintext data", cmd->plaintext); } -static void le_encrypt_rsp(const void *data, uint8_t size) +static void le_encrypt_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_le_encrypt *rsp = data; @@ -6881,7 +7098,7 @@ static void le_encrypt_rsp(const void *data, uint8_t size) print_key("Encrypted data", rsp->data); } -static void le_rand_rsp(const void *data, uint8_t size) +static void le_rand_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_le_rand *rsp = data; @@ -6889,7 +7106,7 @@ static void le_rand_rsp(const void *data, uint8_t size) print_random_number(rsp->number); } -static void le_start_encrypt_cmd(const void *data, uint8_t size) +static void le_start_encrypt_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_start_encrypt *cmd = data; @@ -6899,7 +7116,7 @@ static void le_start_encrypt_cmd(const void *data, uint8_t size) print_key("Long term key", cmd->ltk); } -static void le_ltk_req_reply_cmd(const void *data, uint8_t size) +static void le_ltk_req_reply_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_ltk_req_reply *cmd = data; @@ -6907,7 +7124,7 @@ static void le_ltk_req_reply_cmd(const void *data, uint8_t size) print_key("Long term key", cmd->ltk); } -static void le_ltk_req_reply_rsp(const void *data, uint8_t size) +static void le_ltk_req_reply_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_le_ltk_req_reply *rsp = data; @@ -6915,14 +7132,16 @@ static void le_ltk_req_reply_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void le_ltk_req_neg_reply_cmd(const void *data, uint8_t size) +static void le_ltk_req_neg_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_ltk_req_neg_reply *cmd = data; print_handle(cmd->handle); } -static void le_ltk_req_neg_reply_rsp(const void *data, uint8_t size) +static void le_ltk_req_neg_reply_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_ltk_req_neg_reply *rsp = data; @@ -6930,7 +7149,8 @@ static void le_ltk_req_neg_reply_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void le_read_supported_states_rsp(const void *data, uint8_t size) +static void le_read_supported_states_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_supported_states *rsp = data; @@ -6938,7 +7158,7 @@ static void le_read_supported_states_rsp(const void *data, uint8_t size) print_le_states(rsp->states); } -static void le_receiver_test_cmd(const void *data, uint8_t size) +static void le_receiver_test_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_receiver_test *cmd = data; @@ -6946,7 +7166,8 @@ static void le_receiver_test_cmd(const void *data, uint8_t size) (cmd->frequency * 2) + 2402, cmd->frequency); } -static void le_transmitter_test_cmd(const void *data, uint8_t size) +static void le_transmitter_test_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_transmitter_test *cmd = data; @@ -6956,7 +7177,7 @@ static void le_transmitter_test_cmd(const void *data, uint8_t size) print_field("Packet payload: 0x%2.2x", cmd->payload); } -static void le_test_end_rsp(const void *data, uint8_t size) +static void le_test_end_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_le_test_end *rsp = data; @@ -6964,7 +7185,8 @@ static void le_test_end_rsp(const void *data, uint8_t size) print_field("Number of packets: %d", le16_to_cpu(rsp->num_packets)); } -static void le_conn_param_req_reply_cmd(const void *data, uint8_t size) +static void le_conn_param_req_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_conn_param_req_reply *cmd = data; @@ -6979,7 +7201,8 @@ static void le_conn_param_req_reply_cmd(const void *data, uint8_t size) print_slot_625("Max connection length", cmd->max_length); } -static void le_conn_param_req_reply_rsp(const void *data, uint8_t size) +static void le_conn_param_req_reply_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_conn_param_req_reply *rsp = data; @@ -6987,7 +7210,8 @@ static void le_conn_param_req_reply_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void le_conn_param_req_neg_reply_cmd(const void *data, uint8_t size) +static void le_conn_param_req_neg_reply_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_conn_param_req_neg_reply *cmd = data; @@ -6995,7 +7219,8 @@ static void le_conn_param_req_neg_reply_cmd(const void *data, uint8_t size) print_reason(cmd->reason); } -static void le_conn_param_req_neg_reply_rsp(const void *data, uint8_t size) +static void le_conn_param_req_neg_reply_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_conn_param_req_neg_reply *rsp = data; @@ -7003,7 +7228,8 @@ static void le_conn_param_req_neg_reply_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void le_set_data_length_cmd(const void *data, uint8_t size) +static void le_set_data_length_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_data_length *cmd = data; @@ -7012,7 +7238,8 @@ static void le_set_data_length_cmd(const void *data, uint8_t size) print_field("TX time: %d", le16_to_cpu(cmd->tx_time)); } -static void le_set_data_length_rsp(const void *data, uint8_t size) +static void le_set_data_length_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_set_data_length *rsp = data; @@ -7020,7 +7247,8 @@ static void le_set_data_length_rsp(const void *data, uint8_t size) print_handle(rsp->handle); } -static void le_read_default_data_length_rsp(const void *data, uint8_t size) +static void le_read_default_data_length_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_default_data_length *rsp = data; @@ -7029,7 +7257,8 @@ static void le_read_default_data_length_rsp(const void *data, uint8_t size) print_field("TX time: %d", le16_to_cpu(rsp->tx_time)); } -static void le_write_default_data_length_cmd(const void *data, uint8_t size) +static void le_write_default_data_length_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_write_default_data_length *cmd = data; @@ -7037,14 +7266,16 @@ static void le_write_default_data_length_cmd(const void *data, uint8_t size) print_field("TX time: %d", le16_to_cpu(cmd->tx_time)); } -static void le_generate_dhkey_cmd(const void *data, uint8_t size) +static void le_generate_dhkey_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_generate_dhkey *cmd = data; print_pk256("Remote P-256 public key", cmd->remote_pk256); } -static void le_add_to_resolv_list_cmd(const void *data, uint8_t size) +static void le_add_to_resolv_list_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_add_to_resolv_list *cmd = data; @@ -7054,7 +7285,8 @@ static void le_add_to_resolv_list_cmd(const void *data, uint8_t size) print_key("Local identity resolving key", cmd->local_irk); } -static void le_remove_from_resolv_list_cmd(const void *data, uint8_t size) +static void le_remove_from_resolv_list_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_remove_from_resolv_list *cmd = data; @@ -7062,7 +7294,8 @@ static void le_remove_from_resolv_list_cmd(const void *data, uint8_t size) print_addr("Address", cmd->addr, cmd->addr_type); } -static void le_read_resolv_list_size_rsp(const void *data, uint8_t size) +static void le_read_resolv_list_size_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_resolv_list_size *rsp = data; @@ -7070,7 +7303,8 @@ static void le_read_resolv_list_size_rsp(const void *data, uint8_t size) print_field("Size: %u", rsp->size); } -static void le_read_peer_resolv_addr_cmd(const void *data, uint8_t size) +static void le_read_peer_resolv_addr_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_read_peer_resolv_addr *cmd = data; @@ -7078,7 +7312,8 @@ static void le_read_peer_resolv_addr_cmd(const void *data, uint8_t size) print_addr("Address", cmd->addr, cmd->addr_type); } -static void le_read_peer_resolv_addr_rsp(const void *data, uint8_t size) +static void le_read_peer_resolv_addr_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_peer_resolv_addr *rsp = data; @@ -7086,7 +7321,8 @@ static void le_read_peer_resolv_addr_rsp(const void *data, uint8_t size) print_addr("Address", rsp->addr, 0x01); } -static void le_read_local_resolv_addr_cmd(const void *data, uint8_t size) +static void le_read_local_resolv_addr_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_read_local_resolv_addr *cmd = data; @@ -7094,7 +7330,8 @@ static void le_read_local_resolv_addr_cmd(const void *data, uint8_t size) print_addr("Address", cmd->addr, cmd->addr_type); } -static void le_read_local_resolv_addr_rsp(const void *data, uint8_t size) +static void le_read_local_resolv_addr_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_local_resolv_addr *rsp = data; @@ -7102,21 +7339,24 @@ static void le_read_local_resolv_addr_rsp(const void *data, uint8_t size) print_addr("Address", rsp->addr, 0x01); } -static void le_set_resolv_enable_cmd(const void *data, uint8_t size) +static void le_set_resolv_enable_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_resolv_enable *cmd = data; print_enable("Address resolution", cmd->enable); } -static void le_set_resolv_timeout_cmd(const void *data, uint8_t size) +static void le_set_resolv_timeout_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_resolv_timeout *cmd = data; print_field("Timeout: %u seconds", le16_to_cpu(cmd->timeout)); } -static void le_read_max_data_length_rsp(const void *data, uint8_t size) +static void le_read_max_data_length_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_max_data_length *rsp = data; @@ -7127,7 +7367,7 @@ static void le_read_max_data_length_rsp(const void *data, uint8_t size) print_field("Max RX time: %d", le16_to_cpu(rsp->max_rx_time)); } -static void le_read_phy_cmd(const void *data, uint8_t size) +static void le_read_phy_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_read_phy *cmd = data; @@ -7156,7 +7396,7 @@ static void print_le_phy(const char *prefix, uint8_t phy) print_field("%s: %s (0x%2.2x)", prefix, str, phy); } -static void le_read_phy_rsp(const void *data, uint8_t size) +static void le_read_phy_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_le_read_phy *rsp = data; @@ -7208,14 +7448,15 @@ static void print_le_phys_preference(uint8_t all_phys, uint8_t tx_phys, " (0x%2.2x)", mask); } -static void le_set_default_phy_cmd(const void *data, uint8_t size) +static void le_set_default_phy_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_default_phy *cmd = data; print_le_phys_preference(cmd->all_phys, cmd->tx_phys, cmd->rx_phys); } -static void le_set_phy_cmd(const void *data, uint8_t size) +static void le_set_phy_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_phy *cmd = data; const char *str; @@ -7237,7 +7478,8 @@ static void le_set_phy_cmd(const void *data, uint8_t size) print_field("PHY options preference: %s (0x%4.4x)", str, cmd->phy_opts); } -static void le_enhanced_receiver_test_cmd(const void *data, uint8_t size) +static void le_enhanced_receiver_test_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_enhanced_receiver_test *cmd = data; const char *str; @@ -7262,7 +7504,8 @@ static void le_enhanced_receiver_test_cmd(const void *data, uint8_t size) cmd->modulation_index); } -static void le_enhanced_transmitter_test_cmd(const void *data, uint8_t size) +static void le_enhanced_transmitter_test_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_enhanced_transmitter_test *cmd = data; const char *str; @@ -7293,7 +7536,8 @@ static void le_enhanced_transmitter_test_cmd(const void *data, uint8_t size) print_field("PHY: %s (0x%2.2x)", str, cmd->phy); } -static void le_set_adv_set_rand_addr(const void *data, uint8_t size) +static void le_set_adv_set_rand_addr(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_adv_set_rand_addr *cmd = data; @@ -7379,7 +7623,8 @@ static void print_ext_slot_625(const char *label, const uint8_t value[3]) value_cpu * 0.625, value_cpu); } -static void le_set_ext_adv_params_cmd(const void *data, uint8_t size) +static void le_set_ext_adv_params_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_ext_adv_params *cmd = data; const char *str; @@ -7418,7 +7663,8 @@ static void le_set_ext_adv_params_cmd(const void *data, uint8_t size) print_enable("Scan request notifications", cmd->notif_enable); } -static void le_set_ext_adv_params_rsp(const void *data, uint8_t size) +static void le_set_ext_adv_params_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_set_ext_adv_params *rsp = data; @@ -7426,7 +7672,8 @@ static void le_set_ext_adv_params_rsp(const void *data, uint8_t size) print_power_level(rsp->tx_power, "selected"); } -static void le_set_ext_adv_data_cmd(const void *data, uint8_t size) +static void le_set_ext_adv_data_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_ext_adv_data *cmd = data; const char *str; @@ -7474,7 +7721,8 @@ static void le_set_ext_adv_data_cmd(const void *data, uint8_t size) packet_print_ad(cmd->data, size - sizeof(*cmd)); } -static void le_set_ext_scan_rsp_data_cmd(const void *data, uint8_t size) +static void le_set_ext_scan_rsp_data_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_ext_scan_rsp_data *cmd = data; const char *str; @@ -7522,7 +7770,8 @@ static void le_set_ext_scan_rsp_data_cmd(const void *data, uint8_t size) packet_print_ad(cmd->data, size - sizeof(*cmd)); } -static void le_set_ext_adv_enable_cmd(const void *data, uint8_t size) +static void le_set_ext_adv_enable_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_ext_adv_enable *cmd = data; const struct bt_hci_cmd_ext_adv_set *adv_set; @@ -7550,7 +7799,8 @@ static void le_set_ext_adv_enable_cmd(const void *data, uint8_t size) } } -static void le_read_max_adv_data_len_rsp(const void *data, uint8_t size) +static void le_read_max_adv_data_len_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_max_adv_data_len *rsp = data; @@ -7558,7 +7808,8 @@ static void le_read_max_adv_data_len_rsp(const void *data, uint8_t size) print_field("Max length: %d", rsp->max_len); } -static void le_read_num_supported_adv_sets_rsp(const void *data, uint8_t size) +static void le_read_num_supported_adv_sets_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_num_supported_adv_sets *rsp = data; @@ -7566,7 +7817,8 @@ static void le_read_num_supported_adv_sets_rsp(const void *data, uint8_t size) print_field("Num supported adv sets: %d", rsp->num_of_sets); } -static void le_remove_adv_set_cmd(const void *data, uint8_t size) +static void le_remove_adv_set_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_remove_adv_set *cmd = data; @@ -7591,7 +7843,7 @@ static void print_pa_properties(uint16_t flags) mask); } -static void le_set_pa_params_cmd(const void *data, uint8_t size) +static void le_set_pa_params_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_pa_params *cmd = data; @@ -7601,7 +7853,7 @@ static void le_set_pa_params_cmd(const void *data, uint8_t size) print_pa_properties(cmd->properties); } -static void le_set_pa_data_cmd(const void *data, uint8_t size) +static void le_set_pa_data_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_pa_data *cmd = data; const char *str; @@ -7631,7 +7883,7 @@ static void le_set_pa_data_cmd(const void *data, uint8_t size) print_eir(cmd->data, cmd->data_len, true); } -static void le_set_pa_enable_cmd(const void *data, uint8_t size) +static void le_set_pa_enable_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_pa_enable *cmd = data; @@ -7674,7 +7926,8 @@ static void print_ext_scan_phys(const void *data, uint8_t flags) " (0x%2.2x)", mask); } -static void le_set_ext_scan_params_cmd(const void *data, uint8_t size) +static void le_set_ext_scan_params_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_ext_scan_params *cmd = data; @@ -7683,7 +7936,8 @@ static void le_set_ext_scan_params_cmd(const void *data, uint8_t size) print_ext_scan_phys(cmd->data, cmd->num_phys); } -static void le_set_ext_scan_enable_cmd(const void *data, uint8_t size) +static void le_set_ext_scan_enable_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_ext_scan_enable *cmd = data; @@ -7746,7 +8000,8 @@ static void print_ext_conn_phys(const void *data, uint8_t flags) " (0x%2.2x)", mask); } -static void le_ext_create_conn_cmd(const void *data, uint8_t size) +static void le_ext_create_conn_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_ext_create_conn *cmd = data; const char *str; @@ -7830,7 +8085,8 @@ static void print_create_sync_options(uint8_t flags) } } -static void le_pa_create_sync_cmd(const void *data, uint8_t size) +static void le_pa_create_sync_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_pa_create_sync *cmd = data; @@ -7845,14 +8101,15 @@ static void le_pa_create_sync_cmd(const void *data, uint8_t size) print_create_sync_cte_type(cmd->sync_cte_type); } -static void le_pa_term_sync_cmd(const void *data, uint8_t size) +static void le_pa_term_sync_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_pa_term_sync *cmd = data; print_field("Sync handle: 0x%4.4x", cmd->sync_handle); } -static void le_add_dev_pa_list_cmd(const void *data, uint8_t size) +static void le_add_dev_pa_list_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_add_dev_pa_list *cmd = data; @@ -7861,7 +8118,8 @@ static void le_add_dev_pa_list_cmd(const void *data, uint8_t size) print_field("SID: 0x%2.2x", cmd->sid); } -static void le_remove_dev_pa_list_cmd(const void *data, uint8_t size) +static void le_remove_dev_pa_list_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_remove_dev_pa_list *cmd = data; @@ -7870,7 +8128,8 @@ static void le_remove_dev_pa_list_cmd(const void *data, uint8_t size) print_field("SID: 0x%2.2x", cmd->sid); } -static void le_read_pa_list_size_rsp(const void *data, uint8_t size) +static void le_read_pa_list_size_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_dev_pa_list_size *rsp = data; @@ -7878,7 +8137,8 @@ static void le_read_pa_list_size_rsp(const void *data, uint8_t size) print_field("List size: 0x%2.2x", rsp->list_size); } -static void le_read_tx_power_rsp(const void *data, uint8_t size) +static void le_read_tx_power_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_tx_power *rsp = data; @@ -7887,7 +8147,8 @@ static void le_read_tx_power_rsp(const void *data, uint8_t size) print_field("Max Tx power: %d dBm", rsp->max_tx_power); } -static void le_read_rf_path_comp_rsp(const void *data, uint8_t size) +static void le_read_rf_path_comp_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_rf_path_comp *rsp = data; @@ -7898,7 +8159,8 @@ static void le_read_rf_path_comp_rsp(const void *data, uint8_t size) rsp->rf_rx_path_comp); } -static void le_write_rf_path_comp_cmd(const void *data, uint8_t size) +static void le_write_rf_path_comp_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_write_rf_path_comp *cmd = data; @@ -7908,7 +8170,7 @@ static void le_write_rf_path_comp_cmd(const void *data, uint8_t size) cmd->rf_rx_path_comp); } -static void le_set_priv_mode_cmd(const void *data, uint8_t size) +static void le_set_priv_mode_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_priv_mode *cmd = data; const char *str; @@ -7932,7 +8194,8 @@ static void le_set_priv_mode_cmd(const void *data, uint8_t size) print_field("Privacy Mode: %s (0x%2.2x)", str, cmd->priv_mode); } -static void le_receiver_test_cmd_v3(const void *data, uint8_t size) +static void le_receiver_test_cmd_v3(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_receiver_test_v3 *cmd = data; uint8_t i; @@ -7993,7 +8256,7 @@ static const char *parse_tx_test_payload(uint8_t payload) } } -static void le_tx_test_cmd_v3(const void *data, uint8_t size) +static void le_tx_test_cmd_v3(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_tx_test_v3 *cmd = data; uint8_t i; @@ -8034,7 +8297,7 @@ static void le_tx_test_cmd_v3(const void *data, uint8_t size) print_field(" Antenna ID: %u", cmd->antenna_ids[i]); } -static void le_pa_rec_enable(const void *data, uint8_t size) +static void le_pa_rec_enable(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_set_pa_enable *cmd = data; @@ -8042,7 +8305,7 @@ static void le_pa_rec_enable(const void *data, uint8_t size) print_enable("Reporting", cmd->enable); } -static void le_pa_sync_trans(const void *data, uint8_t size) +static void le_pa_sync_trans(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_periodic_sync_trans *cmd = data; @@ -8051,7 +8314,7 @@ static void le_pa_sync_trans(const void *data, uint8_t size) print_field("Sync handle: %d", cmd->sync_handle); } -static void le_pa_set_info_trans(const void *data, uint8_t size) +static void le_pa_set_info_trans(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_pa_set_info_trans *cmd = data; @@ -8082,7 +8345,8 @@ static void print_sync_mode(uint8_t mode) print_field("Mode: %s (0x%2.2x)", str, mode); } -static void le_pa_sync_trans_params(const void *data, uint8_t size) +static void le_pa_sync_trans_params(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_pa_sync_trans_params *cmd = data; @@ -8095,8 +8359,8 @@ static void le_pa_sync_trans_params(const void *data, uint8_t size) print_create_sync_cte_type(cmd->cte_type); } -static void le_set_default_pa_sync_trans_params(const void *data, - uint8_t size) +static void le_set_default_pa_sync_trans_params(uint16_t index, + const void *data, uint8_t size) { const struct bt_hci_cmd_default_pa_sync_trans_params *cmd = data; @@ -8168,7 +8432,8 @@ static void print_framing(uint8_t value) } } -static void le_read_buffer_size_v2_rsp(const void *data, uint8_t size) +static void le_read_buffer_size_v2_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_buffer_size_v2 *rsp = data; @@ -8183,14 +8448,16 @@ static void le_read_buffer_size_v2_rsp(const void *data, uint8_t size) print_field("ISO max packet: %d", rsp->iso_max_pkt); } -static void le_read_iso_tx_sync_cmd(const void *data, uint8_t size) +static void le_read_iso_tx_sync_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_read_iso_tx_sync *cmd = data; print_field("Handle: %d", le16_to_cpu(cmd->handle)); } -static void le_read_iso_tx_sync_rsp(const void *data, uint8_t size) +static void le_read_iso_tx_sync_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_read_iso_tx_sync *rsp = data; uint32_t offset = 0; @@ -8226,7 +8493,8 @@ static void print_cis_params(const void *data, int i) cis->p_rtn); } -static void le_set_cig_params_cmd(const void *data, uint8_t size) +static void le_set_cig_params_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_cig_params *cmd = data; @@ -8270,7 +8538,8 @@ static void print_cis_params_test(const void *data, int i) print_field("Peripheral to Central Burst Number: 0x%2.2x", cis->p_bn); } -static void le_set_cig_params_test_cmd(const void *data, uint8_t size) +static void le_set_cig_params_test_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_cig_params_test *cmd = data; @@ -8302,7 +8571,8 @@ static void print_cig_handle(const void *data, int i) print_field("Connection Handle #%d: %d", i, handle); } -static void le_set_cig_params_rsp(const void *data, uint8_t size) +static void le_set_cig_params_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_set_cig_params *rsp = data; @@ -8328,7 +8598,7 @@ static void print_cis(const void *data, int i) print_field("ACL Handle: %d", cis->acl_handle); } -static void le_create_cis_cmd(const void *data, uint8_t size) +static void le_create_cis_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_create_cis *cmd = data; @@ -8339,14 +8609,14 @@ static void le_create_cis_cmd(const void *data, uint8_t size) print_list(cmd->cis, size, cmd->num_cis, sizeof(*cmd->cis), print_cis); } -static void le_remove_cig_cmd(const void *data, uint8_t size) +static void le_remove_cig_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_remove_cig *cmd = data; print_field("CIG ID: 0x%02x", cmd->cig_id); } -static void le_remove_cig_rsp(const void *data, uint8_t size) +static void le_remove_cig_rsp(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_rsp_le_remove_cig *rsp = data; @@ -8358,14 +8628,16 @@ static void le_remove_cig_rsp(const void *data, uint8_t size) print_field("CIG ID: 0x%2.2x", rsp->cig_id); } -static void le_accept_cis_req_cmd(const void *data, uint8_t size) +static void le_accept_cis_req_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_accept_cis *cmd = data; print_field("CIS Handle: %d", le16_to_cpu(cmd->handle)); } -static void le_reject_cis_req_cmd(const void *data, uint8_t size) +static void le_reject_cis_req_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_reject_cis *cmd = data; @@ -8387,7 +8659,7 @@ static void print_bis(const struct bt_hci_bis *bis) print_hex_field("Broadcast Code", bis->bcode, 16); } -static void le_create_big_cmd(const void *data, uint8_t size) +static void le_create_big_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_create_big *cmd = data; @@ -8418,7 +8690,8 @@ static void print_bis_test(const void *data, int i) print_hex_field("Broadcast Code", bis->bcode, 16); } -static void le_create_big_cmd_test_cmd(const void *data, uint8_t size) +static void le_create_big_cmd_test_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_create_big_test *cmd = data; @@ -8432,7 +8705,7 @@ static void le_create_big_cmd_test_cmd(const void *data, uint8_t size) print_bis_test); } -static void le_terminate_big_cmd(const void *data, uint8_t size) +static void le_terminate_big_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_term_big *cmd = data; @@ -8447,7 +8720,8 @@ static void print_bis_sync(const void *data, int i) print_field("BIS ID: 0x%2.2x", *bis_id); } -static void le_big_create_sync_cmd(const void *data, uint8_t size) +static void le_big_create_sync_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_big_create_sync *cmd = data; @@ -8468,7 +8742,7 @@ static void le_big_create_sync_cmd(const void *data, uint8_t size) print_bis_sync); } -static void le_big_term_sync_cmd(const void *data, uint8_t size) +static void le_big_term_sync_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_big_term_sync *cmd = data; @@ -8489,7 +8763,8 @@ static void print_iso_path(const char *prefix, uint8_t path) } } -static void le_setup_iso_path_cmd(const void *data, uint8_t size) +static void le_setup_iso_path_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_setup_iso_path *cmd = data; @@ -8505,7 +8780,8 @@ static void le_setup_iso_path_cmd(const void *data, uint8_t size) cmd->codec_cfg_len); } -static void le_setup_iso_path_rsp(const void *data, uint8_t size) +static void le_setup_iso_path_rsp(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_rsp_le_setup_iso_path *rsp = data; @@ -8517,7 +8793,8 @@ static void le_setup_iso_path_rsp(const void *data, uint8_t size) print_field("Handle: %d", le16_to_cpu(rsp->handle)); } -static void le_remove_iso_path_cmd(const void *data, uint8_t size) +static void le_remove_iso_path_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_remove_iso_path *cmd = data; @@ -8525,14 +8802,15 @@ static void le_remove_iso_path_cmd(const void *data, uint8_t size) print_path_direction("Data Path Direction", cmd->direction); } -static void le_req_peer_sca_cmd(const void *data, uint8_t size) +static void le_req_peer_sca_cmd(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_cmd_le_req_peer_sca *cmd = data; print_field("Connection Handle: %d", le16_to_cpu(cmd->handle)); } -static void le_set_host_feature_cmd(const void *data, uint8_t size) +static void le_set_host_feature_cmd(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_cmd_le_set_host_feature *cmd = data; uint64_t mask; @@ -8552,10 +8830,10 @@ struct opcode_data { uint16_t opcode; int bit; const char *str; - void (*cmd_func) (const void *data, uint8_t size); + void (*cmd_func) (uint16_t index, const void *data, uint8_t size); uint8_t cmd_size; bool cmd_fixed; - void (*rsp_func) (const void *data, uint8_t size); + void (*rsp_func) (uint16_t index, const void *data, uint8_t size); uint8_t rsp_size; bool rsp_fixed; }; @@ -9593,14 +9871,14 @@ static const struct vendor_evt *current_vendor_evt(const void *data, return NULL; } -static void inquiry_complete_evt(const void *data, uint8_t size) +static void inquiry_complete_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_inquiry_complete *evt = data; print_status(evt->status); } -static void inquiry_result_evt(const void *data, uint8_t size) +static void inquiry_result_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_inquiry_result *evt = data; @@ -9616,7 +9894,7 @@ static void inquiry_result_evt(const void *data, uint8_t size) packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void conn_complete_evt(const void *data, uint8_t size) +static void conn_complete_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_conn_complete *evt = data; @@ -9627,10 +9905,11 @@ static void conn_complete_evt(const void *data, uint8_t size) print_enable("Encryption", evt->encr_mode); if (evt->status == 0x00) - assign_handle(le16_to_cpu(evt->handle), 0x00); + assign_handle(index, le16_to_cpu(evt->handle), 0x00, + (void *)evt->bdaddr, BDADDR_BREDR); } -static void conn_request_evt(const void *data, uint8_t size) +static void conn_request_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_conn_request *evt = data; @@ -9639,7 +9918,8 @@ static void conn_request_evt(const void *data, uint8_t size) print_link_type(evt->link_type); } -static void disconnect_complete_evt(const void *data, uint8_t size) +static void disconnect_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_disconnect_complete *evt = data; @@ -9651,7 +9931,7 @@ static void disconnect_complete_evt(const void *data, uint8_t size) release_handle(le16_to_cpu(evt->handle)); } -static void auth_complete_evt(const void *data, uint8_t size) +static void auth_complete_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_auth_complete *evt = data; @@ -9659,7 +9939,8 @@ static void auth_complete_evt(const void *data, uint8_t size) print_handle(evt->handle); } -static void remote_name_request_complete_evt(const void *data, uint8_t size) +static void remote_name_request_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_remote_name_request_complete *evt = data; @@ -9668,7 +9949,7 @@ static void remote_name_request_complete_evt(const void *data, uint8_t size) print_name(evt->name); } -static void encrypt_change_evt(const void *data, uint8_t size) +static void encrypt_change_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_encrypt_change *evt = data; @@ -9677,7 +9958,8 @@ static void encrypt_change_evt(const void *data, uint8_t size) print_encr_mode_change(evt->encr_mode, evt->handle); } -static void change_conn_link_key_complete_evt(const void *data, uint8_t size) +static void change_conn_link_key_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_change_conn_link_key_complete *evt = data; @@ -9685,7 +9967,8 @@ static void change_conn_link_key_complete_evt(const void *data, uint8_t size) print_handle(evt->handle); } -static void link_key_type_changed_evt(const void *data, uint8_t size) +static void link_key_type_changed_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_link_key_type_changed *evt = data; @@ -9694,7 +9977,8 @@ static void link_key_type_changed_evt(const void *data, uint8_t size) print_key_flag(evt->key_flag); } -static void remote_features_complete_evt(const void *data, uint8_t size) +static void remote_features_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_remote_features_complete *evt = data; @@ -9703,7 +9987,8 @@ static void remote_features_complete_evt(const void *data, uint8_t size) print_features(0, evt->features, 0x00); } -static void remote_version_complete_evt(const void *data, uint8_t size) +static void remote_version_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_remote_version_complete *evt = data; @@ -9719,7 +10004,8 @@ static void remote_version_complete_evt(const void *data, uint8_t size) } } -static void qos_setup_complete_evt(const void *data, uint8_t size) +static void qos_setup_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_qos_setup_complete *evt = data; @@ -9735,7 +10021,7 @@ static void qos_setup_complete_evt(const void *data, uint8_t size) print_field("Delay variation: %d", le32_to_cpu(evt->delay_variation)); } -static void cmd_complete_evt(const void *data, uint8_t size) +static void cmd_complete_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_cmd_complete *evt = data; uint16_t opcode = le16_to_cpu(evt->opcode); @@ -9828,10 +10114,10 @@ static void cmd_complete_evt(const void *data, uint8_t size) } } - opcode_data->rsp_func(data + 3, size - 3); + opcode_data->rsp_func(index, data + 3, size - 3); } -static void cmd_status_evt(const void *data, uint8_t size) +static void cmd_status_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_cmd_status *evt = data; uint16_t opcode = le16_to_cpu(evt->opcode); @@ -9883,21 +10169,21 @@ static void cmd_status_evt(const void *data, uint8_t size) print_status(evt->status); } -static void hardware_error_evt(const void *data, uint8_t size) +static void hardware_error_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_hardware_error *evt = data; print_field("Code: 0x%2.2x", evt->code); } -static void flush_occurred_evt(const void *data, uint8_t size) +static void flush_occurred_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_flush_occurred *evt = data; print_handle(evt->handle); } -static void role_change_evt(const void *data, uint8_t size) +static void role_change_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_role_change *evt = data; @@ -9906,7 +10192,8 @@ static void role_change_evt(const void *data, uint8_t size) print_role(evt->role); } -static void num_completed_packets_evt(const void *data, uint8_t size) +static void num_completed_packets_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_num_completed_packets *evt = data; @@ -9918,7 +10205,7 @@ static void num_completed_packets_evt(const void *data, uint8_t size) packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void mode_change_evt(const void *data, uint8_t size) +static void mode_change_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_mode_change *evt = data; @@ -9928,7 +10215,7 @@ static void mode_change_evt(const void *data, uint8_t size) print_interval(evt->interval); } -static void return_link_keys_evt(const void *data, uint8_t size) +static void return_link_keys_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_return_link_keys *evt = data; uint8_t i; @@ -9941,21 +10228,21 @@ static void return_link_keys_evt(const void *data, uint8_t size) } } -static void pin_code_request_evt(const void *data, uint8_t size) +static void pin_code_request_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_pin_code_request *evt = data; print_bdaddr(evt->bdaddr); } -static void link_key_request_evt(const void *data, uint8_t size) +static void link_key_request_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_link_key_request *evt = data; print_bdaddr(evt->bdaddr); } -static void link_key_notify_evt(const void *data, uint8_t size) +static void link_key_notify_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_link_key_notify *evt = data; @@ -9964,19 +10251,20 @@ static void link_key_notify_evt(const void *data, uint8_t size) print_key_type(evt->key_type); } -static void loopback_command_evt(const void *data, uint8_t size) +static void loopback_command_evt(uint16_t index, const void *data, uint8_t size) { packet_hexdump(data, size); } -static void data_buffer_overflow_evt(const void *data, uint8_t size) +static void data_buffer_overflow_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_data_buffer_overflow *evt = data; print_link_type(evt->link_type); } -static void max_slots_change_evt(const void *data, uint8_t size) +static void max_slots_change_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_max_slots_change *evt = data; @@ -9984,7 +10272,8 @@ static void max_slots_change_evt(const void *data, uint8_t size) print_field("Max slots: %d", evt->max_slots); } -static void clock_offset_complete_evt(const void *data, uint8_t size) +static void clock_offset_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_clock_offset_complete *evt = data; @@ -9993,7 +10282,8 @@ static void clock_offset_complete_evt(const void *data, uint8_t size) print_clock_offset(evt->clock_offset); } -static void conn_pkt_type_changed_evt(const void *data, uint8_t size) +static void conn_pkt_type_changed_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_conn_pkt_type_changed *evt = data; @@ -10002,14 +10292,15 @@ static void conn_pkt_type_changed_evt(const void *data, uint8_t size) print_pkt_type(evt->pkt_type); } -static void qos_violation_evt(const void *data, uint8_t size) +static void qos_violation_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_qos_violation *evt = data; print_handle(evt->handle); } -static void pscan_mode_change_evt(const void *data, uint8_t size) +static void pscan_mode_change_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_pscan_mode_change *evt = data; @@ -10017,7 +10308,8 @@ static void pscan_mode_change_evt(const void *data, uint8_t size) print_pscan_mode(evt->pscan_mode); } -static void pscan_rep_mode_change_evt(const void *data, uint8_t size) +static void pscan_rep_mode_change_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_pscan_rep_mode_change *evt = data; @@ -10025,7 +10317,8 @@ static void pscan_rep_mode_change_evt(const void *data, uint8_t size) print_pscan_rep_mode(evt->pscan_rep_mode); } -static void flow_spec_complete_evt(const void *data, uint8_t size) +static void flow_spec_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_flow_spec_complete *evt = data; @@ -10043,7 +10336,8 @@ static void flow_spec_complete_evt(const void *data, uint8_t size) print_field("Access latency: %d", le32_to_cpu(evt->access_latency)); } -static void inquiry_result_with_rssi_evt(const void *data, uint8_t size) +static void inquiry_result_with_rssi_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_inquiry_result_with_rssi *evt = data; @@ -10059,7 +10353,8 @@ static void inquiry_result_with_rssi_evt(const void *data, uint8_t size) packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void remote_ext_features_complete_evt(const void *data, uint8_t size) +static void remote_ext_features_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_remote_ext_features_complete *evt = data; @@ -10069,7 +10364,8 @@ static void remote_ext_features_complete_evt(const void *data, uint8_t size) print_features(evt->page, evt->features, 0x00); } -static void sync_conn_complete_evt(const void *data, uint8_t size) +static void sync_conn_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_sync_conn_complete *evt = data; @@ -10084,7 +10380,8 @@ static void sync_conn_complete_evt(const void *data, uint8_t size) print_air_mode(evt->air_mode); } -static void sync_conn_changed_evt(const void *data, uint8_t size) +static void sync_conn_changed_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_sync_conn_changed *evt = data; @@ -10096,7 +10393,7 @@ static void sync_conn_changed_evt(const void *data, uint8_t size) print_field("TX packet length: %d", le16_to_cpu(evt->tx_pkt_len)); } -static void sniff_subrating_evt(const void *data, uint8_t size) +static void sniff_subrating_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_sniff_subrating *evt = data; @@ -10108,7 +10405,8 @@ static void sniff_subrating_evt(const void *data, uint8_t size) print_slot_625("Min local timeout", evt->min_local_timeout); } -static void ext_inquiry_result_evt(const void *data, uint8_t size) +static void ext_inquiry_result_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_ext_inquiry_result *evt = data; @@ -10122,7 +10420,8 @@ static void ext_inquiry_result_evt(const void *data, uint8_t size) print_eir(evt->data, sizeof(evt->data), false); } -static void encrypt_key_refresh_complete_evt(const void *data, uint8_t size) +static void encrypt_key_refresh_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_encrypt_key_refresh_complete *evt = data; @@ -10130,14 +10429,16 @@ static void encrypt_key_refresh_complete_evt(const void *data, uint8_t size) print_handle(evt->handle); } -static void io_capability_request_evt(const void *data, uint8_t size) +static void io_capability_request_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_io_capability_request *evt = data; print_bdaddr(evt->bdaddr); } -static void io_capability_response_evt(const void *data, uint8_t size) +static void io_capability_response_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_io_capability_response *evt = data; @@ -10147,7 +10448,8 @@ static void io_capability_response_evt(const void *data, uint8_t size) print_authentication(evt->authentication); } -static void user_confirm_request_evt(const void *data, uint8_t size) +static void user_confirm_request_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_user_confirm_request *evt = data; @@ -10155,21 +10457,24 @@ static void user_confirm_request_evt(const void *data, uint8_t size) print_passkey(evt->passkey); } -static void user_passkey_request_evt(const void *data, uint8_t size) +static void user_passkey_request_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_user_passkey_request *evt = data; print_bdaddr(evt->bdaddr); } -static void remote_oob_data_request_evt(const void *data, uint8_t size) +static void remote_oob_data_request_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_remote_oob_data_request *evt = data; print_bdaddr(evt->bdaddr); } -static void simple_pairing_complete_evt(const void *data, uint8_t size) +static void simple_pairing_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_simple_pairing_complete *evt = data; @@ -10177,7 +10482,8 @@ static void simple_pairing_complete_evt(const void *data, uint8_t size) print_bdaddr(evt->bdaddr); } -static void link_supv_timeout_changed_evt(const void *data, uint8_t size) +static void link_supv_timeout_changed_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_link_supv_timeout_changed *evt = data; @@ -10185,14 +10491,16 @@ static void link_supv_timeout_changed_evt(const void *data, uint8_t size) print_timeout(evt->timeout); } -static void enhanced_flush_complete_evt(const void *data, uint8_t size) +static void enhanced_flush_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_enhanced_flush_complete *evt = data; print_handle(evt->handle); } -static void user_passkey_notify_evt(const void *data, uint8_t size) +static void user_passkey_notify_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_user_passkey_notify *evt = data; @@ -10200,7 +10508,7 @@ static void user_passkey_notify_evt(const void *data, uint8_t size) print_passkey(evt->passkey); } -static void keypress_notify_evt(const void *data, uint8_t size) +static void keypress_notify_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_keypress_notify *evt = data; const char *str; @@ -10231,7 +10539,8 @@ static void keypress_notify_evt(const void *data, uint8_t size) print_field("Notification type: %s (0x%2.2x)", str, evt->type); } -static void remote_host_features_notify_evt(const void *data, uint8_t size) +static void remote_host_features_notify_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_remote_host_features_notify *evt = data; @@ -10239,7 +10548,8 @@ static void remote_host_features_notify_evt(const void *data, uint8_t size) print_features(1, evt->features, 0x00); } -static void phy_link_complete_evt(const void *data, uint8_t size) +static void phy_link_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_phy_link_complete *evt = data; @@ -10247,14 +10557,15 @@ static void phy_link_complete_evt(const void *data, uint8_t size) print_phy_handle(evt->phy_handle); } -static void channel_selected_evt(const void *data, uint8_t size) +static void channel_selected_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_channel_selected *evt = data; print_phy_handle(evt->phy_handle); } -static void disconn_phy_link_complete_evt(const void *data, uint8_t size) +static void disconn_phy_link_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_disconn_phy_link_complete *evt = data; @@ -10263,7 +10574,8 @@ static void disconn_phy_link_complete_evt(const void *data, uint8_t size) print_reason(evt->reason); } -static void phy_link_loss_early_warning_evt(const void *data, uint8_t size) +static void phy_link_loss_early_warning_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_phy_link_loss_early_warning *evt = data; const char *str; @@ -10294,14 +10606,16 @@ static void phy_link_loss_early_warning_evt(const void *data, uint8_t size) print_field("Reason: %s (0x%2.2x)", str, evt->reason); } -static void phy_link_recovery_evt(const void *data, uint8_t size) +static void phy_link_recovery_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_phy_link_recovery *evt = data; print_phy_handle(evt->phy_handle); } -static void logic_link_complete_evt(const void *data, uint8_t size) +static void logic_link_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_logic_link_complete *evt = data; @@ -10311,7 +10625,8 @@ static void logic_link_complete_evt(const void *data, uint8_t size) print_field("TX flow spec: 0x%2.2x", evt->flow_spec); } -static void disconn_logic_link_complete_evt(const void *data, uint8_t size) +static void disconn_logic_link_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_disconn_logic_link_complete *evt = data; @@ -10320,7 +10635,8 @@ static void disconn_logic_link_complete_evt(const void *data, uint8_t size) print_reason(evt->reason); } -static void flow_spec_modify_complete_evt(const void *data, uint8_t size) +static void flow_spec_modify_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_flow_spec_modify_complete *evt = data; @@ -10328,7 +10644,8 @@ static void flow_spec_modify_complete_evt(const void *data, uint8_t size) print_handle(evt->handle); } -static void num_completed_data_blocks_evt(const void *data, uint8_t size) +static void num_completed_data_blocks_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_num_completed_data_blocks *evt = data; @@ -10343,7 +10660,8 @@ static void num_completed_data_blocks_evt(const void *data, uint8_t size) packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void short_range_mode_change_evt(const void *data, uint8_t size) +static void short_range_mode_change_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_short_range_mode_change *evt = data; @@ -10352,7 +10670,8 @@ static void short_range_mode_change_evt(const void *data, uint8_t size) print_enable("Short range mode", evt->mode); } -static void amp_status_change_evt(const void *data, uint8_t size) +static void amp_status_change_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_amp_status_change *evt = data; @@ -10360,7 +10679,8 @@ static void amp_status_change_evt(const void *data, uint8_t size) print_amp_status(evt->amp_status); } -static void triggered_clock_capture_evt(const void *data, uint8_t size) +static void triggered_clock_capture_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_triggered_clock_capture *evt = data; @@ -10370,14 +10690,16 @@ static void triggered_clock_capture_evt(const void *data, uint8_t size) print_clock_offset(evt->clock_offset); } -static void sync_train_complete_evt(const void *data, uint8_t size) +static void sync_train_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_sync_train_complete *evt = data; print_status(evt->status); } -static void sync_train_received_evt(const void *data, uint8_t size) +static void sync_train_received_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_sync_train_received *evt = data; @@ -10392,7 +10714,8 @@ static void sync_train_received_evt(const void *data, uint8_t size) print_field("Service Data: 0x%2.2x", evt->service_data); } -static void peripheral_broadcast_receive_evt(const void *data, uint8_t size) +static void peripheral_broadcast_receive_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_peripheral_broadcast_receive *evt = data; @@ -10414,7 +10737,8 @@ static void peripheral_broadcast_receive_evt(const void *data, uint8_t size) packet_hexdump(data + 18, size - 18); } -static void peripheral_broadcast_timeout_evt(const void *data, uint8_t size) +static void peripheral_broadcast_timeout_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_peripheral_broadcast_timeout *evt = data; @@ -10422,7 +10746,8 @@ static void peripheral_broadcast_timeout_evt(const void *data, uint8_t size) print_lt_addr(evt->lt_addr); } -static void truncated_page_complete_evt(const void *data, uint8_t size) +static void truncated_page_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_truncated_page_complete *evt = data; @@ -10430,18 +10755,21 @@ static void truncated_page_complete_evt(const void *data, uint8_t size) print_bdaddr(evt->bdaddr); } -static void peripheral_page_response_timeout_evt(const void *data, uint8_t size) +static void peripheral_page_response_timeout_evt(uint16_t index, + const void *data, uint8_t size) { } -static void channel_map_change_evt(const void *data, uint8_t size) +static void channel_map_change_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_channel_map_change *evt = data; print_channel_map(evt->map); } -static void inquiry_response_notify_evt(const void *data, uint8_t size) +static void inquiry_response_notify_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_inquiry_response_notify *evt = data; @@ -10449,14 +10777,15 @@ static void inquiry_response_notify_evt(const void *data, uint8_t size) print_rssi(evt->rssi); } -static void auth_payload_timeout_expired_evt(const void *data, uint8_t size) +static void auth_payload_timeout_expired_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_auth_payload_timeout_expired *evt = data; print_handle(evt->handle); } -static void le_conn_complete_evt(const void *data, uint8_t size) +static void le_conn_complete_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_conn_complete *evt = data; @@ -10473,10 +10802,11 @@ static void le_conn_complete_evt(const void *data, uint8_t size) print_field("Central clock accuracy: 0x%2.2x", evt->clock_accuracy); if (evt->status == 0x00) - assign_handle(le16_to_cpu(evt->handle), 0x01); + assign_handle(index, le16_to_cpu(evt->handle), 0x01, + (void *)evt->peer_addr, evt->peer_addr_type); } -static void le_adv_report_evt(const void *data, uint8_t size) +static void le_adv_report_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_adv_report *evt = data; uint8_t evt_len; @@ -10504,7 +10834,8 @@ report: } } -static void le_conn_update_complete_evt(const void *data, uint8_t size) +static void le_conn_update_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_conn_update_complete *evt = data; @@ -10517,7 +10848,8 @@ static void le_conn_update_complete_evt(const void *data, uint8_t size) le16_to_cpu(evt->supv_timeout)); } -static void le_remote_features_complete_evt(const void *data, uint8_t size) +static void le_remote_features_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_remote_features_complete *evt = data; @@ -10526,7 +10858,8 @@ static void le_remote_features_complete_evt(const void *data, uint8_t size) print_features(0, evt->features, 0x01); } -static void le_long_term_key_request_evt(const void *data, uint8_t size) +static void le_long_term_key_request_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_long_term_key_request *evt = data; @@ -10535,7 +10868,8 @@ static void le_long_term_key_request_evt(const void *data, uint8_t size) print_encrypted_diversifier(evt->ediv); } -static void le_conn_param_request_evt(const void *data, uint8_t size) +static void le_conn_param_request_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_conn_param_request *evt = data; @@ -10548,7 +10882,8 @@ static void le_conn_param_request_evt(const void *data, uint8_t size) le16_to_cpu(evt->supv_timeout)); } -static void le_data_length_change_evt(const void *data, uint8_t size) +static void le_data_length_change_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_data_length_change *evt = data; @@ -10559,7 +10894,8 @@ static void le_data_length_change_evt(const void *data, uint8_t size) print_field("Max RX time: %d", le16_to_cpu(evt->max_rx_time)); } -static void le_read_local_pk256_complete_evt(const void *data, uint8_t size) +static void le_read_local_pk256_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_read_local_pk256_complete *evt = data; @@ -10567,7 +10903,8 @@ static void le_read_local_pk256_complete_evt(const void *data, uint8_t size) print_pk256("Local P-256 public key", evt->local_pk256); } -static void le_generate_dhkey_complete_evt(const void *data, uint8_t size) +static void le_generate_dhkey_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_generate_dhkey_complete *evt = data; @@ -10575,7 +10912,8 @@ static void le_generate_dhkey_complete_evt(const void *data, uint8_t size) print_dhkey(evt->dhkey); } -static void le_enhanced_conn_complete_evt(const void *data, uint8_t size) +static void le_enhanced_conn_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_enhanced_conn_complete *evt = data; @@ -10594,10 +10932,12 @@ static void le_enhanced_conn_complete_evt(const void *data, uint8_t size) print_field("Central clock accuracy: 0x%2.2x", evt->clock_accuracy); if (evt->status == 0x00) - assign_handle(le16_to_cpu(evt->handle), 0x01); + assign_handle(index, le16_to_cpu(evt->handle), 0x01, + (void *)evt->peer_addr, evt->peer_addr_type); } -static void le_direct_adv_report_evt(const void *data, uint8_t size) +static void le_direct_adv_report_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_direct_adv_report *evt = data; @@ -10614,7 +10954,8 @@ static void le_direct_adv_report_evt(const void *data, uint8_t size) packet_hexdump(data + sizeof(*evt), size - sizeof(*evt)); } -static void le_phy_update_complete_evt(const void *data, uint8_t size) +static void le_phy_update_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_phy_update_complete *evt = data; @@ -10717,7 +11058,8 @@ static void print_legacy_adv_report_pdu(uint16_t flags) print_field(" Legacy PDU Type: %s (0x%4.4x)", str, flags); } -static void le_ext_adv_report_evt(const void *data, uint8_t size) +static void le_ext_adv_report_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_ext_adv_report *evt = data; const struct bt_hci_le_ext_adv_report *report; @@ -10804,7 +11146,7 @@ static void le_ext_adv_report_evt(const void *data, uint8_t size) } } -static void le_pa_sync(const void *data, uint8_t size) +static void le_pa_sync(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_per_sync_established *evt = data; @@ -10822,7 +11164,7 @@ static void le_pa_sync(const void *data, uint8_t size) print_field("Advertiser clock accuracy: 0x%2.2x", evt->clock_accuracy); } -static void le_pa_report_evt(const void *data, uint8_t size) +static void le_pa_report_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_le_pa_report *evt = data; const char *color_on; @@ -10883,14 +11225,14 @@ static void le_pa_report_evt(const void *data, uint8_t size) packet_hexdump(evt->data, evt->data_len); } -static void le_pa_sync_lost(const void *data, uint8_t size) +static void le_pa_sync_lost(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_per_sync_lost *evt = data; print_field("Sync handle: %d", evt->handle); } -static void le_adv_set_term_evt(const void *data, uint8_t size) +static void le_adv_set_term_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_adv_set_term *evt = data; @@ -10901,7 +11243,8 @@ static void le_adv_set_term_evt(const void *data, uint8_t size) evt->num_evts); } -static void le_scan_req_received_evt(const void *data, uint8_t size) +static void le_scan_req_received_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_scan_req_received *evt = data; @@ -10911,7 +11254,8 @@ static void le_scan_req_received_evt(const void *data, uint8_t size) evt->scanner_addr_type); } -static void le_chan_select_alg_evt(const void *data, uint8_t size) +static void le_chan_select_alg_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_chan_select_alg *evt = data; const char *str; @@ -10933,7 +11277,8 @@ static void le_chan_select_alg_evt(const void *data, uint8_t size) print_field("Algorithm: %s (0x%2.2x)", str, evt->algorithm); } -static void le_cte_request_failed_evt(const void *data, uint8_t size) +static void le_cte_request_failed_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_cte_request_failed *evt = data; @@ -10941,7 +11286,8 @@ static void le_cte_request_failed_evt(const void *data, uint8_t size) print_field("Connection handle: %d", evt->handle); } -static void le_pa_sync_trans_rec_evt(const void *data, uint8_t size) +static void le_pa_sync_trans_rec_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_pa_sync_trans_rec *evt = data; @@ -10959,7 +11305,8 @@ static void le_pa_sync_trans_rec_evt(const void *data, uint8_t size) print_clock_accuracy(evt->clock_accuracy); } -static void le_cis_established_evt(const void *data, uint8_t size) +static void le_cis_established_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_cis_established *evt = data; @@ -10981,7 +11328,7 @@ static void le_cis_established_evt(const void *data, uint8_t size) print_field("ISO Interval: %u", le16_to_cpu(evt->interval)); } -static void le_req_cis_evt(const void *data, uint8_t size) +static void le_req_cis_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_cis_req *evt = data; @@ -10998,7 +11345,7 @@ static void print_bis_handle(const void *data, int i) print_field("Connection Handle #%d: %d", i, handle); } -static void le_big_complete_evt(const void *data, uint8_t size) +static void le_big_complete_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_big_complete *evt = data; @@ -11017,7 +11364,7 @@ static void le_big_complete_evt(const void *data, uint8_t size) sizeof(*evt->bis_handle), print_bis_handle); } -static void le_big_terminate_evt(const void *data, uint8_t size) +static void le_big_terminate_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_big_terminate *evt = data; @@ -11025,7 +11372,8 @@ static void le_big_terminate_evt(const void *data, uint8_t size) print_reason(evt->reason); } -static void le_big_sync_estabilished_evt(const void *data, uint8_t size) +static void le_big_sync_estabilished_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_big_sync_estabilished *evt = data; @@ -11042,7 +11390,7 @@ static void le_big_sync_estabilished_evt(const void *data, uint8_t size) print_bis_handle); } -static void le_big_sync_lost_evt(const void *data, uint8_t size) +static void le_big_sync_lost_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_big_sync_lost *evt = data; @@ -11050,7 +11398,8 @@ static void le_big_sync_lost_evt(const void *data, uint8_t size) print_reason(evt->reason); } -static void le_req_sca_complete_evt(const void *data, uint8_t size) +static void le_req_sca_complete_evt(uint16_t index, const void *data, + uint8_t size) { const struct bt_hci_evt_le_req_peer_sca_complete *evt = data; @@ -11059,7 +11408,7 @@ static void le_req_sca_complete_evt(const void *data, uint8_t size) print_sca(evt->sca); } -static void le_big_info_evt(const void *data, uint8_t size) +static void le_big_info_evt(uint16_t index, const void *data, uint8_t size) { const struct bt_hci_evt_le_big_info_adv_report *evt = data; @@ -11081,13 +11430,14 @@ static void le_big_info_evt(const void *data, uint8_t size) struct subevent_data { uint8_t subevent; const char *str; - void (*func) (const void *data, uint8_t size); + void (*func) (uint16_t index, const void *data, uint8_t size); uint8_t size; bool fixed; }; -static void print_subevent(const struct subevent_data *subevent_data, - const void *data, uint8_t size) +static void print_subevent(uint16_t index, + const struct subevent_data *subevent_data, + const void *data, uint8_t size) { const char *subevent_color; @@ -11118,7 +11468,7 @@ static void print_subevent(const struct subevent_data *subevent_data, } } - subevent_data->func(data, size); + subevent_data->func(index, data, size); } static const struct subevent_data le_meta_event_table[] = { @@ -11203,7 +11553,7 @@ static const struct subevent_data le_meta_event_table[] = { { } }; -static void le_meta_event_evt(const void *data, uint8_t size) +static void le_meta_event_evt(uint16_t index, const void *data, uint8_t size) { uint8_t subevent = *((const uint8_t *) data); struct subevent_data unknown; @@ -11223,10 +11573,10 @@ static void le_meta_event_evt(const void *data, uint8_t size) } } - print_subevent(subevent_data, data + 1, size - 1); + print_subevent(index, subevent_data, data + 1, size - 1); } -static void vendor_evt(const void *data, uint8_t size) +static void vendor_evt(uint16_t index, const void *data, uint8_t size) { struct subevent_data vendor_data; char vendor_str[150]; @@ -11247,7 +11597,7 @@ static void vendor_evt(const void *data, uint8_t size) vendor_data.size = vnd->evt_size; vendor_data.fixed = vnd->evt_fixed; - print_subevent(&vendor_data, data + consumed_size, + print_subevent(index, &vendor_data, data + consumed_size, size - consumed_size); } else { uint16_t manufacturer; @@ -11264,7 +11614,7 @@ static void vendor_evt(const void *data, uint8_t size) struct event_data { uint8_t event; const char *str; - void (*func) (const void *data, uint8_t size); + void (*func) (uint16_t index, const void *data, uint8_t size); uint8_t size; bool fixed; }; @@ -11696,7 +12046,7 @@ void packet_hci_command(struct timeval *tv, struct ucred *cred, uint16_t index, } } - opcode_data->cmd_func(data, hdr->plen); + opcode_data->cmd_func(index, data, hdr->plen); } void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index, @@ -11776,7 +12126,7 @@ void packet_hci_event(struct timeval *tv, struct ucred *cred, uint16_t index, } } - event_data->func(data, hdr->plen); + event_data->func(index, data, hdr->plen); } void packet_hci_acldata(struct timeval *tv, struct ucred *cred, uint16_t index, diff --git a/monitor/packet.h b/monitor/packet.h index 8a11bc714..a00975eb3 100644 --- a/monitor/packet.h +++ b/monitor/packet.h @@ -23,6 +23,18 @@ #define PACKET_FILTER_SHOW_A2DP_STREAM (1 << 6) #define PACKET_FILTER_SHOW_MGMT_SOCKET (1 << 7) +struct packet_conn_data { + uint16_t index; + uint16_t handle; + uint8_t type; + uint8_t dst[6]; + uint8_t dst_type; + void *data; + void (*destroy)(void *data); +}; + +struct packet_conn_data *packet_get_conn_data(uint16_t handle); + bool packet_has_filter(unsigned long filter); void packet_set_filter(unsigned long filter); void packet_add_filter(unsigned long filter); diff --git a/monitor/vendor.h b/monitor/vendor.h index c70552b66..9430f3736 100644 --- a/monitor/vendor.h +++ b/monitor/vendor.h @@ -14,10 +14,10 @@ struct vendor_ocf { uint16_t ocf; const char *str; - void (*cmd_func) (const void *data, uint8_t size); + void (*cmd_func) (uint16_t index, const void *data, uint8_t size); uint8_t cmd_size; bool cmd_fixed; - void (*rsp_func) (const void *data, uint8_t size); + void (*rsp_func) (uint16_t index, const void *data, uint8_t size); uint8_t rsp_size; bool rsp_fixed; }; @@ -25,7 +25,7 @@ struct vendor_ocf { struct vendor_evt { uint8_t evt; const char *str; - void (*evt_func) (const void *data, uint8_t size); + void (*evt_func) (uint16_t index, const void *data, uint8_t size); uint8_t evt_size; bool evt_fixed; }; From patchwork Fri May 20 04:17:00 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12856288 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 1907BC433EF for ; Fri, 20 May 2022 04:17:13 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234517AbiETERL (ORCPT ); Fri, 20 May 2022 00:17:11 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38308 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S234146AbiETERJ (ORCPT ); Fri, 20 May 2022 00:17:09 -0400 Received: from mail-pj1-x1032.google.com (mail-pj1-x1032.google.com [IPv6:2607:f8b0:4864:20::1032]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id A7BA76B7ED for ; Thu, 19 May 2022 21:17:08 -0700 (PDT) Received: by mail-pj1-x1032.google.com with SMTP id v5-20020a17090a7c0500b001df84fa82f8so6888008pjf.5 for ; Thu, 19 May 2022 21:17:08 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=ChJFvNq/Wsh2RG3EOPiLBgjC/bQ3ZyP8oD3/t6vqWuA=; b=A6sByZCSfMiODYNxLgBGWdtakZad5HElCVnNy7JaTLSNIC67QDorJzGhDuS9u6/Rao eg2SVmTT75mJ25M7Zm54ud2LvDa0FhKdIG7/a1kQlPytuXlBZFxf3QuKCu+4vnmwDe9+ 0A9CnvyPbmjjJNvPHg+H9eMJq/QObyfUY5pXeG/v7fngR465zsyKMthaVn3S/rosMUTb xbI+5T8kxTOz8Dlk1XmyjURYqqajJPdXFXpdKuz/nbEt8yyD6CvO38DpFF4VJpPJvBMJ WrbOyhBNuzNHiRwqTQK6I6z7coO4n6mj8Mv7itGuFHh0JFZHZGz06s01cy0CnIIinXLw xQKw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=ChJFvNq/Wsh2RG3EOPiLBgjC/bQ3ZyP8oD3/t6vqWuA=; b=7BGAN0fO2Eq6E9bYL2tPRbcIpsI76gyyjuL3JkqduTIMbP04shSBrxw09b5RnK8gGr BQaGTQO3H+OdZ9FmPJGSO9ImgRgBXysuI8HQk/+x7ytkrO0DPllD6rQ1jU8Fs92s/jSN 07REWzakFK0elhczXJBEcy8a5fiXliO197qj15yMF1FoTac2lnZZntZta7n/9U+VTVXH e7TODLi8P82WSnyWeSFAYaEmFZ4SHchqwhDWxDP27Fb+Fo9H4o6Tdkx0fN5bWBRj+LxC /AC/TT9b2o2iMJTUTMU5sVt+J2oAjdHQNQaxiryGwFiwN7PRZ38RNX7f8TBx3pSmMud1 c9yw== X-Gm-Message-State: AOAM532sR8lR/FuAYLTfb8+oLwJ52xMpD9KYuZeLK8IWZ2ZdJpJ25h3M xgqqMReIwTTF0z9vAYJPuZEN+aBI+KM= X-Google-Smtp-Source: ABdhPJxDjf25TXP4W8VJVqpCiXoy0TZF4GiBYMmK+CfSNQbozE231vYbn3Oud9HrhEBpZC0u9hLozw== X-Received: by 2002:a17:902:f70a:b0:153:88c7:774 with SMTP id h10-20020a170902f70a00b0015388c70774mr7929647plo.166.1653020227786; Thu, 19 May 2022 21:17:07 -0700 (PDT) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id u13-20020a17090a450d00b001df955c28f6sm381405pjg.37.2022.05.19.21.17.07 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 21:17:07 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 6/7] monitor/att: Decode attribute type Date: Thu, 19 May 2022 21:17:00 -0700 Message-Id: <20220520041701.2572197-6-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220520041701.2572197-1-luiz.dentz@gmail.com> References: <20220520041701.2572197-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This attempt to decode the attribute type if its gatt_db can be loaded: < ACL Data TX: Handle 3585 flags 0x00 dlen 9 ATT: Write Request (0x12) len 4 Handle: 0x000b Type: Client Characteristic Configuration (0x2902) Data: 0200 --- Makefile.tools | 5 +- monitor/att.c | 145 +++++++++++++++++++++++++++++++++++++++++++---- monitor/packet.c | 2 +- 3 files changed, 138 insertions(+), 14 deletions(-) diff --git a/Makefile.tools b/Makefile.tools index a152dad6f..4b513366f 100644 --- a/Makefile.tools +++ b/Makefile.tools @@ -49,7 +49,10 @@ monitor_btmon_SOURCES = monitor/main.c monitor/bt.h \ monitor/msft.h monitor/msft.c \ monitor/jlink.h monitor/jlink.c \ monitor/tty.h monitor/emulator.h \ - monitor/att.h monitor/att.c + monitor/att.h monitor/att.c \ + src/log.h src/log.c \ + src/textfile.h src/textfile.c \ + src/settings.h src/settings.c monitor_btmon_LDADD = lib/libbluetooth-internal.la \ src/libshared-mainloop.la \ $(GLIB_LIBS) $(UDEV_LIBS) -ldl diff --git a/monitor/att.c b/monitor/att.c index 5ad8244db..304c37319 100644 --- a/monitor/att.c +++ b/monitor/att.c @@ -18,11 +18,21 @@ #include #include #include +#include +#include +#include #include "lib/bluetooth.h" #include "lib/uuid.h" +#include "lib/hci.h" +#include "lib/hci_lib.h" #include "src/shared/util.h" +#include "src/shared/queue.h" +#include "src/shared/att.h" +#include "src/shared/gatt-db.h" +#include "src/textfile.h" +#include "src/settings.h" #include "bt.h" #include "packet.h" #include "display.h" @@ -316,11 +326,123 @@ static void att_read_type_rsp(const struct l2cap_frame *frame) frame->data + 1, frame->size - 1); } +struct att_conn_data { + struct gatt_db *ldb; + struct gatt_db *rdb; +}; + +static void att_conn_data_free(void *data) +{ + struct att_conn_data *att_data = data; + + gatt_db_unref(att_data->rdb); + gatt_db_unref(att_data->ldb); + free(att_data); +} + +static void load_gatt_db(struct packet_conn_data *conn) +{ + struct att_conn_data *data; + char filename[PATH_MAX]; + bdaddr_t src; + char local[18]; + char peer[18]; + + if (hci_devba(conn->index, &src) < 0) + return; + + data = new0(struct att_conn_data, 1); + data->rdb = gatt_db_new(); + data->ldb = gatt_db_new(); + conn->data = data; + conn->destroy = att_conn_data_free; + + ba2str(&src, local); + + create_filename(filename, PATH_MAX, "/%s/attributes", local); + + btd_settings_gatt_db_load(data->ldb, filename); + + ba2str((bdaddr_t *)conn->dst, peer); + + create_filename(filename, PATH_MAX, "/%s/cache/%s", local, peer); + + btd_settings_gatt_db_load(data->rdb, filename); +} + +static struct gatt_db_attribute *get_attribute(const struct l2cap_frame *frame, + uint16_t handle, bool rsp) +{ + struct packet_conn_data *conn; + struct att_conn_data *data; + struct gatt_db *db; + + conn = packet_get_conn_data(frame->handle); + if (!conn) + return NULL; + + data = conn->data; + /* Try loading local and remote gatt_db if not loaded yet */ + if (!data) { + load_gatt_db(conn); + data = conn->data; + if (!data) + return NULL; + } + + if (frame->in) { + if (rsp) + db = data->rdb; + else + db = data->ldb; + } else { + if (rsp) + db = data->ldb; + else + db = data->rdb; + } + + return gatt_db_get_attribute(db, handle); +} + +static void print_handle(const struct l2cap_frame *frame, uint16_t handle, + bool rsp) +{ + struct gatt_db_attribute *attr; + const bt_uuid_t *uuid; + char label[21]; + + attr = get_attribute(frame, handle, rsp); + if (!attr) + goto done; + + uuid = gatt_db_attribute_get_type(attr); + if (!uuid) + goto done; + + switch (uuid->type) { + case BT_UUID16: + sprintf(label, "Handle: 0x%4.4x Type", handle); + print_uuid(label, &cpu_to_le16(uuid->value.u16), 2); + return; + case BT_UUID128: + sprintf(label, "Handle: 0x%4.4x Type", handle); + print_uuid(label, &uuid->value.u128, 16); + return; + case BT_UUID_UNSPEC: + case BT_UUID32: + break; + } + +done: + print_field("Handle: 0x%4.4x", handle); +} + static void att_read_req(const struct l2cap_frame *frame) { const struct bt_l2cap_att_read_req *pdu = frame->data; - print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); + print_handle(frame, le16_to_cpu(pdu->handle), false); } static void att_read_rsp(const struct l2cap_frame *frame) @@ -330,7 +452,7 @@ static void att_read_rsp(const struct l2cap_frame *frame) static void att_read_blob_req(const struct l2cap_frame *frame) { - print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_handle(frame, get_le16(frame->data), false); print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); } @@ -346,8 +468,7 @@ static void att_read_multiple_req(const struct l2cap_frame *frame) count = frame->size / 2; for (i = 0; i < count; i++) - print_field("Handle: 0x%4.4x", - get_le16(frame->data + (i * 2))); + print_handle(frame, get_le16(frame->data + (i * 2)), false); } static void att_read_group_type_req(const struct l2cap_frame *frame) @@ -390,7 +511,7 @@ static void att_read_group_type_rsp(const struct l2cap_frame *frame) static void att_write_req(const struct l2cap_frame *frame) { - print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_handle(frame, get_le16(frame->data), false); print_hex_field(" Data", frame->data + 2, frame->size - 2); } @@ -400,14 +521,14 @@ static void att_write_rsp(const struct l2cap_frame *frame) static void att_prepare_write_req(const struct l2cap_frame *frame) { - print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_handle(frame, get_le16(frame->data), false); print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); print_hex_field(" Data", frame->data + 4, frame->size - 4); } static void att_prepare_write_rsp(const struct l2cap_frame *frame) { - print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_handle(frame, get_le16(frame->data), true); print_field("Offset: 0x%4.4x", get_le16(frame->data + 2)); print_hex_field(" Data", frame->data + 4, frame->size - 4); } @@ -436,7 +557,7 @@ static void att_handle_value_notify(const struct l2cap_frame *frame) { const struct bt_l2cap_att_handle_value_notify *pdu = frame->data; - print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); + print_handle(frame, le16_to_cpu(pdu->handle), true); print_hex_field(" Data", frame->data + 2, frame->size - 2); } @@ -444,7 +565,7 @@ static void att_handle_value_ind(const struct l2cap_frame *frame) { const struct bt_l2cap_att_handle_value_ind *pdu = frame->data; - print_field("Handle: 0x%4.4x", le16_to_cpu(pdu->handle)); + print_handle(frame, le16_to_cpu(pdu->handle), true); print_hex_field(" Data", frame->data + 2, frame->size - 2); } @@ -463,7 +584,7 @@ static void att_multiple_vl_rsp(const struct l2cap_frame *frame) if (!l2cap_frame_get_le16(f, &handle)) return; - print_field("Handle: 0x%4.4x", handle); + print_handle(frame, get_le16(frame->data), true); if (!l2cap_frame_get_le16(f, &len)) return; @@ -484,13 +605,13 @@ static void att_multiple_vl_rsp(const struct l2cap_frame *frame) static void att_write_command(const struct l2cap_frame *frame) { - print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_handle(frame, get_le16(frame->data), false); print_hex_field(" Data", frame->data + 2, frame->size - 2); } static void att_signed_write_command(const struct l2cap_frame *frame) { - print_field("Handle: 0x%4.4x", get_le16(frame->data)); + print_handle(frame, get_le16(frame->data), false); print_hex_field(" Data", frame->data + 2, frame->size - 2 - 12); print_hex_field(" Signature", frame->data + frame->size - 12, 12); } diff --git a/monitor/packet.c b/monitor/packet.c index 8608cf2ef..e854c1a8e 100644 --- a/monitor/packet.c +++ b/monitor/packet.c @@ -765,7 +765,7 @@ static void print_handle_native(uint16_t handle) } sprintf(label, "Handle: %d Address", handle); - print_addr(" Address", conn->dst, conn->dst_type); + print_addr(label, conn->dst, conn->dst_type); } static void print_handle(uint16_t handle) From patchwork Fri May 20 04:17:01 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Luiz Augusto von Dentz X-Patchwork-Id: 12856289 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from vger.kernel.org (vger.kernel.org [23.128.96.18]) by smtp.lore.kernel.org (Postfix) with ESMTP id 44A36C433F5 for ; Fri, 20 May 2022 04:17:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S234571AbiETERM (ORCPT ); Fri, 20 May 2022 00:17:12 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:38426 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S233029AbiETERK (ORCPT ); Fri, 20 May 2022 00:17:10 -0400 Received: from mail-pj1-x1034.google.com (mail-pj1-x1034.google.com [IPv6:2607:f8b0:4864:20::1034]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id ED4EF6BFE4 for ; Thu, 19 May 2022 21:17:09 -0700 (PDT) Received: by mail-pj1-x1034.google.com with SMTP id oe17-20020a17090b395100b001df77d29587so10451272pjb.2 for ; Thu, 19 May 2022 21:17:09 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:subject:date:message-id:in-reply-to:references:mime-version :content-transfer-encoding; bh=Gv7CsCeeGdZZYw/wLPt9ZJW1vb4D4muTrAmmQBTZmPE=; b=GM+V1Fl7VaAyCn0eJ7VUXdPR+L6xww+uJ3WNmleFrDkO8CjHOqkMTgn7EO5SucK/OR iyuo+cqqMB4yenvXL0t7ivHdD0+SexX+mIQrO1CHK8r7jsPV4y5LEOMy3bZntgMcGIsL cG2xyyqWKOdV+Th71x+uLEO+c/n7cgsa5/w0YdPl+8gjqmQEjY87b1CBxxRCpydJ6osf tblF2dxtTCgNQtleP6iBzc1QTQMrNLiLrYLBadA6+edbf8z4ZnP7Zedg/Ua3AJRUuC1b YSz1ETmGFSky7nAOKDj460rRY9HCH8uRKnXTjzhNPbRDLQVMh7Xio7+0zPjuWL6tMB+k ktJg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=Gv7CsCeeGdZZYw/wLPt9ZJW1vb4D4muTrAmmQBTZmPE=; b=wdQNHqNw0SR+3XFt16Na1tJjsZzrhBu9HfUkq68J3glaiafJVrYfBiTgFKHlBeehGd DJALYJwPsW3gqXBPUbndL0C72KO7OjvL8KW2t7lIVDeZY5nQMOu2I90wQnPT6Mpg+paf i0+xsnQUQCyRGY0KXEgbDtY0L6qcDP2Jw1AdcxScUAJMl8NKtKTqWODsrG3Z/q708DgG hT7MrhmDiWpyVD9ST0qP90gChtP7OKiXTkjT/rvRckO6ecNxeExERFyxZ6QmBwrl2/WO 4BBAjZXhPClzMlSd2CvR+njUujKYUMrttU5mc1/dMZleoZBfMIMsMzCPKij8ZfysJXCt taSw== X-Gm-Message-State: AOAM532iNlP75/+HuJ2CQ6D+1ULtQuow8ySrOsyZGuSIhS1ZH8A2u9ej kEzcVqbstWGxSD++I+0FAVVR9D8zT40= X-Google-Smtp-Source: ABdhPJy6etU65WXPUgKWB6afrvStjIAyqBH1uBm55pmxOtw/CyW9oTTued0uGVBYOxs94MXVwZGbHg== X-Received: by 2002:a17:902:aa06:b0:158:f13b:4859 with SMTP id be6-20020a170902aa0600b00158f13b4859mr7874356plb.141.1653020228979; Thu, 19 May 2022 21:17:08 -0700 (PDT) Received: from lvondent-mobl4.. (c-71-56-157-77.hsd1.or.comcast.net. [71.56.157.77]) by smtp.gmail.com with ESMTPSA id u13-20020a17090a450d00b001df955c28f6sm381405pjg.37.2022.05.19.21.17.08 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Thu, 19 May 2022 21:17:08 -0700 (PDT) From: Luiz Augusto von Dentz To: linux-bluetooth@vger.kernel.org Subject: [PATCH v2 7/7] monitor/att: Add decoding support for CCC Date: Thu, 19 May 2022 21:17:01 -0700 Message-Id: <20220520041701.2572197-7-luiz.dentz@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220520041701.2572197-1-luiz.dentz@gmail.com> References: <20220520041701.2572197-1-luiz.dentz@gmail.com> MIME-Version: 1.0 Precedence: bulk List-ID: X-Mailing-List: linux-bluetooth@vger.kernel.org From: Luiz Augusto von Dentz This adds decoding support for CCC so its value can be decoded: < ACL Data TX: Handle 3585 flags 0x00 dlen 7 ATT: Read Request (0x0a) len 2 Handle: 0x002c Type: Client Characteristic Configuration (0x2902) > ACL Data RX: Handle 3585 flags 0x02 dlen 6 ATT: Read Response (0x0b) len 1 Value: 01 Notification (0x01) < ACL Data TX: Handle 3585 flags 0x00 dlen 9 ATT: Write Request (0x12) len 4 Handle: 0x002c Type: Client Characteristic Configuration (0x2902) Data: 0100 Notification (0x01) --- monitor/att.c | 241 ++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 223 insertions(+), 18 deletions(-) diff --git a/monitor/att.c b/monitor/att.c index 304c37319..f1af420ba 100644 --- a/monitor/att.c +++ b/monitor/att.c @@ -215,6 +215,82 @@ static void att_error_response(const struct l2cap_frame *frame) print_field("Error: %s (0x%2.2x)", str, pdu->error); } +static const struct bitfield_data ccc_value_table[] = { + { 0, "Notification (0x01)" }, + { 1, "Indication (0x02)" }, + { } +}; + +static void print_ccc_value(uint8_t value) +{ + uint8_t mask = value; + + mask = print_bitfield(4, value, ccc_value_table); + if (mask) + print_text(COLOR_WHITE_BG, " Unknown fields (0x%2.2x)", + mask); +} + +static void gatt_ccc_read(const struct l2cap_frame *frame) +{ + uint8_t value; + + if (!l2cap_frame_get_u8((void *)frame, &value)) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + print_ccc_value(value); +} + +static void gatt_ccc_write(const struct l2cap_frame *frame) +{ + uint8_t value; + + if (!l2cap_frame_get_u8((void *)frame, &value)) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + print_ccc_value(value); +} + +#define GATT_HANDLER(_uuid, _read, _write, _notify) \ +{ \ + .uuid = { \ + .type = BT_UUID16, \ + .value.u16 = _uuid, \ + }, \ + .read = _read, \ + .write = _write, \ + .notify = _notify \ +} + +struct gatt_handler { + bt_uuid_t uuid; + void (*read)(const struct l2cap_frame *frame); + void (*write)(const struct l2cap_frame *frame); + void (*notify)(const struct l2cap_frame *frame); +} gatt_handlers[] = { + GATT_HANDLER(GATT_CLIENT_CHARAC_CFG_UUID, gatt_ccc_read, + gatt_ccc_write, NULL) +}; + +static struct gatt_handler *get_handler(struct gatt_db_attribute *attr) +{ + const bt_uuid_t *uuid = gatt_db_attribute_get_type(attr); + size_t i; + + for (i = 0; i < ARRAY_SIZE(gatt_handlers); i++) { + struct gatt_handler *handler = &gatt_handlers[i]; + + if (!bt_uuid_cmp(&handler->uuid, uuid)) + return handler; + } + + return NULL; +} + static void att_exchange_mtu_req(const struct l2cap_frame *frame) { const struct bt_l2cap_att_exchange_mtu_req *pdu = frame->data; @@ -326,9 +402,16 @@ static void att_read_type_rsp(const struct l2cap_frame *frame) frame->data + 1, frame->size - 1); } +struct att_read { + struct gatt_db_attribute *attr; + uint16_t cid; + void (*func)(const struct l2cap_frame *frame); +}; + struct att_conn_data { struct gatt_db *ldb; struct gatt_db *rdb; + struct queue *reads; }; static void att_conn_data_free(void *data) @@ -337,6 +420,7 @@ static void att_conn_data_free(void *data) gatt_db_unref(att_data->rdb); gatt_db_unref(att_data->ldb); + queue_destroy(att_data->reads, free); free(att_data); } @@ -441,13 +525,67 @@ done: static void att_read_req(const struct l2cap_frame *frame) { const struct bt_l2cap_att_read_req *pdu = frame->data; + uint16_t handle; + struct packet_conn_data *conn; + struct att_conn_data *data; + struct att_read *read; + struct gatt_db_attribute *attr; + struct gatt_handler *handler; - print_handle(frame, le16_to_cpu(pdu->handle), false); + l2cap_frame_pull((void *)frame, frame, sizeof(*pdu)); + + handle = le16_to_cpu(pdu->handle); + print_handle(frame, handle, false); + + attr = get_attribute(frame, handle, false); + if (!attr) + return; + + handler = get_handler(attr); + if (!handler) + return; + + conn = packet_get_conn_data(frame->handle); + data = conn->data; + + if (!data->reads) + data->reads = queue_new(); + + read = new0(struct att_read, 1); + read->attr = attr; + read->cid = frame->cid; + read->func = handler->read; + + queue_push_tail(data->reads, read); +} + +static bool match_read_frame(const void *data, const void *match_data) +{ + const struct att_read *read = data; + const struct l2cap_frame *frame = match_data; + + return read->cid == frame->cid; } static void att_read_rsp(const struct l2cap_frame *frame) { + struct packet_conn_data *conn; + struct att_conn_data *data; + struct att_read *read; + print_hex_field("Value", frame->data, frame->size); + + conn = packet_get_conn_data(frame->handle); + if (!conn) + return; + + data = conn->data; + + read = queue_find(data->reads, match_read_frame, frame); + if (!read) + return; + + read->func(frame); } static void att_read_blob_req(const struct l2cap_frame *frame) @@ -509,10 +647,41 @@ static void att_read_group_type_rsp(const struct l2cap_frame *frame) frame->data + 1, frame->size - 1); } +static void print_write(const struct l2cap_frame *frame, uint16_t handle, + size_t len) +{ + struct gatt_db_attribute *attr; + struct gatt_handler *handler; + + print_handle(frame, handle, false); + print_hex_field(" Data", frame->data, frame->size); + + if (len > frame->size) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + attr = get_attribute(frame, handle, false); + if (!attr) + return; + + handler = get_handler(attr); + if (!handler) + return; + + handler->write(frame); +} + static void att_write_req(const struct l2cap_frame *frame) { - print_handle(frame, get_le16(frame->data), false); - print_hex_field(" Data", frame->data + 2, frame->size - 2); + uint16_t handle; + + if (!l2cap_frame_get_le16((void *)frame, &handle)) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + print_write(frame, handle, frame->size); } static void att_write_rsp(const struct l2cap_frame *frame) @@ -553,20 +722,49 @@ static void att_execute_write_req(const struct l2cap_frame *frame) print_field("Flags: %s (0x%02x)", flags_str, flags); } +static void print_notify(const struct l2cap_frame *frame, uint16_t handle, + size_t len) +{ + struct gatt_db_attribute *attr; + struct gatt_handler *handler; + + print_handle(frame, handle, true); + print_hex_field(" Data", frame->data, len); + + if (len > frame->size) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + attr = get_attribute(frame, handle, true); + if (!attr) + return; + + handler = get_handler(attr); + if (!handler) + return; + + handler->notify(frame); +} + static void att_handle_value_notify(const struct l2cap_frame *frame) { + uint16_t handle; const struct bt_l2cap_att_handle_value_notify *pdu = frame->data; - print_handle(frame, le16_to_cpu(pdu->handle), true); - print_hex_field(" Data", frame->data + 2, frame->size - 2); + l2cap_frame_pull((void *)frame, frame, sizeof(*pdu)); + + handle = le16_to_cpu(pdu->handle); + print_notify(frame, handle, frame->size); } static void att_handle_value_ind(const struct l2cap_frame *frame) { const struct bt_l2cap_att_handle_value_ind *pdu = frame->data; - print_handle(frame, le16_to_cpu(pdu->handle), true); - print_hex_field(" Data", frame->data + 2, frame->size - 2); + l2cap_frame_pull((void *)frame, frame, sizeof(*pdu)); + + print_notify(frame, le16_to_cpu(pdu->handle), frame->size); } static void att_handle_value_conf(const struct l2cap_frame *frame) @@ -591,13 +789,7 @@ static void att_multiple_vl_rsp(const struct l2cap_frame *frame) print_field("Length: 0x%4.4x", len); - print_hex_field(" Data", f->data, - len < f->size ? len : f->size); - - if (len > f->size) { - print_text(COLOR_ERROR, "invalid size"); - return; - } + print_notify(frame, handle, len); l2cap_frame_pull(f, f, len); } @@ -605,14 +797,27 @@ static void att_multiple_vl_rsp(const struct l2cap_frame *frame) static void att_write_command(const struct l2cap_frame *frame) { - print_handle(frame, get_le16(frame->data), false); - print_hex_field(" Data", frame->data + 2, frame->size - 2); + uint16_t handle; + + if (!l2cap_frame_get_le16((void *)frame, &handle)) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + print_write(frame, handle, frame->size); } static void att_signed_write_command(const struct l2cap_frame *frame) { - print_handle(frame, get_le16(frame->data), false); - print_hex_field(" Data", frame->data + 2, frame->size - 2 - 12); + uint16_t handle; + + if (!l2cap_frame_get_le16((void *)frame, &handle)) { + print_text(COLOR_ERROR, "invalid size"); + return; + } + + print_write(frame, handle, frame->size - 12); + print_hex_field(" Data", frame->data, frame->size - 12); print_hex_field(" Signature", frame->data + frame->size - 12, 12); }