Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Characteristic ValueChanged Event is not triggering #19

Closed
CHIRAGGANDHI opened this issue Jul 27, 2018 · 11 comments
Closed

Characteristic ValueChanged Event is not triggering #19

CHIRAGGANDHI opened this issue Jul 27, 2018 · 11 comments

Comments

@CHIRAGGANDHI
Copy link

CHIRAGGANDHI commented Jul 27, 2018

We have developed an UWP application and use latest BLE library to work with BLE devices and everything works fine in UWP application

After that we have developed windows service and used UWP's BLE dll to work with BLE devices. In this application everything works fine except characteristic's ValueChanged event which is not getting trigger.

@drache42
Copy link
Contributor

Does it work with the BluetoothLEExplorer app from the store?

@CHIRAGGANDHI
Copy link
Author

Yes it works fine

@CHIRAGGANDHI
Copy link
Author

CHIRAGGANDHI commented Jul 30, 2018

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Windows.Devices.Bluetooth;
using Windows.Devices.Bluetooth.GenericAttributeProfile;
using Windows.Devices.Enumeration;
using Windows.Security.Cryptography;
using Windows.Storage.Streams;

namespace ConsoleApp1
{
class Program
{
static List devices = new List();

    static BluetoothLEDevice bluetoothLeDevice;

    static GattDeviceService gattDeviceService;

    static string serviceToSelect = "31040";

    static string writeCharacteristicToSelect = "22592";

    static string readCharacteristicToSelect = "54976";

    static GattCharacteristic readCharacteristic, writeCharacteristic;

    static void Main(string[] args)
    {
        DeviceOperations().GetAwaiter().GetResult();

        Console.ReadLine();
    }

    static async Task DeviceOperations()
    {
        string deviceToConnect = "9256A0010";

        await Task.Factory.StartNew(() =>
         {
             SearchBLEDevices();
         });

        // wait scan...
        Task.Delay(10 * 1000).Wait();

        Console.WriteLine("Devices:{0}", string.Join(",", devices.Select(x => x.Name).ToArray()));

        await PairDevice(deviceToConnect);

        await ConnectDevice(deviceToConnect);            

        await WriteCommandToDevice("<a01800100062492?;0566>");           

        await ReadValue();           
    }

    static void SearchBLEDevices()
    {
        string BTLEDeviceWatcherAQSString = "(System.Devices.Aep.ProtocolId:=\"{bb7bb05e-5972-42b5-94fc-76eaa7084d49}\")";

        // Query for extra properties you want returned
        string[] requestedProperties =
            {
                "System.Devices.Aep.Category",
                "System.Devices.Aep.ContainerId",
                "System.Devices.Aep.DeviceAddress",
                "System.Devices.Aep.IsConnected",
                "System.Devices.Aep.IsPaired",
                "System.Devices.Aep.IsPresent",
                "System.Devices.Aep.ProtocolId",
                "System.Devices.Aep.Bluetooth.Le.IsConnectable",
                "System.Devices.Aep.SignalStrength"
            };

        DeviceWatcher deviceWatcher =
                    DeviceInformation.CreateWatcher(
                            BTLEDeviceWatcherAQSString,
                            requestedProperties,
                            DeviceInformationKind.AssociationEndpoint);

        // Register event handlers before starting the watcher.
        // Added, Updated and Removed are required to get all nearby devices
        deviceWatcher.Added += DeviceWatcher_Added;
        deviceWatcher.Updated += DeviceWatcher_Updated;
        deviceWatcher.Removed += DeviceWatcher_Removed;

        // Start the watcher.
        deviceWatcher.Start();
    }

    private static void DeviceWatcher_Removed(DeviceWatcher sender, DeviceInformationUpdate args)
    {
        throw new NotImplementedException();
    }

    private static void DeviceWatcher_Updated(DeviceWatcher sender, DeviceInformationUpdate args)
    {
        throw new NotImplementedException();
    }

    private static void DeviceWatcher_Added(DeviceWatcher sender, DeviceInformation args)
    {
        devices.Add(args);
    }

    static async Task PairDevice(string deviceName)
    {
        DeviceInformation deviceToPair = devices.FirstOrDefault(x => x.Name.IndexOf(deviceName) > -1);

        if (deviceToPair != null)
        {
            DevicePairingResult result = await deviceToPair.Pairing.PairAsync();

            if (result.Status == DevicePairingResultStatus.Paired ||
                    result.Status == DevicePairingResultStatus.AlreadyPaired)
            {
                //return 0;
            }
            else
            {
                //return -2;
            }
        }
    }

