Monitoring (Sniffing) /dev/ttyUSB0 created by FTDI USB Serial Converter - linux

I want to monitor (sniff) the traffic of my /dev/ttyUSB0 which is created by FTDI USB Serial Converter. I've written my own application in Windows and now I try to port it to linux and use /dev/tty/USB0. I want to debug the communication that actually happens.
The software strace is not an option for me because it only shows the syscalls to ioctl.
Using Windows the software "Free Serial Port Monitor" did it by sniffing COM1.
Output of dmesg:
[16975.000221] usb 7-1: new full-speed USB device number 5 using uhci_hcd
[16975.193543] usb 7-1: New USB device found, idVendor=0403, idProduct=6001
[16975.193548] usb 7-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[16975.193552] usb 7-1: Product: FT232R USB UART
[16975.193555] usb 7-1: Manufacturer: FTDI
[16975.193558] usb 7-1: SerialNumber: A400BJII
[16975.200550] ftdi_sio 7-1:1.0: FTDI USB Serial Device converter detected
[16975.200599] usb 7-1: Detected FT232RL
[16975.202604] usb 7-1: FTDI USB Serial Device converter now attached to ttyUSB0
However I tried moserial to do this and the command "echo foobar > /dev/ttyUSB0" to verify, if it works. Also my software doesn't create an output to moserial.
UPDATE:
Found out how to monitor usb directly, now I need to convert USB packets to RS-232 (what FTDI basically does).
Setup usbmon
modprobe usbmon
1.1 With Linux kernels prior to 2.6.23, you will also need to run this command
modprobe -t debugfs none /sys/kernel/debug
usbmon0 will monitor any traffic from all usbmon0 to usbmonX
2.1. Find the correct usb device
cat /sys/kernel/debug/usb/devices|grep FTDI -A 7 -B 4
T: Bus=07 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 12 Spd=12 MxCh= 0
D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 8 #Cfgs= 1
P: Vendor=0403 ProdID=6001 Rev= 6.00
S: Manufacturer=FTDI
S: Product=FT232R USB UART
S: SerialNumber=A400BJII
C:* #Ifs= 1 Cfg#= 1 Atr=a0 MxPwr= 90mA
I:* If#= 0 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=ff Driver=ftdi_sio
E: Ad=81(I) Atr=02(Bulk) MxPS= 64 Ivl=0ms
E: Ad=02(O) Atr=02(Bulk) MxPS= 64 Ivl=0ms
2.2. Note Bus number of the port (Bus=07), so usbmon to monitor will be usbmon7
2.3. Use wireshark to capture the usbmon7 interface or use following command to get output to the console (stdout) ... replace the number with bus-id
cat /sys/kernel/debug/usb/usbmon/7u
What means 'u'?
https://www.kernel.org/doc/Documentation/usb/usbmon.txt
Two formats are supported currently: the original, or '1t' format, and the '1u' format. The '1t' format is deprecated in kernel 2.6.21. The '1u' format adds a few fields, such as ISO frame descriptors, interval, etc. It produces slightly longer lines, but otherwise is a perfect superset of '1t' format.
How do I convert the USB capture to RS-232 capture?
I don't know it ... TODO

With your hint I managed to solve my problem, so there it is my hint for the last point:
Using Wireshark, open usbmon0 and use this filter
usb.capdata or at
Issuing two times the command echo asd > /dev/ttyUSB0 produces the result below in Wireshark
You can extract the whole Leftover Capture Data from a capture file using tshark:
tshark -r capture.pcapng -T fields -e usb.capdata

Related

How to find reasons why an udev rule is not applied?

