Connecting to Serial USB device via WebUSB - webusb

I have hardware which is connected to the mac or windows via USB Serial Mode. Currently, I have a nodejs application which sends and receive messages to this hardware using "serial" node module.
I am trying to connect to the hardware from WebPage. I used WebUSB serial.js. I am able to see the device and guess it is connecting. But when I try to send/receive the message - it says unable to claim the interface.
I would like to know can I use the WebUSB for USB with serial support?

The claimInterface() call is failing because your operating system has already loaded the USB serial class driver for this device (or perhaps a vendor-specific one such as FTDI). USB interfaces can only be claimed by one thing at a time. The option to change the device firmware so that the interface is no longer recognized by the driver (modify the interface class or product IDs) then you will be able to claim the interface and use code like the Arduino WebUSB library's serial.js that you found.
The other option is to wait for Chrome to finish implementing the Serial API. Status on that can be tracked here.

What worked for me was to run sudo modprobe -r ftdi_sio in the console.
That way, it unloads the USB from the OS and makes it available for WebUSB to use it and claim the interface.

Related

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.

Linux tool to send a SET_CONFIGURATION message to a device connected to the USB bus

I have developed a kernel driver for a USB device. Such a device has some pins that can provide functionality both as CDC ACM serial port or as input buttons. So to implement that I had to use two different USB configuration descriptors.
The driver works as expected, but I have to hardcode the chosen setup before compiling and loading the firmware to the micro-controller. I am searching a mechanism to change that device configuration from userspace.
I read about a SET_CONFIGURATION message on USB documentation, but coudn't find any Linux tool to send such kind of standard USB messages from userspace to the USB bus.
Does some of you (with more experience on this topic) know some userspace Linux tool to send a SET_CONFIGURATION message to a device connected to the USB bus?
Thanks in advance! :)
The function libusb_set_configuration() in LibUSB could do that in theory, but there is no need.
One can simply put both HID (for the button) and CDC (serial port) into one configuration using an "Interface association descriptor" (IAD).
This github repo resolves my issue:
https://github.com/avtolstoy/usbtool
No need for any special tools. You can simply do it via sysfs:
Find your device cd /sys/bus/usb/devices/X-Y/ where X is the bus number and Y is the device number.
Edit bConfigurationValue e.g., using sudoedit
Set the file contents to the desired configuration number and save it
That’s it!

WebUSB with FT230x serial chip

I'm hoping to use the newly released WebUSB API to communicate with a device i developed. This devices uses a FT230X USB to serial chip. The drivers of this chip are installed on most devices and communicating with it using minicom works smoothly. Now i want to try communicate with it through the browser. I started by downloading this example for arduino: webusb arduino. I set the filter to { 'vendorId': 0x0403, 'productId': 0x6015 } which shows the device. I'm able to find the device but when i try to connect i get the error: NotFoundError: Device unavailable.
Is there a way to find more specific errors? Should i set up a different interface or do i need to change some other configurations? I'm new to USB drivers so any help getting me on my way would be nice. I did read the (short) getting started documentation here. I use Ubuntu 16.04
The FT230X USB to serial chip does not provide an USB interface that Chrome can take control of. This is because, as you mention, the drivers for this chip are available with your operating system. With the serial driver attached Chrome cannot make the device available to your page through the WebUSB API.
The Arduino example programs the Atmel 32u4 chip on many Arduino and Arduino-compatible boards to add an additional USB interface which is not claimed by any system driver and is therefore available to Chrome.
Some developers have also had success either changing the vendor and product ID of their device so that the OS drivers do not claim it or by manually unbinding the driver.

How to detect when a usb cable is connected/disconnected on the device side in Linux 2.6.37?

I have a embedded device that runs linux 2.6.37.
I want my application to know when the USB is connected.
Currently I can achieve this by pooling
/sys/devices/platform/musb/musb-hdrc.0/vbus.
However this approach does not distinguish between a USB charger or a USB host.
I found this udev approach but I don't think it's available in my version of the kernel. because I did not find any USB related nodes in my /dev. This discussing also shows that it might not be feasible, ether.
I also found linux hotplug and tried the netlink example, but I didn't see any output running the example when I connect/disconnect the USB cable.
What I want to do is to detect connection type on the device, when USB is connected, and prepare (unmount file system) and switch to g_file_storage if device is connected to a host, and do nothing if device is connect to a charger.
How shall I achieve this?
To achieve that, you can use the inotify(7) feature, available in all linux kernels to be awaken as soon as some device node gets created in /sys.
To know what type of device you have, you have to read the usb info from proper usb ioctl call (or if you are not a kernel interface expert, using the libusb interface) to get the device vendor, device id and device class fields coming from the device. Normally, the hotplug software gets informed on these clase of events (via a special socket). The most probably reason you don't get the device properly initialized is some misconfiguration in the config files for udev system, which normally has one entry for each possible device vendor/device id pair and allows it to load the appropiate device driver to control it. The process continues with the device driver module creating dynamically the actual devices, and they'll appear in the /dev/ filesystem as a consequence of some other kernel event to udevd.
Read apropiate documents in <linux_src>/Documentation (this directory directory belongs to the linux kernel source code, so you'll probably need to install it), and udevd(8) man pages to be able to add a new usb.
On 2.6.37 kernel, this could be done by polling
/sys/devices/platform/musb-omap2430.0/musb-hdrc.0/mode
If handshake with host is successful then it will read as "peripheral", if fail it'll be "idle".

Communicating with USB bluetooth dongle from FTDI vinculum 2 USB host controller

I have been asked to figure out how to achieve bluetooth communication through an off-the-shelf dongle (in this case a dongle utilizing the Broadcom BCM2045 chip) using the FTDI Vinculum 2 (VNC2) USB controller. I have custom firmware written for the VNC2 to communicate with a generic USB device with the VNC2 acting as the host, and I can successfully read the VID and PID from the dongle as well as the USB device class, subclass, and protocol. I can also send data to the dongle using the bulk data endpoint and I believe the device is receiving though I have no way to tell at the moment.
So I believe I can communicate with the dongle, the problem is I have no idea WHAT to communicate to it in order to set it up in discoverable mode or to pair it with another discoverable device, nor how to actually transmit data through the wireless link once it is paired. I don't even know if there exists a standard communication protocol for this type of thing or if every device will be different. I have a vague understanding of the bluetooth protocol stack and it is my understanding that I won't be required to fully understand that as it should be implemented in the dongle on one end and in the android smartphone that we hope to connect to on the other end. Like I said, I can currently send data to the bulk endpoint, is it true that this endpoint is only for data transfer over the wireless link and I will need to connect to a different endpoint in order to send setup/configuration messages to the dongle?
In short, I need to know what data to send over the USB bus to control any generic bluetooth dongle if possible or at least one specific bluetooth dongle. I have a USB port sniffer but the complexity of the output while using the dongle to communicate is staggering and I doubt I'll ever figure it out.
Thank you in advance.
Bluetooth dongles communicate with host software stack using HCI (host control interface), which is defined in the Bluetooth spec. For reference, you can look at source code for the open source BlueZ stack (standard linux stack). You could run BlueZ on linux talking to your USB dongle, and use hcidump to capture actual packets going across HCI. You can also check out hcitool and hciconfig for performing specific actions.

Resources