Skip to content

WebBluetooth: any characteristic read panics the wasm engine — Uint8Array::new(DataView) yields an empty array #941

Description

@cfanboy

Where

crates/buttplug_server_hwmgr_webbluetooth/src/webbluetooth_hardware.rs, the WebBluetoothDeviceCommand::Read handler:

let data_view = val; // resolved from characteristic.readValue() => a DataView
let mut body = vec![0u8; data_view.byte_length()];
Uint8Array::new(&data_view).copy_to(&mut body[..]);

What happens

readValue() resolves to a DataView. In JS, new Uint8Array(dataView) does not view the DataView's buffer — a DataView is treated as a plain array-like with length === undefined, so the result is an empty Uint8Array. copy_to then hits js-sys's length assertion and panics, which kills the whole wasm instance:

panicked at js-sys-0.3.104/src/lib.rs:14143:1:
assertion `left == right` failed
  left: 0
 right: 15
Uncaught RuntimeError: unreachable

Net effect: any device whose protocol performs a hardware read over WebBluetooth dies silently after the chooser pairing — the device never appears, and the embedded server is dead from that point on. Native btleplug paths are unaffected, so the same device works fine through Intiface Central, which makes this confusing to diagnose from the outside.

Repro

Sensee Capsule (CCPA10S2, protocol sensee-v2 — its initializer reads model data from Tx). Chrome/macOS, chooser pairs fine, then the panic above. Any read-during-init protocol should reproduce.

Fix

Build the view over the underlying buffer, same as the Subscribe handler a few lines below already does:

let data_view = js_sys::DataView::from(val);
let mut body = vec![0u8; data_view.byte_length()];
Uint8Array::new_with_byte_offset_and_length(
  &JsValue::from(data_view.buffer()),
  data_view.byte_offset() as u32,
  data_view.byte_length() as u32,
)
.copy_to(&mut body[..]);

Patched in our local wasm build and verified against a physical Sensee Capsule (CCPA10S2): device now identifies and runs (vibrate + constrict) through the browser embedded server. Happy to open a PR with this if you'd like (opening the issue first per the contribution policy).

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions