USB HDI 通信

 

USB HDI通信类:

复制代码
  1  internal class HIDDevice
  2     {
  3         #region constants
  4         private const int DIGCF_DEFAULT = 0x1;
  5         private const int DIGCF_PRESENT = 0x2;
  6         private const int DIGCF_ALLCLASSES = 0x4;
  7         private const int DIGCF_PROFILE = 0x8;
  8         private const int DIGCF_DEVICEINTERFACE = 0x10;
  9 
 10         private const short FILE_ATTRIBUTE_NORMAL = 0x80;
 11         private const short INVALID_HANDLE_VALUE = -1;
 12         private const uint GENERIC_READ = 0x80000000;
 13         private const uint GENERIC_WRITE = 0x40000000;
 14         private const uint FILE_SHARE_READ = 0x00000001;
 15         private const uint FILE_SHARE_WRITE = 0x00000002;
 16         private const uint CREATE_NEW = 1;
 17         private const uint CREATE_ALWAYS = 2;
 18         private const uint OPEN_EXISTING = 3;
 19 
 20         #endregion
 21 
 22         #region win32_API_declarations
 23         [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
 24         static extern IntPtr SetupDiGetClassDevs(ref Guid ClassGuid,
 25                                                       IntPtr Enumerator,
 26                                                       IntPtr hwndParent,
 27                                                       uint Flags);
 28 
 29         [DllImport("hid.dll", SetLastError = true)]
 30         private static extern void HidD_GetHidGuid(ref Guid hidGuid);
 31 
 32         [DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
 33         private static extern Boolean SetupDiEnumDeviceInterfaces(
 34            IntPtr hDevInfo,
 35             //ref SP_DEVINFO_DATA devInfo,
 36            IntPtr devInfo,
 37            ref Guid interfaceClassGuid,
 38            UInt32 memberIndex,
 39            ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData
 40         );
 41 
 42         [DllImport(@"setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
 43         private static extern Boolean SetupDiGetDeviceInterfaceDetail(
 44            IntPtr hDevInfo,
 45            ref SP_DEVICE_INTERFACE_DATA deviceInterfaceData,
 46            ref SP_DEVICE_INTERFACE_DETAIL_DATA deviceInterfaceDetailData,
 47            UInt32 deviceInterfaceDetailDataSize,
 48            out UInt32 requiredSize,
 49            ref SP_DEVINFO_DATA deviceInfoData
 50         );
 51 
 52         [DllImport("setupapi.dll", CharSet = CharSet.Auto, SetLastError = true)]
 53         private static extern bool SetupDiDestroyDeviceInfoList(IntPtr DeviceInfoSet);
 54 
 55         [DllImport("kernel32.dll", SetLastError = true)]
 56         private static extern SafeFileHandle CreateFile(string lpFileName, uint dwDesiredAccess,
 57             uint dwShareMode, IntPtr lpSecurityAttributes, uint dwCreationDisposition,
 58             uint dwFlagsAndAttributes, IntPtr hTemplateFile);
 59 
 60         [DllImport("kernel32.dll", SetLastError = true)]
 61         private static extern bool ReadFile(SafeFileHandle hFile, byte[] lpBuffer,
 62            uint nNumberOfBytesToRead, ref uint lpNumberOfBytesRead, IntPtr lpOverlapped);
 63 
 64         [DllImport("kernel32.dll", SetLastError = true)]
 65         private static extern bool WriteFile(SafeFileHandle hFile, byte[] lpBuffer,
 66            uint nNumberOfBytesToWrite, ref uint lpNumberOfBytesWritten, IntPtr lpOverlapped);
 67 
 68         [DllImport("hid.dll", SetLastError = true)]
 69         private static extern bool HidD_GetPreparsedData(
 70             SafeFileHandle hObject,
 71             ref IntPtr PreparsedData);
 72 
 73         [DllImport("hid.dll", SetLastError = true)]
 74         private static extern Boolean HidD_FreePreparsedData(ref IntPtr PreparsedData);
 75 
 76         [DllImport("hid.dll", SetLastError = true)]
 77         private static extern int HidP_GetCaps(
 78             IntPtr pPHIDP_PREPARSED_DATA,                    // IN PHIDP_PREPARSED_DATA  PreparsedData,
 79             ref HIDP_CAPS myPHIDP_CAPS);                // OUT PHIDP_CAPS  Capabilities
 80 
 81         [DllImport("hid.dll", SetLastError = true)]
 82         private static extern Boolean HidD_GetAttributes(SafeFileHandle hObject, ref HIDD_ATTRIBUTES Attributes);
 83 
 84         [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
 85         private static extern bool HidD_GetFeature(
 86            IntPtr hDevice,
 87            IntPtr hReportBuffer,
 88            uint ReportBufferLength);
 89 
 90         [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
 91         private static extern bool HidD_SetFeature(
 92            IntPtr hDevice,
 93            IntPtr ReportBuffer,
 94            uint ReportBufferLength);
 95 
 96         [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
 97         private static extern bool HidD_GetProductString(
 98            SafeFileHandle hDevice,
 99            IntPtr Buffer,
100            uint BufferLength);
101 
102         [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
103         private static extern bool HidD_GetSerialNumberString(
104            SafeFileHandle hDevice,
105            IntPtr Buffer,
106            uint BufferLength);
107 
108         [DllImport("hid.dll", SetLastError = true, CallingConvention = CallingConvention.StdCall)]
109         private static extern Boolean HidD_GetManufacturerString(
110             SafeFileHandle hDevice,
111             IntPtr Buffer,
112             uint BufferLength);
113 
114         #endregion
115 
116         #region structs
117 
118         public struct interfaceDetails
119         {
120             public string manufacturer;
121             public string product;
122             public int serialNumber;
123             public ushort VID;
124             public ushort PID;
125             public string devicePath;
126             public int IN_reportByteLength;
127             public int OUT_reportByteLength;
128             public ushort versionNumber;
129         }
130 
131         // HIDP_CAPS
132         [StructLayout(LayoutKind.Sequential)]
133         private struct HIDP_CAPS
134         {
135             public System.UInt16 Usage;                    // USHORT
136             public System.UInt16 UsagePage;                // USHORT
137             public System.UInt16 InputReportByteLength;
138             public System.UInt16 OutputReportByteLength;
139             public System.UInt16 FeatureReportByteLength;
140             [MarshalAs(UnmanagedType.ByValArray, SizeConst = 17)]
141             public System.UInt16[] Reserved;                // USHORT  Reserved[17];            
142             public System.UInt16 NumberLinkCollectionNodes;
143             public System.UInt16 NumberInputButtonCaps;
144             public System.UInt16 NumberInputValueCaps;
145             public System.UInt16 NumberInputDataIndices;
146             public System.UInt16 NumberOutputButtonCaps;
147             public System.UInt16 NumberOutputValueCaps;
148             public System.UInt16 NumberOutputDataIndices;
149             public System.UInt16 NumberFeatureButtonCaps;
150             public System.UInt16 NumberFeatureValueCaps;
151             public System.UInt16 NumberFeatureDataIndices;
152         }
153 
154         [StructLayout(LayoutKind.Sequential)]
155         private struct SP_DEVINFO_DATA
156         {
157             public uint cbSize;
158             public Guid ClassGuid;
159             public uint DevInst;
160             public IntPtr Reserved;
161         }
162         [StructLayout(LayoutKind.Sequential)]
163         private struct SP_DEVICE_INTERFACE_DATA
164         {
165             public uint cbSize;
166             public Guid InterfaceClassGuid;
167             public uint Flags;
168             public IntPtr Reserved;
169         }
170         [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
171         private struct SP_DEVICE_INTERFACE_DETAIL_DATA
172         {
173             public int cbSize;
174             [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]
175             public string DevicePath;
176         }
177 
178         [StructLayout(LayoutKind.Sequential)]
179         private struct HIDD_ATTRIBUTES
180         {
181             public Int32 Size;
182             public Int16 VendorID;
183             public Int16 ProductID;
184             public Int16 VersionNumber;
185         }
186 
187         [StructLayout(LayoutKind.Sequential)]
188         private struct COMMTIMEOUTS
189         {
190             public UInt32 ReadIntervalTimeout;
191             public UInt32 ReadTotalTimeoutMultiplier;
192             public UInt32 ReadTotalTimeoutConstant;
193             public UInt32 WriteTotalTimeoutMultiplier;
194             public UInt32 WriteTotalTimeoutConstant;
195         }
196 
197         #endregion
198 
199         #region globals
200         public bool deviceConnected { get; set; }
201         private SafeFileHandle handle_read;
202         private SafeFileHandle handle_write;
203         private FileStream FS_read;
204         private FileStream FS_write;
205         private HIDP_CAPS capabilities;
206         public interfaceDetails productInfo;
207         public event dataReceivedEvent dataReceived;    //The calling class can subscribe to this event
208         public delegate void dataReceivedEvent(byte[] message);
209         public byte[] readData;
210         private bool useAsyncReads;
211 
212         #endregion
213 
214         #region static_methods
215 
216         public static interfaceDetails[] getConnectedDevices()
217         {
218             interfaceDetails[] devices = new interfaceDetails[0];
219 
220             //Create structs to hold interface information
221             SP_DEVINFO_DATA devInfo = new SP_DEVINFO_DATA();
222             SP_DEVICE_INTERFACE_DATA devIface = new SP_DEVICE_INTERFACE_DATA();
223             devInfo.cbSize = (uint)Marshal.SizeOf(devInfo);
224             devIface.cbSize = (uint)(Marshal.SizeOf(devIface));
225 
226             Guid G = new Guid();
227             HidD_GetHidGuid(ref G); //Get the guid of the HID device class
228 
229             IntPtr i = SetupDiGetClassDevs(ref G, IntPtr.Zero, IntPtr.Zero, DIGCF_DEVICEINTERFACE | DIGCF_PRESENT);
230 
231             //Loop through all available entries in the device list, until false
232             SP_DEVICE_INTERFACE_DETAIL_DATA didd = new SP_DEVICE_INTERFACE_DETAIL_DATA();
233             if (IntPtr.Size == 8) // for 64 bit operating systems
234                 didd.cbSize = 8;
235             else
236                 didd.cbSize = 4 + Marshal.SystemDefaultCharSize; // for 32 bit systems
237 
238             int j = -1;
239             bool b = true;
240             int error;
241             SafeFileHandle tempHandle;
242 
243             while (b)
244             {
245                 j++;
246 
247                 b = SetupDiEnumDeviceInterfaces(i, IntPtr.Zero, ref G, (uint)j, ref devIface);
248                 error = Marshal.GetLastWin32Error();
249                 if (b == false)
250                     break;
251 
252                 uint requiredSize = 0;
253                 bool b1 = SetupDiGetDeviceInterfaceDetail(i, ref devIface, ref didd, 256, out requiredSize, ref devInfo);
254                 string devicePath = didd.DevicePath;
255 
256                 //create file handles using CT_CreateFile
257                 tempHandle = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
258                     IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
259 
260                 //get capabilites - use getPreParsedData, and getCaps
261                 //store the reportlengths
262                 IntPtr ptrToPreParsedData = new IntPtr();
263                 bool ppdSucsess = HidD_GetPreparsedData(tempHandle, ref ptrToPreParsedData);
264                 if (ppdSucsess == false)
265                     continue;
266 
267                 HIDP_CAPS capabilities = new HIDP_CAPS();
268                 int hidCapsSucsess = HidP_GetCaps(ptrToPreParsedData, ref capabilities);
269 
270                 HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
271                 bool hidAttribSucsess = HidD_GetAttributes(tempHandle, ref attributes);
272 
273                 string productName = "";
274                 string SN = "";
275                 string manfString = "";
276                 IntPtr buffer = Marshal.AllocHGlobal(126);//max alloc for string; 
277                 if (HidD_GetProductString(tempHandle, buffer, 126)) productName = Marshal.PtrToStringAuto(buffer);
278                 if (HidD_GetSerialNumberString(tempHandle, buffer, 126)) SN = Marshal.PtrToStringAuto(buffer);
279                 if (HidD_GetManufacturerString(tempHandle, buffer, 126)) manfString = Marshal.PtrToStringAuto(buffer);
280                 Marshal.FreeHGlobal(buffer);
281 
282                 //Call freePreParsedData to release some stuff
283                 HidD_FreePreparsedData(ref ptrToPreParsedData);
284 
285                 //If connection was sucsessful, record the values in a global struct
286                 interfaceDetails productInfo = new interfaceDetails();
287                 productInfo.devicePath = devicePath;
288                 productInfo.manufacturer = manfString;
289                 productInfo.product = productName;
290                 productInfo.PID = (ushort)attributes.ProductID;
291                 productInfo.VID = (ushort)attributes.VendorID;
292                 productInfo.versionNumber = (ushort)attributes.VersionNumber;
293                 productInfo.IN_reportByteLength = (int)capabilities.InputReportByteLength;
294                 productInfo.OUT_reportByteLength = (int)capabilities.OutputReportByteLength;
295 
296                 if (stringIsInteger(SN))
297                     productInfo.serialNumber = Convert.ToInt32(SN);     //Check that serial number is actually a number
298 
299                 int newSize = devices.Length + 1;
300                 Array.Resize(ref devices, newSize);
301                 devices[newSize - 1] = productInfo;
302             }
303             SetupDiDestroyDeviceInfoList(i);
304 
305             return devices;
306         }
307 
308         #endregion
309 
310         #region constructors
311         /// <summary>
312         /// Creates an object to handle read/write functionality for a USB HID device
313         /// Uses one filestream for each of read/write to allow for a write to occur during a blocking
314         /// asnychronous read
315         /// </summary>
316         /// <param name="VID">The vendor ID of the USB device to connect to</param>
317         /// <param name="PID">The product ID of the USB device to connect to</param>
318         /// <param name="serialNumber">The serial number of the USB device to connect to</param>
319         /// <param name="useAsyncReads">True - Read the device and generate events on data being available</param>
320         public HIDDevice(ushort VID, ushort PID, int serialNumber, bool useAsyncReads)
321         {
322             interfaceDetails[] devices = getConnectedDevices();
323 
324             //loop through all connected devices to find one with the correct details
325             for (int i = 0; i < devices.Length; i++)
326             {
327                 if ((devices[i].VID == VID) && (devices[i].PID == PID) && (devices[i].serialNumber == (int)serialNumber))
328                     initDevice(devices[i].devicePath, useAsyncReads);
329             }
330 
331             if (!deviceConnected)
332             {
333                 string hexVID = numToHexString(VID);
334                 string hexPID = numToHexString(PID);
335                 throw new Exception("Device with VID: 0x" + hexVID + " PID: 0x" + hexPID + " SerialNumber: " + serialNumber.ToString() + " could not be found");
336             }
337         }
338 
339         /// <summary>
340         /// Creates an object to handle read/write functionality for a USB HID device
341         /// Uses one filestream for each of read/write to allow for a write to occur during a blocking
342         /// asnychronous read
343         /// </summary>
344         /// <param name="devicePath">The USB device path - from getConnectedDevices</param>
345         /// <param name="useAsyncReads">True - Read the device and generate events on data being available</param>
346         public HIDDevice(string devicePath, bool useAsyncReads)
347         {
348             initDevice(devicePath, useAsyncReads);
349 
350             if (!deviceConnected)
351             {
352                 throw new Exception("Device could not be found");
353             }
354         }
355 
356 
357         public HIDDevice(interfaceDetails productInfox)
358         {
359 
360 
361 
362 
363 
364 
365             deviceConnected = false;
366 
367             //create file handles using CT_CreateFile
368             handle_read = CreateFile(productInfox.devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
369                 IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
370 
371             handle_write = CreateFile(productInfox.devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
372                 IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
373 
374             //get capabilites - use getPreParsedData, and getCaps
375             //store the reportlengths
376             IntPtr ptrToPreParsedData = new IntPtr();
377             bool ppdSucsess = HidD_GetPreparsedData(handle_read, ref ptrToPreParsedData);
378 
379             capabilities = new HIDP_CAPS();
380             int hidCapsSucsess = HidP_GetCaps(ptrToPreParsedData, ref capabilities);
381 
382             HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
383             bool hidAttribSucsess = HidD_GetAttributes(handle_read, ref attributes);
384 
385 
386 
387             //Call freePreParsedData to release some stuff
388             HidD_FreePreparsedData(ref ptrToPreParsedData);
389             //SetupDiDestroyDeviceInfoList(i);
390 
391             if (handle_read.IsInvalid)
392                 return;
393 
394             deviceConnected = true;
395 
396             //If connection was sucsessful, record the values in a global struct
397             productInfo = productInfox;
398 
399 
400             //use a filestream object to bring this stuff into .NET
401             FS_write = new FileStream(handle_write, FileAccess.ReadWrite, capabilities.InputReportByteLength, false);
402             if (capabilities.OutputReportByteLength > 0)
403             {
404                 FS_read = new FileStream(handle_read, FileAccess.ReadWrite, capabilities.OutputReportByteLength, false);
405             }
406 
407 
408 
409             this.useAsyncReads = true;
410 
411             readAsync();
412 
413 
414         }
415 
416 
417         #endregion
418 
419         #region functions
420         private void initDevice(string devicePath, bool useAsyncReads)
421         {
422             deviceConnected = false;
423 
424             //create file handles using CT_CreateFile
425             handle_read = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
426                 IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
427 
428             handle_write = CreateFile(devicePath, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE,
429                 IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
430 
431             //get capabilites - use getPreParsedData, and getCaps
432             //store the reportlengths
433             IntPtr ptrToPreParsedData = new IntPtr();
434             bool ppdSucsess = HidD_GetPreparsedData(handle_read, ref ptrToPreParsedData);
435 
436             capabilities = new HIDP_CAPS();
437             int hidCapsSucsess = HidP_GetCaps(ptrToPreParsedData, ref capabilities);
438 
439             HIDD_ATTRIBUTES attributes = new HIDD_ATTRIBUTES();
440             bool hidAttribSucsess = HidD_GetAttributes(handle_read, ref attributes);
441 
442             string productName = "";
443             string SN = "";
444             string manfString = "";
445             IntPtr buffer = Marshal.AllocHGlobal(126);//max alloc for string; 
446             if (HidD_GetProductString(handle_read, buffer, 126)) productName = Marshal.PtrToStringAuto(buffer);
447             if (HidD_GetSerialNumberString(handle_read, buffer, 126)) SN = Marshal.PtrToStringAuto(buffer);
448             if (HidD_GetManufacturerString(handle_read, buffer, 126)) manfString = Marshal.PtrToStringAuto(buffer);
449             Marshal.FreeHGlobal(buffer);
450 
451             //Call freePreParsedData to release some stuff
452             HidD_FreePreparsedData(ref ptrToPreParsedData);
453             //SetupDiDestroyDeviceInfoList(i);
454 
455             if (handle_read.IsInvalid)
456                 return;
457 
458             deviceConnected = true;
459 
460             //If connection was sucsessful, record the values in a global struct
461             productInfo = new interfaceDetails();
462             productInfo.devicePath = devicePath;
463             productInfo.manufacturer = manfString;
464             productInfo.product = productName;
465             productInfo.serialNumber = Convert.ToInt32(SN);
466             productInfo.PID = (ushort)attributes.ProductID;
467             productInfo.VID = (ushort)attributes.VendorID;
468             productInfo.versionNumber = (ushort)attributes.VersionNumber;
469             productInfo.IN_reportByteLength = (int)capabilities.InputReportByteLength;
470             productInfo.OUT_reportByteLength = (int)capabilities.OutputReportByteLength;
471 
472             //use a filestream object to bring this stuff into .NET
473             FS_read = new FileStream(handle_read, FileAccess.ReadWrite, capabilities.OutputReportByteLength, false);
474             FS_write = new FileStream(handle_write, FileAccess.ReadWrite, capabilities.InputReportByteLength, false);
475 
476             this.useAsyncReads = useAsyncReads;
477             if (useAsyncReads)
478                 readAsync();
479         }
480 
481         public void close()
482         {
483             if (FS_read != null)
484                 FS_read.Close();
485             if (FS_write != null)
486                 FS_write.Close();
487 
488             if ((handle_read != null) && (!(handle_read.IsInvalid)))
489                 handle_read.Close();
490             if ((handle_write != null) && (!(handle_write.IsInvalid)))
491                 handle_write.Close();
492 
493             this.deviceConnected = false;
494         }
495 
496         public void write(byte[] data)
497         {
498             //if (data.Length > capabilities.OutputReportByteLength)
499             //    throw new Exception("Output report must not exceed " + (capabilities.OutputReportByteLength - 1).ToString() + " bytes");
500 
501             //uint numBytesWritten = 0;
502             byte[] packet = new byte[capabilities.OutputReportByteLength];
503             Array.Copy(data, 0, packet, 1, data.Length);            //start at 1, as the first byte must be zero for HID report
504             packet[0] = 0;
505 
506             if (FS_write.CanWrite)
507                 FS_write.Write(packet, 0, packet.Length);
508             else
509             {
510                 this.close();
511                 //throw new Exception("Device is unable to read");
512             } 
513         }
514 
515         //This read function will be used with asychronous operation, called by the constructor if async reads are used
516         private void readAsync()
517         {
518             readData = new byte[capabilities.InputReportByteLength];
519             if (FS_read.CanRead)
520                 FS_read.BeginRead(readData, 0, readData.Length, new AsyncCallback(GetInputReportData), readData);
521             else
522             {
523                 this.close();
524                 //throw new Exception("Device is unable to read");
525             } 
526         }
527 
528         private void GetInputReportData(IAsyncResult ar)
529         {
530             FS_read.EndRead(ar); //must call an endread before starting another one
531             //TODO handle exception with PCB is reaet
532 
533             //Reset the read thread to read the next report
534             if (FS_read.CanRead)
535                 FS_read.BeginRead(readData, 0, readData.Length, new AsyncCallback(GetInputReportData), readData);
536             else
537             {
538                 this.close();
539                 //throw new Exception("Device is unable to read");
540             }        
541             dataReceived(readData);                                     //triggers the event to be heard by the calling class
542         }
543 
544         /// <summary>
545         /// This read function is for normal synchronous reads
546         /// </summary>
547         /// <returns></returns>
548         public byte[] read()
549         {
550             if (useAsyncReads == true)
551                 throw new Exception("A synchonous read cannot be executed when operating in async mode");
552 
553             //Call readFile
554             byte[] readBuf = new byte[capabilities.InputReportByteLength];
555             FS_read.Read(readBuf, 0, readBuf.Length);
556             return readBuf;
557         }
558         #endregion
559 
560         #region utilities
561 
562         public static bool stringIsInteger(string val)
563         {
564             Double result;
565             return Double.TryParse(val, System.Globalization.NumberStyles.Integer,
566                 System.Globalization.CultureInfo.CurrentCulture, out result);
567         }
568 
569         public static string numToHexString(ushort num)
570         {
571             return String.Format("{0:X}", num);
572         }
573 
574         #endregion
575     }
复制代码

 

使用方法:

复制代码
        HIDDevice device;
        HIDDevice.interfaceDetails[] devices;  


     devices = HIDDevice.getConnectedDevices(); 

  device = new HIDDevice(devices[i]);
                    device.dataReceived += new 
 HIDDevice.dataReceivedEvent(device_dataReceived);   




 device.write(byte[]); 

void device_dataReceived(byte[] message) { }
复制代码

 

posted @   未风  阅读(387)  评论(0编辑  收藏  举报
努力加载评论中...
点击右上角即可分享
微信分享提示