Add the MGMT quality report command and event in doc/mgmt-api.txt.
---
Changes in v6:
- No update in this patch. The patch 3/8 is updated to resolve a
patch conflict.
Changes in v5:
- Use Quality_Report instead of Action in mgmt-api.txt.
- Modify the description of Set Quality Report Command.
Changes in v4:
- Use "Quality Report Event" without the prefix "Bluetooth" word.
- Combine both MGMT quality report command and event changes in a
single patch.
Changes in v3:
- Swap AOSP Bluetooth Quality Report Event and Intel Telemetry Event.
- Add 5 new patches (5/9 - 9/9) to enable the quality report
feature via MGMT_OP_SET_QUALITY_REPORT instead of through the
experimental features.
Changes in v2:
- This is a new patch for adding the event in doc/mgmt-api.txt
doc/mgmt-api.txt | 60 ++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 60 insertions(+)
diff --git a/doc/mgmt-api.txt b/doc/mgmt-api.txt
index ebe56afa4..a429f0ef3 100644
--- a/doc/mgmt-api.txt
+++ b/doc/mgmt-api.txt
@@ -332,6 +332,7 @@ Read Controller Information Command
15 Static Address
16 PHY Configuration
17 Wideband Speech
+ 18 Quality Report
This command generates a Command Complete event on success or
a Command Status event on failure.
@@ -2924,6 +2925,7 @@ Read Extended Controller Information Command
15 Static Address
16 PHY Configuration
17 Wideband Speech
+ 18 Quality Report
The EIR_Data field contains information about class of device,
local name and other values. Not all of them might be present. For
@@ -3858,6 +3860,45 @@ Add Advertisement Patterns Monitor With RSSI Threshold Command
Invalid Parameters
+Set Quality Report Command
+==========================
+
+ Command Code: 0x0057
+ Controller Index: <controller id>
+ Command Parameters: Quality_Report (1 Octet)
+ Return Parameters: Current_Settings (4 Octets)
+
+ This command is used to enable and disable the controller's quality
+ report feature. The allowed values for the Quality_Report command
+ parameter are 0x00 and 0x01. All other values will return Invalid
+ Parameters.
+
+ The value 0x00 disables the Quality Report, and the value 0x01
+ enables the Quality Report feature.
+
+ This command is only available for the controllers that support
+ either AOSP Bluetooth quality report or Intel telemetry event.
+ It is supported if the supported_settings indicate support for it.
+
+ This command requires to use a valid controller index. Otherwise,
+ an Invalid Index status will be returned.
+
+ The command is sent to the controller to enable/disable the quality
+ report feature, and generates a Command Complete event on success.
+ If the controller failed to execute the action, a Failed status will
+ be returned.
+
+ The quality report state is maintained by the kernel over the adapter
+ power cycle. When the adapter is powered off, the quality report
+ feature is disabled by the kernel. When the adapter is powered on, it
+ is enabled again by the kernel if it was enabled before.
+
+ Possible errors: Failed
+ Invalid Index
+ Invalid Parameters
+ Not Supported
+
+
Command Complete Event
======================
@@ -4978,3 +5019,22 @@ Advertisement Monitor Device Lost Event
2 LE Random
This event will be sent to all management sockets.
+
+
+Quality Report Event
+====================
+
+ Event code: 0x0031
+ Controller Index: <controller_id>
+ Event Parameters: Quality_Spec (1 Octet)
+ Report_Len (2 Octets)
+ Report (0-65535 Octets)
+
+ This event carries the Bluetooth quality report sent by the
+ controller.
+
+ Possible values for the Quality_Spec parameter:
+ 0 AOSP Bluetooth Quality Report Event
+ 1 Intel Telemetry Event
+
+ This event will be sent to all management sockets.
--
2.36.1.124.g0e6072fb45-goog
This patch adds the missing decodings of MGMT commands to
btmon --todo.
---
(no changes since v4)
Changes in v4:
- This is a new patch that adds the missing decodings of MGMT commands.
monitor/packet.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/monitor/packet.c b/monitor/packet.c
index 851296ee6..c26a80110 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -15237,4 +15237,13 @@ void packet_todo(void)
printf("\t%s\n", le_meta_event_table[i].str);
}
+
+ printf("MGMT commands with missing decodings:\n");
+
+ for (i = 0; mgmt_command_table[i].str; i++) {
+ if (mgmt_command_table[i].func)
+ continue;
+
+ printf("\t%s\n", mgmt_command_table[i].str);
+ }
}
--
2.36.1.124.g0e6072fb45-goog
The quality report feature is now enabled through
MGMT_OP_SET_QUALITY_REPORT instead of through the experimental
features.
---
Changes in v6:
- Fixed a patch conflict.
Changes in v5:
- Move is_quality_report_supported() implementation to next patch.
The function does not belong to this patch.
Changes in v4:
- Move forward this patch in the patch series so that this
command patch is prior to the quality report event patches.
Changes in v3:
- This is a new patch that enables the quality report feature via
MGMT_OP_SET_QUALITY_REPORT.
src/adapter.c | 14 --------------
src/adapter.h | 1 -
2 files changed, 15 deletions(-)
diff --git a/src/adapter.c b/src/adapter.c
index f7faaa263..2ceea6e1c 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -120,13 +120,6 @@ static const struct mgmt_exp_uuid le_simult_central_peripheral_uuid = {
.str = "671b10b5-42c0-4696-9227-eb28d1b049d6"
};
-/* 330859bc-7506-492d-9370-9a6f0614037f */
-static const struct mgmt_exp_uuid quality_report_uuid = {
- .val = { 0x7f, 0x03, 0x14, 0x06, 0x6f, 0x9a, 0x70, 0x93,
- 0x2d, 0x49, 0x06, 0x75, 0xbc, 0x59, 0x08, 0x33 },
- .str = "330859bc-7506-492d-9370-9a6f0614037f"
-};
-
/* 15c0a148-c273-11ea-b3de-0242ac130004 */
static const struct mgmt_exp_uuid rpa_resolution_uuid = {
.val = { 0x04, 0x00, 0x13, 0xac, 0x42, 0x02, 0xde, 0xb3,
@@ -9621,12 +9614,6 @@ static void le_simult_central_peripheral_func(struct btd_adapter *adapter,
(void *)le_simult_central_peripheral_uuid.val);
}
-static void quality_report_func(struct btd_adapter *adapter, uint8_t action)
-{
- if (action)
- queue_push_tail(adapter->exps, (void *)quality_report_uuid.val);
-}
-
static void set_rpa_resolution_complete(uint8_t status, uint16_t len,
const void *param, void *user_data)
{
@@ -9703,7 +9690,6 @@ static const struct exp_feat {
EXP_FEAT(EXP_FEAT_DEBUG, &debug_uuid, exp_debug_func),
EXP_FEAT(EXP_FEAT_LE_SIMULT_ROLES, &le_simult_central_peripheral_uuid,
le_simult_central_peripheral_func),
- EXP_FEAT(EXP_FEAT_BQR, &quality_report_uuid, quality_report_func),
EXP_FEAT(EXP_FEAT_RPA_RESOLUTION, &rpa_resolution_uuid,
rpa_resolution_func),
EXP_FEAT(EXP_FEAT_CODEC_OFFLOAD, &codec_offload_uuid,
diff --git a/src/adapter.h b/src/adapter.h
index 688ed51c6..3d53a962d 100644
--- a/src/adapter.h
+++ b/src/adapter.h
@@ -257,7 +257,6 @@ bool btd_le_connect_before_pairing(void);
enum experimental_features {
EXP_FEAT_DEBUG = 1 << 0,
EXP_FEAT_LE_SIMULT_ROLES = 1 << 1,
- EXP_FEAT_BQR = 1 << 2,
EXP_FEAT_RPA_RESOLUTION = 1 << 3,
EXP_FEAT_CODEC_OFFLOAD = 1 << 4,
};
--
2.36.1.124.g0e6072fb45-goog
The set quality report feature becomes a mgmt command and
is not included in the experimental features any more.
---
(no changes since v5)
Changes in v5:
- Use quality_report instead of action in cmd_exp_quality().
Changes in v4:
- Add "quality-report" in settings_str.
- Print current_settings in quality_rsp.
Changes in v3:
- This is a new patch that fixes the quality on/off command in
btmgmt.
tools/btmgmt.c | 34 ++++++++++++++++++----------------
1 file changed, 18 insertions(+), 16 deletions(-)
diff --git a/tools/btmgmt.c b/tools/btmgmt.c
index 8f63f12ba..bab67e63b 100644
--- a/tools/btmgmt.c
+++ b/tools/btmgmt.c
@@ -353,6 +353,7 @@ static const char *settings_str[] = {
"static-addr",
"phy-configuration",
"wide-band-speech",
+ "quality-report",
};
static const char *settings2str(uint32_t settings)
@@ -1842,26 +1843,28 @@ static void cmd_exp_privacy(int argc, char **argv)
}
}
-static void exp_quality_rsp(uint8_t status, uint16_t len, const void *param,
+static void quality_rsp(uint8_t status, uint16_t len, const void *param,
void *user_data)
{
- if (status != 0)
+ const struct mgmt_rp_set_quality_report *rp = param;
+ uint32_t current_settings;
+
+ if (status != 0) {
error("Set Quality Report feature failed: 0x%02x (%s)",
status, mgmt_errstr(status));
- else
- print("Quality Report feature successfully set");
+ return bt_shell_noninteractive_quit(EXIT_FAILURE);
+ }
+
+ current_settings = le32_to_cpu(rp->current_settings);
+ print("Quality Report feature successfully set");
+ print("\tcurrent settings: %s", settings2str(current_settings));
bt_shell_noninteractive_quit(EXIT_SUCCESS);
}
static void cmd_exp_quality(int argc, char **argv)
{
- /* 330859bc-7506-492d-9370-9a6f0614037f */
- static const uint8_t uuid[16] = {
- 0x7f, 0x03, 0x14, 0x06, 0x6f, 0x9a, 0x70, 0x93,
- 0x2d, 0x49, 0x06, 0x75, 0xbc, 0x59, 0x08, 0x33,
- };
- struct mgmt_cp_set_exp_feature cp;
+ struct mgmt_cp_set_quality_report cp;
uint8_t val;
if (mgmt_index == MGMT_INDEX_NONE) {
@@ -1878,11 +1881,10 @@ static void cmd_exp_quality(int argc, char **argv)
}
memset(&cp, 0, sizeof(cp));
- memcpy(cp.uuid, uuid, 16);
- cp.action = val;
+ cp.quality_report = val;
- if (mgmt_send(mgmt, MGMT_OP_SET_EXP_FEATURE, mgmt_index,
- sizeof(cp), &cp, exp_quality_rsp, NULL, NULL) == 0) {
+ if (mgmt_send(mgmt, MGMT_OP_SET_QUALITY_REPORT, mgmt_index,
+ sizeof(cp), &cp, quality_rsp, NULL, NULL) == 0) {
error("Unable to send quality report feature cmd");
return bt_shell_noninteractive_quit(EXIT_FAILURE);
}
@@ -5636,10 +5638,10 @@ static const struct bt_shell_menu main_menu = {
cmd_exp_debug, "Set debug feature" },
{ "exp-privacy", "<on/off>",
cmd_exp_privacy, "Set LL privacy feature" },
- { "exp-quality", "<on/off>", cmd_exp_quality,
- "Set bluetooth quality report feature" },
{ "exp-offload", "<on/off>",
cmd_exp_offload_codecs, "Toggle codec support" },
+ { "quality", "<on/off>",
+ cmd_exp_quality, "Set bluetooth quality report feature" },
{ "read-sysconfig", NULL,
cmd_read_sysconfig, "Read System Configuration" },
{ "set-sysconfig", "<-v|-h> [options...]",
--
2.36.1.124.g0e6072fb45-goog
This is automated email and please do not reply to this email!
Dear submitter,
Thank you for submitting the patches to the linux bluetooth mailing list.
This is a CI test results with your patch series:
PW Link:https://patchwork.kernel.org/project/bluetooth/list/?series=645249
---Test result---
Test Summary:
CheckPatch PASS 8.83 seconds
GitLint FAIL 5.88 seconds
Prep - Setup ELL PASS 43.76 seconds
Build - Prep PASS 0.56 seconds
Build - Configure PASS 8.53 seconds
Build - Make PASS 1334.80 seconds
Make Check PASS 11.63 seconds
Make Check w/Valgrind PASS 458.89 seconds
Make Distcheck PASS 239.06 seconds
Build w/ext ELL - Configure PASS 8.89 seconds
Build w/ext ELL - Make PASS 1320.90 seconds
Incremental Build with patchesPASS 10678.68 seconds
Details
##############################
Test: GitLint - FAIL
Desc: Run gitlint with rule in .gitlint
Output:
[BlueZ,v6,2/8] lib: Add structures and constants for quality report command and event
1: T1 Title exceeds max length (85>80): "[BlueZ,v6,2/8] lib: Add structures and constants for quality report command and event"
---
Regards,
Linux Bluetooth
This patch prints the set quality command properly.
---
(no changes since v4)
Changes in v4:
- Use get_u8() to replace *(uint8_t *).
- Use mgmt_new_settings_rsp as the rsp_func in mgmt_command_table
for Set Quality Report.
Changes in v3:
- This is a new patch that prints the set quality command.
monitor/packet.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/monitor/packet.c b/monitor/packet.c
index e854c1a8e..851296ee6 100644
--- a/monitor/packet.c
+++ b/monitor/packet.c
@@ -12552,6 +12552,7 @@ static const struct bitfield_data mgmt_settings_table[] = {
{ 15, "Static Address" },
{ 16, "PHY Configuration" },
{ 17, "Wideband Speech" },
+ { 18, "Quality Report" },
{ }
};
@@ -14148,6 +14149,13 @@ static void mgmt_remove_adv_monitor_patterns_rsp(const void *data,
print_field("Handle: %d", handle);
}
+static void mgmt_set_quality_report_cmd(const void *data, uint16_t size)
+{
+ uint8_t action = get_u8(data);
+
+ print_field("Set Quality Report %u", action);
+}
+
struct mgmt_data {
uint16_t opcode;
const char *str;
@@ -14405,6 +14413,9 @@ static const struct mgmt_data mgmt_command_table[] = {
mgmt_add_adv_monitor_patterns_rssi_cmd, 8,
false,
mgmt_add_adv_monitor_patterns_rsp, 2, true},
+ { 0x0057, "Set Quality Report",
+ mgmt_set_quality_report_cmd, 1, true,
+ mgmt_new_settings_rsp, 4, true },
{ }
};
--
2.36.1.124.g0e6072fb45-goog
This patch supports a new MGMT event of Intel telemetry report.
Reviewed-by: Archie Pusaka <[email protected]>
---
(no changes since v5)
Changes in v5:
- Remove signed-off-by for user space.
- Re: "I wonder why you do not use subevent->attr as an
union?" My reply: The subevent->attr is a pointer that points to the
actual target attribute in either intel_acl_event or intel_sco_event
(both of which are combined as a union in intel_ext_telemetry_event).
In this way, we do not need to define the subevent functions for
the subevents and save lots of code.
- Re: "Is the cast really needed here?"
My reply: Yes, it is needed. Otherwise, we got a warning:
"incompatible pointer types [-Wincompatible-pointer-types]"
- Declare "const uint8_t data[];" in struct mgmt_ev_quality_report
for ev->data in lib/mgmt.h.
- In quality_set_debug(), call intel_set_debug() and aosp_set_debug()
for both specifications.
- Do not use the circular inclusion protection for src/shared/intel.h
Changes in v4:
- Change QUALITY_SPEC_INTEL_TELEMETRY to QUALITY_SPEC_INTEL.
Changes in v2:
- Remove the event printing function. The btmon decoding
patches are ready and will be submitted after these
are accepted.
Makefile.am | 3 +-
src/adapter.c | 5 +
src/shared/intel.c | 243 +++++++++++++++++++++++++++++++++++++++++++++
src/shared/intel.h | 150 ++++++++++++++++++++++++++++
4 files changed, 400 insertions(+), 1 deletion(-)
create mode 100644 src/shared/intel.c
create mode 100644 src/shared/intel.h
diff --git a/Makefile.am b/Makefile.am
index e7b07d345..f644d56a4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -231,7 +231,8 @@ shared_sources = src/shared/io.h src/shared/timeout.h \
src/shared/gap.h src/shared/gap.c \
src/shared/log.h src/shared/log.c \
src/shared/tty.h \
- src/shared/aosp.h src/shared/aosp.c
+ src/shared/aosp.h src/shared/aosp.c \
+ src/shared/intel.h src/shared/intel.c
if READLINE
shared_sources += src/shared/shell.c src/shared/shell.h
diff --git a/src/adapter.c b/src/adapter.c
index 8a8aca715..7dbad7b43 100644
--- a/src/adapter.c
+++ b/src/adapter.c
@@ -48,6 +48,7 @@
#include "src/shared/gatt-db.h"
#include "src/shared/timeout.h"
#include "src/shared/aosp.h"
+#include "src/shared/intel.h"
#include "btio/btio.h"
#include "btd.h"
@@ -9212,6 +9213,9 @@ static void quality_report_callback(uint16_t index, uint16_t length,
if (ev->quality_spec == QUALITY_SPEC_AOSP) {
if (!process_aosp_quality_report(ev))
error("processing aosp quality report");
+ } else if (ev->quality_spec == QUALITY_SPEC_INTEL) {
+ if (!process_intel_telemetry_report(ev))
+ error("processing intel telemetry report");
} else {
error("quality report spec %u not supported.",
ev->quality_spec);
@@ -9802,6 +9806,7 @@ static void quality_report_debug(const char *str, void *user_data)
static void quality_set_debug(struct btd_adapter *adapter)
{
+ intel_set_debug(quality_report_debug, "quality: ");
aosp_set_debug(quality_report_debug, "quality: ");
}
diff --git a/src/shared/intel.c b/src/shared/intel.c
new file mode 100644
index 000000000..5d7c0d0ad
--- /dev/null
+++ b/src/shared/intel.c
@@ -0,0 +1,243 @@
+// SPDX-License-Identifier: LGPL-2.1-or-later
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2021 Google LLC
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <string.h>
+
+#include "lib/bluetooth.h"
+#include "lib/mgmt.h"
+
+#include "src/shared/intel.h"
+#include "src/shared/util.h"
+
+#define COMPANY_ID_INTEL 0x0002
+
+struct intel_ext_telemetry_event tev;
+
+static struct {
+ intel_debug_func_t callback;
+ void *data;
+} intel_debug;
+
+/* Use offsetof to access the attributes of structures. This makes
+ * simple traversing and assigning values to the attributes.
+ */
+#define TELEM_OFFSET(a) offsetof(struct intel_ext_telemetry_event, a)
+#define TELEM_ATTR(a) (((uint8_t *)&tev) + TELEM_OFFSET(a))
+
+#define ACL_OFFSET(a) offsetof(struct intel_acl_event, a)
+#define ACL_ATTR(a) (((uint8_t *)&tev.conn.acl) + ACL_OFFSET(a))
+#define ACL_ATTR_ARRAY(a, i) (ACL_ATTR(a) + i * sizeof(tev.conn.acl.a[0]))
+
+#define SCO_OFFSET(a) offsetof(struct intel_sco_event, a)
+#define SCO_ATTR(a) (((uint8_t *)&tev.conn.sco) + SCO_OFFSET(a))
+
+static const struct intel_ext_subevent {
+ uint8_t id;
+ uint8_t size;
+ uint8_t elements;
+ uint8_t *attr; /* address of the attribute in tev */
+} intel_ext_subevent_table[] = {
+ { 0x01, 1, 1, TELEM_ATTR(telemetry_ev_type) },
+
+ /* ACL audio link quality subevents */
+ { 0x4a, 2, 1, ACL_ATTR(conn_handle) },
+ { 0x4b, 4, 1, ACL_ATTR(rx_hec_error) },
+ { 0x4c, 4, 1, ACL_ATTR(rx_crc_error) },
+ { 0x4d, 4, 1, ACL_ATTR(packets_from_host) },
+ { 0x4e, 4, 1, ACL_ATTR(tx_packets) },
+ { 0x4f, 4, 1, ACL_ATTR_ARRAY(tx_packets_retry, 0) },
+ { 0x50, 4, 1, ACL_ATTR_ARRAY(tx_packets_retry, 1) },
+ { 0x51, 4, 1, ACL_ATTR_ARRAY(tx_packets_retry, 2) },
+ { 0x52, 4, 1, ACL_ATTR_ARRAY(tx_packets_retry, 3) },
+ { 0x53, 4, 1, ACL_ATTR_ARRAY(tx_packets_retry, 4) },
+ { 0x54, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 0) },
+ { 0x55, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 1) },
+ { 0x56, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 2) },
+ { 0x57, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 3) },
+ { 0x58, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 4) },
+ { 0x59, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 5) },
+ { 0x5a, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 6) },
+ { 0x5b, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 7) },
+ { 0x5c, 4, 1, ACL_ATTR_ARRAY(tx_packets_by_type, 8) },
+ { 0x5d, 4, 1, ACL_ATTR(rx_packets) },
+ { 0x5e, 4, 1, ACL_ATTR(link_throughput) },
+ { 0x5f, 4, 1, ACL_ATTR(max_packet_letency) },
+ { 0x60, 4, 1, ACL_ATTR(avg_packet_letency) },
+
+ /* SCO/eSCO audio link quality subevents */
+ { 0x6a, 2, 1, SCO_ATTR(conn_handle) },
+ { 0x6b, 4, 1, SCO_ATTR(packets_from_host) },
+ { 0x6c, 4, 1, SCO_ATTR(tx_packets) },
+ { 0x6d, 4, 1, SCO_ATTR(rx_payload_lost) },
+ { 0x6e, 4, 1, SCO_ATTR(tx_payload_lost) },
+ { 0x6f, 4, 5, SCO_ATTR(rx_no_sync_error) },
+ { 0x70, 4, 5, SCO_ATTR(rx_hec_error) },
+ { 0x71, 4, 5, SCO_ATTR(rx_crc_error) },
+ { 0x72, 4, 5, SCO_ATTR(rx_nak_error) },
+ { 0x73, 4, 5, SCO_ATTR(tx_failed_wifi_coex) },
+ { 0x74, 4, 5, SCO_ATTR(rx_failed_wifi_coex) },
+ { 0x75, 4, 1, SCO_ATTR(samples_inserted_by_CDC) },
+ { 0x76, 4, 1, SCO_ATTR(samples_dropped) },
+ { 0x77, 4, 1, SCO_ATTR(mute_samples) },
+ { 0x78, 4, 1, SCO_ATTR(plc_injection) },
+
+ /* end */
+ { 0x0, 0, 0 }
+};
+
+bool is_manufacturer_intel(uint16_t manufacturer)
+{
+ return manufacturer == COMPANY_ID_INTEL;
+}
+
+void intel_set_debug(intel_debug_func_t callback, void *user_data)
+{
+ intel_debug.callback = callback;
+ intel_debug.data = user_data;
+}
+
+static const struct intel_tlv *process_ext_subevent(
+ struct intel_ext_telemetry_event *tev,
+ const struct intel_tlv *tlv,
+ const struct intel_tlv *last_tlv)
+{
+ const struct intel_tlv *next_tlv = NEXT_TLV(tlv);
+ const struct intel_ext_subevent *subevent = NULL;
+ int i;
+
+ for (i = 0; intel_ext_subevent_table[i].size > 0; i++) {
+ if (intel_ext_subevent_table[i].id == tlv->id) {
+ subevent = &intel_ext_subevent_table[i];
+ break;
+ }
+ }
+
+ if (!subevent) {
+ util_debug(intel_debug.callback, intel_debug.data,
+ "error: unknown Intel telemetry subevent 0x%2.2x",
+ tlv->id);
+ return NULL;
+ }
+
+ if (tlv->length != subevent->size * subevent->elements) {
+ util_debug(intel_debug.callback, intel_debug.data,
+ "error: invalid length %d of subevent 0x%2.2x",
+ tlv->length, tlv->id);
+ return NULL;
+ }
+
+ if (next_tlv > last_tlv) {
+ util_debug(intel_debug.callback, intel_debug.data,
+ "error: subevent 0x%2.2x exceeds the buffer size.",
+ tlv->id);
+ return NULL;
+ }
+
+ /* Assign tlv value to the corresponding attribute of acl/sco struct. */
+ switch (subevent->size) {
+ case 1:
+ *subevent->attr = get_u8(tlv->value);
+ break;
+
+ case 2:
+ *((uint16_t *)subevent->attr) = get_le16(tlv->value);
+ break;
+
+ case 4:
+ if (subevent->elements == 1) {
+ *((uint32_t *)subevent->attr) = get_le32(tlv->value);
+ break;
+ }
+
+ for (i = 0; i < subevent->elements; i++) {
+ /* Both acl and sco structs are __packed such that
+ * the addresses of array elements can be calculated.
+ */
+ *((uint32_t *)(subevent->attr + i * subevent->size)) =
+ get_le32((uint32_t *)tlv->value + i);
+ }
+ break;
+
+ default:
+ util_debug(intel_debug.callback, intel_debug.data,
+ "error: subevent id %u: size %u not supported",
+ subevent->id, subevent->size);
+ break;
+
+ }
+
+ switch (subevent->id) {
+ case EXT_EVT_TYPE:
+ /* Only interested in the LINK_QUALITY_REPORT type for now. */
+ if (*subevent->attr != LINK_QUALITY_REPORT)
+ return NULL;
+ break;
+
+ case ACL_CONNECTION_HANDLE:
+ tev->link_type = TELEMETRY_ACL_LINK;
+ break;
+
+ case SCO_CONNECTION_HANDLE:
+ tev->link_type = TELEMETRY_SCO_LINK;
+ break;
+
+ default:
+ break;
+ }
+
+ return next_tlv;
+}
+
+struct intel_telemetry_data {
+ uint16_t vendor_prefix;
+ uint8_t code;
+ uint8_t data[]; /* a number of struct intel_tlv subevents */
+} __packed;
+
+bool process_intel_telemetry_report(const struct mgmt_ev_quality_report *ev)
+{
+ struct intel_telemetry_data *telemetry =
+ (struct intel_telemetry_data *)ev->data;
+
+ /* The telemetry->data points to a number of consecutive tlv.*/
+ const struct intel_tlv *tlv = (const struct intel_tlv *)telemetry->data;
+ const struct intel_tlv *last_tlv =
+ (const struct intel_tlv *)(ev->data + ev->data_len);
+
+ if (telemetry->code != 0x03) {
+ util_debug(intel_debug.callback, intel_debug.data,
+ "error: %u not Intel telemetry sub-opcode",
+ telemetry->code);
+ return false;
+ }
+
+ /* Read every tlv subevent into tev.
+ * The decoding process terminates normally when tlv == last_tlv.
+ */
+ memset(&tev, 0, sizeof(tev));
+ while (tlv && tlv < last_tlv)
+ tlv = process_ext_subevent(&tev, tlv, last_tlv);
+
+ /* If the decoding completes successfully, tlv would be non-NULL */
+ return !!tlv;
+}
diff --git a/src/shared/intel.h b/src/shared/intel.h
new file mode 100644
index 000000000..f1c5729ef
--- /dev/null
+++ b/src/shared/intel.h
@@ -0,0 +1,150 @@
+/* SPDX-License-Identifier: LGPL-2.1-or-later */
+/*
+ *
+ * BlueZ - Bluetooth protocol stack for Linux
+ *
+ * Copyright (C) 2021 Google LLC
+ *
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ */
+
+#include <stdbool.h>
+
+struct mgmt_ev_quality_report;
+
+enum intel_telemetry_event_type {
+ SYSTEM_EXCEPTION,
+ FATAL_EXCEPTION,
+ DEBUG_EXCEPTION,
+ CONNECTION_EVENT,
+ DISCONNECTION_EVENT,
+ LINK_QUALITY_REPORT,
+};
+
+enum intel_telemetry_link_type {
+ TELEMETRY_UNKNOWN_LINK,
+ TELEMETRY_ACL_LINK,
+ TELEMETRY_SCO_LINK,
+};
+
+/* The subevent indices of the complete list of Intel telemetry subevents. */
+enum intel_subevt_list {
+ EXT_EVT_TYPE = 0x01,
+
+ ACL_CONNECTION_HANDLE = 0x4a,
+ ACL_HEC_ERRORS,
+ ACL_CRC_ERRORS,
+ ACL_PACKETS_FROM_HOST,
+ ACL_TX_PACKETS_TO_AIR,
+ ACL_TX_PACKETS_0_RETRY,
+ ACL_TX_PACKETS_1_RETRY,
+ ACL_TX_PACKETS_2_RETRY,
+ ACL_TX_PACKETS_3_RETRY,
+ ACL_TX_PACKETS_MORE_RETRY,
+ ACL_TX_PACKETS_DH1,
+ ACL_TX_PACKETS_DH3,
+ ACL_TX_PACKETS_DH5,
+ ACL_TX_PACKETS_2DH1,
+ ACL_TX_PACKETS_2DH3,
+ ACL_TX_PACKETS_2DH5,
+ ACL_TX_PACKETS_3DH1,
+ ACL_TX_PACKETS_3DH3,
+ ACL_TX_PACKETS_3DH5,
+ ACL_RX_PACKETS,
+ ACL_LINK_THROUGHPUT,
+ ACL_MAX_PACKET_LATENCY,
+ ACL_AVG_PACKET_LATENCY,
+
+ SCO_CONNECTION_HANDLE = 0x6a,
+ SCO_RX_PACKETS,
+ SCO_TX_PACKETS,
+ SCO_RX_PACKETS_LOST,
+ SCO_TX_PACKETS_LOST,
+ SCO_RX_NO_SYNC_ERROR,
+ SCO_RX_HEC_ERROR,
+ SCO_RX_CRC_ERROR,
+ SCO_RX_NAK_ERROR,
+ SCO_TX_FAILED_BY_WIFI,
+ SCO_RX_FAILED_BY_WIFI,
+ SCO_SAMPLES_INSERTED,
+ SCO_SAMPLES_DROPPED,
+ SCO_MUTE_SAMPLES,
+ SCO_PLC_INJECTION_DATA,
+};
+
+#define INTEL_NUM_SLOTS 5
+#define INTEL_NUM_RETRIES 5
+#define INTEL_NUM_PACKET_TYPES 9
+
+/* An Intel telemetry subevent is of the TLV format.
+ * - id: takes 1 byte. This is the subevent id.
+ * - length: takes 1 byte.
+ * - value: takes |length| bytes.
+ */
+struct intel_tlv {
+ uint8_t id;
+ uint8_t length;
+ uint8_t value[0];
+};
+
+#define TLV_SIZE(tlv) (*((const uint8_t *) tlv + 1) + 2 * sizeof(uint8_t))
+#define NEXT_TLV(tlv) ((const struct intel_tlv *)\
+ ((const uint8_t *)tlv + TLV_SIZE(tlv)))
+
+struct intel_acl_event {
+ uint16_t conn_handle;
+ uint32_t rx_hec_error;
+ uint32_t rx_crc_error;
+ uint32_t packets_from_host;
+ uint32_t tx_packets;
+ uint32_t tx_packets_retry[INTEL_NUM_RETRIES];
+ uint32_t tx_packets_by_type[INTEL_NUM_PACKET_TYPES];
+ uint32_t rx_packets;
+ uint32_t link_throughput;
+ uint32_t max_packet_letency;
+ uint32_t avg_packet_letency;
+} __packed;
+
+struct intel_sco_event {
+ uint16_t conn_handle;
+ uint32_t packets_from_host;
+ uint32_t tx_packets;
+ uint32_t rx_payload_lost;
+ uint32_t tx_payload_lost;
+ uint32_t rx_no_sync_error[INTEL_NUM_SLOTS];
+ uint32_t rx_hec_error[INTEL_NUM_SLOTS];
+ uint32_t rx_crc_error[INTEL_NUM_SLOTS];
+ uint32_t rx_nak_error[INTEL_NUM_SLOTS];
+ uint32_t tx_failed_wifi_coex[INTEL_NUM_SLOTS];
+ uint32_t rx_failed_wifi_coex[INTEL_NUM_SLOTS];
+ uint32_t samples_inserted_by_CDC;
+ uint32_t samples_dropped;
+ uint32_t mute_samples;
+ uint32_t plc_injection;
+} __packed;
+
+struct intel_ext_telemetry_event {
+ uint8_t telemetry_ev_type; /* one in enum intel_telemetry_event_type */
+ uint8_t link_type;
+ union {
+ struct intel_sco_event sco;
+ struct intel_acl_event acl;
+ } conn;
+} __packed;
+
+typedef void (*intel_debug_func_t)(const char *str, void *user_data);
+
+bool is_manufacturer_intel(uint16_t manufacturer);
+void intel_set_debug(intel_debug_func_t callback, void *user_data);
+
+bool process_intel_telemetry_report(const struct mgmt_ev_quality_report *ev);
--
2.36.1.124.g0e6072fb45-goog
Add the new MGMT struct and constants to lib/mgmt.h.
---
(no changes since v5)
Changes in v5:
- Use quality_report instead of action in struct
mgmt_cp_set_quality_report.
- Declare "const uint8_t data[];"
Changes in v4:
- Combine both MGMT command and event changes in a single patch.
- Fix namings of QUALITY_SPEC_AOSP and QUALITY_SPEC_INTEL.
- Use "Quality Report" without the prefix "Bluetooth".
Changes in v3:
- Swap AOSP Bluetooth Quality Report Event and Intel Telemetry Event.
Changes in v2:
- This is a new patch for adding the new struct and constants.
lib/mgmt.h | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
diff --git a/lib/mgmt.h b/lib/mgmt.h
index 922a24367..fd59ef6fa 100644
--- a/lib/mgmt.h
+++ b/lib/mgmt.h
@@ -96,6 +96,7 @@ struct mgmt_rp_read_index_list {
#define MGMT_SETTING_STATIC_ADDRESS 0x00008000
#define MGMT_SETTING_PHY_CONFIGURATION 0x00010000
#define MGMT_SETTING_WIDEBAND_SPEECH 0x00020000
+#define MGMT_SETTING_QUALITY_REPORT 0x00040000
#define MGMT_OP_READ_INFO 0x0004
struct mgmt_rp_read_info {
@@ -757,6 +758,14 @@ struct mgmt_cp_add_adv_patterns_monitor_rssi {
struct mgmt_adv_pattern patterns[0];
} __packed;
+#define MGMT_OP_SET_QUALITY_REPORT 0x0057
+struct mgmt_cp_set_quality_report {
+ uint8_t quality_report;
+} __packed;
+struct mgmt_rp_set_quality_report {
+ uint32_t current_settings;
+} __packed;
+
#define MGMT_EV_CMD_COMPLETE 0x0001
struct mgmt_ev_cmd_complete {
uint16_t opcode;
@@ -1032,6 +1041,15 @@ struct mgmt_ev_adv_monitor_device_lost {
struct mgmt_addr_info addr;
} __packed;
+#define MGMT_EV_QUALITY_REPORT 0x0031
+#define QUALITY_SPEC_AOSP 0x0
+#define QUALITY_SPEC_INTEL 0x1
+struct mgmt_ev_quality_report {
+ uint8_t quality_spec;
+ uint32_t data_len;
+ const uint8_t data[];
+} __packed;
+
static const char *mgmt_op[] = {
"<0x0000>",
"Read Version",
@@ -1172,6 +1190,7 @@ static const char *mgmt_ev[] = {
"Controller Resume",
"Advertisement Monitor Device Found", /* 0x002f */
"Advertisement Monitor Device Lost",
+ "Quality Report", /* 0x0031 */
};
static const char *mgmt_status[] = {
--
2.36.1.124.g0e6072fb45-goog
Hello:
This series was applied to bluetooth/bluez.git (master)
by Marcel Holtmann <[email protected]>:
On Thu, 26 May 2022 19:24:49 +0800 you wrote:
> Add the MGMT quality report command and event in doc/mgmt-api.txt.
>
> ---
>
> Changes in v6:
> - No update in this patch. The patch 3/8 is updated to resolve a
> patch conflict.
>
> [...]
Here is the summary with links:
- [BlueZ,v6,1/8] doc: Introduce the quality report command and event
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=93850c827d54
- [BlueZ,v6,2/8] lib: Add structures and constants for quality report command and event
(no matching commit)
- [BlueZ,v6,3/8] adapter: remove quality report from experimental features
(no matching commit)
- [BlueZ,v6,4/8] adapter: support AOSP MGMT_EV_QUALITY_REPORT
(no matching commit)
- [BlueZ,v6,5/8] adapter: support Intel MGMT_EV_QUALITY_REPORT
(no matching commit)
- [BlueZ,v6,6/8] tools/btmgmt: fix quality report command
(no matching commit)
- [BlueZ,v6,7/8] monitor: print quality report cmd
(no matching commit)
- [BlueZ,v6,8/8] monitor: packet: add missing decodings of MGMT commands to todo
(no matching commit)
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
Hi Marcel:
Do you mean to apply the first patch in the series or to apply the 8
patches in the whole series?
It seems that only the first patch was applied in
https://git.kernel.org/pub/scm/bluetooth/bluez.git
Just would like to confirm with you. Thanks!
Regards,
Joseph
On Fri, Jun 3, 2022 at 12:00 AM <[email protected]> wrote:
>
> Hello:
>
> This series was applied to bluetooth/bluez.git (master)
> by Marcel Holtmann <[email protected]>:
>
> On Thu, 26 May 2022 19:24:49 +0800 you wrote:
> > Add the MGMT quality report command and event in doc/mgmt-api.txt.
> >
> > ---
> >
> > Changes in v6:
> > - No update in this patch. The patch 3/8 is updated to resolve a
> > patch conflict.
> >
> > [...]
>
> Here is the summary with links:
> - [BlueZ,v6,1/8] doc: Introduce the quality report command and event
> https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=93850c827d54
> - [BlueZ,v6,2/8] lib: Add structures and constants for quality report command and event
> (no matching commit)
> - [BlueZ,v6,3/8] adapter: remove quality report from experimental features
> (no matching commit)
> - [BlueZ,v6,4/8] adapter: support AOSP MGMT_EV_QUALITY_REPORT
> (no matching commit)
> - [BlueZ,v6,5/8] adapter: support Intel MGMT_EV_QUALITY_REPORT
> (no matching commit)
> - [BlueZ,v6,6/8] tools/btmgmt: fix quality report command
> (no matching commit)
> - [BlueZ,v6,7/8] monitor: print quality report cmd
> (no matching commit)
> - [BlueZ,v6,8/8] monitor: packet: add missing decodings of MGMT commands to todo
> (no matching commit)
>
> You are awesome, thank you!
> --
> Deet-doot-dot, I am a bot.
> https://korg.docs.kernel.org/patchwork/pwbot.html
>
>
--
Joseph Shyh-In Hwang
Email: [email protected]