Pulse USB data stream __linux Linux

Source: Internet
Author: User
Tags 04x case statement

Note: This article is reproduced from http://club.topsage.com/thread-1231567-1-1.html

The author had a USB device similar to the one used to encrypt "dog" to make it work properly under Linux. However, judging by a small program called Usbview, the Linux kernel cannot drive the USB device, and the device is not found in the "Linux USB Working Devices" list, which means that only a few people are using this type of USB device.
In the Linux/proc/bus/usb/devices file, there are some information about this USB device:

t:bus=01 lev=02 prnt=03 port=02 cnt=01 dev#=4 spd=1.5 mxch=0
d:ver=1.00 cls=ff (Vend.) sub=00 prot=ff mxps=8 #Cfgs =1
p:vendor=0d7a prodid=0001 rev=1.07
S:product=usb Cryptoken
C: * #Ifs =1 cfg#=1 atr=80 mxpwr=16ma
I:if#=0 alt=0 #EPs =0 cls=ff (Vend.) sub=00 prot=ff driver= (None)

You can easily understand the purpose of this USB device by consulting the documentation provided on the USB device product CD. The product CD also provides a shared library where applications can use this USB device through shared libraries. In addition, the product CD provides a small test program to show how different library methods work. With this shared library, the user can access the device directly in a libusb manner. In other words, using this USB device does not require a kernel-level drive. However, the license agreement for this shared library does not allow a program that follows a GPL protocol to use it. Only the above information is not able to drive the USB device, the following from the back of the Linux USB data stream began, to provide you with a way to solve such problems.
You can work around this problem by starting with the latest version 2.6 kernel. The 2.6 version of the kernel can be obtained through a variety of channels, not detailed here.
In the kernel source code of the structure tree in the drivers/usb/core/directory, there are inode.c, DEVICES.C and devio.c three files, the three files together to implement the Usbfs file system. That is, Linux accesses USB devices through these three files. The main work of implementing the FileSystem is done by INODE.C, which provides a variety of VFS code that can be used to create virtual file systems or virtual files. The devices.c file is used to create and read files that represent USB device state information under/proc/bus/usb/devices. The devio.c file is used to control access to USB devices through the Usbfs file system. To enable Linux to access USB devices, you need to make some changes to DEVICES.C and DEVIO.C.
Concrete implementation
1. record access information
Explore USB Data flow starting from logging all USB device access information. In a user program, accessing a USB device via USBFS requires that the IOCTL () command be invoked on the appropriate device file. By further analyzing the devices.c file, it is found that the Usbdev_ioctl () function is invoked every time the IOCTL () is executed, so it should be a good solution to record the access information sent to the USB device. This functionality can be achieved by adding a custom PRINTK () function to each case statement, as follows:

Case Usbdevfs_claiminterface:
PRINTK ("Claiminterface");
RET = Proc_claiminterface (PS, (void __user *) arg);
Case Usbdevfs_releaseinterface:
PRINTK ("Releaseinterface");
RET = Proc_releaseinterface (PS, (void __user *) arg);

After compiling, installing, and so on, each USBFS access is recorded in the kernel log, which can be accessed through the DMESG command.
2. Record control information
By analyzing the description of the USB device in the/proc/bus/usb/devices file, you can learn that the final resolution of the problem must be concerned with the control endpoint of these accesses (Controls ENDP oint). The Proc_control () function in the devio.c file is used to process control messages. The function distinguishes the type of request access by the following statement as a read control message or a write control message:

if (Ctrl.brequesttype & 0x80)

Brequesttype is a binary variable whose highest bit determines the type of request.
Add the following code in the code snippet that handles the read message to record the information for the control request:

PRINTK ("Control read:"
"Brequest=%02x brrequesttype=%02x"
"Wvalue=%04x windex=%04x",
Ctrl.brequest, Ctrl.brequesttype,
Ctrl.wvalue, Ctrl.windex);

Then, add the following code to record the actual data read from the device:

PRINTK ("Control Read:data");
for (j = 0; j < ctrl.wlength; ++j)
PRINTK ("%02x", Ctrl.data[j]);
PRINTK ("");

Similarly, you can add similar code to code snippets that handle write messages. Thus, after the new Usbcore module is generated and reloaded, all bidirectional control messages to the device can be recorded. These messages may return the following information:

Control read:brequest=06 brrequesttype=80 wvalue=0300 windex=0000
Control Read:data 00 00 61 63

3. optimize
The next step is to refine the code to allow the kernel source code to accept the changes well. First, you should fix some of the incorrect places in the PRINTK () call. Second, all PRINTK () calls should have a corresponding log level (Logginglevel), which can be generated in a preprocessing manner. Modify the Include/linux/kernel.h file as follows:

