Skip to content

Commit 87ad1d3

Browse files
committed
RELEASE 2.1.0 (May 4, 2019)
Added experimental Bluetooth Low Energy support on Windows. This part of the library may change in the future. Let me know how it works for you. Fixed a race condition in the exclusivity layer. Fixed a threading bug that cropped up on .NET Core on Linux. Serial devices that use Windows's buggy usbser.sys driver are now compatible with HIDSharp, including the detection of connection and disconnection. Signed-off-by: James F. Bellinger <http://www.zer7.com/software/hidsharp>
1 parent 57553f0 commit 87ad1d3

59 files changed

Lines changed: 3689 additions & 308 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

HidSharp.Test/Program.cs

Lines changed: 132 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,12 @@ under the License. */
2525
using System;
2626
using System.Diagnostics;
2727
using System.Linq;
28+
using System.Text;
2829
using System.Threading;
30+
using HidSharp.Experimental;
2931
using HidSharp.Reports;
3032
using HidSharp.Reports.Encodings;
33+
using HidSharp.Utility;
3134

3235
namespace HidSharp.Test
3336
{
@@ -65,9 +68,137 @@ static void WriteDeviceItemInputParserResult(Reports.Input.DeviceItemInputParser
6568

6669
static void Main(string[] args)
6770
{
71+
//Trace.Listeners.Clear();
72+
//Trace.Listeners.Add(new ConsoleTraceListener());
73+
74+
HidSharpDiagnostics.EnableTracing = true;
75+
HidSharpDiagnostics.PerformStrictChecks = true;
76+
6877
var list = DeviceList.Local;
6978
list.Changed += (sender, e) => Console.WriteLine("Device list changed.");
70-
79+
80+
//Console.WriteLine("Beginning discovery.");
81+
//using (list.BeginBleDiscovery())
82+
{
83+
84+
var allDeviceList = list.GetAllDevices().ToArray();
85+
Console.WriteLine("All device list:");
86+
foreach (Device dev in allDeviceList)
87+
{
88+
Console.WriteLine(dev.ToString() + " @ " + dev.DevicePath);
89+
/*
90+
if (dev is HidDevice)
91+
{
92+
foreach (var serialPort in
93+
(((HidDevice)dev).GetSerialPorts()))
94+
{
95+
Console.WriteLine(" " + serialPort);
96+
}
97+
}
98+
*/
99+
}
100+
101+
var bleDeviceList = list.GetBleDevices().ToArray();
102+
Console.WriteLine("BLE device list:");
103+
foreach (BleDevice dev in bleDeviceList)
104+
{
105+
Console.WriteLine(dev.ToString() + "@" + dev.DevicePath);
106+
foreach (var service in dev.GetServices())
107+
{
108+
Console.WriteLine(string.Format("\tService: {0}", service.Uuid));
109+
foreach (var characteristic in service.GetCharacteristics())
110+
{
111+
Console.WriteLine(string.Format("\t\tCharacteristic: {0} (Properties: {1})", characteristic.Uuid, characteristic.Properties));
112+
foreach (var descriptor in characteristic.GetDescriptors())
113+
{
114+
Console.WriteLine(string.Format("\t\t\tDescriptor: {0}", descriptor.Uuid));
115+
}
116+
}
117+
118+
if (service.Uuid == new BleUuid("63dc0001-fa35-4205-b09f-0fc6072ec515"))
119+
{
120+
try
121+
{
122+
using (var svc = dev.Open(service))
123+
{
124+
Console.WriteLine("Opened!");
125+
126+
BleCharacteristic rx = null;
127+
128+
foreach (var ch in service.GetCharacteristics())
129+
{
130+
Console.WriteLine(string.Format("{0} = {1}", ch.Uuid, ch.IsReadable ? string.Join(" ", svc.ReadCharacteristic(ch)) : "N/A"));
131+
132+
foreach (var d in ch.GetDescriptors())
133+
{
134+
Console.WriteLine(string.Format("\t{0} = {1}", d.Uuid, string.Join(" ", svc.ReadDescriptor(d))));
135+
}
136+
137+
if (BleCccd.Notification != svc.ReadCccd(ch))
138+
{
139+
svc.WriteCccd(ch, BleCccd.Notification);
140+
}
141+
142+
if (ch.Uuid == new BleUuid("63dc0002-fa35-4205-b09f-0fc6072ec515")) { rx = ch; }
143+
}
144+
145+
Action beginReadEvent = null;
146+
AsyncCallback endReadEvent = null;
147+
beginReadEvent = () =>
148+
{
149+
svc.BeginReadEvent(endReadEvent, null);
150+
};
151+
endReadEvent = ar =>
152+
{
153+
BleEvent @event;
154+
155+
try
156+
{
157+
@event = svc.EndReadEvent(ar);
158+
}
159+
catch (ObjectDisposedException)
160+
{
161+
Console.WriteLine("closed");
162+
return;
163+
}
164+
catch (TimeoutException)
165+
{
166+
Console.WriteLine("timed out");
167+
@event = default(BleEvent);
168+
}
169+
170+
if (@event.Value != null)
171+
{
172+
Console.WriteLine(string.Format("{0} -> {1}", @event.Characteristic, string.Join(" ", @event.Value.Select(x => x.ToString()))));
173+
174+
if (rx != null)
175+
{
176+
Console.WriteLine("writing");
177+
svc.WriteCharacteristicWithoutResponse(rx, new[] { (byte)0xdd, (byte)1, (byte)'A' });
178+
}
179+
}
180+
beginReadEvent();
181+
};
182+
beginReadEvent();
183+
184+
Thread.Sleep(30000);
185+
}
186+
}
187+
catch (Exception e)
188+
{
189+
Console.WriteLine(e.ToString());
190+
}
191+
}
192+
}
193+
}
194+
195+
Console.WriteLine();
196+
Console.WriteLine("Press any key");
197+
Console.ReadKey();
198+
Console.WriteLine();
199+
}
200+
//Console.WriteLine("Ending discovery.");
201+
71202
/*
72203
var serialDeviceList = list.GetSerialDevices().ToArray();
73204
Console.WriteLine("Serial device list:");

HidSharp/AsyncResult.cs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,12 @@ internal T EndOperation()
6969
}
7070
}
7171

72+
internal static T EndOperation(IAsyncResult asyncResult)
73+
{
74+
Throw.If.Null(asyncResult);
75+
return ((AsyncResult<T>)asyncResult).EndOperation();
76+
}
77+
7278
public AsyncCallback AsyncCallback
7379
{
7480
get;

HidSharp/CommonException.cs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#region License
2+
/* Copyright 2019 James F. Bellinger <http://www.zer7.com/software/hidsharp>
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
http://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing,
11+
software distributed under the License is distributed on an
12+
"AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
13+
KIND, either express or implied. See the License for the
14+
specific language governing permissions and limitations
15+
under the License. */
16+
#endregion
17+
18+
using System;
19+
20+
namespace HidSharp
21+
{
22+
static class CommonException
23+
{
24+
public static ObjectDisposedException CreateClosedException()
25+
{
26+
return new ObjectDisposedException("Closed.", (Exception)null);
27+
}
28+
}
29+
}

HidSharp/Device.cs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ under the License. */
1717

1818
using System;
1919
using System.Diagnostics;
20+
using HidSharp.Utility;
2021

2122
namespace HidSharp
2223
{
@@ -43,7 +44,8 @@ protected virtual DeviceStream OpenDeviceAndRestrictAccess(OpenConfiguration ope
4344
DeviceOpenUtility openUtility = null;
4445
if (exclusive)
4546
{
46-
openUtility = new DeviceOpenUtility(this, openConfig);
47+
string streamPath = GetStreamPath(openConfig);
48+
openUtility = new DeviceOpenUtility(this, streamPath, openConfig);
4749
openUtility.Open();
4850
}
4951

@@ -57,7 +59,7 @@ protected virtual DeviceStream OpenDeviceAndRestrictAccess(OpenConfiguration ope
5759
openUtility.InterruptRequested += (sender, e) =>
5860
{
5961
stream.OnInterruptRequested();
60-
Debug.WriteLine("** HIDSharp delivered an interrupt request.");
62+
HidSharpDiagnostics.Trace("Delivered an interrupt request.");
6163
};
6264
}
6365
}
@@ -72,6 +74,12 @@ protected virtual DeviceStream OpenDeviceAndRestrictAccess(OpenConfiguration ope
7274

7375
protected abstract DeviceStream OpenDeviceDirectly(OpenConfiguration openConfig);
7476

77+
// Used for exclusion... and also may be used inside OpenDeviceDirectly if desired.
78+
protected virtual string GetStreamPath(OpenConfiguration openConfig)
79+
{
80+
return DevicePath;
81+
}
82+
7583
/// <summary>
7684
/// Tries to make a connection to the device.
7785
/// </summary>

HidSharp/DeviceList.cs

Lines changed: 37 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
#region License
2-
/* Copyright 2015-2016, 2018 James F. Bellinger <http://www.zer7.com/software/hidsharp>
2+
/* Copyright 2015-2016, 2018-2019 James F. Bellinger <http://www.zer7.com/software/hidsharp>
33
44
Licensed under the Apache License, Version 2.0 (the "License");
55
you may not use this file except in compliance with the License.
@@ -20,6 +20,7 @@ under the License. */
2020
using System.ComponentModel;
2121
using System.Linq;
2222
using System.Runtime.InteropServices;
23+
using HidSharp.Experimental;
2324

2425
namespace HidSharp
2526
{
@@ -51,13 +52,44 @@ protected DeviceList()
5152

5253
}
5354

55+
/*
56+
public abstract BleDiscovery BeginBleDiscovery();
57+
*/
58+
59+
public virtual IEnumerable<Device> GetDevices(DeviceTypes types)
60+
{
61+
// Improve performance by implementing this override.
62+
return GetAllDevices().Where(device =>
63+
{
64+
if (device is HidDevice && 0 != (types & DeviceTypes.Hid)) { return true; }
65+
if (device is SerialDevice && 0 != (types & DeviceTypes.Serial)) { return true; }
66+
if (device is BleDevice && 0 != (types & DeviceTypes.Ble)) { return true; }
67+
return false;
68+
});
69+
}
70+
71+
public IEnumerable<Device> GetDevices(DeviceTypes types, DeviceFilter filter)
72+
{
73+
Throw.If.Null(filter, "filter");
74+
return GetDevices(types).Where(device => filter(device));
75+
}
76+
77+
/// <summary>
78+
/// Gets a list of all connected BLE devices.
79+
/// </summary>
80+
/// <returns>The device list.</returns>
81+
public IEnumerable<BleDevice> GetBleDevices()
82+
{
83+
return GetDevices(DeviceTypes.Ble).Cast<BleDevice>();
84+
}
85+
5486
/// <summary>
5587
/// Gets a list of all connected HID devices.
5688
/// </summary>
5789
/// <returns>The device list.</returns>
5890
public IEnumerable<HidDevice> GetHidDevices()
5991
{
60-
return GetAllDevices().OfType<HidDevice>();
92+
return GetDevices(DeviceTypes.Hid).Cast<HidDevice>();
6193
}
6294

6395
/// <summary>
@@ -70,7 +102,7 @@ public IEnumerable<HidDevice> GetHidDevices()
70102
/// <returns>The filtered device list.</returns>
71103
public IEnumerable<HidDevice> GetHidDevices(int? vendorID = null, int? productID = null, int? releaseNumberBcd = null, string serialNumber = null)
72104
{
73-
return GetAllDevices(d => DeviceFilterHelper.MatchHidDevices(d, vendorID, productID, releaseNumberBcd, serialNumber)).Cast<HidDevice>();
105+
return GetDevices(DeviceTypes.Hid, d => DeviceFilterHelper.MatchHidDevices(d, vendorID, productID, releaseNumberBcd, serialNumber)).Cast<HidDevice>();
74106
}
75107

76108
/// <summary>
@@ -79,11 +111,11 @@ public IEnumerable<HidDevice> GetHidDevices(int? vendorID = null, int? productID
79111
/// <returns>The device list.</returns>
80112
public IEnumerable<SerialDevice> GetSerialDevices()
81113
{
82-
return GetAllDevices().OfType<SerialDevice>();
114+
return GetDevices(DeviceTypes.Serial).Cast<SerialDevice>();
83115
}
84116

85117
/// <summary>
86-
/// Gets a list of all connected HID and serial devices.
118+
/// Gets a list of all connected HID, BLE, and serial devices.
87119
/// </summary>
88120
/// <returns>The device list.</returns>
89121
public abstract IEnumerable<Device> GetAllDevices();

0 commit comments

Comments
 (0)