I added an udev rule to generate a separate link to a special tty device. I took the vendor and product id from lsusb:
Bus 001 Device 016: ID abcd:1234 Foo Device
The dmesg output for the device is:
[ 369.384850] usb 1-1.1: new full-speed USB device number 4 using xhci_hcd
[ 369.470492] usb 1-1.1: New USB device found, idVendor=09d8, idProduct=0420
[ 369.470506] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 369.470515] usb 1-1.1: Product: TWN4/B1.06/CCL3.12/PRS1.04
[ 369.470522] usb 1-1.1: Manufacturer: OEM
[ 369.475188] cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device
Normally the Debian system generates an ACM* tty for this device:
$ ls /dev/ttyACM*
/dev/ttyACM0
So I created /ect/udev/rules.d/99-bizrfid.rules:
ACTION=="add", ATTRS{idVendor}=="09d8", ATTRS{idProduct}=="0420", SYMLINK+="ttyMyDevice"
But ls /dev/tty* does not show ttyMyDevice.
What I tried so far without success:
Running udevadm trigger. This should apply the new udev rule.
I did a reboot.
I had a look to udevadm test /dev/ttyACM0. My udevrule is shown at the end. So I am sure that it had not been overridden. But I wonder about the 'unable to open' hint. Nevertheless this hint is present for other ttys, such as tty0 or ttyS0, too.
...
Reading rules file: /lib/udev/rules.d/98-systemd.rules
Reading rules file: /etc/udev/rules.d/99-bizrfid.rules
rules contain 49152 bytes tokens (4096 * 12 bytes), 12883 bytes strings
4240 strings (40079 bytes), 3515 de-duplicated (27922 bytes), 726 trie nodes used
unable to open device '/sys/dev/ttyACM0'
Unload module index
Unloaded link configuration context.
I reconnected the USB device.
I tried another udev rule. This rule is 100% correct because I use this rule already fo other devices. But it does not work for the ttyACM0:
ACTION=="add", KERNEL=="ttyACM*", MODE="0666"
I wonder why this is not working.
How to find reasons why an udev rule is not applied?
For the udev rule
/ect/udev/rules.d/99-bizrfid.rules I would add the SUBSYSTEM:
ACTION=="add", SUBSYSTEM=="tty", ATTRS{idVendor}=="09d8", ATTRS{idProduct}=="0420", SYMLINK+="ttyMyDevice"
You could add also ATTRS{manufacturer}==, but idVendor and idProduct are sufficient.
Otherwise it looks correct and the test run creates the symlink:
creating link '/dev/ttyMyDevice' to '/dev/ttyACM0'
According to the comments I the following can be tried to debug the problem:
Check the driver
Use dmesg to check the driver you are using and ensure that it is a generic one. If it is a custom compiled one, the problem could be inside your custom implementation. If it is a generic one, go on to step two. I found the driver name in the last line: cdc_acm
[ 369.384850] usb 1-1.1: new full-speed USB device number 4 using xhci_hcd
[ 369.470492] usb 1-1.1: New USB device found, idVendor=09d8, idProduct=0420
[ 369.470506] usb 1-1.1: New USB device strings: Mfr=1, Product=2, SerialNumber=0
[ 369.470515] usb 1-1.1: Product: TWN4/B1.06/CCL3.12/PRS1.04
[ 369.470522] usb 1-1.1: Manufacturer: OEM
[ 369.475188] cdc_acm 1-1.1:1.0: ttyACM0: USB ACM device
Check the user permissions
Ensure that the permission of your udev rule is correct:
chmod 644 99-myrule.rules
chown root:root 99-myrule.rules
Do a test run for the add-action
Check the output of udevadm test -a add $(udevadm info -q path -n /dev/ttyACM0). My output looks like this:
calling: test
version 232
This program is for debugging only, it does not run any program
specified by a RUN key. It may show incorrect results, because
some values may be different, or not available at a simulation run.
=== trie on-disk ===
tool version: 232
file size: 8447696 bytes
header size 80 bytes
strings 1849040 bytes
nodes 6598576 bytes
Load module index
Found container virtualization none
timestamp of '/etc/systemd/network' changed
timestamp of '/usr/lib/systemd/network' changed
timestamp of '/lib/systemd/network' changed
Parsed configuration file /lib/systemd/network/99-default.link
Created link configuration context.
timestamp of '/etc/udev/rules.d' changed
Skipping overridden file: /lib/udev/rules.d/99-bizrfid.rules.
Reading rules file: /lib/udev/rules.d/50-firmware.rules
...
Reading rules file: /lib/udev/rules.d/98-systemd.rules
Reading rules file: /etc/udev/rules.d/99-bizrfid.rules
rules contain 49152 bytes tokens (4096 * 12 bytes), 12900 bytes strings
4244 strings (40114 bytes), 3517 de-duplicated (27942 bytes), 728 trie nodes used
GROUP 20 /lib/udev/rules.d/50-udev-default.rules:26
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-serial.rules:7
IMPORT builtin 'usb_id' /lib/udev/rules.d/60-serial.rules:8
/sys/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.1/1-1.1:1.0: if_class 2 protocol 0
IMPORT builtin 'hwdb' /lib/udev/rules.d/60-serial.rules:8
IMPORT builtin 'path_id' /lib/udev/rules.d/60-serial.rules:15
LINK 'serial/by-path/pci-0000:00:14.0-usb-0:1.1:1.0' /lib/udev/rules.d/60-serial.rules:16
IMPORT builtin skip 'usb_id' /lib/udev/rules.d/60-serial.rules:19
LINK 'serial/by-id/usb-OEM_TWN4_B1.06_CCF3.00_PRS1.04-if00' /lib/udev/rules.d/60-serial.rules:23
LINK 'ttyMyDevice' /etc/udev/rules.d/99-bizrfid.rules:1
handling device node '/dev/ttyACM0', devnum=c166:0, mode=0660, uid=0, gid=20
preserve permissions /dev/ttyACM0, 020660, uid=0, gid=20
preserve already existing symlink '/dev/char/166:0' to '../ttyACM0'
found 'c166:0' claiming '/run/udev/links/\x2fserial\x2fby-id\x2fusb-OEM_TWN4_B1.06_CCF3.00_PRS1.04-if00'
creating link '/dev/serial/by-id/usb-OEM_TWN4_B1.06_CCF3.00_PRS1.04-if00' to '/dev/ttyACM0'
preserve already existing symlink '/dev/serial/by-id/usb-OEM_TWN4_B1.06_CCF3.00_PRS1.04-if00' to '../../ttyACM0'
found 'c166:0' claiming '/run/udev/links/\x2fserial\x2fby-path\x2fpci-0000:00:14.0-usb-0:1.1:1.0'
creating link '/dev/serial/by-path/pci-0000:00:14.0-usb-0:1.1:1.0' to '/dev/ttyACM0'
preserve already existing symlink '/dev/serial/by-path/pci-0000:00:14.0-usb-0:1.1:1.0' to '../../ttyACM0'
creating link '/dev/ttyMyDevice' to '/dev/ttyACM0'
creating symlink '/dev/ttyMyDevice' to 'ttyACM0'
created db file '/run/udev/data/c166:0' for '/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.1/1-1.1:1.0/tty/ttyACM0'
ACTION=add
DEVLINKS=/dev/serial/by-path/pci-0000:00:14.0-usb-0:1.1:1.0 /dev/serial/by-id/usb-OEM_TWN4_B1.06_CCF3.00_PRS1.04-if00 /dev/ttyMyDevice
DEVNAME=/dev/ttyACM0
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-1/1-1.1/1-1.1:1.0/tty/ttyACM0
ID_BUS=usb
ID_MODEL=TWN4_B1.06_CCF3.00_PRS1.04
ID_MODEL_ENC=TWN4\x2fB1.06\x2fCCF3.00\x2fPRS1.04
ID_MODEL_FROM_DATABASE=Atom Processor Z36xxx/Z37xxx, Celeron N2000 Series USB xHCI
ID_MODEL_ID=0420
ID_PATH=pci-0000:00:14.0-usb-0:1.1:1.0
ID_PATH_TAG=pci-0000_00_14_0-usb-0_1_1_1_0
ID_PCI_CLASS_FROM_DATABASE=Serial bus controller
ID_PCI_INTERFACE_FROM_DATABASE=XHCI
ID_PCI_SUBCLASS_FROM_DATABASE=USB controller
ID_REVISION=0200
ID_SERIAL=OEM_TWN4_B1.06_CCF3.00_PRS1.04
ID_TYPE=generic
ID_USB_CLASS_FROM_DATABASE=Communications
ID_USB_DRIVER=cdc_acm
ID_USB_INTERFACES=:020201:0a0000:
ID_USB_INTERFACE_NUM=00
ID_VENDOR=OEM
ID_VENDOR_ENC=OEM
ID_VENDOR_FROM_DATABASE=Intel Corporation
ID_VENDOR_ID=09d8
MAJOR=166
MINOR=0
SUBSYSTEM=tty
TAGS=:systemd:
USEC_INITIALIZED=71480300178
Unload module index
Unloaded link configuration context.

