Linux bluetooth development
 help / color / mirror / Atom feed
From: Caleb White <cdwhite3@pm.me>
To: linux-bluetooth@vger.kernel.org
Cc: luiz.von.dentz@intel.com
Subject: Bluetooth: eSCO re-setup after HFP profile switch gets no Sync_Conn_Complete (Intel AX201/AX211, handle 257)
Date: Fri, 11 Sep 2026 19:06:35 +0000	[thread overview]
Message-ID: <DLCQ0KQND9EO.2NFOQQ5PCPL9B@pm.me> (raw)

[-- Attachment #1: Type: text/plain, Size: 4119 bytes --]

Hello!

After updating to both WirePlumber 0.5.17 and Linux 7.2.3, I started
experiencing a weird issue with my Bose headset. I could reproduce the
problem on two different laptops, so I had Grok dig into it and the
following is the result:

# Analysis

After A2DP ↔ HFP profile switching, the controller keeps using eSCO handle
257 without sending HCI_Synchronous_Connection_Complete on the 2nd+ setup.
The host then logs "SCO packet for unknown connection handle 257" and
HFP capture dies after ~0.5s.

This is not the sco_conn lifetime UAF. Patch "Bluetooth: SCO: serialise
sco_conn lifetime against sco_recv_scodata()" does not fix it.

## Hardware

Two System76 laptops, same Bose headset:

1. Intel AX201 USB 8087:0026, firmware intel/ibt-0040-4150.sfi 202-5.26
2. Intel AX211 USB 8087:0033, firmware intel/ibt-0180-0041.sfi 42-20.25

Headset: Bose QC Ultra 2 HP, modalias bluetooth:v009Ep4082d082F, address 68:F2:1F:03:3F:C9

## Software

- Linux 7.1.9.arch1-2: good
- Linux 7.2.3.arch1-3: bad when combined with WirePlumber 0.5.17
- BlueZ 5.87-2 (unchanged)
- PipeWire 1:1.6.8-1 (unchanged)
- WirePlumber 0.5.15: good on both kernels
- WirePlumber 0.5.17: good on 7.1.9, bad on 7.2.3

Same-machine matrix (AX201):

| kernel | WirePlumber | 12× A2DP→HFP 4s pw-record    |
|--------|-------------|------------------------------|
| 7.1.9  | 0.5.15      | 12/12 pass                   |
| 7.1.9  | 0.5.17      | 12/12 pass                   |
| 7.2.3  | 0.5.15      | 12/12 pass                   |
| 7.2.3  | 0.5.17      | 1/12 pass (first cycle only) |

Failure only reproduces after a cold boot (or equivalent). Reloading
btusb/bluetooth without reboot often "heals" it until the next reboot.
Parked on HFP with no profile switch: capture is fine.

Userspace trigger: WirePlumber 0.5.17 BlueZ monitor rewrite (cb92ef98 /
issue #1013). Autoswitch Lua timeouts are unchanged vs 0.5.15.

## Reproducer

    card=bluez_card.<addr>
    src=bluez_input.<addr>

    for i in $(seq 1 12); do
      pactl set-card-profile "$card" a2dp-sink
      sleep 1
      pactl set-card-profile "$card" headset-head-unit
      sleep 1
      timeout 4 pw-record --target "$src" /tmp/cap$i.wav
      ffprobe -v error -show_entries format=duration -of csv=p=0 /tmp/cap$i.wav
    done

Pass: duration ≥ 3s. Fail: ~0.04–0.6s, then spa.bluez5 transport error.

## HCI (btmon)

First HFP open:

- Enhanced Setup Synchronous Connection → Command Status Success
- Synchronous Connect Complete handle 257, eSCO, transparent, 60-byte packets
- Capture succeeds (~4s)

Tear-down (back to A2DP):

- RFCOMM AT+CIEV: 2,0
- HCI Disconnect handle 257 (reason 0x13)
- Disconnect Complete (reason 0x16 Terminated By Local Host)
- Kernel: hci_disconn_complete_evt → hci_conn_del
  deleting SCO type 2 (ESCO) state 9 (BT_CLOSED) handle 257

Later HFP opens:

- Enhanced Setup Synchronous Connection → Command Status Success
- **No Synchronous Connect Complete**
- BR-ESCO data still arrives on handle 257
- Kernel: "SCO packet for unknown connection handle 257"
- Host still issues Disconnect 257 when switching back to A2DP

One failing trace: 5 Enhanced Setup commands, 1 Sync_Conn_Complete.

Debug dump at miss time (conn hash): only ACL handle 256 (Bose) and LE
handle 2048. **No SCO/eSCO hci_conn.** Firmware is still transmitting 257
after the host deleted the object.

## What we tried

- Binding unknown-handle SCO data to a pending BT_CONNECT SCO conn: never
  fired; there is no pending SCO object when the packets arrive.
- sco_conn lifetime serialisation patch: no change.

## Ask

After Disconnect Complete on eSCO 257, the Intel controller reuses 257
without Sync_Conn_Complete. Should the host:

1. refuse a new Enhanced Setup until 257 is really gone, or
2. treat incoming eSCO 257 as completing the pending setup even without the event?

I can attach the .btsnoop and reproduce on either laptop.

WirePlumber report (userspace trigger):
https://gitlab.freedesktop.org/pipewire/wireplumber/-/work_items/1013

[-- Attachment #2: bose-fail.btsnoop --]
[-- Type: application/octet-stream, Size: 303741 bytes --]

             reply	other threads:[~2026-09-11 19:06 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2026-09-11 19:06 Caleb White [this message]
2026-09-11 19:46 ` Bluetooth: eSCO re-setup after HFP profile switch gets no Sync_Conn_Complete (Intel AX201/AX211, handle 257) Luiz Augusto von Dentz
  -- strict thread matches above, loose matches on Subject: below --
2026-09-12  1:24 Caleb White
2026-09-12 23:12 Алексей Воронов

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=DLCQ0KQND9EO.2NFOQQ5PCPL9B@pm.me \
    --to=cdwhite3@pm.me \
    --cc=linux-bluetooth@vger.kernel.org \
    --cc=luiz.von.dentz@intel.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox