public void WriteCccd(BleCharacteristic characteristic, BleCccd cccd, BleRequestFlags requestFlags) { Throw.If.Null(characteristic, "characteristic"); BleDescriptor descriptor; if (!characteristic.TryGetDescriptor(BleUuids.Cccd, out descriptor)) { HidSharpDiagnostics.Trace("Characteristic {0} does not have a CCCD, so {1} could not be written.", characteristic, cccd); return; } if (cccd == BleCccd.Notification) { HidSharpDiagnostics.PerformStrictCheck(characteristic.IsNotifiable, "Characteristic doesn't support Notify."); } if (cccd == BleCccd.Indication) { HidSharpDiagnostics.PerformStrictCheck(characteristic.IsIndicatable, "Characteristic doesn't support Indicate."); } var value = new byte[2]; value[0] = (byte)((ushort)cccd >> 0); value[1] = (byte)((ushort)cccd >> 8); WriteDescriptor(descriptor, value); }
static NativeMethods.BLUETOOTH_GATT_FLAGS GetGattFlags(BleRequestFlags requestFlags) { NativeMethods.BLUETOOTH_GATT_FLAGS flags = 0; if (0 != (requestFlags & BleRequestFlags.Authenticated)) { flags |= NativeMethods.BLUETOOTH_GATT_FLAGS.AUTHENTICATED; } if (0 != (requestFlags & BleRequestFlags.Encrypted)) { flags |= NativeMethods.BLUETOOTH_GATT_FLAGS.ENCRYPTED; } return(flags); }
public BleCccd ReadCccd(BleCharacteristic characteristic, BleRequestFlags requestFlags) { BleDescriptor descriptor; if (!characteristic.TryGetDescriptor(BleUuids.Cccd, out descriptor)) { HidSharpDiagnostics.Trace("Characteristic {0} does not have a CCCD, so it could not be read.", characteristic); return(BleCccd.None); } var value = ReadDescriptor(descriptor, requestFlags); var cccd = BleCccd.None; if (value.Length >= 1 && value[0] == (byte)BleCccd.Notification) { cccd = BleCccd.Notification; } if (value.Length >= 1 && value[0] == (byte)BleCccd.Indication) { cccd = BleCccd.Indication; } return(cccd); }
public override unsafe void WriteDescriptor(BleDescriptor descriptor, byte[] value, int offset, int count, BleRequestFlags requestFlags) { Throw.If.Null(descriptor, "descriptor").Null(value, "value").OutOfRange(value, offset, count); var flags = GetGattFlags(requestFlags); HandleAcquireIfOpenOrFail(); try { lock (_writeSync) { int error; var wd = (WinBleDescriptor)descriptor; var dvp = new NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE_PARAMS(); byte[] data = null; int dataOffset = 0, dataCount = 0; switch (wd.NativeData.DescriptorType) { case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicExtendedProperties: dvp.ExtendedProperties.IsReliableWriteEnabled = (byte)(value.Length >= 1 && 0 != (value[offset] & 1) ? 1 : 0); dvp.ExtendedProperties.IsAuxiliariesWritable = (byte)(value.Length >= 1 && 0 != (value[offset] & 2) ? 1 : 0); data = new byte[0]; break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ClientCharacteristicConfiguration: dvp.Cccd.IsSubscribeToNotification = (byte)(value.Length >= 1 && 0 != (value[offset] & 1) ? 1 : 0); dvp.Cccd.IsSubscribeToIndication = (byte)(value.Length >= 1 && 0 != (value[offset] & 2) ? 1 : 0); data = new byte[0]; break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ServerCharacteristicConfiguration: dvp.Sccd.IsBroadcast = (byte)(value.Length >= 1 && 0 != (value[offset] & 1) ? 1 : 0); data = new byte[0]; break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicFormat: throw new NotImplementedException(); default: data = value; dataOffset = offset; dataCount = count; break; } var db = stackalloc byte[NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE.Size + dataCount]; var dv = (NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE *)db; dv->DescriptorType = wd.NativeData.DescriptorType; dv->DescriptorUuid = wd.NativeData.DescriptorUuid; dv->Params = dvp; dv->Value.DataSize = (uint)dataCount; if (data != null) { Marshal.Copy(data, dataOffset, (IntPtr)(void *)&dv->Value.Data[0], dataCount); } error = NativeMethods.BluetoothGATTSetDescriptorValue(_handle, ref wd.NativeData, dv, flags); if (error != 0) { var message = string.Format("Failed to write {0} bytes to descriptor {1}.", count, descriptor); throw DeviceException.CreateIOException(Device, message, error); } } } finally { HandleRelease(); } }
public override unsafe byte[] ReadDescriptor(BleDescriptor descriptor, BleRequestFlags requestFlags) { Throw.If.Null(descriptor, "descriptor"); var flags = GetGattFlags(requestFlags); HandleAcquireIfOpenOrFail(); try { lock (_readSync) { int error; var wd = (WinBleDescriptor)descriptor; ushort valueSize; error = NativeMethods.BluetoothGATTGetDescriptorValue(_handle, ref wd.NativeData, 0, null, out valueSize, flags | ((requestFlags & BleRequestFlags.Cacheable) == 0 ? NativeMethods.BLUETOOTH_GATT_FLAGS.FORCE_READ_FROM_DEVICE : 0)); if (error != NativeMethods.ERROR_MORE_DATA || valueSize < NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE.Size) { var message = string.Format("Failed to read descriptor {0}.", descriptor); throw DeviceException.CreateIOException(Device, message, error); } var cb = stackalloc byte[valueSize]; var cv = (NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE *)cb; ushort valueSize2; error = NativeMethods.BluetoothGATTGetDescriptorValue(_handle, ref wd.NativeData, valueSize, cv, out valueSize2, flags); if (error != 0 || valueSize != valueSize2 || cv->Value.DataSize > valueSize - NativeMethods.BTH_LE_GATT_DESCRIPTOR_VALUE.Size) { var message = string.Format("Failed to read descriptor {0}.", descriptor); throw DeviceException.CreateIOException(Device, message, error); } byte[] data; switch (cv->DescriptorType) { case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicExtendedProperties: data = new byte[2]; if (0 != cv->Params.ExtendedProperties.IsReliableWriteEnabled) { data[0] |= 1; } if (0 != cv->Params.ExtendedProperties.IsAuxiliariesWritable) { data[0] |= 2; } break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ClientCharacteristicConfiguration: data = new byte[2]; if (0 != cv->Params.Cccd.IsSubscribeToNotification) { data[0] |= 1; } if (0 != cv->Params.Cccd.IsSubscribeToIndication) { data[0] |= 2; } break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.ServerCharacteristicConfiguration: data = new byte[2]; if (0 != cv->Params.Sccd.IsBroadcast) { data[0] |= 1; } break; case NativeMethods.BTH_LE_GATT_DESCRIPTOR_TYPE.CharacteristicFormat: throw new NotImplementedException(); default: //Console.WriteLine(string.Format("{0} {1} {2}", valueSize, cv->DescriptorType, cv->Value.DataSize)); data = new byte[cv->Value.DataSize]; Marshal.Copy((IntPtr)(void *)&cv->Value.Data[0], data, 0, data.Length); break; } return(data); } } finally { HandleRelease(); } }
public override void WriteCharacteristicWithoutResponse(BleCharacteristic characteristic, byte[] value, int offset, int count, BleRequestFlags requestFlags) { Throw.If.Null(characteristic, "characteristic"); HidSharpDiagnostics.PerformStrictCheck(characteristic.IsWritableWithoutResponse, "Characteristic doesn't support Write Without Response."); var flags = GetGattFlags(requestFlags); WriteCharacteristic(characteristic, value, offset, count, flags | NativeMethods.BLUETOOTH_GATT_FLAGS.WRITE_WITHOUT_RESPONSE); }
public override void WriteCharacteristic(BleCharacteristic characteristic, byte[] value, int offset, int count, BleRequestFlags requestFlags) { Throw.If.Null(characteristic, "characteristic"); HidSharpDiagnostics.PerformStrictCheck(characteristic.IsWritable, "Characteristic doesn't support Write."); var flags = GetGattFlags(requestFlags); WriteCharacteristic(characteristic, value, offset, count, flags); }
public override unsafe byte[] ReadCharacteristic(BleCharacteristic characteristic, BleRequestFlags requestFlags) { Throw.If.Null(characteristic, "characteristic"); HidSharpDiagnostics.PerformStrictCheck(characteristic.IsReadable, "Characteristic doesn't support Read."); var flags = GetGattFlags(requestFlags); HandleAcquireIfOpenOrFail(); try { lock (_readSync) { int error; var wc = (WinBleCharacteristic)characteristic; ushort valueSize; error = NativeMethods.BluetoothGATTGetCharacteristicValue(_handle, ref wc.NativeData, 0, null, out valueSize, flags | ((requestFlags & BleRequestFlags.Cacheable) == 0 ? NativeMethods.BLUETOOTH_GATT_FLAGS.FORCE_READ_FROM_DEVICE : 0)); if (error != NativeMethods.ERROR_MORE_DATA || valueSize < NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE.Size) { var message = string.Format("Failed to read characteristic {0}.", characteristic); throw DeviceException.CreateIOException(Device, message, error); } var cb = stackalloc byte[valueSize]; var cv = (NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE *)cb; ushort valueSize2; error = NativeMethods.BluetoothGATTGetCharacteristicValue(_handle, ref wc.NativeData, valueSize, cv, out valueSize2, flags); if (error != 0 || valueSize != valueSize2 || cv->DataSize > valueSize - NativeMethods.BTH_LE_GATT_CHARACTERISTIC_VALUE.Size) { var message = string.Format("Failed to read characteristic {0}.", characteristic); throw DeviceException.CreateIOException(Device, message, error); } var bytes = new byte[cv->DataSize]; Marshal.Copy((IntPtr)(void *)&cv->Data[0], bytes, 0, checked ((int)cv->DataSize)); return(bytes); } } finally { HandleRelease(); } }
public virtual IAsyncResult BeginWriteCharacteristicWithoutResponse(BleCharacteristic characteristic, byte[] value, int offset, int count, BleRequestFlags requestFlags, AsyncCallback callback, object state) { return(AsyncResult <int> .BeginOperation(delegate() { WriteCharacteristicWithoutResponse(characteristic, value, offset, count, requestFlags); return 0; }, callback, state)); }
public abstract void WriteCharacteristicWithoutResponse(BleCharacteristic characteristic, byte[] value, int offset, int count, BleRequestFlags requestFlags);
public abstract byte[] ReadCharacteristic(BleCharacteristic characteristic, BleRequestFlags requestFlags);
public abstract void WriteDescriptor(BleDescriptor descriptor, byte[] value, int offset, int count, BleRequestFlags requestFlags);
public abstract byte[] ReadDescriptor(BleDescriptor descriptor, BleRequestFlags requestFlags);