    static async Task ConnectDevice(string deviceName)
    {
        DeviceInformation deviceToConnect = devices.FirstOrDefault(x => x.Name.IndexOf(deviceName) > -1);

        if (deviceToConnect != null)
        {
            bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(deviceToConnect.Id);
                           
            var result = await bluetoothLeDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached);

            Debug.WriteLine(result.Status);

            if(result.Status == GattCommunicationStatus.Success)
            {
                gattDeviceService = result.Services.FirstOrDefault(ser => GattUuidsService.ConvertUuidToName(ser.Uuid) == serviceToSelect);

                if (gattDeviceService != null)
                {
                    Console.WriteLine($"Service Selected:{GattUuidsService.ConvertUuidToName(gattDeviceService.Uuid)}");

                    var serviceAllCharacteristics = await gattDeviceService.GetCharacteristicsAsync(BluetoothCacheMode.Uncached);

                    if(serviceAllCharacteristics.Status == GattCommunicationStatus.Success)
                    {
                        readCharacteristic = serviceAllCharacteristics.Characteristics.FirstOrDefault(servchar => GattUuidsService.ConvertUuidToName(servchar.Uuid) == readCharacteristicToSelect);                                                 

                        if(readCharacteristic != null)
                        {
                            readCharacteristic.ValueChanged += ReadCharacteristic_ValueChanged;
                            
                            var charResult = await
                                                readCharacteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(
                                                    GattClientCharacteristicConfigurationDescriptorValue.Notify);

                            Console.WriteLine($"Read Characteristic Selected:{GattUuidsService.ConvertUuidToName(readCharacteristic.Uuid)}");

                            /*if (readCharacteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Read))
                            {
                                // This characteristic supports reading from it.
                                
                            }
                            if (readCharacteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Write))
                            {
                                // This characteristic supports writing to it.
                            }
                            if (readCharacteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify))
                            {
                                // This characteristic supports subscribing to notifications.
                            }*/
                        }

                        writeCharacteristic = serviceAllCharacteristics.Characteristics.FirstOrDefault(servchar => GattUuidsService.ConvertUuidToName(servchar.Uuid) == writeCharacteristicToSelect);

                        if (writeCharacteristic != null)
                        {
                            Console.WriteLine($"Write Characteristic Selected:{GattUuidsService.ConvertUuidToName(writeCharacteristic.Uuid)}");
                        }
                    }
                }
            }
        }
    }

    private static void ReadCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
    {
        throw new NotImplementedException();
    }

    static async Task WriteCommandToDevice(string deviceCommandToProcess)
    {
        byte[] byteData = new byte[deviceCommandToProcess.Length];

        int commandLength = deviceCommandToProcess.Length;

        for (int cmdChar = 0; cmdChar < deviceCommandToProcess.Length; cmdChar++)
        {
            byteData[cmdChar] = Convert.ToByte(deviceCommandToProcess[cmdChar]);
        }

        byte[] tmp = new byte[commandLength];

        IBuffer writeBuffer = null;
        BLECommon.ByteCopy(byteData, ref tmp, 0, commandLength);

        // byte to ibuffer
        DataWriter dataWriter = new DataWriter();
        dataWriter.WriteBytes(tmp);
        writeBuffer = dataWriter.DetachBuffer();
        await WriteCharacterValue(writeBuffer);
    }

    private static async Task<int> WriteCharacterValue(IBuffer sndbuf)
    {
        try
        {
            GattCommunicationStatus result = await writeCharacteristic.WriteValueAsync(sndbuf);

            Console.WriteLine($"WriteCharacterValue result:{result}");

            //await selectedReadCharacter.KeepRunnig(selectedWriteCharacter, sndbuf);
            if (result == GattCommunicationStatus.Unreachable)
            {
                return 1;
            }
            else if (result == GattCommunicationStatus.ProtocolError)
            {
                return 2;
            }
            else if (result == GattCommunicationStatus.Success)
            {
                //readCharacteristic.ValueChanged += ReadCharacteristic_ValueChanged;
                Console.WriteLine("Command Write Successfully");
                return 0;
            }
        }
        catch (Exception ex)
        {
            Debug.WriteLine("Write, Exception: " + ex.Message);
        }
        return 0;
    }        

    static async Task ReadValue()
    {
        GattReadResult result = await readCharacteristic.ReadValueAsync(BluetoothCacheMode.Uncached);
        if (result.Status == GattCommunicationStatus.Success)
        {
            var RawBufLen = (int)result.Value.Length;
            byte[] data;
            string strData = null;

            CryptographicBuffer.CopyToByteArray(result.Value, out data);
            //byte[] bytes = WindowsRuntimeBufferExtensions.ToArray(result.Value, 0, (int)result.Value.Length);

            for (int i = 0; i < data.Length; i++)
            {
                if (Convert.ToChar(data[i]) != '\0')
                {
                    strData = strData + Convert.ToChar(data[i]);
                }
            }

            Console.WriteLine("Data Received : " + strData);
        }
    }
} 

}

On Line number 159 "readCharacteristic.ValueChanged += ReadCharacteristic_ValueChanged;" I am registering for ValueChanged event which is not getting triggered but if I call "await ReadValue()" on line number 59 which returns value.

Same works with BLEExplorer app.

Why ReadCharacteristic_ValueChanged is not getting triggered?

@drache42
Copy link
Contributor

drache42 commented Jul 30, 2018 via email

@drache42
Copy link
Contributor

drache42 commented Jul 30, 2018 via email

@CHIRAGGANDHI
Copy link
Author

Yes....It is just to print selected characteristic name.We can comment it

@CHIRAGGANDHI
Copy link
Author

CHIRAGGANDHI commented Jul 30, 2018

As we can see I am writing command (sending command) to device which is to get current firmware version installed in device. So read characteristics will return firmware version.

When we send command to device using write characteristic , it returns value of that command which we can get using read characteristic but here value changed is not getting triggered

@drache42
Copy link
Contributor

drache42 commented Jul 31, 2018 via email

@CHIRAGGANDHI
Copy link
Author

Can we use uwp as windows service or some kind of background app which will keep running without user has to manually start it?

@drache42
Copy link
Contributor

drache42 commented Aug 17, 2018 via email

@FrankGorgenyi
Copy link
Contributor

Closing, as the OP noted above this works fine with the application from the store. The issue is either code or device compat and the OP using the thread for API support vs. form and their questions seem answered.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants