コード例 #1
0
        /// <summary>
        /// This function reads data from the specific BLE characteristic
        /// </summary>
        /// <param name="param"></param>
        //static async Task<int> ReadCharacteristic(string param)
        //{
        //    int retVal = 0;
        //    if (_selectedDevice != null)
        //    {
        //        if (!string.IsNullOrEmpty(param))
        //        {
        //            List<BluetoothLEAttributeDisplay> chars = new List<BluetoothLEAttributeDisplay>();

        //            string charName = string.Empty;
        //            var parts = param.Split('/');
        //            // Do we have parameter is in "service/characteristic" format?
        //            if (parts.Length == 2)
        //            {
        //                string serviceName = Utilities.GetIdByNameOrNumber(_services, parts[0]);
        //                charName = parts[1];

        //                // If device is found, connect to device and enumerate all services
        //                if (!string.IsNullOrEmpty(serviceName))
        //                {
        //                    var attr = _services.FirstOrDefault(s => s.Name.Equals(serviceName));
        //                    IReadOnlyList<GattCharacteristic> characteristics = new List<GattCharacteristic>();

        //                    try
        //                    {
        //                        // Ensure we have access to the device.
        //                        var accessStatus = await attr.service.RequestAccessAsync();
        //                        if (accessStatus == DeviceAccessStatus.Allowed)
        //                        {
        //                            var result = await attr.service.GetCharacteristicsAsync(BluetoothCacheMode.Uncached);
        //                            if (result.Status == GattCommunicationStatus.Success)
        //                                characteristics = result.Characteristics;
        //                        }
        //                    }
        //                    catch (Exception ex)
        //                    {
        //                        Console.WriteLine($"Restricted service. Can't read characteristics: {ex.Message}");
        //                        retVal += 1;
        //                    }

        //                    foreach (var c in characteristics)
        //                        chars.Add(new BluetoothLEAttributeDisplay(c));
        //                }
        //            }
        //            else if (parts.Length == 1)
        //            {
        //                if (_selectedService == null)
        //                {
        //                    if(!Console.IsOutputRedirected)
        //                        Console.WriteLine("No service is selected.");
        //                }
        //                chars = new List<BluetoothLEAttributeDisplay>(_characteristics);
        //                charName = parts[0];
        //            }

        //            // Read characteristic
        //            if (chars.Count > 0 && !string.IsNullOrEmpty(charName))
        //            {
        //                string useName = Utilities.GetIdByNameOrNumber(chars, charName);
        //                var attr = chars.FirstOrDefault(c => c.Name.Equals(useName));
        //                if (attr != null && attr.characteristic != null)
        //                {
        //                    // Read characteristic value
        //                    GattReadResult result = await attr.characteristic.ReadValueAsync(BluetoothCacheMode.Uncached);

        //                    if (result.Status == GattCommunicationStatus.Success)
        //                        Console.WriteLine(Utilities.FormatValue(result.Value, _dataFormat));
        //                    else
        //                    {
        //                        Console.WriteLine($"Read failed: {result.Status}");
        //                        retVal += 1;
        //                    }
        //                }
        //                else
        //                {
        //                    Console.WriteLine($"Invalid characteristic {charName}");
        //                    retVal += 1;
        //                }
        //            }
        //            else
        //            {
        //                Console.WriteLine("Nothing to read, please specify characteristic name or #.");
        //                retVal += 1;
        //            }
        //        }
        //        else
        //        {
        //            Console.WriteLine("Nothing to read, please specify characteristic name or #.");
        //            retVal += 1;
        //        }
        //    }
        //    else
        //    {
        //        Console.WriteLine("No BLE device connected.");
        //        retVal += 1;
        //    }
        //    return retVal;
        //}

        /// <summary>
        /// This function writes data from the specific BLE characteristic
        /// </summary>
        /// <param name="param">
        /// parameters should be:
        ///    [char_name] or [service_name/char_name] - specific characteristics
        ///    [data_value] - data to write; data will be interpreted depending of current display format,
        ///    wrong data format will cause write fail
        /// </param>
        /// <param name="userInput">
        /// we need whole user input (trimmed from spaces on beginning) in case of text input with spaces at the end
        //static async Task<int> WriteCharacteristic(string param)
        //{
        //    int retVal = 0;
        //    if (_selectedDevice != null)
        //    {
        //        if (!string.IsNullOrEmpty(param))
        //        {
        //            List<BluetoothLEAttributeDisplay> chars = new List<BluetoothLEAttributeDisplay>();

        //            string charName = string.Empty;

        //            // First, split data from char name (it should be a second param)
        //            var parts = param.Split(' ');
        //            if (parts.Length < 2)
        //            {
        //                Console.WriteLine("Insufficient data for write, please provide characteristic name and data.");
        //                retVal += 1;
        //                return retVal;
        //            }

        //            // Now try to convert data to the byte array by current format
        //            string data = param.Substring(parts[0].Length + 1);
        //            if (string.IsNullOrEmpty(data))
        //            {
        //                Console.WriteLine("Insufficient data for write.");
        //                retVal += 1;
        //                return retVal;
        //            }
        //            var buffer = Utilities.FormatData(data, _dataFormat);
        //            if (buffer != null)
        //            {
        //                // Now process service/characteristic names
        //                var charNames = parts[0].Split('/');

        //                // Do we have parameter is in "service/characteristic" format?
        //                if (charNames.Length == 2)
        //                {
        //                    string serviceName = Utilities.GetIdByNameOrNumber(_services, charNames[0]);
        //                    charName = charNames[1];

        //                    // If device is found, connect to device and enumerate all services
        //                    if (!string.IsNullOrEmpty(serviceName))
        //                    {
        //                        var attr = _services.FirstOrDefault(s => s.Name.Equals(serviceName));
        //                        IReadOnlyList<GattCharacteristic> characteristics = new List<GattCharacteristic>();
        //                        try
        //                        {
        //                            // Ensure we have access to the device.
        //                            var accessStatus = await attr.service.RequestAccessAsync();
        //                            if (accessStatus == DeviceAccessStatus.Allowed)
        //                            {
        //                                var result = await attr.service.GetCharacteristicsAsync(BluetoothCacheMode.Uncached);
        //                                if (result.Status == GattCommunicationStatus.Success)
        //                                    characteristics = result.Characteristics;
        //                            }
        //                            foreach (var c in characteristics)
        //                                chars.Add(new BluetoothLEAttributeDisplay(c));
        //                        }
        //                        catch (Exception ex)
        //                        {
        //                            Console.WriteLine($"Restricted service. Can't read characteristics: {ex.Message}");
        //                            retVal += 1;
        //                            return retVal;
        //                        }
        //                    }
        //                }
        //                else if (charNames.Length == 1)
        //                {
        //                    if (_selectedService == null)
        //                    {
        //                        if(!Console.IsOutputRedirected)
        //                            Console.WriteLine("No service is selected.");
        //                        retVal += 1;
        //                    }
        //                    chars = new List<BluetoothLEAttributeDisplay>(_characteristics);
        //                    charName = parts[0];
        //                }

        //                // Write characteristic
        //                if (chars.Count > 0 && !string.IsNullOrEmpty(charName))
        //                {
        //                    string useName = Utilities.GetIdByNameOrNumber(chars, charName);
        //                    var attr = chars.FirstOrDefault(c => c.Name.Equals(useName));
        //                    if (attr != null && attr.characteristic != null)
        //                    {
        //                        // Write data to characteristic
        //                        GattWriteResult result = await attr.characteristic.WriteValueWithResultAsync(buffer);
        //                        if (result.Status != GattCommunicationStatus.Success)
        //                        {
        //                            if (!Console.IsOutputRedirected)
        //                                Console.WriteLine($"Write failed: {result.Status}");
        //                            retVal += 1;
        //                        }
        //                    }
        //                    else
        //                    {
        //                        if (!Console.IsOutputRedirected)
        //                            Console.WriteLine($"Invalid characteristic {charName}");
        //                        retVal += 1;
        //                    }
        //                }
        //                else
        //                {
        //                    if (!Console.IsOutputRedirected)
        //                        Console.WriteLine("Please specify characteristic name or # for writing.");
        //                    retVal += 1;
        //                }
        //            }
        //            else
        //            {
        //                if (!Console.IsOutputRedirected)
        //                    Console.WriteLine("Incorrect data format.");
        //                retVal += 1;
        //            }
        //        }
        //    }
        //    else
        //    {
        //        if (!Console.IsOutputRedirected)
        //            Console.WriteLine("No BLE device connected.");
        //        retVal += 1;
        //    }
        //    return retVal;
        ////}

        /// <summary>
        /// This function used to add "ValueChanged" event subscription
        /// </summary>
        /// <param name="param"></param>
        static async Task <int> SubscribeToCharacteristic(string param)
        {
            int retVal = 0;

            if (_selectedDevice != null)
            {
                if (!string.IsNullOrEmpty(param))
                {
                    List <BluetoothLEAttributeDisplay> chars = new List <BluetoothLEAttributeDisplay>();

                    string charName = string.Empty;
                    var    parts    = param.Split('/');
                    // Do we have parameter is in "service/characteristic" format?
                    if (parts.Length == 2)
                    {
                        string serviceName = Utilities.GetIdByNameOrNumber(_services, parts[0]);
                        charName = parts[1];

                        // If device is found, connect to device and enumerate all services
                        if (!string.IsNullOrEmpty(serviceName))
                        {
                            var attr = _services.FirstOrDefault(s => s.Name.Equals(serviceName));
                            IReadOnlyList <GattCharacteristic> characteristics = new List <GattCharacteristic>();

                            try
                            {
                                // Ensure we have access to the device.
                                var accessStatus = await attr.service.RequestAccessAsync();

                                if (accessStatus == DeviceAccessStatus.Allowed)
                                {
                                    var result = await attr.service.GetCharacteristicsAsync(BluetoothCacheMode.Uncached);

                                    if (result.Status == GattCommunicationStatus.Success)
                                    {
                                        characteristics = result.Characteristics;
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
                                if (!Console.IsOutputRedirected)
                                {
                                    Console.WriteLine($"Restricted service. Can't subscribe to characteristics: {ex.Message}");
                                }
                                retVal += 1;
                            }

                            foreach (var c in characteristics)
                            {
                                chars.Add(new BluetoothLEAttributeDisplay(c));
                            }
                        }
                    }
                    else if (parts.Length == 1)
                    {
                        if (_selectedService == null)
                        {
                            if (!Console.IsOutputRedirected)
                            {
                                Console.WriteLine("No service is selected.");
                            }
                            retVal += 1;
                            return(retVal);
                        }
                        chars    = new List <BluetoothLEAttributeDisplay>(_characteristics);
                        charName = parts[0];
                    }

                    // Read characteristic
                    if (chars.Count > 0 && !string.IsNullOrEmpty(charName))
                    {
                        string useName = Utilities.GetIdByNameOrNumber(chars, charName);
                        var    attr    = chars.FirstOrDefault(c => c.Name.Equals(useName));
                        if (attr != null && attr.characteristic != null)
                        {
                            // First, check for existing subscription
                            if (!_subscribers.Contains(attr.characteristic))
                            {
                                var status = await attr.characteristic.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify);

                                if (status == GattCommunicationStatus.Success)
                                {
                                    _subscribers.Add(attr.characteristic);
                                    attr.characteristic.ValueChanged += Characteristic_ValueChanged;
                                }
                                else
                                {
                                    if (!Console.IsOutputRedirected)
                                    {
                                        Console.WriteLine($"Can't subscribe to characteristic {useName}");
                                    }
                                    retVal += 1;
                                }
                            }
                            else
                            {
                                if (!Console.IsOutputRedirected)
                                {
                                    Console.WriteLine($"Already subscribed to characteristic {useName}");
                                }
                                retVal += 1;
                            }
                        }
                        else
                        {
                            if (!Console.IsOutputRedirected)
                            {
                                Console.WriteLine($"Invalid characteristic {useName}");
                            }
                            retVal += 1;
                        }
                    }
                    else
                    {
                        if (!Console.IsOutputRedirected)
                        {
                            Console.WriteLine("Nothing to subscribe, please specify characteristic name or #.");
                        }
                        retVal += 1;
                    }
                }
                else
                {
                    if (!Console.IsOutputRedirected)
                    {
                        Console.WriteLine("Nothing to subscribe, please specify characteristic name or #.");
                    }
                    retVal += 1;
                }
            }
            else
            {
                if (!Console.IsOutputRedirected)
                {
                    Console.WriteLine("No BLE device connected.");
                }
                retVal += 1;
            }
            return(retVal);
        }
コード例 #2
0
        /// <summary>
        /// Connect to the specific device by name or number, and make this device current
        /// </summary>
        /// <param name="deviceName"></param>
        /// <returns></returns>
        static async Task <int> OpenDevice(string deviceName)
        {
            int retVal = 0;

            if (!string.IsNullOrEmpty(deviceName))
            {
                var    devs    = _deviceList.OrderBy(d => d.Name).Where(d => !string.IsNullOrEmpty(d.Name)).ToList();
                string foundId = Utilities.GetIdByNameOrNumber(devs, deviceName);

                // If device is found, connect to device and enumerate all services
                if (!string.IsNullOrEmpty(foundId))
                {
                    _selectedCharacteristic = null;
                    _selectedService        = null;
                    _services.Clear();

                    try
                    {
                        // only allow for one connection to be open at a time
                        if (_selectedDevice != null)
                        {
                            CloseDevice();
                        }

                        _selectedDevice = await BluetoothLEDevice.FromIdAsync(foundId).AsTask().TimeoutAfter(_timeout);

                        if (!Console.IsInputRedirected)
                        {
                            Console.WriteLine($"Connecting to {_selectedDevice.Name}.");
                        }

                        var result = await _selectedDevice.GetGattServicesAsync(BluetoothCacheMode.Uncached);

                        if (result.Status == GattCommunicationStatus.Success)
                        {
                            if (!Console.IsInputRedirected)
                            {
                                Console.WriteLine($"Found {result.Services.Count} services:");
                            }

                            for (int i = 0; i < result.Services.Count; i++)
                            {
                                var serviceToDisplay = new BluetoothLEAttributeDisplay(result.Services[i]);
                                _services.Add(serviceToDisplay);
                                if (!Console.IsInputRedirected)
                                {
                                    Console.WriteLine($"#{i:00}: {_services[i].Name}");
                                }
                            }
                        }
                        else
                        {
                            Console.WriteLine($"Device {deviceName} is unreachable.");
                            retVal += 1;
                        }
                    }
                    catch
                    {
                        Console.WriteLine($"Device {deviceName} is unreachable.");
                        retVal += 1;
                    }
                }
                else
                {
                    retVal += 1;
                }
            }
            else
            {
                Console.WriteLine("Device name can not be empty.");
                retVal += 1;
            }
            return(retVal);
        }
コード例 #3
0
        /// <summary>
        /// Set active service for current device
        /// </summary>
        /// <param name="parameters"></param>
        static async Task <int> SetService(string serviceName)
        {
            int retVal = 0;

            if (_selectedDevice != null)
            {
                if (!string.IsNullOrEmpty(serviceName))
                {
                    string foundName = Utilities.GetIdByNameOrNumber(_services, serviceName);

                    // If device is found, connect to device and enumerate all services
                    if (!string.IsNullOrEmpty(foundName))
                    {
                        var attr = _services.FirstOrDefault(s => s.Name.Equals(foundName));
                        IReadOnlyList <GattCharacteristic> characteristics = new List <GattCharacteristic>();

                        try
                        {
                            // Ensure we have access to the device.
                            var accessStatus = await attr.service.RequestAccessAsync();

                            if (accessStatus == DeviceAccessStatus.Allowed)
                            {
                                // BT_Code: Get all the child characteristics of a service. Use the cache mode to specify uncached characterstics only
                                // and the new Async functions to get the characteristics of unpaired devices as well.
                                var result = await attr.service.GetCharacteristicsAsync(BluetoothCacheMode.Uncached);

                                if (result.Status == GattCommunicationStatus.Success)
                                {
                                    characteristics  = result.Characteristics;
                                    _selectedService = attr;
                                    _characteristics.Clear();
                                    if (!Console.IsInputRedirected)
                                    {
                                        Console.WriteLine($"Selected service {attr.Name}.");
                                    }

                                    if (characteristics.Count > 0)
                                    {
                                        for (int i = 0; i < characteristics.Count; i++)
                                        {
                                            var charToDisplay = new BluetoothLEAttributeDisplay(characteristics[i]);
                                            _characteristics.Add(charToDisplay);
                                            if (!Console.IsInputRedirected)
                                            {
                                                Console.WriteLine($"#{i:00}: {charToDisplay.Name}\t{charToDisplay.Chars}");
                                            }
                                        }
                                    }
                                    else
                                    {
                                        if (!Console.IsOutputRedirected)
                                        {
                                            Console.WriteLine("Service don't have any characteristic.");
                                        }
                                        retVal += 1;
                                    }
                                }
                                else
                                {
                                    if (!Console.IsOutputRedirected)
                                    {
                                        Console.WriteLine("Error accessing service.");
                                    }
                                    retVal += 1;
                                }
                            }
                            // Not granted access
                            else
                            {
                                if (!Console.IsOutputRedirected)
                                {
                                    Console.WriteLine("Error accessing service.");
                                }
                                retVal += 1;
                            }
                        }
                        catch (Exception ex)
                        {
                            if (!Console.IsOutputRedirected)
                            {
                                Console.WriteLine($"Restricted service. Can't read characteristics: {ex.Message}");
                            }
                            retVal += 1;
                        }
                    }
                    else
                    {
                        if (!Console.IsOutputRedirected)
                        {
                            Console.WriteLine("Invalid service name or number");
                        }
                        retVal += 1;
                    }
                }
                else
                {
                    if (!Console.IsOutputRedirected)
                    {
                        Console.WriteLine("Invalid service name or number");
                    }
                    retVal += 1;
                }
            }
            else
            {
                if (!Console.IsOutputRedirected)
                {
                    Console.WriteLine("Nothing to use, no BLE device connected.");
                }
                retVal += 1;
            }

            return(retVal);
        }
コード例 #4
0
        /// <summary>
        /// Event handler for ValueChanged callback
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        static void Characteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args)
        {
            if (_primed)
            {
                // reference on parsing HR values: https://developer.polar.com/wiki/H6,_H7,_H10_and_OH1_Heart_rate_sensors#Bluetooth_LE_API_for_Windows_10

                //var newValue = Utilities.FormatValue(args.CharacteristicValue, _dataFormat);
                var newValue = Utilities.FormatValue(args.CharacteristicValue, DataFormat.Dec);

                // read just the second byte for HR value
                byte[] data;
                CryptographicBuffer.CopyToByteArray(args.CharacteristicValue, out data);
                var hrValue = (int)data[1];// + (data[2] << 8);

                bool rrPresent = ((data[0] & 0x10) >> 4) != 0;

                //if (Console.IsInputRedirected) Console.Write($"{newValue}");
                //else Console.Write($"Value changed for {sender.Uuid}: {newValue}\n");


                Console.Write($"HR {hrValue}");

                // to hold hrSample for LSL outlet
                double[] hrSample = { hrValue, -1.0, -1.0 };

                if (rrPresent)
                {
                    int rrValue = data[2] + (data[3] << 8);


                    Console.Write($"\trr interval: {rrValue}");

                    rrMovingAverage.AddObservation(rrValue);

                    hrSample[1] = rrValue;


                    if (rrMovingAverage.HasFullPeriod)
                    {
                        var rrStdDev = rrMovingAverage.StandardDeviation;
                        Console.Write($"\tstd dev rr: {rrStdDev}");
                        hrSample[2] = rrStdDev;
                    }

                    // push data to LSL outlet
                }

                outlet.push_sample(hrSample);

                Console.Write("\n");

                //if (_notifyCompleteEvent != null)
                //{
                //    _notifyCompleteEvent.Set();
                //    _notifyCompleteEvent = null;
                //}
            }
            else
            {
                _primed = true;
            }
        }