示例#1
0
        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);
        }
示例#2
0
 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);
 }
示例#3
0
        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);
        }
示例#4
0
        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();
            }
        }
示例#5
0
        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();
            }
        }
示例#6
0
        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);
        }
示例#7
0
        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);
        }
示例#8
0
        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();
            }
        }
示例#9
0
 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));
 }
示例#10
0
 public abstract void WriteCharacteristicWithoutResponse(BleCharacteristic characteristic, byte[] value, int offset, int count, BleRequestFlags requestFlags);
示例#11
0
 public abstract byte[] ReadCharacteristic(BleCharacteristic characteristic, BleRequestFlags requestFlags);
示例#12
0
 public abstract void WriteDescriptor(BleDescriptor descriptor, byte[] value, int offset, int count, BleRequestFlags requestFlags);
示例#13
0
 public abstract byte[] ReadDescriptor(BleDescriptor descriptor, BleRequestFlags requestFlags);