Git Product home page Git Product logo

device.net's Introduction

Hid.Net, Usb.Net, SerialPort.Net (Device.Net)

Project Update: this project is on pause. Please read the whole story here.

diagram

Cross-platform .NET framework for talking to connected devices such as USB, Serial Port and Hid devices

Version 4.x

is live on Nuget.org! Take a look at the 4.0 project to see new features and fixes. Version 4 has public interface changes. You will need to read through the documentation to upgrade from version 3 to version 4.

New in 4.2.1

This framework provides a common Task async programming interface across platforms and device types. This allows for dependency injection to use different types of devices on any platform with the same code. The supported device types are Hid, Serial Port, and USB.

Contribute

This project needs funding. Please sponsor me here so that I can contribute more time to improving this framework.

Coin Address
Bitcoin 33LrG1p81kdzNUHoCnsYGj6EHRprTKWu3U
Ethereum 0x7ba0ea9975ac0efb5319886a287dcf5eecd3038e
Litecoin MVAbLaNPq7meGXvZMU4TwypUsDEuU6stpY

This project also needs unit tests, bug fixes and work towards more platforms. Please read this.

Licensing

This framework uses the MIT license. I won't sue you, or your business if you use this for free. If you are developing software for free, I don't expect you to sponsor me. However, if your business makes more than USD 100,000 per year and your software depends on Device.Net, I expect your business to make a serious contribution via sponsorship.

Why Device.Net?

Device communication is fragmented across platforms and device types. If you need to use three different device types across Android, UWP and .NET, you would otherwise need nine different APIs. Device.Net puts a standard layer across all these so that you can share code across all platforms and device types. You don't need to use Windows APIs or learn about Android's API directly. If the device manufacturer decides to switch from USB to Hid, the code remains the same. Write once; run everywhere.

Get Help

Currently supports:

Platform Hid USB Serial Port Bluetooth
.NET Framework Yes Yes Yes No
.NET Core Yes Yes Yes No
Android Yes Yes No No
UWP Yes Yes No No
Linux, MacOS* No (Via LibUsbDotNet) No No
WebAssembly No No No No

Note: Bluetooth, Linux, and macOS, WebAssembly (via WebUsb) support are on the radar. If you can sponsor this project, you might be able to help get there faster.

SerialPort.Net and Device.Net.LibUsb are still in alpha mode. You must use the prerelease version

Example Code

using Device.Net;
using Hid.Net.Windows;
using Microsoft.Extensions.Logging;
using System.Linq;
using System.Reactive.Linq;
using System.Threading.Tasks;
using Usb.Net.Windows;

namespace Usb.Net.WindowsSample
{
    internal class Program
    {
        private static async Task Main()
        {
            //Create logger factory that will pick up all logs and output them in the debug output window
            var loggerFactory = LoggerFactory.Create((builder) =>
            {
                _ = builder.AddDebug().SetMinimumLevel(LogLevel.Trace);
            });

            //----------------------

            // This is Windows specific code. You can replace this with your platform of choice or put this part in the composition root of your app

            //Register the factory for creating Hid devices. 
            var hidFactory =
                new FilterDeviceDefinition(vendorId: 0x534C, productId: 0x0001, label: "Trezor One Firmware 1.6.x", usagePage: 65280)
                .CreateWindowsHidDeviceFactory(loggerFactory);

            //Register the factory for creating Usb devices.
            var usbFactory =
                new FilterDeviceDefinition(vendorId: 0x1209, productId: 0x53C1, label: "Trezor One Firmware 1.7.x")
                .CreateWindowsUsbDeviceFactory(loggerFactory);

            //----------------------

            //Join the factories together so that it picks up either the Hid or USB device
            var factories = hidFactory.Aggregate(usbFactory);

            //Get connected device definitions
            var deviceDefinitions = (await factories.GetConnectedDeviceDefinitionsAsync().ConfigureAwait(false)).ToList();

            if (deviceDefinitions.Count == 0)
            {
                //No devices were found
                return;
            }

            //Get the device from its definition
            var trezorDevice = await hidFactory.GetDeviceAsync(deviceDefinitions.First()).ConfigureAwait(false);

            //Initialize the device
            await trezorDevice.InitializeAsync().ConfigureAwait(false);

            //Create the request buffer
            var buffer = new byte[65];
            buffer[0] = 0x00;
            buffer[1] = 0x3f;
            buffer[2] = 0x23;
            buffer[3] = 0x23;

            //Write and read the data to the device
            var readBuffer = await trezorDevice.WriteAndReadAsync(buffer).ConfigureAwait(false);
        }
    }
}

