* [PATCH BlueZ v3 2/3] profiles: ranging: Add CS Initiator cmd and evt handling
From: Naga Bhavani Akella @ 2026-06-11 12:00 UTC (permalink / raw)
To: linux-bluetooth
Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg,
Naga Bhavani Akella
In-Reply-To: <20260611120044.1641009-1-naga.akella@oss.qualcomm.com>
Introduce support for LE Channel Sounding (CS)
ranging procedures in the Initiator role by enabling
required HCI command sequencing and event handling.
Add handling of core HCI LE CS commands and events
This enables cs capability discovery, cs configuration
management and execution of CS ranging procedures
in the Initiator role.
---
profiles/ranging/rap.c | 9 +-
profiles/ranging/rap_hci.c | 763 ++++++++++++++++++++++++++++++++-----
2 files changed, 673 insertions(+), 99 deletions(-)
diff --git a/profiles/ranging/rap.c b/profiles/ranging/rap.c
index e0a46a87a..dc57eeda6 100644
--- a/profiles/ranging/rap.c
+++ b/profiles/ranging/rap.c
@@ -418,10 +418,11 @@ static int rap_accept(struct btd_service *service)
DBG("Found conn handle 0x%04X for %s", handle, addr);
DBG("Setting up handle mapping: handle=0x%04X",
handle);
- bt_rap_set_conn_handle(data->hci_sm,
- data->rap, handle,
- (const uint8_t *) bdaddr,
- bdaddr_type);
+ bt_rap_set_conn_hndl(data->hci_sm,
+ data->rap, handle,
+ (const uint8_t *) bdaddr,
+ bdaddr_type,
+ btd_device_is_initiator(device));
} else {
error("Failed to find connection handle for device %s",
addr);
diff --git a/profiles/ranging/rap_hci.c b/profiles/ranging/rap_hci.c
index febe23384..c0784502e 100644
--- a/profiles/ranging/rap_hci.c
+++ b/profiles/ranging/rap_hci.c
@@ -16,11 +16,13 @@
#include <unistd.h>
#include <string.h>
#include <endian.h>
+#include <time.h>
#include "lib/bluetooth/bluetooth.h"
#include "src/shared/util.h"
#include "src/shared/queue.h"
#include "src/shared/rap.h"
+#include "src/shared/att.h"
#include "src/log.h"
#include "monitor/bt.h"
@@ -67,6 +69,7 @@ struct cs_state_machine {
struct bt_rap_hci_cs_options cs_opt; /* Per-instance CS options */
uint8_t role_enable; /* Role value for HCI commands (1, 2, or 3) */
struct queue *conn_mappings; /* Per-instance connection mappings */
+ struct timespec last_chan_class_time; /* For 1-second rate limit */
};
/* Connection Handle Mapping */
@@ -74,10 +77,18 @@ struct rap_conn_mapping {
uint16_t handle;
uint8_t bdaddr[6];
uint8_t bdaddr_type;
+ bool is_central; /* true if local device is BLE Central on this link */
struct bt_att *att;
struct bt_rap *rap;
};
+/* Function declarations */
+static bool bt_rap_read_remote_fae_table(void *hci_sm, uint16_t handle);
+static void rap_send_hci_cs_create_config_command(struct cs_state_machine *sm,
+ uint16_t handle);
+static bool bt_rap_read_remote_supported_capabilities(void *hci_sm,
+ uint16_t handle);
+
/* Connection Mapping Helper Functions */
static void mapping_free(void *data)
{
@@ -97,14 +108,6 @@ static bool match_mapping_handle(const void *a, const void *b)
return mapping->handle == handle;
}
-static bool match_mapping_rap(const void *a, const void *b)
-{
- const struct rap_conn_mapping *mapping = a;
- const struct bt_rap *rap = b;
-
- return mapping->rap == rap;
-}
-
static struct rap_conn_mapping *find_mapping_by_handle(
struct cs_state_machine *sm,
uint16_t handle)
@@ -118,19 +121,14 @@ static struct rap_conn_mapping *find_mapping_by_handle(
static bool add_conn_mapping(struct cs_state_machine *sm, uint16_t handle,
const uint8_t *bdaddr, uint8_t bdaddr_type,
- struct bt_att *att, struct bt_rap *rap)
+ bool is_central, struct bt_att *att,
+ struct bt_rap *rap)
{
struct rap_conn_mapping *mapping;
if (!sm)
return false;
- if (!sm->conn_mappings) {
- sm->conn_mappings = queue_new();
- if (!sm->conn_mappings)
- return false;
- }
-
/* Check if mapping already exists */
mapping = find_mapping_by_handle(sm, handle);
if (mapping) {
@@ -138,6 +136,7 @@ static bool add_conn_mapping(struct cs_state_machine *sm, uint16_t handle,
if (bdaddr)
memcpy(mapping->bdaddr, bdaddr, 6);
mapping->bdaddr_type = bdaddr_type;
+ mapping->is_central = is_central;
mapping->att = att;
mapping->rap = rap;
return true;
@@ -152,6 +151,7 @@ static bool add_conn_mapping(struct cs_state_machine *sm, uint16_t handle,
if (bdaddr)
memcpy(mapping->bdaddr, bdaddr, 6);
mapping->bdaddr_type = bdaddr_type;
+ mapping->is_central = is_central;
mapping->att = att;
mapping->rap = rap;
@@ -171,13 +171,28 @@ static void remove_conn_mapping(struct cs_state_machine *sm, uint16_t handle)
mapping_free(mapping);
}
-static void remove_rap_mappings(struct cs_state_machine *sm)
+static struct bt_rap *resolve_handle_to_rap(struct cs_state_machine *sm,
+ uint16_t handle)
{
- if (!sm || !sm->conn_mappings)
- return;
+ struct rap_conn_mapping *mapping;
+
+ if (!sm)
+ return NULL;
+
+ /* Try to find in mapping cache */
+ mapping = find_mapping_by_handle(sm, handle);
+ if (mapping && mapping->rap) {
+ DBG("Found handle 0x%04X in mapping cache", handle);
+ return mapping->rap;
+ }
+
+ /* Profile layer should have called bt_rap_set_conn_handle() during
+ * connection establishment. If we reach here, the mapping was not set.
+ */
+ DBG("No mapping found for handle 0x%04X", handle);
+ DBG("Profile layer should call bt_rap_set_conn_handle() on connect");
- queue_remove_all(sm->conn_mappings, match_mapping_rap, sm->rap,
- mapping_free);
+ return NULL;
}
/* State Machine Functions */
@@ -194,6 +209,7 @@ static void cs_state_machine_init(struct cs_state_machine *sm,
sm->hci = hci;
sm->initiator = false;
sm->procedure_active = false;
+ sm->conn_mappings = queue_new();
/* Store role_enable for HCI commands (1, 2, or 3 from config) */
sm->role_enable = role;
@@ -219,8 +235,8 @@ static void cs_set_state(struct cs_state_machine *sm,
return;
/* Validate state values before array access */
- if (sm->current_state > CS_STATE_UNSPECIFIED ||
- new_state > CS_STATE_UNSPECIFIED) {
+ if ((unsigned int)sm->current_state >= ARRAY_SIZE(state_names) ||
+ (unsigned int)new_state >= ARRAY_SIZE(state_names)) {
error("Invalid state transition attempted");
return;
}
@@ -238,11 +254,85 @@ static enum cs_state cs_get_current_state(struct cs_state_machine *sm)
return sm ? sm->current_state : CS_STATE_UNSPECIFIED;
}
+static bool is_initiator_role(const struct cs_state_machine *sm)
+{
+ return sm->role_enable == 0x01 || sm->role_enable == 0x03;
+}
+
+/* Helper function to send read remote capabilities for all connections */
+static void send_read_remote_cap_for_mapping(void *data, void *user_data)
+{
+ struct rap_conn_mapping *mapping = data;
+ struct cs_state_machine *sm = user_data;
+
+ if (!mapping || !sm)
+ return;
+
+ DBG("Sending read remote capabilities for handle 0x%04X",
+ mapping->handle);
+ bt_rap_read_remote_supported_capabilities(sm, mapping->handle);
+}
+
/* HCI Event Callbacks */
+static void rap_rd_loc_supp_cap_done_cb(const void *data, uint8_t size,
+ void *user_data)
+{
+ const struct bt_hci_rsp_le_cs_rd_loc_supp_cap *rsp;
+ struct cs_state_machine *sm = (struct cs_state_machine *) user_data;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_rsp_le_cs_rd_loc_supp_cap))
+ return;
+
+ DBG("size=0x%02X", size);
+
+ rsp = (const struct bt_hci_rsp_le_cs_rd_loc_supp_cap *) data;
+
+ if (rsp->status != 0) {
+ error("Read Local Supported Capabilities failed: 0x%02X",
+ rsp->status);
+ return;
+ }
+
+ DBG("Local CS Capabilities:");
+ DBG(" Num Config Supported: %u", rsp->num_config_supported);
+ DBG(" Max Consecutive Procedures: %u",
+ rsp->max_consecutive_procedures_supported);
+ DBG(" Num Antennas: %u", rsp->num_antennas_supported);
+ DBG(" Max Antenna Paths: %u", rsp->max_antenna_paths_supported);
+ DBG(" Roles Supported: 0x%02X", rsp->roles_supported);
+ DBG(" Modes Supported: 0x%02X", rsp->modes_supported);
+ DBG(" RTT Capability: 0x%02X", rsp->rtt_capability);
+ DBG(" RTT AA Only N: %u", rsp->rtt_aa_only_n);
+ DBG(" RTT Sounding N: %u", rsp->rtt_sounding_n);
+ DBG(" RTT Random Payload N: %u", rsp->rtt_random_payload_n);
+ DBG(" NADM Sounding Capability: 0x%04X",
+ rsp->nadm_sounding_capability);
+ DBG(" NADM Random Capability: 0x%04X", rsp->nadm_random_capability);
+ DBG(" CS Sync PHYs Supported: 0x%02X", rsp->cs_sync_phys_supported);
+ DBG(" Subfeatures Supported: 0x%04X", rsp->subfeatures_supported);
+ DBG(" T_IP1 Times Supported: 0x%04X", rsp->t_ip1_times_supported);
+ DBG(" T_IP2 Times Supported: 0x%04X", rsp->t_ip2_times_supported);
+ DBG(" T_FCS Times Supported: 0x%04X", rsp->t_fcs_times_supported);
+ DBG(" T_PM Times Supported: 0x%04X", rsp->t_pm_times_supported);
+ DBG(" T_SW Time Supported: %u", rsp->t_sw_time_supported);
+ DBG(" TX SNR Capability: 0x%02X", rsp->tx_snr_capability);
+
+ /* Transition to INIT state before reading remote capabilities */
+ cs_set_state(sm, CS_STATE_INIT);
+
+ /* Send read remote capabilities for all connected devices */
+ if (sm->conn_mappings) {
+ DBG("Sending read remote capabilities for all connections");
+ queue_foreach(sm->conn_mappings,
+ send_read_remote_cap_for_mapping, sm);
+ }
+}
+
static void rap_def_settings_done_cb(const void *data, uint8_t size,
void *user_data)
{
- struct bt_hci_rsp_le_cs_set_def_settings *rp;
+ const struct bt_hci_rsp_le_cs_set_def_settings *rp;
struct cs_state_machine *sm = user_data;
if (!sm || !data || size < sizeof(*rp))
@@ -250,10 +340,11 @@ static void rap_def_settings_done_cb(const void *data, uint8_t size,
DBG("size=0x%02X", size);
- rp = (struct bt_hci_rsp_le_cs_set_def_settings *) data;
+ rp = (const struct bt_hci_rsp_le_cs_set_def_settings *) data;
- if (cs_get_current_state(sm) != CS_STATE_INIT) {
- DBG("Event received in Wrong State!! Expected : CS_STATE_INIT");
+ if (cs_get_current_state(sm) == CS_STATE_STOPPED ||
+ cs_get_current_state(sm) == CS_STATE_UNSPECIFIED) {
+ DBG("Def settings response in terminal state, ignoring");
return;
}
@@ -261,9 +352,13 @@ static void rap_def_settings_done_cb(const void *data, uint8_t size,
/* Success - proceed to configuration */
cs_set_state(sm, CS_STATE_WAIT_CONFIG_CMPLT);
- /* Reflector role */
- DBG("Waiting for CS Config Completed event...");
- /* TODO: Initiator role - Send CS Config complete cmd */
+ /* If role is initiator, send CS Create Config command */
+ if (is_initiator_role(sm)) {
+ rap_send_hci_cs_create_config_command(sm, rp->handle);
+ } else {
+ /* Reflector role */
+ DBG("Reflector role: Waiting for CS Config Completed");
+ }
} else {
/* Error - transition to stopped */
error("CS Set default setting failed with status 0x%02X",
@@ -272,8 +367,196 @@ static void rap_def_settings_done_cb(const void *data, uint8_t size,
}
}
-static void rap_send_hci_def_settings_command(struct cs_state_machine *sm,
+static void rap_send_hci_cs_create_config_command(struct cs_state_machine *sm,
uint16_t handle)
+{
+ struct bt_hci_cmd_le_cs_create_config cmd;
+ unsigned int status;
+
+ uint8_t channel_map[10] = {
+ 0xFC, 0xFF, 0x7F, 0xFC, 0xFF,
+ 0xFF, 0xFF, 0xFF, 0xFF, 0x1F
+ };
+
+ if (!sm || !sm->hci) {
+ error("CS Create Config: sm or hci is null");
+ return;
+ }
+
+ DBG("Sending CS Create Config command for handle 0x%04X", handle);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.handle = cpu_to_le16(handle);
+ cmd.create_context = 1;
+ /* Default values, will change to pick user given values later */
+ cmd.config_id = 0x00;
+ cmd.main_mode_type = 0x01;
+ cmd.sub_mode_type = 0xFF;
+ cmd.min_main_mode_steps = 0x02;
+ cmd.max_main_mode_steps = 0x03;
+ cmd.main_mode_repetition = 0x01;
+ cmd.mode_0_steps = 0x02;
+ cmd.role = 0x00;
+ cmd.rtt_type = 0x00;
+ cmd.cs_sync_phy = 0x01;
+ memcpy(cmd.channel_map, channel_map, 10);
+ cmd.channel_map_repetition = 0x01;
+ cmd.channel_selection_type = 0x00;
+ cmd.ch3c_shape = 0x00;
+ cmd.ch3c_jump = 0x02;
+ cmd.reserved = 0x00;
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_CREATE_CONFIG,
+ &cmd, sizeof(cmd), NULL, sm, NULL);
+
+ if (!status) {
+ error("Failed to send CS Create Config command");
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+
+ DBG("CS Create Config command sent successfully");
+}
+
+static void rap_send_hci_cs_remove_config_command(struct cs_state_machine *sm,
+ uint16_t handle)
+{
+ struct bt_hci_cmd_le_cs_remove_config cmd;
+ unsigned int status;
+
+ if (!sm || !sm->hci) {
+ error("CS Remove Config: sm or hci is null");
+ return;
+ }
+
+ DBG("Sending CS Remove Config command for handle 0x%04X", handle);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.handle = cpu_to_le16(handle);
+ cmd.config_id = 0x00; /* Default config ID */
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_REMOVE_CONFIG,
+ &cmd, sizeof(cmd), NULL, sm, NULL);
+
+ if (!status) {
+ error("Failed to send CS Remove Config command");
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+
+ DBG("CS Remove Config command sent successfully");
+}
+
+static void rap_send_hci_cs_security_enable_command(
+ struct cs_state_machine *sm, uint16_t handle)
+{
+ struct bt_hci_cmd_le_cs_sec_enable cmd;
+ unsigned int status;
+
+ if (!sm || !sm->hci) {
+ error("CS Security Enable: sm or hci is null");
+ return;
+ }
+
+ DBG("Sending CS Security Enable command for handle 0x%04X", handle);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.handle = cpu_to_le16(handle);
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_SEC_ENABLE,
+ &cmd, sizeof(cmd), NULL, sm, NULL);
+
+ if (!status) {
+ error("Failed to send CS Security Enable command");
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+
+ DBG("CS Security Enable command sent successfully");
+}
+
+static bool rap_send_hci_cs_set_procedure_parameters(
+ struct cs_state_machine *sm, uint16_t handle)
+{
+ struct bt_hci_cmd_le_cs_set_proc_params cmd;
+ unsigned int status;
+ uint8_t min_sub_event_len[3] = {
+ 0x00, 0x20, 0x00
+ };
+
+ uint8_t max_sub_event_len[3] = {
+ 0x03, 0x20, 0x00
+ };
+
+ if (!sm || !sm->hci) {
+ error("CS Set Procedure Parameters: sm or hci is null");
+ return false;
+ }
+
+ DBG("Sending CS Set Procedure Parameters for handle 0x%04X", handle);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.handle = cpu_to_le16(handle);
+ /* Default values, will change to pick user given values later */
+ cmd.config_id = 0x00;
+ cmd.max_procedure_len = 0x0640;
+ cmd.min_procedure_interval = 0x1E;
+ cmd.max_procedure_interval = 0x96;
+ cmd.max_procedure_count = 0x00;
+ memcpy(cmd.min_subevent_len, min_sub_event_len, 3);
+ memcpy(cmd.max_subevent_len, max_sub_event_len, 3);
+ cmd.tone_antenna_config_selection = 0x07;
+ cmd.phy = 0x01;
+ cmd.tx_power_delta = 0x80;
+ cmd.preferred_peer_antenna = 0x03;
+ cmd.snr_control_initiator = 0xFF;
+ cmd.snr_control_reflector = 0xFF;
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_SET_PROC_PARAMS,
+ &cmd, sizeof(cmd), NULL, sm, NULL);
+
+ if (!status) {
+ error("Failed to send CS Set Procedure Parameters command");
+ return false;
+ }
+
+ DBG("CS Set Procedure Parameters command sent successfully");
+ return true;
+}
+
+static bool rap_send_hci_cs_procedure_enable(struct cs_state_machine *sm,
+ uint16_t handle,
+ bool enable_proc)
+{
+ struct bt_hci_cmd_le_cs_proc_enable cmd;
+ unsigned int status;
+
+ if (!sm || !sm->hci) {
+ error("CS Procedure Enable: sm or hci is null");
+ return false;
+ }
+
+ DBG("Sending CS Procedure Enable for handle 0x%04X", handle);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.handle = cpu_to_le16(handle);
+ cmd.config_id = 0x00; /* Default config Id */
+ cmd.enable = enable_proc ? 0x01 : 0x00;
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_PROC_ENABLE,
+ &cmd, sizeof(cmd), NULL, sm, NULL);
+
+ if (!status) {
+ error("Failed to send CS Procedure Enable command");
+ return false;
+ }
+
+ DBG("CS Procedure Enable command sent successfully");
+ return true;
+}
+
+static void rap_send_hci_def_settings_command(struct cs_state_machine *sm,
+ const struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *ev)
{
struct bt_hci_cmd_le_cs_set_def_settings cp;
unsigned int status;
@@ -285,8 +568,8 @@ static void rap_send_hci_def_settings_command(struct cs_state_machine *sm,
memset(&cp, 0, sizeof(cp));
- if (handle)
- cp.handle = handle;
+ if (ev->handle)
+ cp.handle = ev->handle;
cp.role_enable = sm->role_enable; /* Use preserved HCI command value */
cp.cs_sync_antenna_selection = sm->cs_opt.cs_sync_ant_sel;
@@ -302,12 +585,93 @@ static void rap_send_hci_def_settings_command(struct cs_state_machine *sm,
error("Failed to send default settings cmd");
}
+static void rap_rd_rem_fae_cmplt_evt(const void *data, uint8_t size,
+ void *user_data)
+{
+ struct cs_state_machine *sm = (struct cs_state_machine *) user_data;
+ const struct bt_hci_evt_le_cs_rd_rem_fae_complete *evt;
+ struct iovec iov;
+ int i;
+
+ if (!sm || !data ||
+ size < sizeof(struct bt_hci_evt_le_cs_rd_rem_fae_complete))
+ return;
+
+ /* Initialize iovec with the event data */
+ iov.iov_base = (void *) data;
+ iov.iov_len = size;
+
+ /* Pull the entire structure at once */
+ evt = util_iov_pull_mem(&iov, sizeof(*evt));
+
+ if (!evt) {
+ error("Failed to pull remote FAE complete struct");
+ return;
+ }
+
+ DBG("status=0x%02X, handle=0x%04X", evt->status, evt->handle);
+
+ /* Check status */
+ if (evt->status != 0) {
+ /* Status 0x11 (Unsupported Feature or Parameter Value) means
+ * the remote has zero FAE, the procedure continues
+ * to the Default Settings step.
+ */
+ if (evt->status == 0x11) {
+ DBG("Remote FAE=0 (No_FAE), proceed to Def Settings");
+ if (is_initiator_role(sm)) {
+ struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete
+ tmp_ev;
+
+ memset(&tmp_ev, 0, sizeof(tmp_ev));
+ tmp_ev.handle = evt->handle;
+ DBG("Initiator: send def settings (No_FAE)");
+ rap_send_hci_def_settings_command(sm, &tmp_ev);
+ } else {
+ DBG("Reflector role: continuing after No_FAE");
+ cs_set_state(sm, CS_STATE_INIT);
+ }
+ return;
+ }
+ error("Remote FAE Table read failed with status 0x%02X",
+ evt->status);
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+
+ DBG("Remote FAE Table received:");
+ for (i = 0; i < 72; i += 8) {
+ DBG(" [%02d-%02d]: %02X %02X %02X %02X %02X %02X %02X %02X",
+ i, i+7,
+ evt->remote_fae_table[i], evt->remote_fae_table[i+1],
+ evt->remote_fae_table[i+2], evt->remote_fae_table[i+3],
+ evt->remote_fae_table[i+4], evt->remote_fae_table[i+5],
+ evt->remote_fae_table[i+6], evt->remote_fae_table[i+7]);
+ }
+
+ /* After receiving FAE Table, send default settings */
+ /* Local capabilities already read before this event */
+ if (is_initiator_role(sm)) {
+ struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete tmp_ev;
+
+ memset(&tmp_ev, 0, sizeof(tmp_ev));
+ tmp_ev.handle = evt->handle;
+ DBG("Initiator role: send def settings after FAE table");
+ rap_send_hci_def_settings_command(sm, &tmp_ev);
+ } else {
+ DBG("Reflector role: Proceeding after FAE Table");
+ cs_set_state(sm, CS_STATE_INIT);
+ }
+}
+
static void rap_rd_rmt_supp_cap_cmplt_evt(const void *data, uint8_t size,
void *user_data)
{
struct cs_state_machine *sm = user_data;
const struct bt_hci_evt_le_cs_rd_rem_supp_cap_complete *evt;
+ struct bt_rap *rap;
struct iovec iov;
+ uint16_t subfeatures_supported;
if (!sm || !data || size < sizeof(*evt))
return;
@@ -334,6 +698,16 @@ static void rap_rd_rmt_supp_cap_cmplt_evt(const void *data, uint8_t size,
return;
}
+ /* Resolve handle to RAP instance */
+ rap = resolve_handle_to_rap(sm, evt->handle);
+
+ if (!rap) {
+ DBG("[WARN] Could not resolve handle 0x%04X to RAP instance",
+ evt->handle);
+ /* Continue with state machine RAP for now */
+ rap = sm->rap;
+ }
+
DBG("num_config=%u, ",
evt->num_config_supported);
DBG("max_consecutive_proc=%u, num_antennas=%u, ",
@@ -343,9 +717,26 @@ static void rap_rd_rmt_supp_cap_cmplt_evt(const void *data, uint8_t size,
evt->max_antenna_paths_supported,
evt->roles_supported,
evt->modes_supported);
+ subfeatures_supported = le16_to_cpu(evt->subfeatures_supported);
+ DBG("subfeatures_supported=0x%04X", subfeatures_supported);
- rap_send_hci_def_settings_command(sm, evt->handle);
- cs_set_state(sm, CS_STATE_INIT);
+ /* Check Bit 1 of subfeatures_supported (0x0002) */
+ if (!(subfeatures_supported & 0x0002)) {
+ DBG("Bit 1 not set, sending Read Remote FAE Table");
+ bt_rap_read_remote_fae_table(sm, evt->handle);
+ return;
+ }
+
+ /* Local capabilities already read before this event */
+ if (is_initiator_role(sm)) {
+ DBG("Initiator role: send def settings cmd for handle 0x%04X",
+ evt->handle);
+ rap_send_hci_def_settings_command(sm, evt);
+ } else {
+ DBG("Reflector role: send def settings cmd");
+ cs_set_state(sm, CS_STATE_INIT);
+ rap_send_hci_def_settings_command(sm, evt);
+ }
}
static void rap_cs_config_cmplt_evt(const void *data, uint8_t size,
@@ -383,8 +774,15 @@ static void rap_cs_config_cmplt_evt(const void *data, uint8_t size,
/* Check status */
if (evt->status != 0) {
- error("Configuration failed with status 0x%02X",
- evt->status);
+ if (evt->action != 0x00) {
+ /* Create/update failed — try to remove the config */
+ error("Configuration failed with status 0x%02X",
+ evt->status);
+ rap_send_hci_cs_remove_config_command(sm, evt->handle);
+ } else {
+ error("CS Config Remove failed with status 0x%02X",
+ evt->status);
+ }
cs_set_state(sm, CS_STATE_STOPPED);
return;
}
@@ -428,12 +826,40 @@ static void rap_cs_config_cmplt_evt(const void *data, uint8_t size,
rap_ev.main_mode_type, rap_ev.sub_mode_type,
rap_ev.role, rap_ev.rtt_type);
+ if (rap_ev.action == 0x00) {
+ cs_set_state(sm, CS_STATE_UNSPECIFIED);
+ DBG("CS Config Removed !!!");
+ bt_rap_hci_cs_config_complete_callback(size, &rap_ev, sm->rap);
+ return;
+ }
/* Success - proceed to Security enable complete */
cs_set_state(sm, CS_STATE_WAIT_SEC_CMPLT);
- /* Reflector role */
- DBG("Waiting for security enable event...");
- /* TODO: Initiator role - Send CS Security enable cmd */
+ /* CS Security Enable may only be issued by the BLE Central */
+ if (rap_ev.role == 0x00) {
+ /* Initiator role */
+ struct rap_conn_mapping *mapping;
+
+ mapping = find_mapping_by_handle(sm, evt->handle);
+ if (!mapping || !mapping->is_central) {
+ error("CS Security Enable skipped: not BLE Central");
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+
+ if (bt_att_get_security(mapping->att, NULL) <
+ BT_ATT_SECURITY_MEDIUM) {
+ error("CS Security Enable skipped: not encrypted");
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+
+ DBG("Central,encrypted: Sending CS Security Enable command");
+ rap_send_hci_cs_security_enable_command(sm, evt->handle);
+ } else {
+ /* Reflector role */
+ DBG("Reflector role: Waiting for security enable event...");
+ }
/* Send callback to RAP Profile */
bt_rap_hci_cs_config_complete_callback(size, &rap_ev, sm->rap);
@@ -486,9 +912,27 @@ static void rap_cs_sec_enable_cmplt_evt(const void *data, uint8_t size,
/* Success - proceed to configuration */
cs_set_state(sm, CS_STATE_WAIT_PROC_CMPLT);
- /* Reflector role */
- DBG("Waiting for CS Proc complete event...");
- /* TODO: Initiator - Send CS Proc Set Parameter and enable */
+ /* Check if role is initiator */
+ if (sm->cs_opt.role == CS_INITIATOR) {
+ DBG("Initiator role: Sending CS Set Procedure Params");
+ if (!rap_send_hci_cs_set_procedure_parameters(
+ sm, handle)) {
+ error("Failed to send CS Set Procedure Params");
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+
+ DBG("Initiator role: Sending CS Procedure Enable");
+ if (!rap_send_hci_cs_procedure_enable(sm, handle,
+ true)) {
+ error("Failed to send CS Procedure Enable");
+ cs_set_state(sm, CS_STATE_STOPPED);
+ return;
+ }
+ } else {
+ // Reflector role
+ DBG("Reflector role: Waiting for CS Proc compl event");
+ }
} else {
/* Error - transition to stopped */
error("Security enable failed with status 0x%02X",
@@ -565,8 +1009,13 @@ static void rap_cs_proc_enable_cmplt_evt(const void *data, uint8_t size,
rap_ev.proc_intrvl);
/* Success - procedure started */
- cs_set_state(sm, CS_STATE_STARTED);
- sm->procedure_active = true;
+ if (rap_ev.state == 0x01) {
+ cs_set_state(sm, CS_STATE_STARTED);
+ sm->procedure_active = true;
+ } else if (rap_ev.state == 0x00) {
+ cs_set_state(sm, CS_STATE_STOPPED);
+ sm->procedure_active = false;
+ }
/* Send callback to RAP Profile */
bt_rap_hci_cs_procedure_enable_complete_callback(size,
@@ -800,6 +1249,54 @@ static void parse_cs_step(struct iovec *iov, struct cs_step_data *step,
}
}
+/*
+ * Handle the common step-parsing tail shared by both subevent result variants.
+ * Fixes truncation (num_steps_reported > CS_MAX_STEPS) by zeroing the step
+ * count and trimming send_len to header_size, matching the abort-status path.
+ */
+static void cs_parse_steps(struct iovec *iov,
+ uint8_t num_steps_reported,
+ uint8_t proc_done_status,
+ uint8_t subevt_done_status,
+ uint8_t abort_reason,
+ uint8_t cs_role, uint8_t cs_rtt_type,
+ uint8_t max_paths,
+ struct cs_step_data *step_data,
+ uint8_t *num_steps_out,
+ size_t *send_len,
+ size_t header_size)
+{
+ uint8_t steps = MIN(num_steps_reported, CS_MAX_STEPS);
+ uint8_t i;
+
+ if (num_steps_reported > CS_MAX_STEPS) {
+ DBG("Too many steps reported: %u (max %u)",
+ num_steps_reported, CS_MAX_STEPS);
+ *num_steps_out = 0;
+ *send_len = header_size;
+ return;
+ }
+
+ if (subevt_done_status == 0xF || proc_done_status == 0xF) {
+ DBG("CS Procedure/Subevent aborted: ");
+ DBG("sub evt status = %d, proc status = %d, reason = %d",
+ subevt_done_status, proc_done_status, abort_reason);
+ /*
+ * Step bytes were never parsed; zero-initialised step_data[]
+ * entries would appear as spurious mode-0 quality=0 steps to
+ * the BCS algorithm. Clear the count so an aborted subevent
+ * carries no fake measurements.
+ */
+ *num_steps_out = 0;
+ *send_len = header_size;
+ return;
+ }
+
+ for (i = 0; i < steps; i++)
+ parse_cs_step(iov, &step_data[i], cs_role, cs_rtt_type,
+ max_paths);
+}
+
static void rap_cs_subevt_result_evt(const void *data, uint8_t size,
void *user_data)
{
@@ -822,7 +1319,6 @@ static void rap_cs_subevt_result_evt(const void *data, uint8_t size,
uint8_t abort_reason;
uint8_t num_ant_paths;
uint8_t num_steps_reported;
- uint8_t i;
if (!sm || !data ||
size < sizeof(struct bt_hci_evt_le_cs_subevent_result))
@@ -883,28 +1379,13 @@ static void rap_cs_subevt_result_evt(const void *data, uint8_t size,
rap_ev->num_ant_paths = num_ant_paths;
rap_ev->num_steps_reported = steps;
- if (num_steps_reported > CS_MAX_STEPS) {
- DBG("Too many steps reported: %u (max %u)",
- num_steps_reported, CS_MAX_STEPS);
- goto send_event;
- }
-
- /* Early exit for error conditions */
- if (rap_ev->subevt_done_status == 0xF ||
- rap_ev->proc_done_status == 0xF) {
- DBG("CS Procedure/Subevent aborted: ");
- DBG("sub evt status = %d, proc status = %d, reason = %d",
- rap_ev->subevt_done_status, rap_ev->proc_done_status,
- rap_ev->abort_reason);
- goto send_event;
- }
+ cs_parse_steps(&iov, num_steps_reported,
+ proc_done_status, subevt_done_status, abort_reason,
+ cs_role, cs_rtt_type, max_paths,
+ rap_ev->step_data, &rap_ev->num_steps_reported,
+ &send_len,
+ offsetof(struct rap_ev_cs_subevent_result, step_data));
- /* Parse interleaved step data from remaining iovec data */
- for (i = 0; i < steps; i++)
- parse_cs_step(&iov, &rap_ev->step_data[i], cs_role, cs_rtt_type,
- max_paths);
-
-send_event:
DBG("CS subevent result processed: %zu bytes, ", send_len);
bt_rap_hci_cs_subevent_result_callback(send_len, rap_ev, sm->rap);
free(rap_ev);
@@ -920,7 +1401,7 @@ static void rap_cs_subevt_result_cont_evt(const void *data, uint8_t size,
uint8_t cs_rtt_type;
uint8_t max_paths;
uint8_t steps;
- size_t send_len = 0;
+ size_t send_len;
uint16_t handle;
uint8_t config_id;
uint8_t proc_done_status;
@@ -928,7 +1409,6 @@ static void rap_cs_subevt_result_cont_evt(const void *data, uint8_t size,
uint8_t abort_reason;
uint8_t num_ant_paths;
uint8_t num_steps_reported;
- uint8_t i;
if (!sm || !data ||
size < sizeof(struct bt_hci_evt_le_cs_subevent_result_continue))
@@ -981,28 +1461,14 @@ static void rap_cs_subevt_result_cont_evt(const void *data, uint8_t size,
rap_ev->num_ant_paths = num_ant_paths;
rap_ev->num_steps_reported = steps;
- if (num_steps_reported > CS_MAX_STEPS) {
- DBG("Too many steps reported: %u (max %u)",
- num_steps_reported, CS_MAX_STEPS);
- goto send_event;
- }
-
- /* Early exit for error conditions */
- if (rap_ev->subevt_done_status == 0xF ||
- rap_ev->proc_done_status == 0xF) {
- DBG("CS Procedure/Subevent aborted: ");
- DBG("sub evt status = %d, proc status = %d, reason = %d",
- rap_ev->subevt_done_status, rap_ev->proc_done_status,
- rap_ev->abort_reason);
- goto send_event;
- }
+ cs_parse_steps(&iov, num_steps_reported,
+ proc_done_status, subevt_done_status, abort_reason,
+ cs_role, cs_rtt_type, max_paths,
+ rap_ev->step_data, &rap_ev->num_steps_reported,
+ &send_len,
+ offsetof(struct rap_ev_cs_subevent_result_cont,
+ step_data));
- /* Parse interleaved step data from remaining iovec data */
- for (i = 0; i < steps; i++)
- parse_cs_step(&iov, &rap_ev->step_data[i], cs_role, cs_rtt_type,
- max_paths);
-
-send_event:
DBG("CS subevent result cont processed: %zu bytes, ", send_len);
bt_rap_hci_cs_subevent_result_cont_callback(send_len, rap_ev, sm->rap);
free(rap_ev);
@@ -1010,6 +1476,96 @@ send_event:
/* Subevent handler function type */
+/* Set Ch Classif cmd handling to be added after DBus support enabled */
+
+static bool bt_rap_read_remote_fae_table(void *hci_sm, uint16_t handle)
+{
+ struct cs_state_machine *sm = hci_sm;
+ struct bt_hci_cmd_le_cs_rd_rem_fae cmd;
+ unsigned int status;
+
+ if (!sm || !sm->hci) {
+ error("Invalid state machine or HCI");
+ return false;
+ }
+
+ DBG("Sending Read Remote FAE Table for handle 0x%04X", handle);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.handle = cpu_to_le16(handle);
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_RD_REM_FAE,
+ &cmd, sizeof(cmd), NULL, sm, NULL);
+
+ if (!status) {
+ error("Failed to send Read Remote FAE Table command");
+ return false;
+ }
+
+ DBG("Read Remote FAE Table command sent successfully");
+ return true;
+}
+
+/* This cmd is used by host to start cs distance measurement procedure
+ * function will be used when user start distance measurement
+ * keeping it unused till DBUS API is added
+ */
+static bool bt_rap_read_local_supported_capabilities(
+ void *hci_sm)
+{
+ struct cs_state_machine *sm = hci_sm;
+ unsigned int status;
+
+ if (!sm || !sm->hci) {
+ error("Invalid state machine or HCI");
+ return false;
+ }
+
+ DBG("Sending Read Local Supported Capabilities command");
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_RD_LOC_SUPP_CAP,
+ NULL, 0, rap_rd_loc_supp_cap_done_cb,
+ sm, NULL);
+
+ if (!status) {
+ error("Failed to send Read Local Supported Capabilities");
+ return false;
+ }
+
+ DBG("Read Local Supported Capabilities command sent successfully");
+ return true;
+}
+
+static bool bt_rap_read_remote_supported_capabilities(void *hci_sm,
+ uint16_t handle)
+{
+ struct cs_state_machine *sm = hci_sm;
+ struct bt_hci_cmd_le_cs_rd_rem_supp_cap cmd;
+ unsigned int status;
+
+ if (!sm || !sm->hci) {
+ error("Invalid state machine or HCI");
+ return false;
+ }
+
+ DBG("Sending Read Remote Supported Capabilities for handle 0x%04X",
+ handle);
+
+ memset(&cmd, 0, sizeof(cmd));
+ cmd.handle = cpu_to_le16(handle);
+
+ status = bt_hci_send(sm->hci, BT_HCI_CMD_LE_CS_RD_REM_SUPP_CAP,
+ &cmd, sizeof(cmd), NULL, sm, NULL);
+
+ if (!status) {
+ error("Failed to send Read Remote Capabilities command");
+ return false;
+ }
+
+ DBG("Read Remote Capabilities command sent successfully");
+ return true;
+}
+
static void unregister_event_id(void *data, void *user_data)
{
struct bt_hci *hci = user_data;
@@ -1040,7 +1596,15 @@ void *bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci,
cs_state_machine_init(sm, rap, hci, role, cs_sync_ant_sel,
max_tx_power);
+ /* place holder, need DBus API to be called */
+ bt_rap_read_local_supported_capabilities(sm);
+
sm->event_ids = queue_new();
+ if (!sm->event_ids) {
+ error("Failed to allocate event_ids queue");
+ free(sm);
+ return NULL;
+ }
/* Register each LE Meta subevent individually */
id = bt_hci_register_subevent(hci,
@@ -1051,6 +1615,15 @@ void *bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci,
queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
+ id = bt_hci_register_subevent(hci,
+ BT_HCI_EVT_LE_CS_RD_REM_FAE_COMPLETE,
+ rap_rd_rem_fae_cmplt_evt, sm, NULL);
+
+ if (!id)
+ goto fail;
+
+ queue_push_tail(sm->event_ids, UINT_TO_PTR(id));
+
id = bt_hci_register_subevent(hci,
BT_HCI_EVT_LE_CS_CONFIG_COMPLETE,
rap_cs_config_cmplt_evt, sm, NULL);
@@ -1100,12 +1673,14 @@ fail:
error("Failed to register hci le meta subevents");
queue_foreach(sm->event_ids, unregister_event_id, hci);
queue_destroy(sm->event_ids, NULL);
+ queue_destroy(sm->conn_mappings, mapping_free);
free(sm);
return NULL;
}
-bool bt_rap_set_conn_handle(void *hci_sm, struct bt_rap *rap, uint16_t handle,
- const uint8_t *bdaddr, uint8_t bdaddr_type)
+bool bt_rap_set_conn_hndl(void *hci_sm, struct bt_rap *rap,
+ uint16_t handle, const uint8_t *bdaddr, uint8_t bdaddr_type,
+ bool is_central)
{
struct cs_state_machine *sm = hci_sm;
struct bt_att *att;
@@ -1124,7 +1699,8 @@ bool bt_rap_set_conn_handle(void *hci_sm, struct bt_rap *rap, uint16_t handle,
bdaddr[2], bdaddr[1], bdaddr[0], bdaddr_type);
}
- return add_conn_mapping(sm, handle, bdaddr, bdaddr_type, att, rap);
+ return add_conn_mapping(sm, handle, bdaddr, bdaddr_type, is_central,
+ att, rap);
}
void bt_rap_clear_conn_handle(void *hci_sm, uint16_t handle)
@@ -1157,9 +1733,6 @@ void bt_rap_detach_hci(struct bt_rap *rap, void *hci_sm)
queue_destroy(sm->event_ids, NULL);
/* Clean up per-instance connection mappings */
- remove_rap_mappings(sm);
-
- /* Destroy the connection mappings queue */
queue_destroy(sm->conn_mappings, mapping_free);
/* Free the state machine */
--
^ permalink raw reply related
* [PATCH BlueZ v3 1/3] shared: rap: Check role before sending CS Sec Enable cmd
From: Naga Bhavani Akella @ 2026-06-11 12:00 UTC (permalink / raw)
To: linux-bluetooth
Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg,
Naga Bhavani Akella
In-Reply-To: <20260611120044.1641009-1-naga.akella@oss.qualcomm.com>
Add the is_central parameter to verify whether
the local role is central before sending
the HCI CS Security Enable command.
---
src/shared/rap.h | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/src/shared/rap.h b/src/shared/rap.h
index d3ced61b1..a5095aa35 100644
--- a/src/shared/rap.h
+++ b/src/shared/rap.h
@@ -212,6 +212,17 @@ void *bt_rap_attach_hci(struct bt_rap *rap, struct bt_hci *hci,
void bt_rap_detach_hci(struct bt_rap *rap, void *hci_sm);
/* Connection handle mapping functions */
+/* Old API preserved as wrapper */
bool bt_rap_set_conn_handle(void *hci_sm, struct bt_rap *rap, uint16_t handle,
- const uint8_t *bdaddr, uint8_t bdaddr_type);
+ const uint8_t *bdaddr, uint8_t bdaddr_type);
+
+bool bt_rap_set_conn_hndl(void *hci_sm,
+ struct bt_rap *rap,
+ uint16_t handle,
+ const uint8_t *bdaddr,
+ uint8_t bdaddr_type,
+ bool is_central);
+
+
+
void bt_rap_clear_conn_handle(void *hci_sm, uint16_t handle);
--
^ permalink raw reply related
* [PATCH BlueZ v3 0/3] Initial Channel Sounding Support for
From: Naga Bhavani Akella @ 2026-06-11 12:00 UTC (permalink / raw)
To: linux-bluetooth
Cc: luiz.dentz, quic_mohamull, quic_hbandi, quic_anubhavg,
Naga Bhavani Akella
This series adds initial LE Channel Sounding (CS) Initiator support by
introducing the required HCI command flow and event handling for CS
procedures.
The changes include
1. Adding an is_central parameter to validate that
current local role is central before issuing
HCI_LE_CS_Security_Enable command.
2. Introduction of initial LE Channel Sounding (CS)
Initiator support by adding required HCI command flow
and event handling for CS capability discovery,
configuration management, and ranging procedures.
Changes in v3:
src/shared/rap.h :
- add wrapper API to prevent compilation issue
Changes in v2:
profiles/ranging/rap_hci.c :
- remove unused bt_rap_set_channel_classification
- remove __maybe_used macro usage
Naga Bhavani Akella (3):
shared: rap: Check role before sending CS Sec Enable cmd
profiles: ranging: Add CS Initiator cmd and evt handling
shared: rap: remove the old wrapper API
profiles/ranging/rap.c | 9 +-
profiles/ranging/rap_hci.c | 763 ++++++++++++++++++++++++++++++++-----
src/shared/rap.h | 11 +-
3 files changed, 682 insertions(+), 101 deletions(-)
--
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-11 11:01 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1093445
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: L2CAP: Fix UAF in channel timeout by holding conn ref
From: Marco Elver @ 2026-06-11 10:32 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Marcel Holtmann, linux-bluetooth, linux-kernel, kasan-dev, stable,
Siwei Zhang, Luiz Augusto von Dentz
In-Reply-To: <CABBYNZKRHj0z6n9kJhOST53tpnbpS1wikgB-sjanZaYdXxNk+w@mail.gmail.com>
On Fri, 5 Jun 2026 at 17:48, Luiz Augusto von Dentz
<luiz.dentz@gmail.com> wrote:
[..]
> While I consider this a much cleaner approach than any the previous,
> perhaps we could go one step further and stop using chan->conn as an
> indiciation that l2cap_chan_del has run/detach l2cap_chan and instead
> perhaps use a flag e.g. FLAG_DEL, that way we can make chan->conn be
> used for reference tracking alone and don't need to introduce yet
> another field for it.
I agree in theory, but this is a larger refactor and needs a careful
audit of every user of conn in conditionals. Haven't had time to look
at that yet.
Thanks,
-- Marco
^ permalink raw reply
* [obexd/map] PushMessage does not expose outgoing MAP handle, causing MNS status events to be dropped
From: J.L. @ 2026-06-11 7:23 UTC (permalink / raw)
To: linux-bluetooth
Hi,
While debugging the BlueZ obexd MAP SMS sending flow, I found a race
condition in the outgoing message path.
When an application sends an SMS through
org.bluez.obex.MessageAccess1.PushMessage(), it only receives a
Transfer1 object. It does not receive the MAP message handle assigned
by the remote MSE. If the phone later reports SendingSuccess /
MessageShift / DeliverySuccess through MNS before obexd has created a
Message1 object for that handle, these events are silently ignored.
As a result, a D-Bus client cannot reliably associate a PushMessage
transfer with the resulting MAP message handle or sent/delivery
status.
Test environment:
- OS: Manjaro Linux rolling
- Kernel: Linux 6.12.91-1-MANJARO x86_64
- BlueZ source baseline: 5.86
- BlueZ source commit: 74770b1fd2be612f9c2cf807db81fcdcc35e6560
- Commit subject: Release 5.86
Problem description:
1. The client calls MessageAccess1.PushMessage().
2. The returned Transfer1 object becomes complete. The message is
accepted by the phone and the phone starts sending it.
3. The phone reports an MNS event such as:
<event type="SendingSuccess"
handle="0400000000008A1C"
folder="telecom/msg/sent"
msg_type="SMS_GSM" />
It may also report MessageShift or DeliverySuccess.
4. However, if obexd has not yet created a Message1 object for this
handle in `map->messages`, SendingSuccess / MessageShift will just
return. No Message1 object is created, and no state change is exposed
to the D-Bus client.
5. The client is left with an unreliable workaround: after PushMessage
completes, immediately call ListMessages("outbox") or
ListMessages("sent") and hope that obexd materializes a Message1
object from the listing result. This is not atomic and still races
with status/folder transitions on the phone side.
Source analysis:
1. The D-Bus API documentation says PushMessage only returns a
Transfer1 object, not the MAP message handle
doc/org.bluez.obex.MessageAccess.rst:179-195
PushMessage(string sourcefile, string folder, dict args) transfers
a bMessage.
The returned object path represents the newly created transfer and
is used to check transfer success/failure.
The documentation does not expose a MAP message handle or define a
way to associate the transfer with a message handle.
2. map.c implements PushMessage as a PUT transfer, with a NULL queue callback
obexd/client/map.c:1829-1851
In push_message():
transfer = obc_transfer_put("x-bt/message", folder, filename,
NULL, 0, &err);
obc_transfer_set_apparam(transfer, apparam);
if (!obc_session_queue(map->session, transfer, NULL, NULL, &err))
goto fail;
return obc_transfer_create_dbus_reply(transfer, message);
There is no MAP-level completion callback here, so there is no
chance to bind the PushMessage result to a MAP handle in
`map->messages`.
map_push_message() only parses the D-Bus arguments and then calls
push_message():
obexd/client/map.c:1944-1980
3. The transfer completion path only updates Transfer1 status;
PushMessage currently has no callback
obexd/client/transfer.c:657-685
xfer_complete() sets the Transfer1 status to complete/error and
invokes the callback only if one exists.
Since PushMessage queues the transfer with a NULL callback, the
MAP layer is not notified that the PUT completed in a way that would
allow it to parse or preserve the resulting MAP handle.
4. The gobex PUT response path does not expose final response
AppParams to the MAP layer
gobex/gobex-transfer.c:181-220
transfer_response() handles GET response bodies, but for PUT it
calls transfer_complete() directly on success. If the remote MSE
returns a message handle or related AppParams in the PUT response,
that information is not currently exposed to obexd/client/map.c.
5. ListMessages lazily creates Message1 objects
obexd/client/map.c:1274-1325
In msg_element(), while parsing a message listing:
handle = strtoull(values[i], NULL, 16);
msg = g_hash_table_lookup(data->messages, &handle);
if (msg == NULL) {
msg = map_msg_create(data, handle, parser->request->folder, NULL);
...
}
map_msg_create() registers org.bluez.obex.Message1 and inserts it
into `data->messages`:
obexd/client/map.c:959-985
This means Message1 creation depends on either a NewMessage event
or a ListMessages result. PushMessage itself does not create the
corresponding Message1.
6. MNS parsing does recognize SendingSuccess / DeliverySuccess /
MessageShift and their handle
obexd/client/map-event.h:13-35
obexd/client/mns.c:151-177
mns.c parses SendingSuccess / DeliverySuccess / MessageShift into
map_event and parses the handle.
7. However, status/folder MNS events require an existing Message1
object, otherwise they are silently dropped
obexd/client/map.c:2075-2093
map_handle_status_changed():
msg = g_hash_table_lookup(map->messages, &event->handle);
if (msg == NULL)
return;
obexd/client/map.c:2095-2116
map_handle_folder_changed():
msg = g_hash_table_lookup(map->messages, &event->handle);
if (!msg)
return;
obexd/client/map.c:2118-2150
map_handle_notification() dispatches SendingSuccess /
DeliverySuccess / MessageShift to these status/folder handlers.
Therefore, if Message1 has not yet been created by NewMessage or
ListMessages, these events are silently ignored.
Race conditions:
1. There is a gap between PushMessage completion and Message1 creation
PushMessage completion only tells the application that the
bMessage has been PUT to the remote MSE.
obexd does not create a Message1 at that point and does not expose
the remote handle to the D-Bus client.
2. MNS events may arrive before the client can run the ListMessages workaround
The phone may send SendingSuccess / MessageShift shortly after the
PUT completes.
If the client has not yet called ListMessages("outbox") or
ListMessages("sent"), obexd has no matching handle in `map->messages`,
so the event is dropped.
3. The ListMessages workaround is not reliable
A client can call ListMessages("outbox") after PushMessage
completes, causing obexd to create Message1 objects from the listing
result.
However, the message may already have moved from outbox to sent,
or the phone-side state may already have changed, so outbox listing
may miss it.
Listing sent instead still does not provide an atomic ordering
guarantee with respect to MNS events.
There is no way for an application to atomically obtain the handle
immediately after PushMessage completion.
Expected behavior:
After PushMessage succeeds, obexd should provide a reliable way for
the D-Bus client to obtain the MAP message handle, or at least ensure
that subsequent MNS status/folder events for that handle are not
dropped just because Message1 has not yet been materialized.
Possible fixes:
1. Create or cache an outgoing message entry when PushMessage completes
If the MAP PUT response provides a message handle, obexd could
create or cache
a handle-indexed outgoing message entry in the PushMessage completion path.
This entry could be exported immediately as org.bluez.obex.Message1, or, if
exposing a partially populated D-Bus object is not desirable, it could first
be kept as an internal-only entry. The important part is that subsequent MNS
events such as SendingSuccess / MessageShift / DeliverySuccess can find the
handle instead of returning early.
With the current map_msg_create() implementation, creating Message1 also
registers the D-Bus object and would make clients observe an
org.freedesktop.DBus.ObjectManager.InterfacesAdded signal for
org.bluez.obex.Message1. If maintainers prefer not to emit InterfacesAdded
at this stage, a separate internal stub/cache path could be added, and the
object could be exported later when enough message metadata is available.
2. Add a D-Bus API that exposes the real MAP message handle and allows
handle-based access
MAP itself already has a handle-based GetMessage operation. BlueZ also
already uses this model internally: org.bluez.obex.Message1.Get() formats
msg->handle and sends an OBEX GET request with type "x-bt/message":
obexd/client/map.c:450-485
snprintf(handle, sizeof(handle), "%" PRIx64, msg->handle);
transfer = obc_transfer_get("x-bt/message", handle,
target_file, &err);
However, the current D-Bus API only exposes Get() on an existing
org.bluez.obex.Message1 object. There is no MessageAccess1 method such as
GetMessageByHandle() or CreateMessageFromHandle(), and MessageAccess1 only
exposes ListMessages() and PushMessage():
obexd/client/map.c:1986-2008
This means a client that already knows the real MAP handle still cannot use
it unless obexd has first materialized a Message1 object through
NewMessage or ListMessages.
A possible API-level fix would be to preserve the MAP-specific response
metadata on the Transfer1 object returned by PushMessage. For example, when
the remote MSE returns a handle or other MAP application parameters for the
pushed message, obexd could expose them as Transfer1 properties, at minimum
with Handle itself, With that, the client can atomically obtain
the real handle from the
PushMessage transfer result, then query or materialize the corresponding
message by handle. Today this is not possible because the handle is not
preserved or exposed after PushMessage completes, so clients are forced to
infer the message by racing ListMessages(folder) against remote status and
folder changes.
Questions:
1. Is this an expected limitation of the current obexd MAP client, or
should this be considered a bug?
2. Which fix direction would be preferred: creating Message1 in the
PushMessage completion path, adding a D-Bus signal?
3. I can provide a redacted btmon capture and the corresponding
MAP-event-report snippets to show the actual event ordering observed
on real devices if needed
Thanks.
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: btintel_pcie: Separate coredump work from RX work
From: Paul Menzel @ 2026-06-11 6:29 UTC (permalink / raw)
To: Kiran K, Ravindra
Cc: linux-bluetooth, ravishankar.srivatsa, chethan.tumkur.narayan,
chandrashekar.devegowda
In-Reply-To: <20260610162544.240444-1-kiran.k@intel.com>
Dear Ravindra, dear Kiran,
Thank you for your patch.
Am 10.06.26 um 18:25 schrieb Kiran K:
> From: Ravindra <ravindra@intel.com>
>
> Sharing a single workqueue between coredump processing and RX
> delays evacuation of RX events while a coredump is in progress.
How big is the delay?
Is the coredump processed on the Bluetooth device?
> The firmware's RX buffers can overflow during that window, leading
> to dropped events. The issue was observed in HID use cases where
> HID reports arrive in bursts and quickly fill the RX path while a
> coredump is being collected.
How big are the RX buffers, and does Linux log an error in this situation?
> Move coredump processing to a dedicated ordered coredump_workqueue
> with its own coredump_work, so coredumps run independently of RX.
> All four coredump trigger sources (FW assert, HW exception, user
> sysfs trigger, and resume-error detection) are switched to this new
> workqueue. Ordering serialises concurrent triggers without blocking
> RX.
Please paste the logs, and please describe the test setup, how to force
a coredump, and then, how the workqueues can be displayed to see it’s
working.
> Signed-off-by: Ravindra <ravindra@intel.com>
> Signed-off-by: Kiran K <kiran.k@intel.com>
> ---
> changes in v2:
> - Fix the race condition reported by Sashiko b/w reset_work() and
> .remove()
>
> drivers/bluetooth/btintel_pcie.c | 102 +++++++++++++++++++++++++------
> drivers/bluetooth/btintel_pcie.h | 5 ++
> 2 files changed, 87 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
> index 52293d19c817..e2f64d42c11c 100644
> --- a/drivers/bluetooth/btintel_pcie.c
> +++ b/drivers/bluetooth/btintel_pcie.c
> @@ -1457,7 +1457,7 @@ static void btintel_pcie_msix_fw_trigger_handler(struct btintel_pcie_data *data)
> if (!test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags))
> data->dmp_hdr.trigger_reason = BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT;
>
> - queue_work(data->workqueue, &data->rx_work);
> + queue_work(data->coredump_workqueue, &data->coredump_work);
> }
>
> static void btintel_pcie_msix_hw_exp_handler(struct btintel_pcie_data *data)
> @@ -1474,16 +1474,21 @@ static void btintel_pcie_msix_hw_exp_handler(struct btintel_pcie_data *data)
> if (!test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags))
> data->dmp_hdr.trigger_reason = BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT;
>
> - queue_work(data->workqueue, &data->rx_work);
> + queue_work(data->coredump_workqueue, &data->coredump_work);
> }
>
> -static void btintel_pcie_rx_work(struct work_struct *work)
> +static void btintel_pcie_coredump_worker(struct work_struct *work)
> {
> struct btintel_pcie_data *data = container_of(work,
> - struct btintel_pcie_data, rx_work);
> - struct sk_buff *skb;
> + struct btintel_pcie_data, coredump_work);
> int err;
>
> + /* hdev is NULL until setup_hdev() succeeds, and is cleared on
> + * teardown after disable_work_sync() drains us; bail in that case.
> + */
> + if (!data->hdev)
> + return;
Excuse my ignorance, but why should the worker not run in this case? Was
the coredump processed?
> +
> if (test_bit(BTINTEL_PCIE_FWTRIGGER_DUMP_INPROGRESS, &data->flags)) {
> err = btintel_pcie_dump_fwtrigger_event(data);
> if (err)
> @@ -1507,6 +1512,13 @@ static void btintel_pcie_rx_work(struct work_struct *work)
> btintel_pcie_read_hwexp(data);
> clear_bit(BTINTEL_PCIE_HWEXP_INPROGRESS, &data->flags);
> }
> +}
> +
> +static void btintel_pcie_rx_work(struct work_struct *work)
> +{
> + struct btintel_pcie_data *data = container_of(work,
> + struct btintel_pcie_data, rx_work);
> + struct sk_buff *skb;
>
> /* Process the sk_buf in queue and send to the HCI layer */
> while ((skb = skb_dequeue(&data->rx_skb_q))) {
> @@ -2181,9 +2193,11 @@ static int btintel_pcie_send_frame(struct hci_dev *hdev,
>
> static void btintel_pcie_release_hdev(struct btintel_pcie_data *data)
> {
> - struct hci_dev *hdev;
> + struct hci_dev *hdev = data->hdev;
> +
> + if (!hdev)
> + return;
>
> - hdev = data->hdev;
> hci_unregister_dev(hdev);
> hci_free_dev(hdev);
> data->hdev = NULL;
> @@ -2603,6 +2617,10 @@ static void btintel_pcie_reset_work(struct work_struct *wk)
> btintel_pcie_synchronize_irqs(data);
>
> flush_work(&data->rx_work);
> + /* Drain any in-flight coredump and block new ones across reset.
> + * Safe from self-deadlock: coredump_work runs on a separate wq.
> + */
> + disable_work_sync(&data->coredump_work);
>
> bt_dev_dbg(data->hdev, "Release bluetooth interface");
> if (data->reset_type == BTINTEL_PCIE_IOSF_PRR_PLDR) {
> @@ -2610,16 +2628,27 @@ static void btintel_pcie_reset_work(struct work_struct *wk)
> * pci_rescan_remove_lock. This mutex serializes against PCI device
> * addition/removal (hotplug), so no device can be added to or
> * removed from the bus list while this code runs.
> + *
> + * device_reprobe() inside btintel_pcie_perform_pldr() destroys
> + * 'data' via .remove(); a fresh probe re-INIT_WORKs the
> + * coredump_work with disable count 0, so we must not call
> + * enable_work() on this path.
> */
> btintel_pcie_perform_pldr(data);
> goto out;
> }
> btintel_pcie_release_hdev(data);
>
> - err = pci_reset_function(pdev);
> + /* Use pci_try_reset_function() rather than pci_reset_function() to
> + * avoid an ABBA deadlock against btintel_pcie_remove(): the PCI core
> + * calls .remove() with device_lock held, and remove() then waits for
> + * this work via cancel_work_sync(); pci_reset_function() would in
> + * turn try to acquire the same device_lock, deadlocking both paths.
> + */
> + err = pci_try_reset_function(pdev);
This is not mentioned in the commit message. Should that be a separate
commit for easier review, and easier backporting to the LTS series?
> if (err) {
> BT_ERR("Failed resetting the pcie device (%d)", err);
> - goto out;
> + goto out_enable;
> }
>
> btintel_pcie_enable_interrupts(data);
> @@ -2629,7 +2658,7 @@ static void btintel_pcie_reset_work(struct work_struct *wk)
> if (err) {
> BT_ERR("Failed to enable bluetooth hardware after reset (%d)",
> err);
> - goto out;
> + goto out_enable;
> }
>
> btintel_pcie_reset_ia(data);
> @@ -2639,8 +2668,15 @@ static void btintel_pcie_reset_work(struct work_struct *wk)
> err = btintel_pcie_setup_hdev(data);
> if (err) {
> BT_ERR("Failed registering hdev (%d)", err);
> - goto out;
> + goto out_enable;
> }
> +
> +out_enable:
> + /* Balance disable_work_sync() above on every exit. Leaving the
> + * counter incremented on a failed reset would permanently disable
> + * coredump_work even after a later successful reset.
> + */
> + enable_work(&data->coredump_work);
> out:
> pci_dev_put(pdev);
> pci_unlock_rescan_remove();
> @@ -2774,7 +2810,6 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data)
> hdev->bus = HCI_PCI;
> hci_set_drvdata(hdev, data);
>
> - data->hdev = hdev;
> SET_HCIDEV_DEV(hdev, &data->pdev->dev);
>
> hdev->manufacturer = 2;
> @@ -2793,15 +2828,17 @@ static int btintel_pcie_setup_hdev(struct btintel_pcie_data *data)
> err = hci_register_dev(hdev);
> if (err < 0) {
> BT_ERR("Failed to register to hdev (%d)", err);
> - goto exit_error;
> + hci_free_dev(hdev);
> + return err;
> }
>
> + /* Publish hdev only after successful registration; the coredump
> + * worker bails on !data->hdev, so it never observes a half-set-up
> + * device.
> + */
> + data->hdev = hdev;
> data->dmp_hdr.driver_name = KBUILD_MODNAME;
> return 0;
> -
> -exit_error:
> - hci_free_dev(hdev);
> - return err;
> }
>
> static int btintel_pcie_probe(struct pci_dev *pdev,
> @@ -2832,9 +2869,16 @@ static int btintel_pcie_probe(struct pci_dev *pdev,
> if (!data->workqueue)
> return -ENOMEM;
>
> + data->coredump_workqueue = alloc_ordered_workqueue(KBUILD_MODNAME "_cd", 0);
> + if (!data->coredump_workqueue) {
> + destroy_workqueue(data->workqueue);
> + return -ENOMEM;
> + }
> +
> skb_queue_head_init(&data->rx_skb_q);
> INIT_WORK(&data->rx_work, btintel_pcie_rx_work);
> INIT_WORK(&data->reset_work, btintel_pcie_reset_work);
> + INIT_WORK(&data->coredump_work, btintel_pcie_coredump_worker);
>
> data->boot_stage_cache = 0x00;
> data->img_resp_cache = 0x00;
> @@ -2877,6 +2921,8 @@ static int btintel_pcie_probe(struct pci_dev *pdev,
> /* reset device before exit */
> btintel_pcie_reset_bt(data);
>
> + destroy_workqueue(data->coredump_workqueue);
> +
> pci_clear_master(pdev);
>
> pci_set_drvdata(pdev, NULL);
> @@ -2894,13 +2940,20 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
> return;
> }
>
> + /* Permanently block coredump triggers and drain the worker before
> + * tearing down. Must run before cancel_work_sync(&reset_work) so
> + * the disable counter stays >= 1 even after reset_work()'s
> + * balanced enable_work() (counter 2 -> 1, never reaching 0).
> + */
> + disable_work_sync(&data->coredump_work);
> +
> /* Cancel pending reset work. Skip only when remove() is called from
> * within the reset work itself (PLDR device_reprobe path) to avoid
> * deadlock. current_work() returns the work_struct of the caller if
> * we are in a workqueue context.
> */
> if (current_work() != &data->reset_work)
> - cancel_work_sync(&data->reset_work);
> + disable_work_sync(&data->reset_work);
>
> btintel_pcie_disable_interrupts(data);
>
> @@ -2920,6 +2973,7 @@ static void btintel_pcie_remove(struct pci_dev *pdev)
>
> btintel_pcie_release_hdev(data);
>
> + destroy_workqueue(data->coredump_workqueue);
> destroy_workqueue(data->workqueue);
>
> btintel_pcie_free(data);
> @@ -2935,11 +2989,19 @@ static void btintel_pcie_coredump(struct device *dev)
> struct pci_dev *pdev = to_pci_dev(dev);
> struct btintel_pcie_data *data = pci_get_drvdata(pdev);
>
> + if (!data)
> + return;
> +
> if (test_and_set_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags))
> return;
>
> data->dmp_hdr.trigger_reason = BTINTEL_PCIE_TRIGGER_REASON_USER_TRIGGER;
> - queue_work(data->workqueue, &data->rx_work);
> + /* queue_work() returns false if the work is disabled (reset or
> + * remove in progress); clear the in-progress bit so a later
> + * trigger can succeed once the work is re-enabled.
> + */
> + if (!queue_work(data->coredump_workqueue, &data->coredump_work))
> + clear_bit(BTINTEL_PCIE_COREDUMP_INPROGRESS, &data->flags);
> }
> #endif
>
> @@ -3080,7 +3142,7 @@ static int btintel_pcie_resume(struct device *dev)
> &data->flags)) {
> data->dmp_hdr.trigger_reason =
> BTINTEL_PCIE_TRIGGER_REASON_FW_ASSERT;
> - queue_work(data->workqueue, &data->rx_work);
> + queue_work(data->coredump_workqueue, &data->coredump_work);
> }
> set_bit(BTINTEL_PCIE_CORE_HALTED, &data->flags);
> btintel_pcie_reset(data->hdev);
> diff --git a/drivers/bluetooth/btintel_pcie.h b/drivers/bluetooth/btintel_pcie.h
> index e4a8fa479188..7caee093e316 100644
> --- a/drivers/bluetooth/btintel_pcie.h
> +++ b/drivers/bluetooth/btintel_pcie.h
> @@ -466,6 +466,8 @@ struct btintel_pcie_dump_header {
> * @workqueue: workqueue for RX work
> * @rx_skb_q: SKB queue for RX packet
> * @rx_work: RX work struct to process the RX packet in @rx_skb_q
> + * @coredump_workqueue: dedicated workqueue for coredump collection
> + * @coredump_work: work struct for coredump trace collection
> * @dma_pool: DMA pool for descriptors, index array and ci
> * @dma_p_addr: DMA address for pool
> * @dma_v_addr: address of pool
> @@ -514,6 +516,9 @@ struct btintel_pcie_data {
> struct work_struct rx_work;
> struct work_struct reset_work;
>
> + struct workqueue_struct *coredump_workqueue;
> + struct work_struct coredump_work;
> +
> struct dma_pool *dma_pool;
> dma_addr_t dma_p_addr;
> void *dma_v_addr;
Kind regards,
Paul
^ permalink raw reply
* Re: [PATCH v2 6/7] arm64: dts: qcom: sm8350: modernize PCIe entries
From: Manivannan Sadhasivam @ 2026-06-11 6:13 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Konrad Dybcio, Qiang Yu, Jeff Johnson,
Liam Girdwood, Mark Brown, Krzysztof Kozlowski, Conor Dooley,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Bjorn Andersson,
Konrad Dybcio, linux-arm-msm, linux-pci, linux-kernel,
linux-wireless, ath11k, devicetree, Bartosz Golaszewski,
linux-bluetooth, Bartosz Golaszewski
In-Reply-To: <20260608-sm8350-wifi-v2-6-efb68f1ff04c@oss.qualcomm.com>
On Mon, Jun 08, 2026 at 09:59:24AM +0300, Dmitry Baryshkov wrote:
> The recent suggestion is to have PERST# / WAKE pins and PHYs in the PCIe
> port rather than RC device. The kernel recently started warning about
> the older style of DT. Modernize DT for SM8350 platform by moving the
> entries under the root port device node.
>
> Reviewed-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
- Mani
> ---
> arch/arm64/boot/dts/qcom/sm8350-hdk.dts | 18 +++++++++++-------
> arch/arm64/boot/dts/qcom/sm8350.dtsi | 12 ++++--------
> 2 files changed, 15 insertions(+), 15 deletions(-)
>
> diff --git a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> index 5f975d009465..4973a3eb11b5 100644
> --- a/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> +++ b/arch/arm64/boot/dts/qcom/sm8350-hdk.dts
> @@ -493,12 +493,14 @@ &pcie0 {
> pinctrl-names = "default";
> pinctrl-0 = <&pcie0_default_state>;
>
> - perst-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
> - wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
> -
> status = "okay";
> };
>
> +&pcie0_port0 {
> + reset-gpios = <&tlmm 94 GPIO_ACTIVE_LOW>;
> + wake-gpios = <&tlmm 96 GPIO_ACTIVE_HIGH>;
> +};
> +
> &pcie0_phy {
> vdda-phy-supply = <&vreg_l5b_0p88>;
> vdda-pll-supply = <&vreg_l6b_1p2>;
> @@ -507,15 +509,17 @@ &pcie0_phy {
> };
>
> &pcie1 {
> - perst-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
> - wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
> -
> - pinctrl-names = "default";
> pinctrl-0 = <&pcie1_default_state>;
> + pinctrl-names = "default";
>
> status = "okay";
> };
>
> +&pcie1_port0 {
> + reset-gpios = <&tlmm 97 GPIO_ACTIVE_LOW>;
> + wake-gpios = <&tlmm 99 GPIO_ACTIVE_HIGH>;
> +};
> +
> &pcie1_phy {
> status = "okay";
> vdda-phy-supply = <&vreg_l5b_0p88>;
> diff --git a/arch/arm64/boot/dts/qcom/sm8350.dtsi b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> index eb2a795d8edb..136daa444865 100644
> --- a/arch/arm64/boot/dts/qcom/sm8350.dtsi
> +++ b/arch/arm64/boot/dts/qcom/sm8350.dtsi
> @@ -1583,12 +1583,9 @@ pcie0: pcie@1c00000 {
>
> power-domains = <&gcc PCIE_0_GDSC>;
>
> - phys = <&pcie0_phy>;
> - phy-names = "pciephy";
> -
> status = "disabled";
>
> - pcie@0 {
> + pcie0_port0: pcie@0 {
> device_type = "pci";
> reg = <0x0 0x0 0x0 0x0 0x0>;
> bus-range = <0x01 0xff>;
> @@ -1596,6 +1593,7 @@ pcie@0 {
> #address-cells = <3>;
> #size-cells = <2>;
> ranges;
> + phys = <&pcie0_phy>;
> };
> };
>
> @@ -1692,12 +1690,9 @@ pcie1: pcie@1c08000 {
>
> power-domains = <&gcc PCIE_1_GDSC>;
>
> - phys = <&pcie1_phy>;
> - phy-names = "pciephy";
> -
> status = "disabled";
>
> - pcie@0 {
> + pcie1_port0: pcie@0 {
> device_type = "pci";
> reg = <0x0 0x0 0x0 0x0 0x0>;
> bus-range = <0x01 0xff>;
> @@ -1705,6 +1700,7 @@ pcie@0 {
> #address-cells = <3>;
> #size-cells = <2>;
> ranges;
> + phys = <&pcie1_phy>;
> };
> };
>
>
> --
> 2.47.3
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v2 1/7] PCI: qcom: fix parsing of PERST# in the legacy case
From: Manivannan Sadhasivam @ 2026-06-11 6:12 UTC (permalink / raw)
To: Dmitry Baryshkov
Cc: Lorenzo Pieralisi, Krzysztof Wilczyński, Rob Herring,
Bjorn Helgaas, Konrad Dybcio, Qiang Yu, Jeff Johnson,
Liam Girdwood, Mark Brown, Krzysztof Kozlowski, Conor Dooley,
Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
Balakrishna Godavarthi, Rocky Liao, Bjorn Andersson,
Konrad Dybcio, linux-arm-msm, linux-pci, linux-kernel,
linux-wireless, ath11k, devicetree, Bartosz Golaszewski,
linux-bluetooth
In-Reply-To: <20260608-sm8350-wifi-v2-1-efb68f1ff04c@oss.qualcomm.com>
On Mon, Jun 08, 2026 at 09:59:19AM +0300, Dmitry Baryshkov wrote:
> Commit deed8aec62dc ("PCI: qcom: Handle mixed PERST#/PHY DT
> configuration") fixed support for the "mixed" platforms which declare
> PERST# pin the RC node and the PHY in the RP node, however it also broke
> support for a majority of existing platforms, which declare both PERST#
> and PHY in the RC node, because now PERST# is first acquired in
> qcom_pcie_parse_ports(), which then returns -ENODEV (as there are no
> PHYs in the RP nodes). Later qcom_pcie_parse_legacy_binding() tries to
> acquire the PERST# GPIO again and fails with -EBUSY (as the GPIO has
> already been requested).
>
> Move parsing of RC's perst-gpios to qcom_pcie_probe(), making it obvious
> that it's shared for both cases and skip parsing it in both functions.
>
> Fixes: deed8aec62dc ("PCI: qcom: Handle mixed PERST#/PHY DT configuration")
> Closes: https://lore.kernel.org/r/gieaybsg2ckxpctvqj77nlwu7utama2yeyvebkonmexsxrra3v@v3fobqasxnmy/
> Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
This issue is fixed now. You can drop this patch in next revision.
- Mani
> ---
> drivers/pci/controller/dwc/pcie-qcom.c | 25 ++++++++++---------------
> 1 file changed, 10 insertions(+), 15 deletions(-)
>
> diff --git a/drivers/pci/controller/dwc/pcie-qcom.c b/drivers/pci/controller/dwc/pcie-qcom.c
> index 11fc60489892..7664c7c28c0e 100644
> --- a/drivers/pci/controller/dwc/pcie-qcom.c
> +++ b/drivers/pci/controller/dwc/pcie-qcom.c
> @@ -1907,15 +1907,6 @@ static int qcom_pcie_parse_ports(struct qcom_pcie *pcie)
> struct device *dev = pcie->pci->dev;
> int ret = -ENODEV;
>
> - if (of_find_property(dev->of_node, "perst-gpios", NULL)) {
> - pcie->reset = devm_gpiod_get_optional(dev, "perst",
> - GPIOD_OUT_HIGH);
> - if (IS_ERR(pcie->reset))
> - return PTR_ERR(pcie->reset);
> -
> - dev_warn(dev, "Reusing PERST# from Root Complex node. DT needs to be fixed!\n");
> - }
> -
> for_each_available_child_of_node_scoped(dev->of_node, of_port) {
> if (!of_node_is_type(of_port, "pci"))
> continue;
> @@ -1942,7 +1933,6 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie)
> struct device *dev = pcie->pci->dev;
> struct qcom_pcie_perst *perst;
> struct qcom_pcie_port *port;
> - struct gpio_desc *reset;
> struct phy *phy;
> int ret;
>
> @@ -1950,10 +1940,6 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie)
> if (IS_ERR(phy))
> return PTR_ERR(phy);
>
> - reset = devm_gpiod_get_optional(dev, "perst", GPIOD_OUT_HIGH);
> - if (IS_ERR(reset))
> - return PTR_ERR(reset);
> -
> ret = phy_init(phy);
> if (ret)
> return ret;
> @@ -1970,7 +1956,7 @@ static int qcom_pcie_parse_legacy_binding(struct qcom_pcie *pcie)
> INIT_LIST_HEAD(&port->list);
> list_add_tail(&port->list, &pcie->ports);
>
> - perst->desc = reset;
> + perst->desc = pcie->reset;
> INIT_LIST_HEAD(&port->perst);
> INIT_LIST_HEAD(&perst->list);
> list_add_tail(&perst->list, &port->perst);
> @@ -2107,6 +2093,15 @@ static int qcom_pcie_probe(struct platform_device *pdev)
>
> pp->ops = &qcom_pcie_dw_ops;
>
> + if (of_find_property(dev->of_node, "perst-gpios", NULL)) {
> + pcie->reset = devm_gpiod_get_optional(dev, "perst",
> + GPIOD_OUT_HIGH);
> + if (IS_ERR(pcie->reset))
> + return PTR_ERR(pcie->reset);
> +
> + dev_warn(dev, "Reusing PERST# from Root Complex node. DT needs to be updated!\n");
> + }
> +
> ret = qcom_pcie_parse_ports(pcie);
> if (ret) {
> if (ret != -ENODEV) {
>
> --
> 2.47.3
>
--
மணிவண்ணன் சதாசிவம்
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: qca: Add BT FW build version to kernel log
From: Xiuzhuo Shang @ 2026-06-11 2:51 UTC (permalink / raw)
To: Paul Menzel
Cc: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
linux-arm-msm, linux-bluetooth, linux-kernel, cheng.jiang,
quic_chezhou, wei.deng, shuai.zhang, mengshi.wu, jinwang.li,
Bartosz Golaszewski
In-Reply-To: <809ea8e8-c95e-4200-8d2f-1a0354cd523c@molgen.mpg.de>
On 6/11/2026 4:54 AM, Paul Menzel wrote:
> Dear Xiuzhuo,
>
>
> Thank you for the patch, which was applied today.
>
> Am 10.06.26 um 08:42 schrieb Xiuzhuo Shang:
>> Firmware version is critical for bug triage. Users reporting issues
>> typically share dmesg output rather than debugfs contents, requiring
>> extra communication rounds to collect this information. Log the FW
>> build version directly to the kernel log so it is immediately
>> available in bug reports.
>>
>> Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
>> Signed-off-by: Xiuzhuo Shang <xiuzhuo.shang@oss.qualcomm.com>
>> ---
>> Example output:
>> Bluetooth: hci0: QCA FW build version: BTFW.MOSELLE.1.1.3-00106-MSL_PATCHZ-1
>
> Please put it in the commit message next time.
>
> Also, just for completeness, could you please paste all the Bluetooth/hci0/QCA logs, so that maybe a more condensed logging format can be found?
Hi,Paul,
Thanks for your suggestion.
root@rb3gen2-core-kit:/# dmesg | grep -iE "bluetooth|hci|wcn|btqca|btfm|rfkill"
[ 5.159228] sdhci_msm 8804000.mmc: Got CD GPIO
[ 5.219919] mmc2: SDHCI controller on 8804000.mmc [8804000.mmc] using ADMA 64-bit
[ 11.806187] ath11k 17a10040.wifi: wcn6750 hw1.0
[ 11.818575] ath11k 17a10040.wifi: wcn6750 hw1.0
[ 11.823714] ath11k 17a10040.wifi: wcn6750 hw1.0
[ 20.284824] pci 0001:04:00.0: xHCI HW not ready after 5 sec (HC bug?) status = 0x801
[ 20.338018] Bluetooth: Core ver 2.22
[ 20.341805] NET: Registered PF_BLUETOOTH protocol family
[ 20.347310] Bluetooth: HCI device and connection manager initialized
[ 20.347327] Bluetooth: HCI socket layer initialized
[ 20.347333] Bluetooth: L2CAP socket layer initialized
[ 20.347352] Bluetooth: SCO socket layer initialized
[ 20.479734] Bluetooth: HCI UART driver ver 2.3
[ 20.496850] Bluetooth: HCI UART protocol H4 registered
[ 20.515949] Bluetooth: HCI UART protocol LL registered
[ 20.516004] Bluetooth: HCI UART protocol QCA registered
[ 20.528204] Bluetooth: hci0: setting up wcn6750
[ 20.699447] Modules linked in: iris_vpu(O+) nf_conntrack audioreach_driver(O) qcom_pbs nf_defrag_ipv6 v4l2_mem2mem videobuf2_v4l2 snd_q6dsp_common qcom_spmi_temp_alarm qcom_spmi_adc_tm5 nf_defrag_ipv4 qcom_spmi_adc5 rtc_pm8xxx qcom_pon nvmem_qcom_spmi_sdam videobuf2_common qcom_vadc_common videodev iptable_filter hci_uart ip_tables btqca gpio_shared_proxy x_tables apr mc msm_kgsl(O+) pwrseq_qcom_wcn videocc_sc7280 phy_qcom_qmp_combo dispcc_sc7280 coresight_stm camcc_sc7280 qcom_refgen_regulator qcom_stats spi_geni_qcom dwc3_qcom usb_f_fs aux_bridge stm_p_basic msm typec gpi phy_qcom_snps_femto_v2 qcom_eud icc_bwmon bluetooth stm_core bridge ubwc_config coresight_cti coresight_tpdm ecdh_generic stp kpp llc overlay ecc libcomposite ath11k_ahb llcc_qcom ath11k snd_soc_lpass_va_macro snd_soc_lpass_wsa_macro ocmem mac80211 qcom_q6v5_pas soundwire_qcom snd_soc_lpass_macro_common coresight_replicator gpu_sched qcom_pil_info libarc4 coresight_tmc qcom_q6v5 drm_gpuvm snd_soc_core snd_compress coresight_etm4x qcom_sysmon
[ 20.791274] coresight_funnel qrtr gpucc_sc7280 qcrypto drm_display_helper snd_pcm qcom_common sha256 snd_timer cec qcom_glink_smem coresight pmic_glink sha1 soundwire_bus lpassaudiocc_sc7280 snd drm_dp_aux_bus mdt_loader libdes pdr_interface pinctrl_sc7280_lpass_lpi cfg80211 drm_client_lib soundcore qcom_pdr_msg authenc pinctrl_lpass_lpi slimbus pci_pwrctrl_tc9563 rfkill icc_osm_l3 socinfo qmi_helpers display_connector drm_kms_helper qcom_rng nvmem_reboot_mode sch_fq_codel fuse
[ 21.170589] xhci-pci-renesas 0001:04:00.0: failed to load firmware renesas_usb_fw.mem: -2
[ 21.213198] xhci-pci-renesas 0001:04:00.0: probe with driver xhci-pci-renesas failed with error -2
[ 22.627369] Bluetooth: hci0: command 0xfc00 tx timeout
[ 22.639919] Bluetooth: hci0: Reading QCA version information failed (-110)
[ 22.652097] Bluetooth: hci0: Retry BT power ON:0
[ 22.706596] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 22.719197] Bluetooth: BNEP filters: protocol multicast
[ 22.719204] Bluetooth: BNEP socket layer initialized
[ 23.123401] Bluetooth: hci0: QCA Product ID :0x00000015
[ 23.132217] Bluetooth: hci0: QCA SOC Version :0x40140110
[ 23.150091] Bluetooth: hci0: QCA ROM Version :0x00000101
[ 23.155714] Bluetooth: hci0: QCA Patch Version:0x000024c7
[ 23.165303] Bluetooth: hci0: QCA controller version 0x01100101
[ 23.172966] Bluetooth: hci0: QCA Downloading qca/msbtfw11.mbn
[ 24.193137] Bluetooth: hci0: QCA Downloading qca/msnv11.bin
[ 24.325620] Bluetooth: hci0: QCA FW build version: BTFW.MOSELLE.1.1.3-00106-MSL_PATCHZ-1
[ 24.335237] Bluetooth: hci0: QCA setup on UART is completed
[ 287.493900] Bluetooth: MGMT ver 1.23
[ 287.498546] Bluetooth: hci0: setting up wcn6750
[ 287.562270] Bluetooth: hci0: QCA Product ID :0x00000015
[ 287.567880] Bluetooth: hci0: QCA SOC Version :0x40140110
[ 287.573507] Bluetooth: hci0: QCA ROM Version :0x00000101
[ 287.579290] Bluetooth: hci0: QCA Patch Version:0x000024c
[ 287.596249] Bluetooth: hci0: QCA controller version 0x01100101
[ 287.602763] Bluetooth: hci0: QCA Downloading qca/msbtfw11.mbn
[ 288.629814] Bluetooth: hci0: QCA Downloading qca/msnv11.bin
[ 288.751030] Bluetooth: hci0: QCA FW build version: BTFW.MOSELLE.1.1.3-00106-MSL_PATCHZ-1
[ 288.759441] Bluetooth: hci0: QCA setup on UART is completed
[ 288.834672] Bluetooth: RFCOMM TTY layer initialized
[ 288.839721] Bluetooth: RFCOMM socket layer initialized
[ 288.845032] Bluetooth: RFCOMM ver 1.11
>
>> drivers/bluetooth/btqca.c | 2 ++
>> 1 file changed, 2 insertions(+)
>>
>> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
>> index dda76365726f..04ebe290bc78 100644
>> --- a/drivers/bluetooth/btqca.c
>> +++ b/drivers/bluetooth/btqca.c
>> @@ -143,6 +143,8 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
>> hci_set_fw_info(hdev, "%s", build_label);
>> + bt_dev_info(hdev, "QCA FW build version: %s", build_label);
>> +
>> kfree(build_label);
>> out:
>> kfree_skb(skb);
>
>
> Kind regards,
>
> Paul
^ permalink raw reply
* Re: [PATCH] Bluetooth: hci_bcm4377: Use named initializers for pci_device_id array
From: Uwe Kleine-König (The Capable Hub) @ 2026-06-10 21:08 UTC (permalink / raw)
To: Luiz Augusto von Dentz
Cc: Sven Peter, Janne Grunau, Neal Gompa, Marcel Holtmann,
Markus Schneider-Pargmann, asahi, linux-arm-kernel,
linux-bluetooth, linux-kernel
In-Reply-To: <CABBYNZKuOdtxa8ksEZM1FyjYJCQ22H6NzaX31t6LcZuvn0LMNg@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 2008 bytes --]
Hello,
On Wed, Jun 10, 2026 at 01:13:44PM -0400, Luiz Augusto von Dentz wrote:
> On Wed, Jun 10, 2026 at 12:59 PM Uwe Kleine-König (The Capable Hub)
> <u.kleine-koenig@baylibre.com> wrote:
> >
> > On Mon, May 04, 2026 at 06:09:40PM +0200, Uwe Kleine-König (The Capable Hub) wrote:
> > > Initializing a struct using list initializers is hard to read, compared
> > > to that using named initializers is more ideomatic. Convert the macro
> > > used to assign values in the driver's pci_device_id array accordingly.
> > >
> > > This change doesn't introduce any changes to the compiled array on an
> > > x86 and an arm64 build.
> > >
> > > Signed-off-by: Uwe Kleine-König (The Capable Hub) <u.kleine-koenig@baylibre.com>
> > > ---
> > > Hello,
> > >
> > > this is a preparing change for making struct pci_device_id::driver_data an
> > > anonymous union (similar to
> > > https://lore.kernel.org/all/cover.1776579304.git.u.kleine-koenig@baylibre.com/).
> > > This requires named initializers for .driver_data. But even without that
> > > this is a nice cleanup making the macro better readable.
> > >
> > > Gcc is happy with simplifying the assignment further using
> > > PCI_VDEVICE(BROADCOM, BCM ## id ## _DEVICE_ID), but this is a bit fishy
> > > because PCI_VDEVICE also assigns .class and .class_mask (using list
> > > initializers), so I didn't convert that.
> >
> > In the meantime I learned that doing that would break W=1 builds, so it
> > was a good choice to not go that path.
> >
> > > Once all pci_device_id use
> > > named initializers, the two zeros can be dropped from PCI_VDEVICE and
> > > this entry simplified accordingly.
> >
> > Is this patch still on someone's radar? Ideally for application in time
> > for 7.2-rc1?
>
> It is no longer in patchwork so if you really want to get in please resend.
Instead I unarchived the patch, so it appears in the patch list again. I
hope this is easier for everyone (it is for me).
Best regards
Uwe
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 488 bytes --]
^ permalink raw reply
* Re: [PATCH v2] Bluetooth: qca: Add BT FW build version to kernel log
From: Paul Menzel @ 2026-06-10 20:54 UTC (permalink / raw)
To: Xiuzhuo Shang
Cc: Bartosz Golaszewski, Marcel Holtmann, Luiz Augusto von Dentz,
linux-arm-msm, linux-bluetooth, linux-kernel, cheng.jiang,
quic_chezhou, wei.deng, shuai.zhang, mengshi.wu, jinwang.li,
Bartosz Golaszewski
In-Reply-To: <20260610064232.2385866-1-xiuzhuo.shang@oss.qualcomm.com>
Dear Xiuzhuo,
Thank you for the patch, which was applied today.
Am 10.06.26 um 08:42 schrieb Xiuzhuo Shang:
> Firmware version is critical for bug triage. Users reporting issues
> typically share dmesg output rather than debugfs contents, requiring
> extra communication rounds to collect this information. Log the FW
> build version directly to the kernel log so it is immediately
> available in bug reports.
>
> Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
> Signed-off-by: Xiuzhuo Shang <xiuzhuo.shang@oss.qualcomm.com>
> ---
> Example output:
> Bluetooth: hci0: QCA FW build version: BTFW.MOSELLE.1.1.3-00106-MSL_PATCHZ-1
Please put it in the commit message next time.
Also, just for completeness, could you please paste all the
Bluetooth/hci0/QCA logs, so that maybe a more condensed logging format
can be found?
> drivers/bluetooth/btqca.c | 2 ++
> 1 file changed, 2 insertions(+)
>
> diff --git a/drivers/bluetooth/btqca.c b/drivers/bluetooth/btqca.c
> index dda76365726f..04ebe290bc78 100644
> --- a/drivers/bluetooth/btqca.c
> +++ b/drivers/bluetooth/btqca.c
> @@ -143,6 +143,8 @@ static int qca_read_fw_build_info(struct hci_dev *hdev)
>
> hci_set_fw_info(hdev, "%s", build_label);
>
> + bt_dev_info(hdev, "QCA FW build version: %s", build_label);
> +
> kfree(build_label);
> out:
> kfree_skb(skb);
Kind regards,
Paul
^ permalink raw reply
* [Bug 221637] Regression for Intel Corporation Device a876 (rev 10)
From: bugzilla-daemon @ 2026-06-10 20:03 UTC (permalink / raw)
To: linux-bluetooth
In-Reply-To: <bug-221637-62941@https.bugzilla.kernel.org/>
https://bugzilla.kernel.org/show_bug.cgi?id=221637
Bianca Fürstenau (furstenau+kernelbugWGvWw1PW1l@posteo.net) changed:
What |Removed |Added
----------------------------------------------------------------------------
Regression|No |Yes
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* [Bug 221637] New: Regression for Intel Corporation Device a876 (rev 10)
From: bugzilla-daemon @ 2026-06-10 19:46 UTC (permalink / raw)
To: linux-bluetooth
https://bugzilla.kernel.org/show_bug.cgi?id=221637
Bug ID: 221637
Summary: Regression for Intel Corporation Device a876 (rev 10)
Product: Drivers
Version: 2.5
Hardware: All
OS: Linux
Status: NEW
Severity: normal
Priority: P3
Component: Bluetooth
Assignee: linux-bluetooth@vger.kernel.org
Reporter: furstenau+kernelbugWGvWw1PW1l@posteo.net
Regression: No
On my Dell Pro 14 Premium PA14250, the Bluetooth works with the firmware
version 20260309, but it regressed to not-working in 20260410 and it has not
been fixed as of 20260519. (Speculation: The firmware is crashing.) Via lspci,
the Bluetooth device is:
00:14.7 Bluetooth: Intel Corporation Device a876 (rev 10)
Two sample outputs of dmesg (first working, second not-working, both on NixOS
with the only configuration difference being the firmware override):
Kernel 7.0.11, Firmware 20260309 $ sudo dmesg | grep -i bluetooth
[ 13.782762] Bluetooth: Core ver 2.22
[ 13.782883] NET: Registered PF_BLUETOOTH protocol family
[ 13.782884] Bluetooth: HCI device and connection manager initialized
[ 13.782886] Bluetooth: HCI socket layer initialized
[ 13.782888] Bluetooth: L2CAP socket layer initialized
[ 13.782892] Bluetooth: SCO socket layer initialized
[ 13.805444] Bluetooth: hci0: Device revision is 0
[ 13.805449] Bluetooth: hci0: Secure boot is enabled
[ 13.805450] Bluetooth: hci0: OTP lock is disabled
[ 13.805450] Bluetooth: hci0: API lock is enabled
[ 13.805451] Bluetooth: hci0: Debug lock is disabled
[ 13.805452] Bluetooth: hci0: Minimum firmware build 1 week 10 2014
[ 13.805453] Bluetooth: hci0: Bootloader timestamp 2023.33 buildtype 1 build
45995
[ 13.806042] Bluetooth: hci0: Found device firmware:
intel/ibt-0190-0291-iml.sfi
[ 13.806046] Bluetooth: hci0: Boot Address: 0x30098800
[ 13.806046] Bluetooth: hci0: Firmware Version: 15-3.26
[ 13.860697] Bluetooth: hci0: Waiting for firmware download to complete
[ 13.860704] Bluetooth: hci0: Firmware loaded in 53377 usecs
[ 13.863006] Bluetooth: hci0: Waiting for device to boot
[ 13.863023] Bluetooth: hci0: Device booted in 2254 usecs
[ 13.863024] Bluetooth: hci0: Waiting for device transition to d0
[ 13.863025] Bluetooth: hci0: Device moved to D0 in 0 usecs
[ 13.863191] Bluetooth: hci0: dsbr: enable: 0x01 value: 0x0b
[ 13.866100] Bluetooth: hci0: Found device firmware:
intel/ibt-0190-0291-pci.sfi
[ 13.866112] Bluetooth: hci0: Boot Address: 0x10000800
[ 13.866113] Bluetooth: hci0: Firmware Version: 15-3.26
[ 14.395735] Bluetooth: hci0: Waiting for firmware download to complete
[ 14.395763] Bluetooth: hci0: Firmware loaded in 517244 usecs
[ 14.433393] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 14.433452] Bluetooth: hci0: Waiting for device to boot
[ 14.433861] Bluetooth: hci0: Device booted in 37190 usecs
[ 14.433862] Bluetooth: hci0: Waiting for device transition to d0
[ 14.433980] Bluetooth: hci0: Device moved to D0 in 115 usecs
[ 14.437701] Bluetooth: hci0: Found Intel DDC parameters:
intel/ibt-0190-0291-pci.ddc
[ 14.437877] Bluetooth: hci0: Applying Intel DDC parameters completed
[ 14.438188] Bluetooth: hci0: Firmware timestamp 2026.3 buildtype 1 build
9743
[ 14.438190] Bluetooth: hci0: Firmware SHA1: 0xd68504ef
[ 14.438460] Bluetooth: hci0: Fseq status: Success (0x00)
[ 14.438463] Bluetooth: hci0: Fseq executed: 00.00.04.202
[ 14.438464] Bluetooth: hci0: Fseq BT Top: 00.00.04.202
[ 15.814470] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 15.814476] Bluetooth: BNEP socket layer initialized
[ 15.815604] Bluetooth: MGMT ver 1.23
[ 28.005710] Bluetooth: RFCOMM TTY layer initialized
[ 28.005717] Bluetooth: RFCOMM socket layer initialized
[ 28.005719] Bluetooth: RFCOMM ver 1.11
Kernel 7.0.11, Firmware 20260519 $ sudo dmesg | grep -i bluetooth
[ 11.552083] Bluetooth: Core ver 2.22
[ 11.552591] NET: Registered PF_BLUETOOTH protocol family
[ 11.552593] Bluetooth: HCI device and connection manager initialized
[ 11.552596] Bluetooth: HCI socket layer initialized
[ 11.552598] Bluetooth: L2CAP socket layer initialized
[ 11.552600] Bluetooth: SCO socket layer initialized
[ 11.586234] Bluetooth: hci0: Device revision is 0
[ 11.586239] Bluetooth: hci0: Secure boot is enabled
[ 11.586239] Bluetooth: hci0: OTP lock is disabled
[ 11.586240] Bluetooth: hci0: API lock is enabled
[ 11.586240] Bluetooth: hci0: Debug lock is disabled
[ 11.586241] Bluetooth: hci0: Minimum firmware build 1 week 10 2014
[ 11.586242] Bluetooth: hci0: Bootloader timestamp 2023.33 buildtype 1 build
45995
[ 11.587640] Bluetooth: hci0: Found device firmware:
intel/ibt-0190-0291-iml.sfi
[ 11.587646] Bluetooth: hci0: Boot Address: 0x30098800
[ 11.587646] Bluetooth: hci0: Firmware Version: 99-13.26
[ 11.647652] Bluetooth: hci0: Waiting for firmware download to complete
[ 11.647659] Bluetooth: hci0: Firmware loaded in 58608 usecs
[ 11.649893] Bluetooth: hci0: Waiting for device to boot
[ 11.649927] Bluetooth: hci0: Device booted in 2205 usecs
[ 11.649927] Bluetooth: hci0: Waiting for device transition to d0
[ 11.649928] Bluetooth: hci0: Device moved to D0 in 0 usecs
[ 11.650058] Bluetooth: hci0: dsbr: enable: 0x01 value: 0x0b
[ 11.653394] Bluetooth: hci0: Found device firmware:
intel/ibt-0190-0291-pci.sfi
[ 11.653410] Bluetooth: hci0: Boot Address: 0x10000800
[ 11.653411] Bluetooth: hci0: Firmware Version: 99-13.26
[ 11.890541] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 11.891227] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 11.909517] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 11.932472] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 11.932823] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 11.937740] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 11.938063] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 12.229448] Bluetooth: hci0: Waiting for firmware download to complete
[ 12.229468] Bluetooth: hci0: Firmware loaded in 562566 usecs
[ 12.264949] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 12.264978] Bluetooth: hci0: Controller in error state
[ 13.444947] Bluetooth: BNEP (Ethernet Emulation) ver 1.3
[ 13.444957] Bluetooth: BNEP socket layer initialized
[ 15.238165] Bluetooth: hci0: Timeout (3000 ms) on alive interrupt, alive
context: intel_reset1
[ 15.238170] Bluetooth: hci0: Failed to send frame (-62)
[ 15.238171] Bluetooth: hci0: sending frame failed (-62)
[ 15.238199] Bluetooth: hci0: Failed to send Intel Reset command
[ 15.238208] Bluetooth: hci0: Intel Soft Reset failed (-62)
[ 15.238211] Bluetooth: hci0: Firmware download retry count: 1
[ 15.277649] Bluetooth: hci0: Device revision is 0
[ 15.277650] Bluetooth: hci0: Secure boot is enabled
[ 15.277651] Bluetooth: hci0: OTP lock is disabled
[ 15.277651] Bluetooth: hci0: API lock is enabled
[ 15.277652] Bluetooth: hci0: Debug lock is disabled
[ 15.277652] Bluetooth: hci0: Minimum firmware build 1 week 10 2014
[ 15.277653] Bluetooth: hci0: Bootloader timestamp 2023.33 buildtype 1 build
45995
[ 15.277855] Bluetooth: hci0: Found device firmware:
intel/ibt-0190-0291-iml.sfi
[ 15.277856] Bluetooth: hci0: Boot Address: 0x30098800
[ 15.277857] Bluetooth: hci0: Firmware Version: 99-13.26
[ 15.331235] Bluetooth: hci0: Waiting for firmware download to complete
[ 15.331248] Bluetooth: hci0: Firmware loaded in 52141 usecs
[ 15.333516] Bluetooth: hci0: Waiting for device to boot
[ 15.333518] Bluetooth: hci0: Device booted in 2200 usecs
[ 15.333519] Bluetooth: hci0: Waiting for device transition to d0
[ 15.333519] Bluetooth: hci0: Device moved to D0 in 0 usecs
[ 15.333705] Bluetooth: hci0: dsbr: enable: 0x01 value: 0x0b
[ 15.336014] Bluetooth: hci0: Found device firmware:
intel/ibt-0190-0291-pci.sfi
[ 15.336025] Bluetooth: hci0: Boot Address: 0x10000800
[ 15.336026] Bluetooth: hci0: Firmware Version: 99-13.26
[ 15.354944] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.381773] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.436473] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.437607] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.478120] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.479335] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.483759] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.487062] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.490408] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.500570] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.506638] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.506756] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.515964] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.517688] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.517933] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.532163] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.532282] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.635134] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.636578] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.636707] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.638224] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.638413] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.642802] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.643026] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.704576] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.704711] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.710823] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.734369] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.734563] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.753238] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.756902] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.757166] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.779988] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.780134] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.782630] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.782757] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.792866] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.952898] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.953061] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.956667] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.957829] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.957963] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.960131] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.960433] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 15.986218] Bluetooth: hci0: Waiting for firmware download to complete
[ 15.986223] Bluetooth: hci0: Firmware loaded in 634965 usecs
[ 16.021756] Bluetooth: hci0: Received gp1 mailbox interrupt
[ 16.021778] Bluetooth: hci0: Controller in error state
[ 19.013291] Bluetooth: hci0: Timeout (3000 ms) on alive interrupt, alive
context: intel_reset1
[ 19.013304] Bluetooth: hci0: Failed to send frame (-62)
[ 19.013307] Bluetooth: hci0: sending frame failed (-62)
[ 19.013333] Bluetooth: hci0: Failed to send Intel Reset command
[ 19.013359] Bluetooth: hci0: Intel Soft Reset failed (-62)
Regression originally reported downstream:
https://github.com/NixOS/nixpkgs/issues/530344
--
You may reply to this email to add a comment.
You are receiving this mail because:
You are the assignee for the bug.
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-10 19:22 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1106927
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-10 19:22 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1108786
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-10 19:22 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1108823
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-10 19:22 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1108826
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-10 19:22 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1108830
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-10 19:22 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1108834
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez]
From: BluezTestBot @ 2026-06-10 19:22 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/1109089
Home: https://github.com/bluez/bluez
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* [bluez/bluez] ea4b49: btio: handle error from broadcast ISO socket
From: Šimon Mikuda @ 2026-06-10 19:21 UTC (permalink / raw)
To: linux-bluetooth
Branch: refs/heads/master
Home: https://github.com/bluez/bluez
Commit: ea4b494414f60beda3cf69aef9278354c07b74f1
https://github.com/bluez/bluez/commit/ea4b494414f60beda3cf69aef9278354c07b74f1
Author: Michal Dzik <michal.dzik@streamunlimited.com>
Date: 2026-06-09 (Tue, 09 Jun 2026)
Changed paths:
M btio/btio.c
Log Message:
-----------
btio: handle error from broadcast ISO socket
If not handled, server_cb() will be stuck in endless loop of calling
accept() on the socket.
Commit: 6ea27ab0dcfc1ac38467d8e88ceccb5784494cb5
https://github.com/bluez/bluez/commit/6ea27ab0dcfc1ac38467d8e88ceccb5784494cb5
Author: Michal Dzik <michal.dzik@streamunlimited.com>
Date: 2026-06-09 (Tue, 09 Jun 2026)
Changed paths:
M profiles/audio/bap.c
Log Message:
-----------
bap: log errors in BIG sync
Commit: 8c580d30d2655f75796c31ca0d496ffd1578cb46
https://github.com/bluez/bluez/commit/8c580d30d2655f75796c31ca0d496ffd1578cb46
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M btio/btio.c
Log Message:
-----------
btio: Handle EOPNOTSUPP from accept() to prevent busy loop
When accept() returns EOPNOTSUPP on an L2CAP SEQPACKET server socket
(e.g. AVCTP browsing channel, PSM 0x1b), the error is permanent and
retrying will never succeed. Previously, only EBADFD was treated as
fatal, causing server_cb to return TRUE for EOPNOTSUPP. Since the fd
remains readable, this creates an infinite busy loop that hangs
bluetoothd.
Treat EOPNOTSUPP the same as EBADFD by returning FALSE to remove the
GLib IO watch and stop the loop.
Commit: abf0911e25ef414f06b895b22a6a9aa05c03360e
https://github.com/bluez/bluez/commit/abf0911e25ef414f06b895b22a6a9aa05c03360e
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M src/profile.c
Log Message:
-----------
profile: Check if bearer is enabled on registration
btd_profile_register now verifies that the profile's bearer type is
compatible with btd_opts.mode before registering. If the required bearer
is not enabled (e.g. LE-only profile when mode is BR/EDR, or BR/EDR-only
profile when mode is LE), registration is rejected with -ENOTSUP.
Commit: 7b5895d8063505798ec5988a4b3bb545834afb1a
https://github.com/bluez/bluez/commit/7b5895d8063505798ec5988a4b3bb545834afb1a
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M profiles/audio/a2dp.c
M profiles/audio/avrcp.c
M profiles/audio/hfp-hf.c
M profiles/audio/micp.c
M profiles/input/manager.c
M profiles/network/manager.c
M src/gatt-database.c
Log Message:
-----------
plugins: Check btd_profile_register return value
Ensure all plugin init functions check the return value of
btd_profile_register. If registration fails (e.g. bearer not enabled),
the plugin init propagates the error instead of continuing with an
unregistered profile.
Commit: 8c821a150b8f5319b8201b5e7d8fdaa6a67d3bd1
https://github.com/bluez/bluez/commit/8c821a150b8f5319b8201b5e7d8fdaa6a67d3bd1
Author: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M src/bearer.c
Log Message:
-----------
bearer: Check btd_opts.mode on btd_bearer_new
Only create the bearer interface if the corresponding transport is
enabled. Return NULL if BREDR bearer is requested in LE-only mode or
LE bearer in BREDR-only mode, so the D-Bus interface is never
registered for unsupported bearers.
Commit: 39ad431de60b896a03904887a0f1d0285b719edd
https://github.com/bluez/bluez/commit/39ad431de60b896a03904887a0f1d0285b719edd
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M profiles/audio/avdtp.c
Log Message:
-----------
avdtp: Return correct error when SEP is inuse
This fixes AVDTP/SNK/ACP/SIG/SMG/BI-08-C
Commit: 249e2bedfacf51fc6c89f43a0adb9a12d761c2b7
https://github.com/bluez/bluez/commit/249e2bedfacf51fc6c89f43a0adb9a12d761c2b7
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M profiles/audio/avrcp.c
Log Message:
-----------
avrcp: Abort continuing response on fragmented CT replies
Send AbortContinuingResponse when a Get Element Attributes reply
arrives fragmented, as the CT side does not reassemble fragments.
Fixes PTS test AVRCP/CT/RCR/BV-03-C
Commit: 2e00b83c07885f960fc0d53568b4ab0091ffb09c
https://github.com/bluez/bluez/commit/2e00b83c07885f960fc0d53568b4ab0091ffb09c
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M src/shared/bap.c
Log Message:
-----------
shared/bap: Report invalid-length ASE CP write via notification
A zero-length write to the ASE Control Point returned an ATT error, but
ASCS requires the write to succeed at ATT level and the failure to be
carried by a CP notification. Build a response with the truncated error
code and return success instead.
Fixes PTS tests ASCS/SR/SPE/BI-01-C and BI-02-C
Commit: 3047c2a4c5ea8313bcf5a9edbb18f9c9a187a7fd
https://github.com/bluez/bluez/commit/3047c2a4c5ea8313bcf5a9edbb18f9c9a187a7fd
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M profiles/audio/transport.c
M src/shared/bap.c
Log Message:
-----------
transport: Complete Acquire for Sink ASE entering Enabling
On the QoS to Enabling transition the IO is not yet available because
the CIS is not established, so the handler returns early and a pending
Acquire is left unanswered once the IO later arrives.
Notify the connecting callbacks once the fd is attached so the
transport can re-run the Enabling handling and complete the Acquire.
Commit: 5d836f1c697cde166981d31276e2dd828996f3e7
https://github.com/bluez/bluez/commit/5d836f1c697cde166981d31276e2dd828996f3e7
Author: Simon Mikuda <simon.mikuda@streamunlimited.com>
Date: 2026-06-10 (Wed, 10 Jun 2026)
Changed paths:
M src/adapter.c
Log Message:
-----------
adapter: Fix failed bonding attempt after LE link disconnection
What happens when issue occurs:
- device is connected to both bearers BR/EDR and LE
- bonding is requested
- LE link disconnects
- pairing keys arrive
BlueZ would finish bonding request with error and mark device as
temporary. Then it would be disconnected+removed after default
temporary timeout (30 seconds).
Compare: https://github.com/bluez/bluez/compare/912d67d1d3a4...5d836f1c697c
To unsubscribe from these emails, change your notification settings at https://github.com/bluez/bluez/settings/notifications
^ permalink raw reply
* Re: [PATCH BlueZ] transport: Complete Acquire for Sink ASE entering Enabling
From: patchwork-bot+bluetooth @ 2026-06-10 18:40 UTC (permalink / raw)
To: Simon Mikuda; +Cc: linux-bluetooth
In-Reply-To: <20260609211130.3887817-1-simon.mikuda@streamunlimited.com>
Hello:
This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 9 Jun 2026 23:11:29 +0200 you wrote:
> On the QoS to Enabling transition the IO is not yet available because
> the CIS is not established, so the handler returns early and a pending
> Acquire is left unanswered once the IO later arrives.
>
> Notify the connecting callbacks once the fd is attached so the
> transport can re-run the Enabling handling and complete the Acquire.
>
> [...]
Here is the summary with links:
- [BlueZ] transport: Complete Acquire for Sink ASE entering Enabling
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=3047c2a4c5ea
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH BlueZ] shared/bap: Report invalid-length ASE CP write via notification
From: patchwork-bot+bluetooth @ 2026-06-10 18:40 UTC (permalink / raw)
To: Simon Mikuda; +Cc: linux-bluetooth
In-Reply-To: <20260609211104.3887577-1-simon.mikuda@streamunlimited.com>
Hello:
This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 9 Jun 2026 23:11:04 +0200 you wrote:
> A zero-length write to the ASE Control Point returned an ATT error, but
> ASCS requires the write to succeed at ATT level and the failure to be
> carried by a CP notification. Build a response with the truncated error
> code and return success instead.
>
> Fixes PTS tests ASCS/SR/SPE/BI-01-C and BI-02-C
>
> [...]
Here is the summary with links:
- [BlueZ] shared/bap: Report invalid-length ASE CP write via notification
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=2e00b83c0788
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
* Re: [PATCH BlueZ] avrcp: Abort continuing response on fragmented CT replies
From: patchwork-bot+bluetooth @ 2026-06-10 18:40 UTC (permalink / raw)
To: Simon Mikuda; +Cc: linux-bluetooth
In-Reply-To: <20260609212656.3900190-1-simon.mikuda@streamunlimited.com>
Hello:
This patch was applied to bluetooth/bluez.git (master)
by Luiz Augusto von Dentz <luiz.von.dentz@intel.com>:
On Tue, 9 Jun 2026 23:26:56 +0200 you wrote:
> Send AbortContinuingResponse when a Get Element Attributes reply
> arrives fragmented, as the CT side does not reassemble fragments.
>
> Fixes PTS test AVRCP/CT/RCR/BV-03-C
> ---
> profiles/audio/avrcp.c | 25 +++++++++++++++++++++++++
> 1 file changed, 25 insertions(+)
Here is the summary with links:
- [BlueZ] avrcp: Abort continuing response on fragmented CT replies
https://git.kernel.org/pub/scm/bluetooth/bluez.git/?id=249e2bedfacf
You are awesome, thank you!
--
Deet-doot-dot, I am a bot.
https://korg.docs.kernel.org/patchwork/pwbot.html
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox