1

我正在尝试使用带有网络蓝牙 api 的 BLE 从我的 Windows 10 机器连接到 Microchip“RN4678”双模蓝牙设备。我可以找到设备 -> 服务 -> 我需要的特性,但我不断收到“GATT 错误:未配对”。尝试启动有关特征的通知时。

我的 JavaScript 经验很少,所以我认为我可能一直在错误地链接我的承诺,但是在尝试添加特征之前直接打印出设备信息显示“已连接”的值为 true。

我还验证了设备、服务和特性是否可以与我的 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):

当调用 startNotifications() 方法时,必须返回一个新的 Promise Promise 并并行运行以下步骤。有关接收通知的详细信息,请参阅 §5.6.4 响应通知和指示。

  1. 如果 this.uuid 被列入读取阻止名单,则使用 SecurityError 拒绝承诺并中止这些步骤。
  2. 如果 this.service.device.gatt.connected 为 false,则使用 NetworkError 拒绝承诺并中止这些步骤。
  3. 让特征是this.[[representedCharacteristic]]。
  4. 如果特征为空,则返回一个被 InvalidStateError 拒绝的承诺并中止这些步骤。
  5. 如果 Notify 或 Indicate 位都没有在特性的属性中设置,则使用 NotSupportedError 拒绝承诺并中止这些步骤。
  6. 如果特征的活动通知上下文集包含 navigator.bluetooth,则使用此解决承诺并中止这些步骤。
  7. 如果 UA 当前正在使用蓝牙系统,它可能会使用 NetworkError 拒绝承诺并中止这些步骤。ISSUE 9:实现可能能够避免此 NetworkError,但目前站点需要序列化他们对该 API 的使用和/或为用户提供重试失败操作的方法。 https://github.com/WebBluetoothCG/web-bluetooth/issues/188

  8. 如果特征具有客户端特征配置描述符,则使用任何特征描述符过程来确保设置特征的客户端特征配置描述符中的通知或指示位之一,匹配特征属性中的约束。UA 应该避免设置这两个位,并且如果两个位都设置了,则必须对值更改事件进行重复数据删除。按照 §5.7 错误处理中的描述处理错误。注意:某些设备的特性包括通知或指示位,但没有客户端特性配置描述符。这些不符合标准的特性倾向于无条件地发送通知或指示,因此该规范允许应用程序简单地订阅它们的消息。

  9. 如果上一步返回错误,则拒绝带有该错误的承诺并中止这些步骤。

  10. 将 navigator.bluetooth 添加到特征的活动通知上下文集中。
  11. 以此来兑现诺言。启用通知后,直到当前微任务检查点之后才会传递生成的值更改事件。这允许开发人员在结果承诺的 .then 处理程序中设置处理程序。

编辑:我使用的是 Chrome 版本 74,Windows 10.0.17134

4

1 回答 1

0

我找到了适用于我的设备的解决方案,希望它也适用于您。事实证明,在通过 Web 蓝牙建立连接之前,设备必须与 Windows 操作系统配对。因此,即使网络蓝牙会“连接”并显示所有 GATT 属性 - 设备收到命令时实际上正在断开连接startNotifications()(因为它没有通过操作系统配对)。此外,(在我的情况下,但这可能是特定于设备的)我的“默认密码”是 000000(需要正好是 6 个零)。与 Windows 操作系统配对时,请务必仔细检查。

编辑:此行为(必须在建立 Web 蓝牙连接之前将设备与操作系统配对)是除 Windows 之外在 macOS 上发现的错误。有关更多信息,请参阅此chrome-bug

于 2019-05-22T22:04:31.670 回答