Получите доступ к серверу GATT на устройстве Bluetooth, обнаруженном с помощью экспериментального сканирования BLE в Chrome

Я работаю над POC, где я использую экспериментальный интерфейс сканирования BLE для обнаружения нескольких устройств Bluetooth и подключения к их службам GATT из веб-приложения.

Запрос одного устройства с использованием navigator.bluetooth.requestDevice дает устройство, на котором я могу подключиться к серверу GATT.

Когда я пытаюсь обнаружить устройства с помощью requestLEScan, полученные мной устройства не позволяют мне подключиться к серверу GATT.

  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();
  ...
}

Вызов device.gatt.connect() вызывает ошибку:

Операция GATT не разрешена

Как мне получить доступ к серверу GATT на обнаруженном устройстве?

Моя проблема в том, что мне нужно вызвать permissions.request(), который еще не реализован для Bluetooth? (Статус реализации Bluetooth)

Я попытался вместо установки acceptAllAdvertisement передать filters с UUID службы, который, как я знаю, поддерживает мои устройства и который я хочу запросить, но тогда я не вижу результатов сканирования.

Я использую Chrome 83.0.4103.97 на MacOS с включенными «экспериментальными веб-функциями».


person Pete    schedule 06.06.2020    source источник


Ответы (1)


requestLEScan() API только дает разрешение на запуск сканирования и просмотр рекламных пакетов с ближайших устройств, но не дает разрешения на подключение к этим устройствам. Для этого вам нужно будет использовать requestDevice() и добавить службы, которые вы хотите использовать, в фильтр или в optionalServices.

В Chrome приглашение, отображаемое, когда requestDevice() требует, чтобы пользователь выбрал устройство Bluetooth, к которому он хочет разрешить соединение с сайтом, тогда как приглашение, отображаемое для requestLEScan(), только спрашивает, хочет ли пользователь разрешить сайту сканировать близлежащие устройства Bluetooth. Вот почему вы не можете подключиться к этим устройствам.

person Ovidio Ruiz-Henríquez    schedule 08.06.2020
comment
Спасибо, но если я сначала просканировал устройства и нашел те, с которыми интересно поговорить, как я могу конкретно запросить это устройство? requestDevice({ deviceId: event.device.id }) не работает? В моем конкретном приложении мне нужно будет подключиться к нескольким устройствам, которые, как мне кажется, я могу обнаружить на основе информации производителя. - person Pete; 09.06.2020
comment
RequestDeviceOptions не содержит способа указать идентификатор устройства. Если вы хотите специально отфильтровать устройство, вы можете добавить поля name и services, а также данные о любых услугах и производителях. Если вы хотите получить доступ к каким-либо дополнительным услугам, которых нет в рекламном пакете, вам нужно добавить это в optionalServices, чтобы получить для них разрешение. К сожалению, на данный момент нет простого способа предоставить разрешение сразу нескольким устройствам. - person Ovidio Ruiz-Henríquez; 09.06.2020
comment
Имеет смысл, что API должен включить сканирование - ›Подключиться в конечном итоге. Однако requestLEScan сейчас только прототип, и разработка приостановлена. В конце концов, имеет смысл разрешить путь для device.gatt.connect() для работы, но для этого потребуется разработка спецификации того, как будет запрашиваться разрешение пользователя, и его реализация. - person Vincent Scheib; 10.06.2020