Как привязать вручную к устройству с низким энергопотреблением BlueTooth в WinForm с помощью С#?

На этот вопрос в основном отвечает: Windows UWP подключается к BLE устройство после обнаружения

На данный момент я пишу настраиваемую службу и тестирую, используя C # .NET WinForm в Windows 10 для подключения к устройству Bluetooth с низким энергопотреблением (BLE). Я использую Framework 4.6.1. Мы используем оценочную плату TI SmartRF06 с дочерняя карта TI CC2650 BLE. Другой разработчик занимается прошивкой платы.

В настоящее время используются методы, аналогичные справочному ответу выше Я могу подключиться к уже привязанному устройству BLE. Это устройство было привязано вручную, и Windows требовала от меня ввода PIN-кода. Поскольку у устройства нет PIN-кода, просто введите «0», чтобы устройство могло подключиться. Подключившись таким образом, я могу получить доступ ко всем службам GATT и делать то, что мне нужно. Так что у меня нет проблем с поиском и получением рекламного BLE-устройства.

Проблема в том, как мне подключиться к устройству BLE, которое еще не было сопряжено? Я прошел через сеть и нашел много примеров кода BLE, но ничего конкретного, показывающего, как выполняется сопряжение в коде. Не уверен, что мне даже нужно это для сопряжения, но Windows, похоже, показывает мои службы GATT только на сопряженных устройствах.

Когда я делаю это с непарным устройством:

private void BleWatcherOnReceived(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
{       
    var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
    // dev.DeviceInformation.Pairing.CanPair is true
    // dpr.Status is Failed
    DevicePairingResult dpr = await dev.DeviceInformation.Pairing.PairAsync(DevicePairingProtectionLevel.None);
    var service = await GattDeviceService.FromIdAsync(dev.DeviceInformation.Id);
}

Результат dpr всегда терпит неудачу, если устройство не было сопряжено вручную. В результате GattDeviceServices становится пустым. Но я могу получить рекламу и свойства устройства BLE.

Существует также такой метод подключения, но я не могу понять, как его использовать:

var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None,IDevicePairingSettings);

IdeviceParingSettings — это интерфейс. Не уверен, какой класс использовать с ним. Я думаю, что здесь я могу установить PIN-код «O», который мне может понадобиться?

Удалось ли кому-нибудь подключиться к устройству BLE в Windows с помощью С#, где устройство BLE не имеет защиты. В основном она должна быть широко открыта. Я чувствую, что упускаю что-то простое или это просто невозможно (что я видел в некоторых сообщениях, утверждающих, что это так. Большинству из них было много лет).

Я попробовал методы, описанные в упомянутом посте, без какой-либо разницы в результате.

Любая помощь приветствуется. Если вам нужно больше кода, посмотрите ссылку, которую я предоставил вверху, так как это то, с чего я начал. Я буду рад предоставить весь мой фактический код, если есть, возможно, последовательность, которую я делаю не к месту.


person Michael Frederick    schedule 01.01.2017    source источник
comment
Я включил ссылки на таблицы. Если они неверны, было бы здорово, если бы вы их исправили.   -  person zx485    schedule 02.01.2017


Ответы (1)


Я понял. Я был на правильном пути.

После подключения с помощью:

var dev = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);

Вам нужно сделать пользовательское сопряжение:

var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None);

Но это просто даст вам ошибку. Вы также должны создать обработчик событий device.DeviceInformation.Pairing.Custom.PairingRequested.

Поэтому я создал этот обработчик:

private void handlerPairingReq(DeviceInformationCustomPairing CP, DevicePairingRequestedEventArgs DPR)
        {
            //so we get here for custom pairing request.
            //this is the magic place where your pin goes.
            //my device actually does not require a pin but
            //windows requires at least a "0".  So this solved 
            //it.  This does not pull up the Windows UI either.
            DPR.Accept("0");


}

Подключил его непосредственно перед вызовом PairAsync.

device.DeviceInformation.Pairing.Custom.PairingRequested += handlerPairingRequested;

