Simulate a USB Device for Automation - linux

I have to simulate a USB Device for automation and testing purposes (in Linux). Original driver/application for this device uses “libusb” to communicate with it.
I don’t have much experience in Linux and Simulation, after some searching I have understood that I need to write a kernel level driver and an application in user-space to simulate that device. Is this right? If Yes, How can this be done?
Thanks in Advance.

Finally implemented it by modifying "libusb", modified it to send and receive usb transfers from message queue instead of usbfs. Programmed my simulator to create libsub type transfers and send/receive them using message queues as well.
Simulator now interprets the incoming transfers and sends it to a command parser, which sends request/message to automation system using sockets in a specific format. Automation system sends it's instruction by sending to command parser using socket. This socket invokes method specific to each request in simulator, Now simulator forms an appropriate transfer structure and passes to device plugin (via libusb) through message queue.

I think what you're looking for would be called a virtual USB device. Currently there is nothing in standard Kernel.Some virtual machine provides USB emulation.e.g. KVM provides USB emulation. There is framework gadget in which might look for your solution.
Or find something in Linux USB project
Thanks,
Abhijeet

The usb-vhci project could be of use if you want the device to be presented to the kernel in the same way as real hardware.

Related

WebUSB API, for pushing commands/configuration to the device through webApp

I am doing some research on the WebUSB API for our company because we are going to start to manufacture devices in house.
Our current device manufacture comes with an application so the team can plug the device into a computer and diagnose it. Their application allows us to read outputs from the device, as well as pushing commands/configuration to the device over a wired connection.
Since this device is 100% ours, we are also responsible for building out the diagnostic tooling. We need some sort of interface that allows a user to read outputs and send commands/configuration to the device over a wired USB connection.
Is the webUSB the correct API? If not, what are some suggestions for accomplishing the requirement? Are we limited to building some sort of desktop or mobile application?
I would recommend resources below to read to help you understand if the WebUSB API fits your needs or not:
https://web.dev/devices-introduction/ helps you pick the appropriate API to communicate with a hardware device of your choice.
https://web.dev/build-for-webusb/ explains how to build a device to take full advantage of the WebUSB API.
From what you describe, WebUSB isn't strictly required but won't hurt either.
First and foremost, you will need to implement the USB interfaces reading data and sending configurations. It will be a custom protocol, and not one of the standard USB device classes such as HID, video or mass storage. The details of the protocol and if you use control, interrupt or bulk transfers is your choice.
I'm assuming you will connect the devices to Windows PCs, and you likely don't want to put money into writing device drivers. If so, the easiest approach is to add the required descriptors and control requests required for Microsoft OS 2.0 Descriptors. That way, the WinUSB driver will be installed automatically when the device is plugged in.
Using the WinUSB API, a Windows application will then be able to communicate with the USB device. No additional drivers are needed. (On macOS and Linux it's even easier as you don't need the Microsoft OS 2.0 Descriptors in the first place.)
On top of that you can implement the additional descriptors and control requests for WebUSB. It will provide the additional benefit that you can write a web application (instead of a native application) for communicating with the USB device. (Currently, you are restricted to the Chrome browser.) WebUSB devices should implement the WinUSB descriptors as the alternative (.INF files, manual installation process) is a pain.
The already mentioned web page https://web.dev/build-for-webusb/ is a complete example of how to implement it.

How to create a simple Linux USB device to "echo" whatever is sent to it from the host?

As a web developer, I am new to USB and gadget development. I am creating a Windows Desktop application that communicates, using the Node-USB library, with a USB Device. To start, I am trying to create a mock USB device using Linux on my Raspberry Pi 4. I have set it up to boot as a USB device using this script, which is based on this guide, which sets the usb provider/vendor IDs, a rndis function, and more. Windows recognizes the device when plugging it into the computer, and I am able to open a connection to it using the NodeJS library.
I am now stuck on how to configure the device to set up a function that simply listens to data sent to it on a "bulk in" endpoint from the host, and echo it back automatically to the host, so that the Windows application receives it. I have been advised that there are many scripts available to set up a simple "demo" gadget like this on Linux, but I cannot find any.
It's not clear to me,
How to set up a usb function on the device to listen to a bulk "out" endpoint
How to set up a "driver" or a custom-made application to "listen" to the aforementioned function
How to make the listening application itself. The node-usb library says it's made for communicating with USB devices, not for devices itself, so it seems I can't use it?
Is there a simple bash script or built-in linux command that can automatically echo data to the host from the "in" endpoint?
I'd appreciate any guidance to point me in the right direction!
You need to write a USB function driver in kernel or use functionfs to do it in userspace. Either way you'll need to prepare USB descriptors which are presented to the host during enumeration (when your device is being plugged in) and then handle incoming USB requests on registered endpoints.
To setup one of the drivers already existing in kernel you can do it through configfs or using libusbgx wrapper library. There are also legacy function drivers which activate automatically after loading the module.
The node-usb library is wrapper for libusb, which is host-side library. So you're right, you cannot use it to create device-side function driver.
There is f_loopback function in kernel which does exactly what you need. This is probably the best starting point if you want to create your own USB function driver.

