Skip to content

Linux and MacOS Support

Christian Findlay edited this page Dec 30, 2018 · 13 revisions

Linux and MacOS support is possible. What is required is to write a wrapper for some other Hid/USB library on the required platform. Any library that supports the basic IDevice members should work as an alternative to the existing IDevice implementations.

The most common Linux/Windows cross platform library is called LibUsb. There is a C# wrapper for it called LibUsbDotNet. You can use this to bring Linux support to your Device.Net based app. Here is a wrapper class:

    public class LibUsbDevice : IDevice
    {
        #region Fields
        private UsbEndpointReader _UsbEndpointReader;
        private UsbEndpointWriter _UsbEndpointWriter;
        private int ReadPacketSize;
        private SemaphoreSlim _WriteAndReadLock = new SemaphoreSlim(1, 1);
        #endregion

        #region Public Properties
        public IUsbDevice UsbDevice { get; }
        public int VendorId => UsbDevice.VendorId;
        public int ProductId => UsbDevice.ProductId;
        public int Timeout { get; }
        #endregion

        #region Events
        public event EventHandler Connected;
        public event EventHandler Disconnected;
        #endregion

        #region Constructor
        public LibUsbDevice(IUsbDevice usbDevice, int timeout)
        {
            UsbDevice = usbDevice;
            Timeout = timeout;
        }
        #endregion

        #region Implementation
        public void Dispose()
        {
            UsbDevice.Dispose();
        }

        public async Task<bool> GetIsConnectedAsync()
        {
            return true;
        }

        public async Task InitializeAsync()
        {
            await Task.Run(() =>
            {
                //TODO: Error handling etc.
                UsbDevice.Open();
                UsbDevice.ClaimInterface(UsbDevice.Configs[0].Interfaces[0].Number);
                _UsbEndpointWriter = UsbDevice.OpenEndpointWriter(WriteEndpointID.Ep01);
                _UsbEndpointReader = UsbDevice.OpenEndpointReader(ReadEndpointID.Ep01);
                ReadPacketSize = _UsbEndpointReader.EndpointInfo.MaxPacketSize;
            });
        }

        public async Task<byte[]> ReadAsync()
        {
            return await Task.Run(() =>
            {
                var buffer = new byte[ReadPacketSize];

                _UsbEndpointReader.Read(buffer, Timeout, out var bytesRead);

                return buffer;
            });
        }

        public async Task WriteAsync(byte[] data)
        {
            await Task.Run(() =>
            {
                _UsbEndpointWriter.Write(data, Timeout, out var bytesWritten);
            });
        }

        public async Task<byte[]> WriteAndReadAsync(byte[] writeBuffer)
        {
            await _WriteAndReadLock.WaitAsync();

            try
            {
                await WriteAsync(writeBuffer);
                return await ReadAsync();
            }
            finally
            {
                _WriteAndReadLock.Release();
            }
        }
        #endregion
    }

Code Reference

HIDSharp is another cross platform library that looks promising. It seems to have providers for MacOS and Linux. I haven't tested this, but I'd really like to hear from anyone who has tried it.