See Also

Human Interface Device Wikipedia Page - Good for understanding the difference between the meaning of the two terms: USB and Hid.

USB human interface device class Wikipedia Page - as above

USB Wikipedia Page - as above

Jax Axelson's USB Page - General C# USB Programming

device.net's People

Contributors

g9c9 avatar melbournedeveloper avatar sanjay900 avatar www avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

device.net's Issues

WinUSB Device Implementation

This library currently supports direct USB access on Android and UWP. It can also connect to a USB device on Windows if that USB device has a Hid interface. However, in order to communicate with a USB device without Hid, a 3rd party library like LibUsbDotNet must be used.

I'm struggling to find a USB sample for windows that uses the winusb.dll C library. I have documented the problem here. Please comment if you have any tips:

https://stackoverflow.com/questions/53689682/windows-api-usb-io-winusb-dll

UWP Limitations for Specific Collections

I am attempting to enumerate an HID device in a UWP app on Win 10 IOT platform. The device is a touchscreen monitor and utilizes the Consumer Usage Page collection. (https://www.chalk-elec.com/?p=2060)

I have added the device capabilities to the Package.appxmanifest, but have been unsuccessfull at enumerating the device, as the output of DeviceManager.Current.GetDevicesAsync method always returns null with no error.

The Official UWP HID API documents the blocking of device usages under the the Consumer Usage Page collection. Does this limitation still apply to this library?

Cancellation Tokens and Timeouts

Hi. May be will be good if you add CancellationTokenSource or just timeout for read\write operation. Something like this:

//One sec timeout by default
public int Timeout { get; set; } = 1000;

...

CancellationTokenSource cancellationTokenSource = new CancellationTokenSource(Timeout);
await _ReadFileStream.ReadAsync(bytes, 0, bytes.Length, cancellationTokenSource.Token);

Device Polling Layer

Put a layer over polling for all platforms

-The factories should hang on to a reference of the devices that they have created
-Logic for checking if the device is connected should be disconnected from the device itself (i.e. Android's CheckForDevice)
-The factories should handle disconnection and connection
-When the factory scans for devices is, if an existing device is still connected, this device should be retrieved so as to not create a new one. The question is, what to do if the handle is no longer valid... Connect and disconnect?

On platforms like Windows, polling will occur with a timer. When the timer is called, the factory should check to see if the device is still connected. If not, the device should be disposed which should call the Disconnected event.

On Android, there is no need for a timer because there is an event for when a device is connected or disconnected. This might be possible on Windows and UWP in the long run...

Linux/OSX Raw API Libraries

Linux and MacOS are now supported. See this wiki entry. However, this has been done via LibUsbDotNet. I'd like to build libraries that are not dependent on LibUsbDotNet, and possibly not dependent on LibUsb. Contributions on this are very welcome.

The UsbDevice is a base class that doesn't depends on IUsbInterfaceManager to inject the platform specifics in. The IUsbInterface class is where the platform specifics need to be implemented:

    public interface IUsbInterface : IDisposable
    {
        IUsbInterfaceEndpoint ReadEndpoint { get; set; }
        IList<IUsbInterfaceEndpoint> UsbInterfaceEndpoints { get; }
        IUsbInterfaceEndpoint WriteEndpoint { get; set; }
        IUsbInterfaceEndpoint InterruptWriteEndpoint { get; set; }
        IUsbInterfaceEndpoint InterruptReadEndpoint { get; set; }
        //TODO: Remove these. They should come from the endpoint... or be specified there
        ushort ReadBufferSize { get; }
        ushort WriteBufferSize { get; }
        Task WriteAsync(byte[] data, CancellationToken cancellationToken = default);
        Task<ReadResult> ReadAsync(uint bufferLength, CancellationToken cancellationToken = default);
        byte InterfaceNumber { get; }
        Task ClaimInterface();

        /// <summary>
        /// This is for internal use and should need to be called. This will probably be removed in future versions.
        /// TODO
        /// </summary>
        void RegisterDefaultEndpoints();
    }

The WindowsUsbInterface is an example of such an interface.

Bare in mind that these interfaces are quite cluttered and need some work, so refactoring is always an option.

Read Data Event

Currently, Device.Net is designed around the Request/Response model (see here). You are supposed to send some data to the device, and then wait for the device to return some data with WriteAndReadAsync().

However, many devices such as joysticks and so on do not work this way. The input originates from the device itself and could send data to the computer at any point in time. So, there needs to be an event that is registered when data is received. The UWP providers actually work in this way. They receive events when the device sends the computer data. This should be harnessed to achieve the desired functionality.

Perhaps there needs to be two modes for devices: Request/Response, and Ad Hoc...

USB - Interfaces Other Than Default

Any given USB device can have multiple different interfaces, and pipes within those interfaces. There should be a way to select which interface is used before InitializeAsync is called.

TODOs

Go through TODOs and handle the situations

DeviceListener - Polling Starts in the Constructor

When the device listener is constructed, it automatically starts polling. This is bad because the user may want to delay the start of the polling. But, also, the event handlers are hooked up after the polling is started. It's probably not possible that an event would fire before the event handlers are first hooked up, but it's at least theoretically possible.

DeviceListener Doesn't Dispose Devices

In some cases they don't get disposed when the listener is dispoed. This means that they don't get finalized. Also, test to make sure that with disposal, they do get finalized.

Dispose Resources on Finalize

While more of the Dispose pattern has been implemented with Finalizers, the Finalizers don't seem to be getting called for at least some devices. This means that the classes may not be getting garbage collected.

Done:
Classes don't dispose resources on finalize if the dispose method is not called. Need to implement something similar to the dispose pattern correctly.

NuGet Build Script

Need a script (powershell, batch, MSBuild?) to put all the DLLs in the right places.

Android Listening Without Polling

See #24 but for Android.

This should be possible with Broadcast receivers, but the question is whether or not these trigger activities in external apps...

Can't Enumerate All Devices on Windows

Calls to GetHidAttributes and so on fail for some devices . This means that there will be an error and no devices will be returned.

This issue is fixed in commit 338132d but has not been rolled out to a NuGet package. It should be included in release 2.3

The "ResolveLibraryProjectImports" task failed- problem

I downloaded the sample. but I can't run it on my visual studio. I get error message-
The "ResolveLibraryProjectImports" task failed unexpectedly.System.IO.FileNotFoundException: Could not load assembly 'Device.Net, Version=0.0.0.0, Culture=neutral, PublicKeyToken='. Perhaps it doesn't exist in the Mono for Android profile?File name: 'Device.Net.dll' at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(AssemblyNameReference reference, ReaderParameters parameters) at Java.Interop.Tools.Cecil.DirectoryAssemblyResolver.Resolve(String fullName) at Xamarin.Android.Tasks.ResolveLibraryProjectImports.Extract(DirectoryAssemblyResolver res, ICollection1 jars, ICollection1 resolvedResourceDirectories, ICollection1 resolvedAssetDirectories, ICollection1 resolvedEnvironments) at Xamarin.Android.Tasks.ResolveLibraryProjectImports.Execute() at Microsoft.Build.BackEnd.TaskExecutionHost.Microsoft.Build.BackEnd.ITaskExecutionHost.Execute() at Microsoft.Build.BackEnd.TaskBuilder.d__26.MoveNext()

I tried a lot of "google" solutions. including rebuild and so on. with no success.
do you have any idea how to run the project?

Consistent Exceptions

The messaging is ad hoc across platforms and device types. The messages should be defined in a single location.

Implement a Windows Error code handler in Windows libraries so that we get a textual, meaningful error from the error codes.

Hid Guid Hard Coded

Don't use the hard coded Hid Guid. Call the method to get the Hid Guid on the machine before enumerating Hid devices.

Exception will be thrown on some computers.

I have tested my program on my PC and it works fine(except read,Idon't know why my input report won't be picked up via WriteAndReadAsync()),but at least it won't throw an exception.
On my laptop,it will throw a lot of exceptions,after starting the listener.
//exception below
An exception of type 'System.Exception' occurred in test.exe but was not handled in user code
Could not get device interface detail. Error code: 122
//==============
and call stack lead me to WindowsDeviceFactoryBase.cs,line:76

It seems my laptop has some wired hid devices made the SetupDiGetDeviceInterfaceDetail() failed,because the program can‘t listen to the device and initialize device.
Maybe listener should try not to get all hid devices on the computer?I don't know.

WindowsUsbDevice - Can't Close Interface Handle - Error on Second Access

This problem doesn't seem to happen in the UWP version. The UWP version seems to close the interface handles, but when I attempt to call CloseHandle with the WinUSB handle, I get an error. I suspect this is why a device cannot be opened twice in a row. I suspect that this issue is the same thing: trezor/trezor-mcu#444

Here is a full Stack Overflow discussion:
https://stackoverflow.com/questions/54189056/c-sharp-winusb-cant-call-closehandle-on-interface

Android Refactor

The AndroidUsbDevice class is a mess. There is logic there that is mixed up between scanning for devices, receiving events, and polling.

-Implement the factory pattern in other platforms
-Remove any CheckForDevice methods and deal with this in some other way
-This issue is dependent on #3 because polling is necessary on Android

USB - Raw COM Port Access

It is possible to scan through COM ports and listen for data. While I haven't got a need for this, one use case is for GPS devices. Would anyone find this useful? Anyone willing to help? I have code for it already, but I'd just need for it to be integrated in to Device.Net in a useful way.

Fill In DeviceDefinition

When the device is initialized, as much of the DeviceDefinition should be filled in as possible.

GetConnectedDeviceDefinitionsAsync never finishes

Take this basic example:

using Device.Net;
using Hid.Net.Windows;
using System;

namespace ConsoleApp
{
    class Program
    {
        static void Main(string[] args)
        {
            Test.Find();
            Console.ReadLine();
        }
    }

    class Test
    {
        public static async void Find()
        {
            WindowsHidDeviceFactory.Register();
            var devices = await DeviceManager.Current.GetConnectedDeviceDefinitionsAsync(new FilterDeviceDefinition { VendorId = 0x04D9, ProductId = 0x0130 });
            Console.WriteLine("this is never printed to console");
            foreach (var device in devices)
            {
                Console.WriteLine(device.DeviceId);
            }
        }
    }
}

The application hangs before Console.WriteLine("this is never printed to console"); is reached.

Windows 10 x64 with netcore 2.2

Close Vs. Dispose

Devices are currently getting initialized, disposed, and then reinitialized. I don't suppose that this is causing any issues right now, but it's not a good look for profilers and so on. Once an object is disposed, it's supposed to get finalized. So, Dispose should be broken in to two methods: Close, and Dispose. Close should be called when the device is unplugged or we temporarily don't want to use the device. Dispose should only be called when the DeviceListener is completely done with the device or the app is shutting down.

Device.Net.LibUsb 2.6 missing on NuGet

Hello. currently https://www.nuget.org/packages/Device.Net.LibUsb/ misses the 2.6 version, thus it will fail with runtime exceptions, if the version 2.6 of device.net is installed.

The error is always:

TypeLoadException: Method 'Close' in type 'Device.Net.LibUsb.LibUsbDevice' from assembly 'Device.Net.LibUsb, Version=2.5.1.0, Culture=neutral, PublicKeyToken=918542c6e3a3318a' does not have an implementation.

Some Devices Don't Get Picked Up (Windows)

If a Hid device can't get a serial number, it will not be picked up. This is bug because you can still connect to the device. Serial number is not necessary.

Fix: Don't throw an exception if we can't get serial number.

What's the difference between DEVINTERFACE_USB_DEVICE and WinUSB?

I noticed there are 3 type devices defined in WindowsDeviceConstants.cs

public static Guid GUID_DEVINTERFACE_HID = new Guid("4D1E55B2-F16F-11CF-88CB-001111000030");
public static Guid GUID_DEVINTERFACE_USB_DEVICE = new Guid("A5DCBF10-6530-11D2-901F-00C04FB951ED");
public static Guid WinUSBGuid = new Guid("dee824ef-729b-4a0e-9c14-b7117d33a817");

So, what's the difference between DEVINTERFACE_USB_DEVICE and WinUSB?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.