I am trying to detect an USB insert regardless of the device it is. Eg: A phone, a battery pack, a biometric system etc., which may or may not be recognized by Linux (no drivers or nothing to "Drive/run"). Presumably, Linux will detect the USB insert (independent of the device), and then proceed to register and act on Recognized devices only. For instance it will list recognized USB device details in /dev/bus/usb/ etc. Instead, I would like to trap/process everything that is inserted into a USB slot. This presumably implies, that I can't depend on stuff like udevadm as it kick in only on recognized devices. This also means that I will need to trap the insert event early on the curve. How do I do this?
I don't believe that you can accomplish this with dumb devices as mentioned in @meuh comment here.. With devices that actually communicate
udevadm monitor works fine. Here's an example of plugging and unplugging an android phone (powered on):
$ udevadm monitor monitor will print the received events for: UDEV - the event which udev sends out after rule processing KERNEL - the kernel uevent KERNEL[115749.498687] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6 (usb) KERNEL[115749.499591] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6/2-1.6:1.0 (usb) UDEV [115749.511659] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6 (usb) UDEV [115749.516846] add /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6/2-1.6:1.0 (usb) KERNEL[115767.515839] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6/2-1.6:1.0 (usb) KERNEL[115767.516143] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6 (usb) UDEV [115767.517088] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6/2-1.6:1.0 (usb) UDEV [115767.522116] remove /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.6 (usb)
A flash drive produces similar but much more verbose results. If you wanted to make use of this information to trigger some action, you could redirect the output to a file and use
tail to monitor the file for new activity.
Tests with an android phone (turned off, but charging) indicated no change whatsoever in
lsusb -v |grep Power output which IMHO confirms that dumb devices that just draw or supply power can't be detected.
Another simple way to detect devices that aren't dumb is to store baseline information and compare current info to that. There are numerous ways to do this. One simple alternative to
udevadm mentioned above that leaps to mind is to simply collect baseline data for the system without the device to be detected plugged in. For example:
Collect baseline data:
lsusb > baseline.txt
Check current data and compare:
while true; do lsusb > compare.txt ; diff compare.txt baseline.txt; sleep 1; done
This will compare the current USB connections to the baseline once every second.
If your script updates your baseline data upon detection you will also be able to detect device removal by this method.
One way of capturing all traffic over USB is to use wireshark after inserting the usbmon kernel module, as detailed in:
That's about as 'early in the curve' as you can get. But I'm assuming your intention is to use some sort of programmatic trigger, like an event, to do something interesting - so, given that running 'lsusb -t' gives you a static list of inserted USB devices, along with their respective drivers (if they exist), you could create a cron job to run lsusb and compare it with the previous version to ascertain if a new device has been inserted, even if it hasn't a driver associated with it.
The downside to this simple solution is the large latency that cron gives between insertion and detection.