protected override void Run(Action readyCallback) { using (var manager = NativeMethods.IOHIDManagerCreate(IntPtr.Zero).ToCFType()) { RunAssert(manager.IsSet, "HidSharp IOHIDManagerCreate failed."); using (var matching = NativeMethods.IOServiceMatching("IOHIDDevice").ToCFType()) { RunAssert(matching.IsSet, "HidSharp IOServiceMatching failed."); var devicesChangedCallback = new NativeMethods.IOHIDDeviceCallback(DevicesChangedCallback); NativeMethods.IOHIDManagerSetDeviceMatching(manager.Handle, matching.Handle); NativeMethods.IOHIDManagerRegisterDeviceMatchingCallback(manager.Handle, devicesChangedCallback, IntPtr.Zero); NativeMethods.IOHIDManagerRegisterDeviceRemovalCallback(manager.Handle, devicesChangedCallback, IntPtr.Zero); var runLoop = NativeMethods.CFRunLoopGetCurrent(); NativeMethods.CFRetain(runLoop); NativeMethods.IOHIDManagerScheduleWithRunLoop(manager, runLoop, NativeMethods.kCFRunLoopDefaultMode); try { readyCallback(); NativeMethods.CFRunLoopRun(); } finally { NativeMethods.IOHIDManagerUnscheduleFromRunLoop(manager, runLoop, NativeMethods.kCFRunLoopDefaultMode); NativeMethods.CFRelease(runLoop); } GC.KeepAlive(devicesChangedCallback); } } }
internal void Init(NativeMethods.io_string_t path) { IntPtr handle; int retryCount = 0, maxRetries = 10; while (true) { var newPath = path.Clone(); using (var service = NativeMethods.IORegistryEntryFromPath(0, ref newPath).ToIOObject()) { string error; if (service.IsSet) { handle = NativeMethods.IOHIDDeviceCreate(IntPtr.Zero, service); if (handle != IntPtr.Zero) { var ret = NativeMethods.IOHIDDeviceOpen(handle); if (ret == NativeMethods.IOReturn.Success) { break; } NativeMethods.CFRelease(handle); // TODO: Only count up if IOReturn is ExclusiveAccess or Offline. error = string.Format("Unable to open HID class device (error {1}): {0}", newPath.ToString(), ret); } else { error = string.Format("HID class device not found: {0}", newPath.ToString()); } } else { error = string.Format("HID class device path not found: {0}", newPath.ToString()); } if (++retryCount == maxRetries) { throw DeviceException.CreateIOException(Device, error); } Debug.WriteLine(string.Format("Retrying ({0})", error)); Thread.Sleep(100); } } _handle = handle; HandleInitAndOpen(); _readThread.Start(); _writeThread.Start(); }
internal void Init(NativeMethods.io_string_t path, MacHidDevice device) { IntPtr handle; using (var service = NativeMethods.IORegistryEntryFromPath(0, ref path).ToIOObject()) { handle = NativeMethods.IOHIDDeviceCreate(IntPtr.Zero, service); if (handle == IntPtr.Zero) { throw new IOException("HID class device not found."); } if (NativeMethods.IOReturn.Success != NativeMethods.IOHIDDeviceOpen(handle)) { NativeMethods.CFRelease(handle); throw new IOException("Unable to open HID class device."); } } _device = device; _handle = handle; HandleInitAndOpen(); _readThread.Start(); _writeThread.Start(); }
internal override void HandleFree() { NativeMethods.CFRelease(_handle); _handle = IntPtr.Zero; }