public async Task <bool> BleClientWriteChar(BleGattCharacteristic character, byte[] data) { return(await Task.Run(() => { if (!character.Service.GattDevice.Connected) { Error("[CSR]:BleClientWriteChar when device is not connect!"); return false; } var value = Marshal.AllocHGlobal(data.Length); Marshal.Copy(data, 0, value, data.Length); if (CsrBleDll.CsrBleClientWriteCharByHandle( character.Service.GattDevice.Handle, false, character.Handle, (ushort)data.Length, value)) { if (_writeEvent.WaitOne(5000)) { Marshal.FreeHGlobal(value); Debug("[CSR]:BleClientWriteChar Success!"); return true; } } Marshal.FreeHGlobal(value); Debug("[CSR]:BleClientWriteChar Fail!"); return false; })); }
/// <summary> /// Get the list of the GATT characteristics included in a specific GATT service /// </summary> /// <returns>List of the included GATT characteristics</returns> public async Task <IList <BleGattCharacteristic> > GetCharacteristicsAsync(BleGattService service) { List <BleGattCharacteristic> characteristics = new List <BleGattCharacteristic>(); GattDeviceService gatt_service = service.Context as GattDeviceService; GattCharacteristicsResult result = await gatt_service.GetCharacteristicsAsync(BluetoothCacheMode.Uncached); foreach (GattCharacteristic characteristic in result.Characteristics) { BleGattCharacteristic ble_characteristic = new BleGattCharacteristic(); ble_characteristic.Name = ""; ble_characteristic.Guid = characteristic.Uuid; ble_characteristic.Context = characteristic; ble_characteristic.CanRead = characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Read); ble_characteristic.CanWrite = ((characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Write)) || (characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.WriteWithoutResponse))); ble_characteristic.CanNotify = ((characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify)) || (characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Indicate))); characteristics.Add(ble_characteristic); _ble_characteristics.Add(characteristic, ble_characteristic); } return(characteristics); }
public void BleClientWriteConfig(BleGattCharacteristic character, byte config) { if (!character.Service.GattDevice.Connected) { Error("[CSR]:BleClientWriteConfig when device is not connect!"); return; } if (!CsrBleDll.CsrBleClientWriteConfiguration(character.Service.GattDevice.Handle, character.DescriptorHandle, character.Handle, config)) { Error("[CSR]:BleClientWriteConfig Fail!"); } }
/// <summary> /// Write a value into a GATT characteristic /// </summary> /// <param name="characteristic">GATT characteristic</param> /// <param name="value">Value</param> /// <returns>true if the operation succeeded, false otherwise</returns> public async Task <bool> WriteValueAsync(BleGattCharacteristic characteristic, BleValue value) { bool ret = false; GattCharacteristic gatt_characteristic = characteristic.Context as GattCharacteristic; IBuffer buffer = CryptographicBuffer.CreateFromByteArray(value.Value); GattWriteResult result = await gatt_characteristic.WriteValueWithResultAsync(buffer, GattWriteOption.WriteWithResponse); if (result.Status == GattCommunicationStatus.Success) { ret = true; } return(ret); }
/// <summary> /// Read a value from a GATT characteristic /// </summary> /// <param name="characteristic">GATT characteristic</param> /// <param name="value">Value</param> /// <returns>true if the operation succeeded, false otherwise</returns> public async Task <bool> ReadValueAsync(BleGattCharacteristic characteristic, BleValue value) { bool ret = false; GattCharacteristic gatt_characteristic = characteristic.Context as GattCharacteristic; GattReadResult result = await gatt_characteristic.ReadValueAsync(BluetoothCacheMode.Uncached); if (result.Status == GattCommunicationStatus.Success) { byte[] val; CryptographicBuffer.CopyToByteArray(result.Value, out val); value.Value = val; ret = true; } return(ret); }
/// <summary> /// Called on notification on a GATT characteristic /// </summary> /// <param name="sender">GATT characteristic</param> /// <param name="args">Notified value</param> private void OnCharacteristicNotification(GattCharacteristic sender, GattValueChangedEventArgs args) { try { BleGattCharacteristic ble_characteristic = _ble_characteristics[sender]; IBuffer value = args.CharacteristicValue; CryptographicBuffer.CopyToByteArray(value, out byte[] val); Action <BleGattCharacteristic, BleValue> listener = null; lock (_ble_notification_listeners) { listener = _ble_notification_listeners[ble_characteristic]; } listener.Invoke(ble_characteristic, new BleValue(val)); } catch (KeyNotFoundException) {} }
/// <summary> /// Unregister from notifications from a GATT characteristic /// </summary> /// <param name="characteristic">GATT characteristic</param> /// <param name="listener">Method which is called on each value notification</param> /// <returns>true if the operation succeeded, false otherwise</returns> public async Task <bool> UnregisterValueNotificationAsync(BleGattCharacteristic characteristic, Action <BleGattCharacteristic, BleValue> listener) { bool ret = false; if (!_ble_notification_listeners.ContainsKey(characteristic)) { GattCharacteristic gatt_characteristic = characteristic.Context as GattCharacteristic; await gatt_characteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(GattClientCharacteristicConfigurationDescriptorValue.None); lock (_ble_notification_listeners) { _ble_notification_listeners.Remove(characteristic); } gatt_characteristic.ValueChanged -= OnCharacteristicNotification; ret = true; } return(ret); }
/// <summary> /// Get the list of the GATT descriptors included in a specific GATT characteristic /// </summary> /// <returns>List of the included GATT descriptors</returns> public async Task <IList <BleGattDescriptor> > GetDescriptorsAsync(BleGattCharacteristic characteristic) { List <BleGattDescriptor> descriptors = new List <BleGattDescriptor>(); GattCharacteristic gatt_characteristic = characteristic.Context as GattCharacteristic; GattDescriptorsResult result = await gatt_characteristic.GetDescriptorsAsync(BluetoothCacheMode.Uncached); foreach (GattDescriptor descriptor in result.Descriptors) { BleGattDescriptor ble_descriptor = new BleGattDescriptor(); ble_descriptor.Name = ""; ble_descriptor.Guid = descriptor.Uuid; ble_descriptor.Context = descriptor; descriptors.Add(ble_descriptor); } return(descriptors); }
/// <summary> /// Register to notifications from a GATT characteristic /// </summary> /// <param name="characteristic">GATT characteristic</param> /// <param name="listener">Method which will be called on each value notification</param> /// <returns>true if the operation succeeded, false otherwise</returns> public async Task <bool> RegisterValueNotificationAsync(BleGattCharacteristic characteristic, Action <BleGattCharacteristic, BleValue> listener) { bool ret = false; GattCharacteristic gatt_characteristic = characteristic.Context as GattCharacteristic; GattClientCharacteristicConfigurationDescriptorValue value; if (gatt_characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Notify)) { value = GattClientCharacteristicConfigurationDescriptorValue.Notify; } else if (gatt_characteristic.CharacteristicProperties.HasFlag(GattCharacteristicProperties.Indicate)) { value = GattClientCharacteristicConfigurationDescriptorValue.Indicate; } else { value = GattClientCharacteristicConfigurationDescriptorValue.None; } if (value != GattClientCharacteristicConfigurationDescriptorValue.None) { if (!_ble_notification_listeners.ContainsKey(characteristic)) { GattWriteResult result = await gatt_characteristic.WriteClientCharacteristicConfigurationDescriptorWithResultAsync(value); if (result.Status == GattCommunicationStatus.Success) { lock (_ble_notification_listeners) { _ble_notification_listeners.Add(characteristic, listener); } gatt_characteristic.ValueChanged += OnCharacteristicNotification; ret = true; } } } return(ret); }
public async Task <byte[]> BleClientReadChar(BleGattCharacteristic character) { return(await Task.Run(() => { if (!character.Service.GattDevice.Connected) { Error("[CSR]:BleClientReadChar when device is not connect!"); return null; } if (CsrBleDll.CsrBleClientReadCharByHandle(character.Service.GattDevice.Handle, character.Handle)) { if (_readEvent.WaitOne(5000)) { Debug("[CSR]:BleClientReadChar Success!"); return _readBytes; } } Debug("[CSR]:BleClientReadChar Fail!"); return null; })); }
private void OnClientDatabaseDiscoveryResult(CSR_BLE_DATABASE_DISCOVERY_RESULT database) { var gattDevice = GattConnectDevices.Find(d => d.Handle == database.connectHandle); if (gattDevice == null || database.result != 0) { Error("[CSR]:Database Discover Error " + gattDevice?.Address); return; } gattDevice.NService = database.nServices; //update GattDevice services and characteristics for (var i = 0; i < database.nServices; i++) { var service = (CSR_BLE_SERVICE) Marshal.PtrToStructure(database.services + i * Marshal.SizeOf(typeof(CSR_BLE_SERVICE)), typeof(CSR_BLE_SERVICE)); Debug($"[CSR]:Service -Uuid:{service.uuid} -nCharacters:{service.nCharacteristics}"); var gattService = new BleGattService { GattDevice = gattDevice, Uuid = service.uuid.uuid16, StartHandle = service.startHandle, EndHandle = service.endHandle, NCharacters = service.nCharacteristics }; gattDevice.AddGattService(gattService); // add gattCharacteristic to gattService for (var j = 0; j < service.nCharacteristics; j++) { var character = (CSR_BLE_CHARACTERISTIC) Marshal.PtrToStructure( service.characteristics + j * Marshal.SizeOf(typeof(CSR_BLE_CHARACTERISTIC)), typeof(CSR_BLE_CHARACTERISTIC)); var gattCharacter = new BleGattCharacteristic { Service = gattService, Uuid = character.uuid.uuid16, Handle = character.handle, DeclarationHandle = character.declHandle, NDescriptors = character.nDescriptors, Properties = character.properties }; if (character.nDescriptors > 0) { var descriptor = (CSR_BLE_CHARACTERISTIC_DSC)Marshal.PtrToStructure(character.descriptors, typeof(CSR_BLE_CHARACTERISTIC_DSC)); gattCharacter.DescriptorHandle = descriptor.handle; } gattService.AddCharacter(gattCharacter); } } _databaseEvent.Set(); }