Hardware communication with Python

Is it possible to write an API with Python so you can connect a physical ON and OFF switch via USB to a PC and when user presses the switch to ON or OFF, the python program detects it and send a signal to a web app and shows ON or OFF message on the website?
I am sorry if what I am asking its not clear enough!
Yes, it is possible. Reading USB devices can be done with Python. In linux USB device inputs can be found in some files(e.g. /dev/ttyUSB0). By reading those files you can get the information that you need. Putting here link that will be helpful
similar post
Firstly, you can't write an API to interact with hardware in python. You would have to use the pre-existing windows API(or the API provided by the Operating system that you are using) in order to interact with hardware in such a high-level language.
If you want to interact with hardware in python, and detect switch presses, releases etc, I would recommend you used a microcontroller such as a raspberry pi(for python) or an arduino(for C++). The respberry pi provides a very easy way to interact with hardware in python. If you still want to interact with a USB stick in python(but not acting as a switch) you can use the pyusb library.

What data can a HID device receive?

I am designing a USB keyboard with special capabilities. What information can such a HID device receive from the host?
Can I via USB:
Read data from a form on the screen?
Find out what OS the user is on?
Find out if there's been an error message?
Even 'know' what's going on visually on the screen, i.e. what program is selected or whether the program is windowed or fullscreen?
Thank you!
The device can't get any of this information from a standard driver that the operating system supplies because that would be a security issue. It can receive any information that your own driver or application sends it. There are many ways to communicate with it - your device could present multiple interfaces (which will appear as separate devices), multiple endpoints, or use the control channel. You will definitely need to study the spec, and I also found this tutorial helpful.
I have done something similar and used the control channel to exchange feature data with a Windows application (over the standard Windows driver). On Windows, the API calls are HidD_SetFeature() and HidD_GetFeature().
On the device side, my hardware ran embedded Linux and I used the GadgetFS library to create a user-mode driver - much easier to debug than a kernel driver.
As others have said, you'll run into issues if you try this with a normal HID. However, there is a project called the USB Rubber Ducky. From their description:
The USB Rubber Ducky isn't your ordinary HID (Human Interface Device).
Coupled with a powerful 60 MHz 32-bit processor and a simple scripting language
The USB Rubber Ducky looks like a usb-device and is recognized as a HID, but is programmable. You can make a small script that will be typed onto the screen which will allow you to performs the queries you seek.
With the USB Rubber Ducky you can:
Read data from a form on the screen? Yes
Find out what OS the user is on? Yes
Find out if there's been an error message? Yes
Even 'know' what's going on visually on the screen, i.e. what program is selected or whether the program is windowed or fullscreen? Yes
If you aren't hoping to buy this device, at least their firmware is on github so it can provide you a starting point

Teensy 2.0 / Atmega32u4 as Keyboard: Send and Receive

I'm currently working on a device which is able to work as a keyboard and communicate via Serial with a self-written software.
Now I have to install serial drivers (from Arduino) on different computers if I want to communicate with my application which I actually want to avoid.
Is there any other solution to solve this problem? Is it possible that my microcontroller works as a keyboard AND is able to send and receive data as HID device?
Thanks and greetings!
I actually do something similar with a 32u4, but it receives its serial over the built-in UART. I do this because it's linking between two separate systems. If it were only one system I could implement a 2nd interface. (Don't forget, a USB HID device must have an IN endpoint even if you are not using it.) Or you could just throw a $2 USB/TTL converter on and do it the same as I did.

Resources