private static async Task <GattCharacteristic> GetCharacteristicAsync(GattDeviceService service, Guid uuid) { var result = await service.GetCharacteristicsForUuidAsync(uuid); return(result.Characteristics[0]); }
// -->> Connect to sensor <<-- // Looks for an specific service and characteristic //_________________________________________________ private async void connectButton_Click(object sender, RoutedEventArgs e) { connectButton.IsEnabled = false; graph.Initialize(graphStackPanel, 1); graph.Background(Colors.WhiteSmoke); graph.AddPlot(Colors.Red); graph.AddPlot(Colors.Blue); graph.AddPlot(Colors.LimeGreen); rootPage.ShowProgressRing(connectingProgressRing, true); if (IsValueChangedHandlerRegistered) {// Reconnecting acquireButton.IsEnabled = false; foreach (GattCharacteristic characteristic in selectedCharacteristic) { characteristic.ValueChanged -= Characteristic_ValueChanged; } OnNewDataEnqueued -= OnNewDataEnqueuedFxn; IsValueChangedHandlerRegistered = false; acquireButton.Label = "Acquire"; acquireButton.Icon = new FontIcon { Glyph = "\uE9D9" }; selectedService = null; selectedCharacteristic = null; } if (rootPage.selectedDeviceId != null) {// A device has been selected try { // Creates BLE device from the selected DeviceID sensorTagBLE = await BluetoothLEDevice.FromIdAsync(rootPage.selectedDeviceId); } catch (Exception ex) when((uint)ex.HResult == 0x800710df) { // ERROR_DEVICE_NOT_AVAILABLE because the bluetooth radio is off } if (sensorTagBLE != null) { GattDeviceServicesResult servicesResult = null; GattCharacteristicsResult characResult = null; try // Try to get the service from the UUID Uncached { // Gets the UUID specific service directly from the device servicesResult = await sensorTagBLE.GetGattServicesForUuidAsync( BrService.BREATHINGSERVICE_UUID, BluetoothCacheMode.Uncached); } catch (Exception ex) { rootPage.notifyFlyout(ex.Message, connectButton); } //await dataService.Services.Single(s => s.Uuid == rootPage.COUNTER_SERVICE_UUID).GetCharacteristicsAsync(); if (servicesResult.Status == GattCommunicationStatus.Success) { selectedService = servicesResult.Services.Single(); Debug.WriteLine($"Service found: {selectedService.Uuid}"); try { // Gets the Breathing characteristic characResult = await selectedService.GetCharacteristicsForUuidAsync( BrService.BREATHING_UUID, BluetoothCacheMode.Uncached); } catch (Exception ex) { rootPage.notifyFlyout( "Can't read characteristics. Make sure service is not restricted. " + ex.Message, connectButton); } if (characResult.Status == GattCommunicationStatus.Success) { // SUCCESS!!! int number = characResult.Characteristics.Count(); rootPage.notifyFlyout(number.ToString() + " characteristics found", connectButton); foreach (GattCharacteristic characteristic in characResult.Characteristics) { selectedCharacteristic.Add(characteristic); } nameDeviceConnected.Text = $"Connected to {rootPage.selectedDeviceName}"; connectButton.Label = "Reconnect"; acquireButton.IsEnabled = true; rootPage.folderName = "Data Acquired"; rootPage.fileName = "data-" + rootPage.selectedDeviceName + DateTime.Now.ToString("_yyyy-dd-MM_HHmmss") + ".zZz"; rootPage.dataFolder = await ApplicationData.Current.LocalFolder.CreateFolderAsync(rootPage.folderName, CreationCollisionOption.OpenIfExists); rootPage.dataFile = await rootPage.dataFolder.CreateFileAsync(rootPage.fileName, CreationCollisionOption.ReplaceExisting); } else { rootPage.notifyFlyout( "Connection failed. Characteristic " + characResult.Status.ToString(), connectButton); } } else { // Failed because device... rootPage.notifyFlyout( "Connection failed: " + servicesResult.Status.ToString(), connectButton); } } else { // Device not found rootPage.notifyFlyout( "Connection failed. Check that the device is on.", connectButton); } } rootPage.ShowProgressRing(connectingProgressRing, false); connectButton.IsEnabled = true; }
private async void BleReceived(BluetoothLEAdvertisementWatcher w, BluetoothLEAdvertisementReceivedEventArgs btAdv) { if (w == null) { return; } if (btAdv == null) { return; } TimeSpan minTimeBetweenChecks = TimeSpan.FromSeconds(10); lock (_discoverylocker) { if (!_discover) { return; } //Stop(); if (_nonLaunchDevices.Contains(btAdv.BluetoothAddress)) { return; } if (!_lastChecked.ContainsKey(btAdv.BluetoothAddress)) { _lastChecked.Add(btAdv.BluetoothAddress, DateTime.Now); } else if (DateTime.Now - _lastChecked[btAdv.BluetoothAddress] < minTimeBetweenChecks) { return; } _lastChecked[btAdv.BluetoothAddress] = DateTime.Now; } Debug.WriteLine($"BLE advertisement received, aquiring device ..."); var deviceAwaiting = BluetoothLEDevice.FromBluetoothAddressAsync(btAdv.BluetoothAddress); if (deviceAwaiting == null) { return; } BluetoothLEDevice device = await deviceAwaiting; if (device == null) { return; } Debug.WriteLine($"BLE Device: {device.Name} ({device.DeviceId})"); if (device.Name != "Launch") { Debug.WriteLine("Not a Launch"); _nonLaunchDevices.Add(device.BluetoothAddress); device.Dispose(); return; } bool foundAndConnected = false; try { Thread.Sleep(1000); // SERVICES!! GattDeviceService service = (await device.GetGattServicesForUuidAsync(Launch.Uids.MainService)) .Services.FirstOrDefault(); if (service == null) { return; } Debug.WriteLine($"{device.Name} Main Services found!"); Debug.WriteLine("Service UUID found!"); GattCharacteristic writeCharacteristics = (await service.GetCharacteristicsForUuidAsync(Launch.Uids.WriteCharacteristics)).Characteristics .FirstOrDefault(); GattCharacteristic notifyCharacteristics = (await service.GetCharacteristicsForUuidAsync(Launch.Uids.StatusNotificationCharacteristics)) .Characteristics.FirstOrDefault(); GattCharacteristic commandCharacteristics = (await service.GetCharacteristicsForUuidAsync(Launch.Uids.CommandCharacteristics)) .Characteristics.FirstOrDefault(); if (writeCharacteristics == null || commandCharacteristics == null || notifyCharacteristics == null) { return; } Debug.WriteLine("Characteristics found!"); Launch launch = new Launch(device, writeCharacteristics, notifyCharacteristics, commandCharacteristics); bool init = await launch.Initialize(); Debug.WriteLine("Launch Initialized: " + init.ToString().ToUpper() + "!"); foundAndConnected = true; OnDeviceFound(launch); Stop(); } catch (Exception e) { Debug.WriteLine("Exception: " + e.Message); device.Dispose(); } finally { if (!foundAndConnected) { Debug.WriteLine("Connect failed, try again ..."); Start(); } } }
public Toio(ulong address, GattDeviceService service) { SerialNumber = serialNumberCounter; serialNumberCounter++; Address = address; Service = service; // Initialize required characteristics Task task = Task.Run(async() => { var characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_IDInformation, BluetoothCacheMode.Uncached); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicIDInformation = characteristics.Characteristics.FirstOrDefault(); CharacteristicIDInformation.ValueChanged += CharacteristicIDInformation_ValueChanged; await CharacteristicIDInformation.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); this.characteristics.Add(CharacteristicIDInformation); } characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_MotionOrMagneticSensorInformation); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicMotionOrMagneticSensorInformation = characteristics.Characteristics.FirstOrDefault(); CharacteristicMotionOrMagneticSensorInformation.ValueChanged += CharacteristicMotionOrMagneticSensorInformation_ValueChanged; await CharacteristicMotionOrMagneticSensorInformation.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); this.characteristics.Add(CharacteristicMotionOrMagneticSensorInformation); } characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_ButtonInformation); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicButtonInformation = characteristics.Characteristics.FirstOrDefault(); CharacteristicButtonInformation.ValueChanged += CharacteristicButtonInformation_ValueChanged; await CharacteristicButtonInformation.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); this.characteristics.Add(CharacteristicButtonInformation); } characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_BatteryInformation); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicBatteryInformation = characteristics.Characteristics.FirstOrDefault(); CharacteristicBatteryInformation.ValueChanged += CharacteristicBatteryInformation_ValueChanged; await CharacteristicBatteryInformation.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.Notify); this.characteristics.Add(CharacteristicBatteryInformation); } characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_MotorControl); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicMotorControl = characteristics.Characteristics.FirstOrDefault(); this.characteristics.Add(CharacteristicMotorControl); } characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_LightControl); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicLightControl = characteristics.Characteristics.FirstOrDefault(); //await CharacteristicLightControl.WriteClientCharacteristicConfigurationDescriptorAsync(GattClientCharacteristicConfigurationDescriptorValue.) this.characteristics.Add(CharacteristicLightControl); } characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_SoundControl); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicSoundControl = characteristics.Characteristics.FirstOrDefault(); this.characteristics.Add(CharacteristicSoundControl); } characteristics = await Service.GetCharacteristicsForUuidAsync(Toio.CharacteristicUUID_Configuration); if (characteristics.Status == GattCommunicationStatus.Success) { CharacteristicConfiguration = characteristics.Characteristics.FirstOrDefault(); this.characteristics.Add(CharacteristicConfiguration); } }); task.Wait(); }
/// <summary> /// 连接函数,要使用await等待返回 /// </summary> /// <param name="deviceItem">ListView中选择的Item</param> /// <returns></returns> public async Task <bool> Connect(object deviceItem) { if (!await ClearBluetoothLEDeviceAsync()) { Update("重置状态错误,请重试"); return(false); } try { // BT_Code: BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent. var deviceID = deviceItem as DeviceInformationDisplayBase; bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(deviceID.Id); if (bluetoothLeDevice == null) { Update("连接设备失败"); } } catch (Exception ex) when(ex.HResult == E_DEVICE_NOT_AVAILABLE) { Update("蓝牙设备未开启"); return(false); } catch (Exception ex) when(ex.GetType() == typeof(NullReferenceException)) { Update("没有成功选择列表里的选项"); return(false); } if (bluetoothLeDevice != null) { // Note: BluetoothLEDevice.GattServices property will return an empty list for unpaired devices. For all uses we recommend using the GetGattServicesAsync method. // BT_Code: GetGattServicesAsync returns a list of all the supported services of the device (even if it's not paired to the system). // If the services supported by the device are expected to change during BT usage, subscribe to the GattServicesChanged event. GattDeviceServicesResult deviceServicesResult = await bluetoothLeDevice.GetGattServicesForUuidAsync(serviceGuid); if (deviceServicesResult.Status == GattCommunicationStatus.Success) { //服务处理 deviceService = deviceServicesResult.Services[0]; Update($"对于选定设备,找到了 {deviceServicesResult.Services.Count} 个服务。"); //读特征处理 GattCharacteristicsResult readCharacteristicsResult = await deviceService.GetCharacteristicsForUuidAsync(readGuid); if (readCharacteristicsResult.Status == GattCommunicationStatus.Success) { readCharacteristic = readCharacteristicsResult.Characteristics[0]; Update($"对于选定设备,指定的GUID,找到了读特征。"); //订阅通知 // TODO: 这里暂时没有使用,因为string有bug,没想好怎么解决 // readCharacteristic.ValueChanged += ReadCharacteristic_ValueChanged; } else { Update("读特征查询失败"); /*return false;*/ } //写特征处理 GattCharacteristicsResult writeCharacteristicsResult = await deviceService.GetCharacteristicsForUuidAsync(writeGuid); if (writeCharacteristicsResult.Status == GattCommunicationStatus.Success) { writeCharacteristic = writeCharacteristicsResult.Characteristics[0]; Update($"对于选定设备,指定的GUID,找到了写特征。"); } else { Update("写特征查询失败"); return(false); } } else { Update("未找到任何服务"); return(false); } return(true); } else { MessageBox.Show("设备为null,请检查!", "对象错误", MessageBoxButton.OK, MessageBoxImage.Error); return(false); } }
/// <summary> /// Setup and connect to services for the discovered device. /// </summary> async Task SetupDevice() { State = BlueState.Connecting; try { Debug.WriteLineIf(sw.TraceVerbose, "++> Getting Bluetooth LE device"); // BluetoothLEDevice.FromIdAsync must be called from a UI thread because it may prompt for consent. bluetoothLeDevice = await BluetoothLEDevice.FromIdAsync(DeviceInfo.Id); } catch (Exception ex) when((uint)ex.HResult == 0x800710df) { ErrorMessage = "ERROR_DEVICE_NOT_AVAILABLE because the Bluetooth radio is not on."; } catch (Exception ex) { ErrorMessage = "FromIdAsync ERROR: " + ex.Message; } if (bluetoothLeDevice == null) { Disconnect(); return; } var sr = await bluetoothLeDevice.GetGattServicesForUuidAsync(uuidService, BluetoothCacheMode.Uncached); if (sr.Status != GattCommunicationStatus.Success || !sr.Services.Any()) { ErrorMessage = "Can't find service: " + sr.Status.ToString(); Disconnect(); return; } Service = sr.Services.First(); Debug.WriteLineIf(sw.TraceVerbose, "++> GattService found"); var accessStatus = await Service.RequestAccessAsync(); if (accessStatus != DeviceAccessStatus.Allowed) { // Not granted access ErrorMessage = "Error accessing service:" + accessStatus.ToString(); Disconnect(); return; } var charResult = await Service.GetCharacteristicsForUuidAsync(uuidTX, BluetoothCacheMode.Uncached); if (charResult.Status != GattCommunicationStatus.Success || !charResult.Characteristics.Any()) { ErrorMessage = "Error getting TX characteristic: " + charResult.Status.ToString(); Disconnect(); return; } _TX = charResult.Characteristics.First(); charResult = await Service.GetCharacteristicsForUuidAsync(uuidRX, BluetoothCacheMode.Uncached); if (charResult.Status != GattCommunicationStatus.Success || !charResult.Characteristics.Any()) { ErrorMessage = "Error getting RX characteristic: " + charResult.Status.ToString(); Disconnect(); return; } _RX = charResult.Characteristics.First(); try { Debug.WriteLineIf(sw.TraceVerbose, "++> Setting Notify descriptor"); var res = await _RX.WriteClientCharacteristicConfigurationDescriptorAsync( GattClientCharacteristicConfigurationDescriptorValue.Notify); if (res != GattCommunicationStatus.Success) { ErrorMessage = "Error setting RX notify: " + charResult.Status.ToString(); Disconnect(); return; } } catch (Exception ex) { ErrorMessage = "Exception setting RX notify: " + ex.Message; Disconnect(); return; } _RX.ValueChanged += Receive_ValueChanged; bluetoothLeDevice.ConnectionStatusChanged += BluetoothLeDevice_ConnectionStatusChanged; // now that services are connected, we're ready to go State = BlueState.Connected; }
public static async Task GetCharacteristic() { GattCharacteristic = (await GattDeviceService.GetCharacteristicsForUuidAsync(guid)).Characteristics[0]; }