Pete
Pete

Reputation: 12553

Get access to GATT server on a bluetooth device discovered using experimental BLE scanning in Chrome

I am working on a POC where I use the experimental BLE scan interface to discover multiple Bluetooth devices, and connect to their GATT services from a web application.

Requesting a single device using navigator.bluetooth.requestDevice yields a device where I can connect to the GATT server.

When when I try to discover devices using requestLEScan, the devices I receive does not allow me to connect to the GATT server.

  const [ devices, dispatch ] = useReducer(reducer, {});
  const scanClick = () => {
    navigator.bluetooth.requestLEScan({
      acceptAllAdvertisements: true,
    }).then((scan) => {
      setTimeout(() => scan.stop(), 10000);
    });
    navigator.bluetooth.addEventListener('advertisementreceived', (event) => {
      console.log("DEVICE DETECTED", event);
      parseBluetoothDevice(event.device).then(x => x && dispatch(x));
    });
  }

const parseBluetoothDevice = async (device) => {
  // Should return a representation with the device information I want to display
  await device.gatt.connect();
  ...
}

The call to device.gatt.connect() throws an error:

GATT operation not authorized

How do I get authorized to access the GATT server on the detected device?

Is my problem that I need to call permissions.request(), which is not yet implemented for Bluetooth? (Bluetooth implementation status)

I have tried instead of setting acceptAllAdvertisement, to pass filters with a service UUID that I know my devices support - and that I want to query, but then I don't see any scan results.

I am running Chrome 83.0.4103.97 on MacOS with "experimental web features" enabled.

Upvotes: 0

Views: 1411

Answers (1)

The requestLEScan() API only grants permission to start a scan and see advertisement packets from nearby devices, but it does not grant permission to connect to these devices. To do this, you would need to use requestDevice() and add the services that you're interested in using to the filter or to optionalServices.

In Chrome, the prompt displayed when requestDevice() requires the user to select the Bluetooth device that they want to allow the site to connect to, whereas the prompt displayed for requestLEScan() only asks if the user wants to allow the site to scan for nearby Bluetooth devices. This is why you aren't able to connect to these devices.

Upvotes: 0

Related Questions