Esempio n. 1
0
 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");
         }
 }
Esempio n. 2
0
 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));
             }
         }
 }
Esempio n. 3
0
        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()));
        }