#define Kern_emerg ""/* system is unusable * *
#define KERN_ALERT ""/* action must be taken immediately * *
#define KERN_CRIT ""/* Critical conditions * *
#define KERN_ERR ""/* ERROR conditions * *
#define KERN_WARNING ""/* WARNING conditions * *
#define KERN_NOTICE "" * Normal but significant condition * *
#define KERN_INFO ""/* Informational *
#define KERN_DEBUG ""/* debug-level Messages * *

When the above modifications are complete, call the PRINTK () in the Usbfs_ioctl () function from the "PRINTK" ("Claiminterface"); Modified to "PRINTK (kern_info" Claiminte rface); ".
In fact, not all messages need to be recorded in the log. You can use the macros provided in the header file Include/linux/device.h (including DEV_PRINTK (), De v_dbg (), Dev_warn (), Dev_info (), and Dev_err () To determine what type of USB device access message needs to be logged. These macros require an additional pointer to a struct type to identify the unique device ID. Modify the Dev_info () call as follows:

Dev_info (&dev->dev, "claiminterface");

The PRINTK () call to determine read and write message requests is then modified as follows:

Dev_info (&dev->dev, "control read:"
"Brequest=%02x brrequesttype=%02x"
"Wvalue=%04x windex=%04x",
Ctrl.brequest, Ctrl.brequesttype,
Ctrl.wvalue, Ctrl.windex);
Dev_info (&dev->dev, "Control Read:data");
for (j = 0; j < ctrl.wlength; ++j)
PRINTK ("%02x", Ctrl.data[j]);
PRINTK ("");

After the above modification, get the following return information:

USB 1-1: Control
USB 1-1: Control read:brequest=06 brrequesttype=80 wvalue=0300 windex=0000
USB 1-1: Control Read:data 00 00 61 63

It is not difficult to see that, after the above modification, the removal of the irrelevant USB device message logging information.
The above process creates a usability problem where the message logging information is not generated at the time of the user's request, causing the user's message record to be too large. Adding the following line of code to the de vio.c file resolves this problem:

static int usbfs_snoop = 0;
Module_param (Usbfs_snoop, bool, S_irugo | S_IWUSR);
Module_parm_desc (Usbfs_snoop, "True to log all USBFS traffic");

The code above defines a new Module_param () function to replace the original Module_parm () function. The main difference between the two is that Module_param () contains a new parameter "Usbfs_snoop". You can run the Modinfo command to see the modified effect:

$ modinfo Usbcore
Parm:blinkenlights:true to cycle LEDs on hubs
Parm:usbfs_snoop:true to log all USBFS traffic

The normal module load commands are as follows:

#modprobe Usbcore

After modification, you can load the module with the following command:

#modprobe Usbcore Usbfs_snoop=1

When Usbfs_snoop is not 0 o'clock, it is displayed in Sysfs and allows the user to query and modify options when the module is loaded, in the form of the following:

$ ls-l/sys/module/usbcore/
-r--r--r--1 root root 4096 may 15:33 blinkenlights
-r--r--r--1 root root 4096 may 15:33 refcnt
-rw-r--r--1 root root 4096 may 15:33 Usbfs_snoop

If you want to turn on the message logging feature, you can do the following:

#echo 1 >/sys/module/usbcore/usbfs_snoop

If you want to determine whether the user wants to turn on the message logging feature, you need to make a further change to Dev_info () to create the following macros:

#define SNOOP (Dev, format, arg ...)
do {
if (Usbfs_snoop)
Dev_info (Dev, format, # # ARG);
} while (0)

This macro is used to test the value of the parameter Usbfs_snoop, and if "true", call Dev_info (dev, format, # #arg).
Next, change the previous call to the Dev_info () macro to call the Snoop () macro:

Snoop (&dev->dev, "control read:", "brequest=%02x brrequesttype=%02x", "wvalue=
%04x windex=%04x ", Ctrl.brequest, CT rl.brequesttype,ctrl.wvalue, ctrl.windex);

In order to print the data correctly, you need to make a simple change to the Snoop () macro (just judge the value of the Usbfs_snoop):

if (Usbfs_snoop) {
Dev_info (&dev->dev, "Control Read:data");
for (j = 0; j < ctrl.wlength; ++j)
PRINTK ("%02x", Ctrl.data[j]);
PRINTK ("");


At this point, the modification work is completed. In this way, when accessing a USB device via LIBUSB, you should get a good USBFS access information.

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.