"GATT Error: Not paired." with web-bluetooth when device shows as connected

"GATT Error: Not paired." with web-bluetooth when device shows as connected

我正在尝试使用 BLE 和网络蓝牙 api 从我的 Windows 10 机器连接到 Microchip "RN4678" 双模式蓝牙设备。我可以找到设备 -> 服务 -> 我需要的特征,但在尝试启动特征通知时我一直收到 "GATT Error: Not paired."。

我的 JavaScript 经验很少,所以我认为我可能一直在错误地兑现我的承诺,但是在尝试添加特征之前直接打印出设备信息显示了 "connected" 的值是真的。

我还验证了我的 android 设备上的 "nRF Connect" 应用程序可以正常使用该设备、服务和特性。

这是我的代码:

let targetService = '49535343-fe7d-4ae5-8fa9-9fafd205e455';
let txCharacteristicId = '49535343-1e4d-4bd9-ba61-23c647249616';
let rxCharacteristicId = '49535343-8841-43f4-a8d4-ecbe34729bb3';

function onButtonClick(event) {

  // Find bluetooth device
  console.log('Requesting Bluetooth Device...');
  navigator.bluetooth.requestDevice({
    acceptAllDevices: true,
    optionalServices: [targetService]
  })
  // Connect to device
  .then(device => device.gatt.connect())
  // Get the server we want
  .then(server => {
    console.log('Getting UART transparent service...');
    return server.getPrimaryService(targetService);
  })
  // Handle the characteristics we need
  .then(service => {
    return service.getCharacteristic(txCharacteristicId)
  })
  .then(characteristic => {
    console.dir(characteristic.service.device);
    return characteristic.startNotifications();
  })
  .then(characteristic => {
    characteristic.addEventListener('characteristicvaluechanged',
                                    handleTx);
  })
  .catch(error => { 
    console.log(error);
    console.log(error.code);
    console.log(error.message); 
    console.log(error.name); 
  });

}

function handleTx(event) {
  console.log(event.target.value);
}

这是我收到的控制台消息:

index.html:18 Requesting Bluetooth Device...
index.html:27 Getting UART transparent service...
index.html:35 BluetoothDevice
                gatt: BluetoothRemoteGATTServer
                  connected: true
                  device: BluetoothDevice {id: "p+lJYscejR+Xl4eX+VbNkA==", name: "Dual-SPP", gatt: BluetoothRemoteGATTServer, ongattserverdisconnected: null}
                  __proto__: BluetoothRemoteGATTServer
                id: "p+lJYscejR+Xl4eX+VbNkA=="
                name: "Dual-SPP"
                ongattserverdisconnected: null
                __proto__: BluetoothDevice
index.html:44 DOMException
index.html:45 19
index.html:46 GATT Error: Not paired.
index.html:47 NetworkError

这是网络蓝牙 startNotifications() 函数 (https://webbluetoothcg.github.io/web-bluetooth/#dom-bluetoothremotegattcharacteristic-startnotifications) 的文档:

The startNotifications() method, when invoked, MUST return a new promise promise and run the following steps in parallel. See §5.6.4 Responding to Notifications and Indications for details of receiving notifications.

  1. If this.uuid is blocklisted for reads, reject promise with a SecurityError and abort these steps.
  2. If this.service.device.gatt.connected is false, reject promise with a NetworkError and abort these steps.
  3. Let characteristic be this.[[representedCharacteristic]].
  4. If characteristic is null, return a promise rejected with an InvalidStateError and abort these steps.
  5. If neither of the Notify or Indicate bits are set in characteristic’s properties, reject promise with a NotSupportedError and abort these steps.
  6. If characteristic’s active notification context set contains navigator.bluetooth, resolve promise with this and abort these steps.
  7. If the UA is currently using the Bluetooth system, it MAY reject promise with a NetworkError and abort these steps. ISSUE 9: Implementations may be able to avoid this NetworkError, but for now sites need to serialize their use of this API and/or give the user a way to retry failed operations. https://github.com/WebBluetoothCG/web-bluetooth/issues/188

  8. If the characteristic has a Client Characteristic Configuration descriptor, use any of the Characteristic Descriptors procedures to ensure that one of the Notification or Indication bits in characteristic’s Client Characteristic Configuration descriptor is set, matching the constraints in characteristic’s properties. The UA SHOULD avoid setting both bits, and MUST deduplicate value-change events if both bits are set. Handle errors as described in §5.7 Error handling. Note: Some devices have characteristics whose properties include the Notify or Indicate bit but that don’t have a Client Characteristic Configuration descriptor. These non-standard-compliant characteristics tend to send notifications or indications unconditionally, so this specification allows applications to simply subscribe to their messages.

  9. If the previous step returned an error, reject promise with that error and abort these steps.

  10. Add navigator.bluetooth to characteristic’s active notification context set.
  11. Resolve promise with this. After notifications are enabled, the resulting value-change events won’t be delivered until after the current microtask checkpoint. This allows a developer to set up handlers in the .then handler of the result promise.

编辑: 我正在使用 Chrome 版本 74,Windows 10.0.17134

我找到了适用于我的设备的解决方案,希望它也适用于您。事实证明,设备必须先与 Windows OS 配对才能通过 Web 蓝牙建立连接。因此,即使 Web Bluetooth 会 "connect" 并显示所有 GATT 属性 - 设备 在收到 startNotifications() 命令时实际上断开连接(因为它没有通过配对OS)。此外,(在我的例子中,但这可能是特定于设备的)我的 "default passcode" 是 000000(需要恰好是 6 个零)。与 Windows OS.

配对时一定要仔细检查

编辑:此行为(在建立 Web 蓝牙连接之前必须将设备与 OS 配对)是在 mac 上发现的错误OS 除了 Windows。有关详细信息,请参阅此 chrome-bug