Пример кода для кода BlueToothAdvertisementWatcher, который устанавливает мое соединение:

    private BluetoothLEAdvertisementWatcher BTWatch = new BluetoothLEAdvertisementWatcher();

    private void Inits() 
        {
           BTWatch.Received += new TypedEventHandler<BluetoothLEAdvertisementWatcher, BluetoothLEAdvertisementReceivedEventArgs>(BtAddRx);
           BTWatch.Start();
        }

    private async void BtAddRx(BluetoothLEAdvertisementWatcher bw, BluetoothLEAdvertisementReceivedEventArgs args)
        {
            GattCommunicationStatus srslt;
            GattReadResult rslt;
            bw.Stop();//Stop this while inside.

            device = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
                if (device.DeviceInformation.Pairing.IsPaired == false)
                {   

                    /* Optional Below - Some examples say use FromIdAsync
                    to get the device. I don't think that it matters.   */            
                    var did = device.DeviceInformation.Id; //I reuse did to reload later.
                    device.Dispose();
                    device = null;
                    device = await BluetoothLEDevice.FromIdAsync(did);
                    /* end optional */
                    var handlerPairingRequested = new TypedEventHandler<DeviceInformationCustomPairing, DevicePairingRequestedEventArgs>(handlerPairingReq);
                    device.DeviceInformation.Pairing.Custom.PairingRequested += handlerPairingRequested;
                    log("Pairing to device now...."); 

                    var prslt = await device.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ProvidePin, DevicePairingProtectionLevel.None);                  
                    log("Custom PAIR complete status: " + prslt.Status.ToString() + " Connection Status: " + device.ConnectionStatus.ToString());

                    device.DeviceInformation.Pairing.Custom.PairingRequested -= handlerPairingRequested; //Don't need it anymore once paired.


                    if (prslt.Status != DevicePairingResultStatus.Paired)
                    { //This should not happen. If so we exit to try again.
                        log("prslt exiting.  prslt.status=" + prslt.Status.ToString());// so the status may have updated.  lets drop out of here and get the device again.  should be paired the 2nd time around?
                        bw.Start();//restart this watcher.
                        return;
                    }
                    else
                    {
                        // The pairing takes some time to complete. If you don't wait you may have issues. 5 seconds seems to do the trick.

                        System.Threading.Thread.Sleep(5000); //try 5 second lay.
                        device.Dispose();
                       //Reload device so that the GATT services are there. This is why we wait.                     
                       device = await BluetoothLEDevice.FromIdAsync(did);

                    }
 var services = device.GattServices;
//then more code to finish it up.
}

Если вы хотите отключиться, просто используйте:

await device.DeviceInformation.Pairing.UnpairAsync();

Извините за беспорядочный код. Если есть кто-то, кто находит полезным или имеет вопрос, дайте мне знать. Я нигде не смог найти примеры этого кода для WinForm. На самом деле я не смог найти никакого кода, чтобы показать, как выполнить сопряжение с PIN-кодом без пользовательского интерфейса. Поэтому я надеюсь, что это поможет любому, кто может застрять.

person Michael Frederick    schedule 02.01.2017
comment
См. сценарии 8 и 9 по адресу github.com/Microsoft/Windows- универсальные образцы/дерево/мастер/ - person Emil; 02.01.2017
comment
Спасибо - я нашел такие примеры. Искал что-то более оконное и более прямое. Эта информация кажется действительно похороненной. - person Michael Frederick; 03.01.2017
comment
@MichaelFrederick очень помог, спасибо! Однако есть одна проблема с моей реализацией. Сопряженное устройство не отображается в пользовательском интерфейсе Windows (например, если вы хотите отменить сопряжение без моего приложения). Были ли у вас проблемы с этим? - person Werner; 21.06.2019
comment
Все еще есть вопросы по этому поводу. Я могу запустить наблюдатель, найти устройство, пройти через await BluetoothLEDevice.FromBluetoothAddressAsync(addres), но обработчик PairingReq не вызывается, поэтому сопряжение не удается. Я добавил его, как вы упомянули, но у меня это не работает :( - person Persike; 20.03.2020
comment
@MichaelFrederick, ваш код мне очень помогает, спасибо - person Nitin S; 28.04.2021