How can i send a binary file via serial in linux?

I want to control a hdmi matrix switch via serial connection.
In Windows i already tried it successful by the following steps:
Decode the necessary HEX from a simple textfile to a binary:
certutil -decodehex on.txt on.bin
Then configure the mode for my comport:
MODE COM1:19,n,8,1
copy on.bin \\.\com1 /b
Now i try to do the same in linux (debian). Since the files are binary i figured i can reuse them, so i transferred them to the linux system and tried the following to configure the comport:
stty -F /dev/ttyUSB0 19200 cs8 -cstopb -parenb
And sending the binary:
cat on.bin > /dev/ttyUSB0
But that won't do anything.´
EDIT:
It's a different PC, but the USB2Serial Converter ist the same.
lsusb gives me:
Bus 001 Device 003: ID 1a86:7523 QinHeng Electronics HL-340 USB-Serial adapter
dmesg shows
[ 5.070075] usbserial: USB Serial support registered for generic
[ 5.072824] usbserial: USB Serial support registered for ch341-uart
[ 5.073476] usb 1-9: ch341-uart converter now attached to ttyUSB0

/dev/input file created, but contains no data stream

So, I'm trying to read a USB device in a brand new installation of Linux Mint.
The way I've done it before is to read the raw stream found in /dev/input/by-id
The device is being detected, and it is producing the expected device:
$ ls /dev/input/by-id/
usb-Generic_WebCam_SC-13HDL11939N_200901010001-event-if00
usb-Logitech_Logitech_Buzz_tm__Controller_V1-event-if00
But when I look at the file using
tail -f /dev/input/by-id/usb-Generic_WebCam_SC-13HDL11939N_200901010001-event-if00
No data is output to the terminal when I press some keys. I've tried it with sudo, I've tried changing the rights for the file. It basically waits where it is, unchanged.
There's a lot of questions about devices not appearing, or about IO errors when reading a file, but I can't find anyone else who's had the same problem.
Why might Linux Mint be detecting the device, but not reading the data from it?
Additional requested information:
# ls -lRa /dev/input/by-id
/dev/input/by-id:
total 0
drwxr-xr-x 2 root root 80 Jul 2 21:38 .
drwxr-xr-x 4 root root 360 Jul 2 21:38 ..
lrwxrwxrwx 1 root root 9 Jul 2 21:24 usb-Generic_WebCam_SC-13HDL11939N_200901010001-event-if00 -> ../event9
lrwxrwxrwx 1 root root 10 Jul 2 21:38 usb-Logitech_Logitech_Buzz_tm__Controller_V1-event-if00 -> ../event10
I tried tail -f on /dev/input/event10, too. Same result.
Also, the last few lines of dmesg
[ 263.440421] usb 2-1.1: new low-speed USB device number 5 using ehci-pci
[ 263.538270] usb 2-1.1: New USB device found, idVendor=054c, idProduct=0002
[ 263.538280] usb 2-1.1: New USB device strings: Mfr=3, Product=1, SerialNumber=0
[ 263.538285] usb 2-1.1: Product: Logitech Buzz(tm) Controller V1
[ 263.538290] usb 2-1.1: Manufacturer: Logitech
[ 263.585640] hidraw: raw HID events driver (C) Jiri Kosina
[ 263.597332] usbcore: registered new interface driver usbhid
[ 263.597338] usbhid: USB HID core driver
[ 263.615420] input: Logitech Logitech Buzz(tm) Controller V1 as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0/0003:054C:0002.0001/input/input11
[ 263.668811] sony 0003:054C:0002.0001: input,hidraw0: USB HID v1.11 Joystick [Logitech Logitech Buzz(tm) Controller V1] on usb-0000:00:1d.0-1.1/input0
[ 811.582183] usb 2-1.1: USB disconnect, device number 5
[ 813.318275] usb 2-1.1: new low-speed USB device number 6 using ehci-pci
[ 813.416196] usb 2-1.1: New USB device found, idVendor=054c, idProduct=0002
[ 813.416207] usb 2-1.1: New USB device strings: Mfr=3, Product=1, SerialNumber=0
[ 813.416213] usb 2-1.1: Product: Logitech Buzz(tm) Controller V1
[ 813.416218] usb 2-1.1: Manufacturer: Logitech
[ 813.422041] input: Logitech Logitech Buzz(tm) Controller V1 as /devices/pci0000:00/0000:00:1d.0/usb2/2-1/2-1.1/2-1.1:1.0/0003:054C:0002.0002/input/input12
[ 813.422335] sony 0003:054C:0002.0002: input,hidraw0: USB HID v1.11 Joystick [Logitech Logitech Buzz(tm) Controller V1] on usb-0000:00:1d.0-1.1/input0
I have found that it can be read using the evtest utility (https://wiki.ubuntu.com/DebuggingTouchpadDetection/evtest), but only as root, or using sudo.
Also as root or sudo, I am unable to see any data in the path mentioned above.
P.S. I am able to push control data to the lamps in these controllers via /sys/class/leds/
The problem here is with the tail program, not with the input devices themselves. tail is trying to read data until "the end of the file" before it starts printing anything -- but an input device has no "end of the file", so it will never print anything. cat, on the other hand, writes out data immediately as it comes in, so that works correctly. I don't know why tail worked for you with other input devices in the past.

Is this Possible to know device Mounting and Unmounting Time in Ubuntu?

from dmesg we can know that particular device has been mounted or unmounted.
But I want to know on which time the device has been mounted or unmounted.
Solution 1:
dmesg output isn't having human readable date-time information
Instead using dmesg you can use kernel log available, and filter it according to your need.
for e.g. Ubuntu, Debian stores kernel log at /var/log/kern.log
cat /var/log/kern.log | grep "usb"
It will give output like,
Apr 30 11:42:23 debian kernel: [ 1537.984584] usb 1-1.1: USB disconnect, device number 3
Apr 30 11:42:23 debian kernel: [ 1538.207012] usb 1-1.1: new low-speed USB device number 5 using ehci_hcd
Apr 30 11:42:29 debian kernel: [ 1543.409629] usb 1-1.1: new low-speed USB device number 6 using ehci_hcd
Apr 30 11:42:29 debian kernel: [ 1543.504880] usb 1-1.1: New USB device found, idVendor=04f3, idProduct=0235
Apr 30 11:42:29 debian kernel: [ 1543.504885] usb 1-1.1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
Apr 30 11:42:29 debian kernel: [ 1543.504888] usb 1-1.1: Product: OM
Solution 2:
I've found one perl script to convert dmesg date-time to human readable.
Try it,
#!/usr/bin/perl
use strict;
use warnings;
my #dmesg_new = ();
my $dmesg = "/bin/dmesg";
my #dmesg_old = `$dmesg`;
my $now = time();
my $uptime = `cat /proc/uptime | cut -d"." -f1`;
my $t_now = $now - $uptime;
sub format_time {
my #time = localtime $_[0];
$time[4]+=1; # Adjust Month
$time[5]+=1900; # Adjust Year
return sprintf '%4i-%02i-%02i %02i:%02i:%02i', #time[reverse 0..5];
}
foreach my $line ( #dmesg_old )
{
chomp( $line );
if( $line =~ m/\[\s*(\d+)\.(\d+)\](.*)/i )
{
# now - uptime + sekunden
my $t_time = format_time( $t_now + $1 );
push( #dmesg_new , "[$t_time] $3" );
}
}
print join( "\n", #dmesg_new );
print "\n";
Save and apply execute permission.
$chmod a+x script.pl
$./script.pl
[Sample output:]
[2014-04-30 11:17:27] eth0: no IPv6 routers present
[2014-04-30 11:42:18] hub 1-1:1.0: port 1 disabled by hub (EMI?), re-enabling...
[2014-04-30 11:42:18] usb 1-1.1: USB disconnect, device number 3
[2014-04-30 11:42:19] usb 1-1.1: new low-speed USB device number 5 using ehci_hcd
[2014-04-30 11:42:24] hub 1-1:1.0: unable to enumerate USB device on port 1
[2014-04-30 11:42:24] usb 1-1.1: new low-speed USB device number 6 using ehci_hcd
[2014-04-30 11:42:24] usb 1-1.1: New USB device found, idVendor=04f3, idProduct=0235
[2014-04-30 11:42:24] usb 1-1.1: New USB device strings: Mfr=0, Product=2, SerialNumber=0
[2014-04-30 11:42:24] usb 1-1.1: Product: OM
[2014-04-30 11:42:24] input: OM as /devices/pci0000:00/0000:00:1a.0/usb1/1-1/1-1.1/1-1.1:1.0/input/input11
[2014-04-30 11:42:24] generic-usb 0003:04F3:0235.0004: input,hidraw0: USB HID v1.11 Mouse [OM] on usb-0000:00:1a.0-1.1/input0
Solution 3:
If your distro supports -T option for dmesg
Try dmesg -T. For me it worked on Debian, It should work for you too on Ubuntu. It enables time-stamp for output.
[From man page]
-T, --ctime
Print human readable timestamps. The timestamp could be inaccurate!
The time source used for the logs is not updated after system SUSPEND/RESUME.
In linux /var/log directory contains various log details. We can also get history of previous logs from this directory. Kernel zips the previous log details. In case of yours you have to open kern.log. But If you are looking for details which is not in kern.log, you can see kern.log.1 or in case you are interested in very old details, you have to unzip kern.log.2.gz

RS232 console communication - set baudrate to 1 MBaud

Within a bash script, I use the following:
$ stty -F /dev/ttyUSB0 921600 raw
$ echo -n "some test data" >/dev/ttyUSB0
and it works as expected.
Using a PL2303 USB to RS232 adapter:
$ lsusb
...
Bus 006 Device 010: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Bus 006 Device 011: ID 067b:2303 Prolific Technology, Inc. PL2303 Serial Port
Now I tried to do the same with 1 MBd, but got an error:
$ stty -F /dev/ttyUSB0 1000000 raw
stty: /dev/ttyUSB0: unable to perform all requested operations
Also the same message when I try with 500 kBd. Trying 250 kBd the error message is different:
$ stty -F /dev/ttyUSB0 250000 raw
stty: invalid argument `250000'
Try `stty --help' for more information.
As seen here, it's a problem in the PL2303 linux driver.
I'm working on Kubuntu 12.04, 32 Bit. Unfortunally, I don't know how to fix that driver on my system (getting driver source, patch em, compile, install … hmm, maybe I learn a bit and give it a try - advice is welcome).
But maybe there is an updated driver avaliable which is easy to install?
Or does someone know an alternate USB to RS232 adapter which works at 1 MBd (hardware flowcontrol via rts/cts is needed, which works pretty well with the PL2303)?
After the realization that »Prolific and FTDI are competitors«, I bought Ftdi US232R-10 which is a FT232R based device and specified for 1 MBd transfer rate.
With this adapter I'd successfully tested communication at 1 MBd by transfering some GiB data without any error (including usage of Rts/Cts hardware flow control).
Configuring this device using stty like:
$ stty -F /dev/ttyUSB0 1000000 raw
works successfully.

Resources