public void TestAddMatchSubsystem() { using (var udev = new Context()) using (var e = new Enumerator(udev)) { e.AddMatchSubsystem("mem"); e.ScanDevices(); Assert.Contains(e, d => d.DevNode == "/dev/null"); } }
static IEnumerable <Serial.DeviceInfo> Find(Action <Enumerator> filter = null) { using (var udev = new Context()) using (var e = new Enumerator(udev)) { e.AddMatchSubsystem("tty"); filter?.Invoke(e); e.ScanDevices(); foreach (var d in e) { yield return(new DeviceInfo(d)); } } }
public IDisposable Connect() { if (monitor != null) { throw new InvalidOperationException("already connected"); } monitor = new Monitor(udev); monitor.AddMatchSubsystem("hidraw"); monitor.EnableReceiving(); var tokenSource = new CancellationTokenSource(); var token = tokenSource.Token; Task.Run(() => { try { var enumerator = new Enumerator(udev); enumerator.AddMatchSubsystem("hidraw"); enumerator.ScanDevices(); foreach (var device in enumerator) { if (token.IsCancellationRequested) { break; } var hids = TryGetHidDevices(device); if (hids == null) { continue; } foreach (var hid in hids) { subject.OnNext(hid); } } var pollfds = new Pollfd[] { new Pollfd { fd = monitor.Fd, events = PollEvents.POLLIN } }; while (!token.IsCancellationRequested) { // FIXME: it would be nice if we didn't wake up every 100ms // not sure how to interrupt a system call though // pinvoke pthread_kill() maybe? var ret = Syscall.poll(pollfds, 100); if (ret == -1) { var err = Stdlib.GetLastError(); if (err == Errno.EINTR) { continue; } UnixMarshal.ThrowExceptionForError(err); } if (token.IsCancellationRequested) { break; } if (ret == 0) { // timed out continue; } if (pollfds[0].revents.HasFlag(PollEvents.POLLNVAL)) { // monitor file descriptor is closed, monitor must // have been disposed, so complete gracefully break; } var device = monitor.TryReceiveDevice(); var hids = TryGetHidDevices(device); if (hids == null) { continue; } foreach (var hid in hids) { subject.OnNext(hid); } } subject.OnCompleted(); } catch (Exception ex) { subject.OnError(ex); } finally { monitor.Dispose(); monitor = null; } }, token); return(Disposable.Create(() => tokenSource.Cancel())); }