Получение уведомлений с устройства BLE в C # с GATT не работает - PullRequest
0 голосов
/ 15 ноября 2018

Я разрабатываю приложение для получения данных от Arduino с модулем HM-10. Я пишу приложение WPF .NET, используя библиотеки UWP для подключения к BLE. Ранее я также написал программу для отправки данных из Arduino в консольное приложение .NET, которая работала нормально, и я мог отправлять текст в Arduino и получать текст обратно. Когда я переместил это в мой оригинальный проект, он перестал работать.

Код ошибки не задан, программа просто остановилась при попытке подписаться на уведомления из характеристики, от которой я пытался получать уведомления.

private static async void subscribeToData()
    {
        if (readwrite.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify))
        {
            Console.WriteLine("Attempting subscription");
            GattCommunicationStatus status = await readwrite.WriteClientCharacteristicConfigurationDescriptorAsync(
                                    GattClientCharacteristicConfigurationDescriptorValue.None);
            if (status == GattCommunicationStatus.Success)
            {
                Console.WriteLine("Recieving notifcations from device.");
                recieve = false;
            }
            else
            {
                Console.WriteLine(status);
            }
        }

    }

В приведенном выше коде переменная readwrite - это характеристика, от которой я пытаюсь получать уведомления. Консоль печатает «Попытка подписки», затем останавливается без кода ошибки. Этот код прекрасно работает в консольном приложении, но не при копировании.

Это полный класс:

class BluetoothHandler
    {
        private static BluetoothLEAdvertisementWatcher watcher = new 
BluetoothLEAdvertisementWatcher { ScanningMode = 
BluetoothLEScanningMode.Active };
        private static BluetoothLEDevice ble;
        private static List<GattCharacteristic> characterstics = new 
List<GattCharacteristic> { };
        private static GattCharacteristic readwrite;
        private static bool subscribe = true;
        private static bool recieve = true;

    public static void InitiateConnection()
    {
        GetDiscoverableDevices();
        while (subscribe)
        {
            //Block code
        }
        subscribeToData();
        while (recieve)
        {
            //Block code
        }
        readwrite.ValueChanged += recieveDataAsync;
    }

    private static async void subscribeToData()
    {
        if (readwrite.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify))
        {
            Console.WriteLine("Attempting subscription");
            GattCommunicationStatus status = await readwrite.WriteClientCharacteristicConfigurationDescriptorAsync(
                                    GattClientCharacteristicConfigurationDescriptorValue.None);
            if (status == GattCommunicationStatus.Success)
            {
                Console.WriteLine("Recieving notifcations from device.");
                recieve = false;
            }
            else
            {
                Console.WriteLine(status);
            }
        }

    }

    private static void recieveDataAsync(GattCharacteristic sender, GattValueChangedEventArgs args)
    {
        var reader = DataReader.FromBuffer(args.CharacteristicValue);
        //var stream = new Windows.Storage.Streams.InMemoryRandomAccessStream();
        reader.UnicodeEncoding = Windows.Storage.Streams.UnicodeEncoding.Utf8;
        uint bufferLength = (uint)reader.UnconsumedBufferLength;
        string receivedString = "";
        receivedString += reader.ReadString(bufferLength) + "\n";
        Console.WriteLine("Recieved Message: " + receivedString);
    }

    public static void GetDiscoverableDevices()
    {
        Console.WriteLine("Search started");
        watcher.Received += bluetoothFoundAsync;
        watcher.ScanningMode = BluetoothLEScanningMode.Active;
        watcher.Start();
    }

    private static async void bluetoothFoundAsync(BluetoothLEAdvertisementWatcher sender, BluetoothLEAdvertisementReceivedEventArgs args)
    {
        string deviceName = args.Advertisement.LocalName;
        if (deviceName == "Carduino")
        {
            var bdevice = await BluetoothLEDevice.FromBluetoothAddressAsync(args.BluetoothAddress);
            watcher.Stop();
            Console.WriteLine("Scan complete: Found Carduino");
            bdevice.DeviceInformation.Pairing.Custom.PairingRequested +=
                    (ss, ev) =>
                    {
                        ev.Accept();
                    };
            var result = await bdevice.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ConfirmOnly);
            Console.WriteLine($"Pairing Result: {result.Status}");
            if (result.Status == DevicePairingResultStatus.AlreadyPaired)
            {
                Console.WriteLine("Attempting Reconnection");
                var a = await bdevice.DeviceInformation.Pairing.UnpairAsync();
                var result2 = await bdevice.DeviceInformation.Pairing.Custom.PairAsync(DevicePairingKinds.ConfirmOnly);
                Console.WriteLine($"Pairing Result: {result2.Status}");
            }
            ble = bdevice;
            getServices();
        }
        else
        {
            Console.WriteLine("Couldn't find device: 'Carduino'");
        }
    }

    private static async void getServices()
    {
        GattDeviceServicesResult result = await ble.GetGattServicesAsync();
        if (result.Status == GattCommunicationStatus.Success)
        {
            var services = result.Services;
            getCharacterstics(services);
        }
    }

    private static async void getCharacterstics(IReadOnlyList<GattDeviceService> services)
    {
        foreach (GattDeviceService s in services)
        {
            GattCharacteristicsResult result = await s.GetCharacteristicsAsync();
            if (result.Status == GattCommunicationStatus.Success)
            {
                var characteristicss = result.Characteristics;
                foreach (GattCharacteristic c in characteristicss)
                {
                    characterstics.Add(c);
                    if (c.Uuid == Guid.Parse("0000ffe1-0000-1000-8000-00805f9b34fb"))
                    {
                        readwrite = c;
                        Console.WriteLine("Found read/write characteristic");
                    }
                }
            }
        }
        subscribe = false;
        Console.WriteLine("Got characteristics");

    }

}

Заранее спасибо.

Изменить:

После дальнейшего тестирования кажется, что он работает только в консольном приложении .NET, а не в приложении формы Windows или .NET WPF.

...