Browser-side test pages and matching ESP32-C3 firmware that exercise the Web Bluetooth ATT MTU exchange path in Chromium. Used to observe behavior of issues 40265040, 40686244 and 40163619 across platforms.
kWebBluetoothRequestLargerMtu). Demos consistently see effective MTU 517.BluetoothRemoteGATTCharacteristic.getMTU() method.writeValueWithoutResponse() rejected payloads > 20 bytes on Windows. Current behavior on Windows: 1 to 512 byte writes succeed on both APIs.Launch Chrome with the flag below so getMTU() and the new BLE GATT session handling are available:
--enable-features=NewBLEGattSessionHandling,WebBluetooth
The flag is only required for the new MTU API; the write-size and image-streaming demos otherwise work on stable Chrome too.
Flash ESP32C3_All_BLE_Tester to a single ESP32-C3 board. It advertises as dino tester and serves both demos from the same characteristic:
RX seq=<n> len=<L> first=0xXX last=0xYY mtu=<peerMTU>.lets go + get <seq> -- progressive JPEG pull-mode streamer.Service: 0000ffe0-0000-1000-8000-00805f9b34fb
Characteristic: 0000ffe1-0000-1000-8000-00805f9b34fb
Device name: dino tester
Connects to the dino tester peripheral, calls getMTU(), then pulls the embedded progressive JPEG chunk-by-chunk using a get <seq> pull-mode protocol. The browser reassembles the JPEG and paints successive scans (blurry to sharp) as bytes arrive. Notification payload is capped at 244 bytes to work around the Chromium notification cap on macOS/CoreBluetooth (see notes below).
BluetoothRemoteGATTCharacteristic.getMTU() API.Runs eight checks against the new API: it exists, returns a Promise, resolves to an integer in the spec range, matches the device-reported peerMTU, is idempotent, handles concurrent calls, and the reported MTU actually drives the maximum write size. Point reviewers at this page on each platform to verify the API end-to-end.
Connects to the same dino tester peripheral, then writes a deterministic payload at sizes 1, 19, 20, 21, 22, 32, 64, 100, 182, 200, 244, 247, 300, 400, 512 through both writeValueWithResponse() and writeValueWithoutResponse(). The firmware echoes the actual received length so the page can flag silent truncation. On Windows with effective MTU 517, both APIs accept payloads up to 512 bytes.
Tested with an ESP32-C3 SuperMini development board (ESP32-C3FN4). Any ESP32-C3 with the Espressif Arduino core and the NimBLE-Arduino library should work.
Serial monitor baud: 115200. Recommended Arduino IDE settings:
Board: ESP32C3 Dev Module
USB CDC On Boot: Enabled
Flash Size: 4MB
CPU Frequency: 160MHz
Upload Speed: 921600
Pre-built Chrome for Android APKs from CL 7879985 ("Web Bluetooth: Expose ATT MTU via getMTU()"), on top of Chromium main. Install with adb install -r <file>.apk on a device with the prior Chrome uninstalled. Launch flag still required at runtime:
adb shell 'echo --enable-features=NewBLEGattSessionHandling,WebBluetooth > /data/local/tmp/chrome-command-line'