Linux event after creating /dev/ttyUSB* - linux

I have been using a 3G dongle on cubieboard for internet connection. I have installed usb_modeswitch which basically switched dongle from USB storage mode to USB modem mode. I verified that the switching automatically happens after boot (usb_modeswitch is working fine). After switching takes place, system adds /dev/ttyUSB* dev names for modem. After this happens, I need to run model script to dial and connect to internet. In order to automate the process, I wanted to know if there is any event trigger for creation of /dev/ttyUSB* so that after that, I can automatically run dial script?

A general approach is to use udev to listen for events and then to react according to your own logic.

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.

beaglebone black wireless bluetooth AVRCP

I am working on a project with the beagle bone black wireless, where I need to be able to send music control commands to a phone. Note, I don't want to stream music to my beaglebone. I have spent about a week looking online, and found very little about this.
The OS for the beaglebone is Debian Jessie. I can get things like hci0tool, Bluetoothctl, hciconfig to work. I can detect and pair to a device. It seems though that my connection only lasts for the pairing process, and fails every time afterwards.
My current process is executing:
sudo su
bluetoothctl
power on
agent on
default-agent
scan on
I get the mac address
scan off
pair <MAC Address>
trust <MAC Address>
connect <MAC Address>
As of now pairing and trust succeed, though the connection ends after pairing finishes. And I have no idea of where to start for sending a command to a phone.
Connect call on Device1 interface will tries to connect all the profiles supported between the device and adapter. This happens by negotiating or exchanging the supported profiles.
Connection may not be possible when Adapter doesn't support the minimal requirement of profiles which is needed by the Device. In this case, you may need A2DP provider in adapter end to get connection successful. Yes, this is contradictory to this statement.
If you don't want to connect with all the profiles between Device and Adapter, then you can use ConnectProfile method in Device1 interface.
But bluetoothctl doesn't provide commands to achieve neither ConnectProfile nor you AVRCP commands.
You need to use D-Bus calls to get the communication with Bluetoothd. If your application is command line/shell based, you can use dbus-send/gdbus commands to address the D-Bus interface.
Although bluez-tools implements media control AVRCP commands, it doesn't provide any utility which uses it. Either you can compile bluez-tools as library and develop application using the media control API or use dbus-send/gdbus.
I have started with some samples using GDBUS, but not yet for AVRCP controls. See here : https://gist.github.com/parthitce
and Documentation here: https://www.linumiz.com/category/blog/

C++ Detecting USB serial device plugged/unplugged

I need to detect when a USB serial device is plugged or unplugged on my embedded system and know what is the tty associated with it.
My system runs over a 2.6 Linux Kernel.
Since I don't have write access to udev rules, nowadays I'm trying to get this information from the file system, looking for modifications in /sys/bus/usb/devices directory. However, I'm facing some problems with this approach.
I know what is the Id BUS of the USB port connected (e.g 1-1.3). So, I search for the associated tty (looking for a directory in /sys/bus/usb/devices/<Id BUS>:1.0/tty/ - e.g. /sys/bus/usb/devices/1-1.3:1.0/tty/ttyACM0). This way I know that I should use /dev/ttyACM0 to communicate with my device.
But, sometimes, this device (/dev/ttyACM0) does not exist.
Is there any better way to get this information?
I even thought trying to get this information from the syslog, but I don't know whether this is a pretty good idea.
Edit:
Only to clarify, my system needs to be able to detect state changes in the USB bus, i.e. detecting when a new device is plugged (and getting the tty name linked to it) or an existing one is unplugged.
The system is monitoring up to N USB/serial devices, which are plugged to it using an USB HUB. During its normal execution new devices can be plugged, existing devices can be removed (or rebooted by a remote command - out of this scope). When a device is rebooted, it could receive a different tty from the previous one used before (e.g. ttyACM0 -> ttyACM3), since the kernel designates to it a tty which is free at the moment, and it is a big problem to me.
Netlink is the preferred mechanism for communication between kernel and userspace.
You would create a Netlink socket with family NETLINK_KOBJECT_UEVENT, listen on that socket and filter out messages that contain SUBSYSTEM=usb and ACTION=add for USB plug events or ACTION=remove for USB unplug events.
I wrote a USB abstraction library called libusbp. You should look at its port_name example, which shows how to use libusbp to get the serial port name (e.g. /dev/ttyACM0) for a USB serial device. Behind the scenes, libusbp gets this information using libudev.
Check if the virtual file is deleted using stat.
#include <sys/statvfs.h>
...
struct stat sb;
return (stat("/dev/ttyUSB0", &sb) == 0); // true if open, false otherwise

Use a Linux Computer as a USB Coupler

I am on debian and:
I have a USB controller hooked up to a USB port on my PC (Device 1).
I have a male to male USB cord hooked up to another port on the PC that connects to Device 2. (it is a "bridging" usb cord, and has the chip for it)
I want to make them connect to each other as if they were one cord, so neither device knows that there is a computer in the middle.
This would be called a 'Coupler', except that I am using a PC as a coupler.
Here is a (really bad) diagram I made:
What I have done:
I have been able to connect the two devices independently of each other and sniff the results for when they fail to connect. The devices don't send a large volume of data back and forth.
Maybe there is some kind of command tool that I could use, for example (psudocode):
$ couple-usb-ports PORT1 PORT2
You're trying to reinvent the wheel here.
You might consider looking at this link instead.
http://dan3lmi.blogspot.com/2012/10/sniffing-usb-traffic-different.html
Specifically this.
Windows: You cannot directly capture raw USB traffic on Windows with Wireshark/WinPcap, but it is possible to capture and debug USB traffic on a virtual Windows machine under Oracle Virtual Box.
You cannot use a simple PC as transparent USB sniffer without extra (expensive) hardware. An USB bus has always one host (and one or more devices), and the PC can only be the host. This is a hardware limitation.
But you can capture USB data in a Windows machine using Wireshark and USBPcap, eliminating the need for the middle box in most cases.
As this post is tagged Linux, I suppose the controller PC is a Linux machine. Instead of connecting USB ports with a male-male connector, which is all kinds of bad (you are connecting the 5V lines of both machine with each other!), just run Wireshark in the controller PC.
There might be a little work to be done previously, as you have to enable Wireshark for USB monitoring (Particularly in Debian, this is disabled by default), and you might have to install a small driver to enable the monitoring. Have a look at this page for more information.
Once you get it working, Wireshark is an excellent tool for this!

FTDI chip detection issue

I'm trying to do some transactions over serial ftdi interface to an ARM based board. On windows i'm able to detect it but when from virtualbox i'm unable to detect the same.
When i connect the same board to a linux sever box, it gets detected and gives me the port /dev/ttyuSB0. Any idea why Virtualbox does not detect?
By default, your VMs in VirtualBox can't see any of your 'real' hardware. You can "move" a USB device from the host to the guest. (Appears as a disconnect from the host, then a connect to the guest), but it's an odd two-step process:
When the VM isn't running, create a USB "filter" on your device.
Then, when it's running, sometimes it grabs it, and sometimes you must click the USB icon (at the bottom of your running VM window, next to your disk/CD/mouse indicators).
Make sure you have a recent version of VirtualBox. I think before 4.x, the USB support was not included in the free version. But I can confirm it works in 4.1.

Resources