using System; using System.Runtime.InteropServices; using Microsoft.Win32.SafeHandles; namespace WorkIndicator.Delcom { public class Delcom { [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct HidTxPacketStruct { public Byte MajorCmd; public Byte MinorCmd; public Byte LSBData; public Byte MSBData; public Byte HidData0; public Byte HidData1; public Byte HidData2; public Byte HidData3; public Byte ExtData0; public Byte ExtData1; public Byte ExtData2; public Byte ExtData3; public Byte ExtData4; public Byte ExtData5; public Byte ExtData6; public Byte ExtData7; } [StructLayout(LayoutKind.Sequential, Pack = 1)] public struct HidRxPacketStruct { public Byte Data0; public Byte Data1; public Byte Data2; public Byte Data3; public Byte Data4; public Byte Data5; public Byte Data6; public Byte Data7; } private readonly DeviceManagement _deviceManagement = new DeviceManagement(); private readonly HID _hid = new HID(); private SafeFileHandle _deviceHandle; private Boolean _deviceDetected; private String _devicePathName; private UInt32 _matchingDevicesFound; private HidTxPacketStruct _transmitPacket; public bool RawCommand(int major, int minor, int lsbData, int msbData) { _transmitPacket.MajorCmd = Convert.ToByte(major); _transmitPacket.MinorCmd = Convert.ToByte(minor); _transmitPacket.LSBData = Convert.ToByte(lsbData); _transmitPacket.MSBData = Convert.ToByte(msbData); return HID.HidD_SetFeature(_deviceHandle, StructureToByteArray(_transmitPacket), 8); } public int WriteBlink(int lsb, int msb) { try { _transmitPacket.MajorCmd = 101; _transmitPacket.MinorCmd = 20; _transmitPacket.LSBData = Convert.ToByte(lsb); _transmitPacket.MSBData = Convert.ToByte(msb); int r = HID.HidD_SetFeature(_deviceHandle, StructureToByteArray(_transmitPacket), 8) ? 0 : 1; _transmitPacket.MajorCmd = 101; _transmitPacket.MinorCmd = 25; _transmitPacket.LSBData = Convert.ToByte(msb); _transmitPacket.MSBData = Convert.ToByte(0); HID.HidD_SetFeature(_deviceHandle, StructureToByteArray(_transmitPacket), 8); return r; } catch (Exception) { return 2; } } public int WritePorts(int port0, int port1) { try { _transmitPacket.MajorCmd = 101; _transmitPacket.MinorCmd = 10; _transmitPacket.LSBData = Convert.ToByte(port0); _transmitPacket.MSBData = Convert.ToByte(port1); return HID.HidD_SetFeature(_deviceHandle, StructureToByteArray(_transmitPacket), 8) ? 0 : 1; } catch (Exception) { return 2; } } public UInt32 ReadPort0(ref UInt32 port0) { try { Byte[] buffer = new Byte[16]; buffer[0] = 100; // Read ports command if (!HID.HidD_GetFeature(_deviceHandle, buffer, 8)) return 1; port0 = Convert.ToUInt32(buffer[0]); return 0; } catch (Exception) { return 2; } } public int ReadPorts(ref int port0, ref int port1) { try { Byte[] buffer = new Byte[16]; buffer[0] = 100; // Read ports command if (!HID.HidD_GetFeature(_deviceHandle, buffer, 8)) return 1; port0 = Convert.ToInt32(buffer[0]); port1 = Convert.ToInt32(buffer[1]); return 0; } catch (Exception) { return 2; } } public UInt32 Close() { try { if (_deviceHandle != null && !_deviceHandle.IsClosed) _deviceHandle.Close(); return 0; } catch (Exception) { return 2; } } public UInt32 Open() { return OpenNthDevice(1); } public UInt32 OpenNthDevice(UInt32 deviceIndex) { if (_deviceHandle != null) Close(); if (!FindTheHID(deviceIndex)) return 1; _deviceHandle = FileIODeclarations.CreateFile(_devicePathName, FileIODeclarations.GenericRead | FileIODeclarations.GenericWrite, FileIODeclarations.FileShareRead | FileIODeclarations.FileShareWrite, IntPtr.Zero, FileIODeclarations.OpenExisting, 0, 0); return _deviceHandle.IsInvalid ? 2 : (uint) 0; } public string GetDeviceName() { return _devicePathName; } public UInt32 GetDevicesCount() { FindTheHID(0); return _matchingDevicesFound; } private Boolean FindTheHID(UInt32 deviceIndex) { const ushort productId = 0xB080; const ushort vendorId = 0x0FC5; String[] devicePathName = new String[128]; Guid hidGuid = Guid.Empty; UInt32 matchingDevices = 0; _deviceDetected = false; HID.HidD_GetHidGuid(ref hidGuid); Boolean deviceFound = _deviceManagement.FindDeviceFromGuid(hidGuid, ref devicePathName); if (deviceFound) { Int32 memberIndex = 0; do { SafeFileHandle hidHandle = FileIODeclarations.CreateFile(devicePathName[memberIndex], FileIODeclarations.GenericRead | FileIODeclarations.GenericWrite, FileIODeclarations.FileShareRead | FileIODeclarations.FileShareWrite, IntPtr.Zero, FileIODeclarations.OpenExisting, 0, 0); if (!hidHandle.IsInvalid) { _hid.DeviceAttributes.Size = Marshal.SizeOf(_hid.DeviceAttributes); Boolean success = HID.HidD_GetAttributes(hidHandle, ref _hid.DeviceAttributes); if (success) { if (_hid.DeviceAttributes.VendorID == vendorId && _hid.DeviceAttributes.ProductID == productId) { matchingDevices++; _deviceDetected = true; } if (_deviceDetected && matchingDevices == deviceIndex) { _devicePathName = devicePathName[memberIndex]; hidHandle.Close(); } else { _deviceDetected = false; hidHandle.Close(); } } else { _deviceDetected = false; hidHandle.Close(); } } memberIndex = memberIndex + 1; } while (!(_deviceDetected || memberIndex == devicePathName.Length)); } _matchingDevicesFound = matchingDevices; return _deviceDetected; } private static byte[] StructureToByteArray(object obj) { int length = Marshal.SizeOf(obj); byte[] buffer = new byte[length]; IntPtr ptr = Marshal.AllocHGlobal(length); Marshal.StructureToPtr(obj, ptr, true); Marshal.Copy(ptr, buffer, 0, length); Marshal.FreeHGlobal(ptr); return buffer; } } }