From 907e901b6178256e0d7570c6d4f9736709347306 Mon Sep 17 00:00:00 2001 From: Jack Hsieh Date: Tue, 29 Jul 2025 23:53:13 -0700 Subject: [PATCH 1/2] Add cancel gatt connect test --- cancel_gatt_connect/device_code.js | 48 ++++++++++++++ cancel_gatt_connect/index.html | 91 ++++++++++++++++++++++++++ cancel_gatt_connect/web_app.js | 100 +++++++++++++++++++++++++++++ index.html | 1 + 4 files changed, 240 insertions(+) create mode 100644 cancel_gatt_connect/device_code.js create mode 100644 cancel_gatt_connect/index.html create mode 100644 cancel_gatt_connect/web_app.js diff --git a/cancel_gatt_connect/device_code.js b/cancel_gatt_connect/device_code.js new file mode 100644 index 0000000..6bb24a9 --- /dev/null +++ b/cancel_gatt_connect/device_code.js @@ -0,0 +1,48 @@ +/** + * Copyright 2022 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +function onInit() { + // Put into a known state. + digitalWrite(LED, 0); + + NRF.setServices({ + '0b30acec-193e-11eb-adc1-0242ac120002': { + '0b30afd0-193e-11eb-adc1-0242ac120002': { + value: [17], + broadcast: false, + readable: true, + writable: false, + notify: false, + description: 'Single read-only characteristic', + } + } + }); + + + NRF.on('disconnect', (reason) => { + // Provide feedback that device is no longer connected. + digitalWrite(LED, 0); + }); + + NRF.on('connect', (addr) => { + // Provide feedback that device is connected. + // TODO: Maybe only do this for some devices when external power is + // available. For example, this will turn on the backlight on the + // Pixl.js screen, which might not be desirable when powered by the + // CR2032 coin cell battery. + digitalWrite(LED, 1); + }); +} diff --git a/cancel_gatt_connect/index.html b/cancel_gatt_connect/index.html new file mode 100644 index 0000000..5eae0fb --- /dev/null +++ b/cancel_gatt_connect/index.html @@ -0,0 +1,91 @@ + + + + + + + + Cancel GATT connect + + + + + + + +

Cancel GATT connect

+

This is a simple test to check if gatt.connect() can be cancelled by gatt.disconnect(). +

+
+

Step 1

+
+
+
+ Press the button to load the code to the Espruino IDE. + From there, flash any Bluetooth capable Espruino device. +
+
+ View source. +
+
+ +
+
+
+ +

Step 2

+
+
+
+ Press the button to start pairing. +
+
+ +
+
+
+ +

Step 3

+
+
+
+ Unplug the Espruino Pixl.js from power source and click the button. +
+
+ +
+
+
+ +

Status:

+

+  
+ + + + + + + diff --git a/cancel_gatt_connect/web_app.js b/cancel_gatt_connect/web_app.js new file mode 100644 index 0000000..a04de0f --- /dev/null +++ b/cancel_gatt_connect/web_app.js @@ -0,0 +1,100 @@ +/** + * Copyright 2025 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +// Espruino devices publish a UART service by default. +const nordicUARTService = '6e400001-b5a3-f393-e0a9-e50e24dcca9e'; + +let device = undefined; + +/** + * Load the device code to the Espruino IDE. + */ +function loadEspruinoDeviceCode() { + fetch('device_code.js').then(response => response.text()).then(data => { + let url = 'http://www.espruino.com/webide?code=' + encodeURIComponent(data); + window.open(url, '_window'); + }); +} + +async function startPairing() { + clearStatus(); + logInfo('Starting test'); + + $('btn_load_code').disabled = true; + $('btn_start_pairing').disabled = true; + $('btn_connect_then_cancel').disabled = true; + + try { + const options = { + filters: [ + { services: [nordicUARTService] } + ], + }; + + device = await navigator.bluetooth.requestDevice(options); + logInfo(`Paired to Bluetooh device with name: ${device.name}`); + } catch (error) { + logError(`Unexpected failure: ${error}`); + } + + $('btn_load_code').disabled = false; + $('btn_start_pairing').disabled = false; + $('btn_connect_then_cancel').disabled = false; +} + +async function connectThenCancel() { + $('btn_load_code').disabled = true; + $('btn_start_pairing').disabled = true; + $('btn_connect_then_cancel').disabled = true; + + logInfo('Try to connect then cancel'); + try { + setTimeout(() => { + device.gatt.disconnect(); + }, 100); + await device.gatt.connect(); + logError('connect() promise was not rejected'); + } catch (e) { + if (e.name !== 'AbortError') { + logError(`connect() promise was rejected with unexpected error: ${e}`); + } + logInfo('connect() promise was rejected with Abort error'); + } + + $('btn_load_code').disabled = false; + $('btn_start_pairing').disabled = false; + $('btn_connect_then_cancel').disabled = false; + testDone(); +} + +async function init() { + if (!isBluetoothSupported()) { + console.log('Bluetooth not supported.'); + $('bluetooth_available').style.display = 'none'; + if (window.isSecureContext) { + $('bluetooth_none').style.visibility = 'visible'; + } else { + $('bluetooth_insecure').style.visibility = 'visible'; + } + return; + } + + const available = await navigator.bluetooth.getAvailability(); + if (!available) { + $('bluetooth_available').style.display = 'none'; + $('bluetooth_unavailable').style.visibility = 'visible'; + } +} diff --git a/index.html b/index.html index 78292ab..d124545 100644 --- a/index.html +++ b/index.html @@ -43,6 +43,7 @@

Tests

  • Test navigator.bluetooth.getDevices
  • Test BluetoothDevice.watchAdvertisements
  • Test BluetoothDevice.forget
  • +
  • Test cancelling a GATT connection
  • From 66424f6343d052dc85d7eb1fc3ea06c01f9b041b Mon Sep 17 00:00:00 2001 From: Chengwei Hsieh Date: Mon, 4 Aug 2025 14:07:05 -0700 Subject: [PATCH 2/2] Update year --- cancel_gatt_connect/device_code.js | 2 +- cancel_gatt_connect/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/cancel_gatt_connect/device_code.js b/cancel_gatt_connect/device_code.js index 6bb24a9..b5c23ab 100644 --- a/cancel_gatt_connect/device_code.js +++ b/cancel_gatt_connect/device_code.js @@ -1,5 +1,5 @@ /** - * Copyright 2022 Google LLC + * Copyright 2025 Google LLC * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/cancel_gatt_connect/index.html b/cancel_gatt_connect/index.html index 5eae0fb..484015c 100644 --- a/cancel_gatt_connect/index.html +++ b/cancel_gatt_connect/index.html @@ -1,6 +1,6 @@