Как выполнить сопряжение и поиск услуг Bluetooth Low Energy на телефоне в настольном приложении Windows?

У нас есть телефонное приложение, на котором размещен сервер GATT с сервисом и характеристиками. В настольном приложении мы пытаемся найти его с помощью UWP API с помощью DeviceWatcher.

var deviceWatcher = DeviceInformation.CreateWatcher(
        BluetoothLEDevice.GetDeviceSelectorFromPairingState(false),
        new List<string>(),
        DeviceInformationKind.AssociationEndpoint);

Затем мы пытаемся получить обслуживание с устройства

var serviceResult = await device.GetGattServicesForUuidAsync(ServiceId);

Но такой подход очень нестабилен. На поиск устройства и подключение к нему требуется 30-60 секунд. Иногда он не находит устройство или находит устройство, но не может получить обслуживание.

Также мы пытались связать устройство с ПК и проверять только сопряженные или подключенные устройства.

var deviceWatcher = DeviceInformation.CreateWatcher(
        BluetoothLEDevice.GetDeviceSelectorFromPairingState(true),
        new List<string>(),
        DeviceInformationKind.AssociationEndpoint);

Но этот наблюдатель ничего не нашел. Мы пробовали разные фильтры AQS и получили те же результаты.

Также мы попытались использовать 32feet lib, чтобы получить только сопряженные подключенные устройства.

var client = new BluetoothClient();
var paired = client.DiscoverDevices(5, true, true, false);
foreach (var bluetoothDeviceInfo in paired)
{
   var addressBytes = bluetoothDeviceInfo.DeviceAddress.ToByteArray();
   var addr = BitConverter.ToUInt64(addressBytes, 0);
   var device = await BluetoothLEDevice.FromBluetoothAddressAsync(addr));
   var serviceResult = await device.GetGattServicesForUuidAsync(ServiceId);
}

Он работает быстро и находит телефон, но найденное устройство не содержит нашу службу GATT, а его адрес bluetooth отличается от устройств, обнаруженных DeviceWatcher. Похоже, что на одном телефоне есть два устройства bluetooth: первое устройство имеет нашу службу BLE, второе сопряжено, но не имеет службы.

Есть ли способ подключить правильное устройство BLE и выполнять поиск только в паре?


person Salavat Gainetdinov    schedule 10.04.2018    source источник
comment
Вы пробуете код из официального BluetoothLE? В моем тесте, когда сервер запускается, клиент может быстро его найти. Не могли бы вы предоставить минимальный образец репродукции, чтобы помочь мне разобраться в вашей проблеме?   -  person Breeze Liu - MSFT    schedule 11.04.2018
comment
@ BreezeLiu-MSFT Здравствуйте! Мы выяснили, почему так долго ищут правильное устройство. Получение сервиса device.GetGattServicesForUuidAsync (ServiceId) занимает много времени. Мы обнаружили, что можем выполнять поиск службы напрямую через Bluetooth.   -  person Salavat Gainetdinov    schedule 17.04.2018


Ответы (1)


Наконец, я узнал, как искать сервисы напрямую с помощью BluetoothLEAdvertiseWatcher.

_watcher = new BluetoothLEAdvertisementWatcher();
_watcher.ScanningMode = BluetoothLEScanningMode.Active;
_watcher.SignalStrengthFilter = new BluetoothSignalStrengthFilter
                                    {
                                         InRangeThresholdInDBm = -75,
                                         OutOfRangeThresholdInDBm = -76,
                                         OutOfRangeTimeout  = TimeSpan.FromSeconds(2),
                                         SamplingInterval = TimeSpan.FromSeconds(2)
                                    };
_watcher.AdvertisementFilter =
     new BluetoothLEAdvertisementFilter
         {
              Advertisement =
                  new BluetoothLEAdvertisement
                      {
                            ServiceUuids =
                                {
                                        BLEHelper.ServiceId
                                }
                       }
        };
_watcher.Received += OnWatcherOnReceived;
_watcher.Start();

В OnWatcherOnReceived мы можем получить адрес bluetooth для подключения к сервису и получить характеристику

    private void OnWatcherOnReceived(BluetoothLEAdvertisementWatcher w, BluetoothLEAdvertisementReceivedEventArgs a)
    {
        // use a.BluetoothAddress to connect to device
    }
person Salavat Gainetdinov    schedule 17.04.2018