USB_ModeSwitch - Activating Switchable USB Devices on Linux

 
本文档来自于: http://www.draisberghof.de/usb_modeswitch/
主要是介绍一种3G卡在windows下是autorun而在linux下如何转换这种模式为com的方法。在该网址经常有新的设备及型号更新。
 
  • Introduction
  • Download
  • How to install
  • How to use (and to automate)
  • Known working hardware
  • Troubleshooting
  • Kernel support
  • Contribute
  • Whodunit
  • History
Version française içi - merci au Bullteam
If you don't like the text column width, adjust your browser window

Introduction

USB_ModeSwitch is (surprise!) a mode switching tool for controlling "flip flop" (multiple device) USB gear.
Several new USB devices (especially high-speed wireless WAN stuff, there seems to be a chipset from Qualcomm offering that feature) have their MS Windows drivers onboard; when plugged in for the first time they act like a flash storage and start installing the driver from there. After that (and on every consecutive plugging) this driver switches the mode internally, the storage device vanishes (in most cases), and a new device (like an USB modem) shows up. The WWAN gear maker Option calls that feature "ZeroCD (TM)".
As you may have guessed, nothing of this is documented in any form and so far there are no official Linux drivers available (with the notable exception of Option products). On the good side, most of the known devices work out of the box with the available Linux drivers like "usb-storage" or "usbserial" (in recent kernels quite a lot of devices are acknowledged by the "option" module). That leaves the problem of the mode switching from storage to modem or whatever the thing is supposed to do.
Fortunately there are things like human reason, USB sniffing programs and "libusb". It is possible to eavesdrop the communication of the MS Windows driver, to isolate the command or action that does the switching, and to reproduce the same thing with Linux.
USB_ModeSwitch makes the last step considerably easier by taking the important parameters from a configuration file and doing all the initialization and communication stuff.
Starting from version 0.9.7 it has an optional success check which spares the manual call of "lsusb" to note any changes after execution. This comes at a price though: to work properly, the success check needs a system/device dependent delay to give the device time to settle after the switch. This delay is configurable, but it obviously prevents USB_ModeSwitch to return immediately. Thus it is mostly useful during testing.
Please read the information on this page carefully before you go around posting questions! This is no tool that does it all for you automagically (yet). It really helps to understand in principle what is happening, which in turn makes it easy to adapt the config file to your setup or even do your own exploring of new devices.
For hints about doing your own sniffing see paragraph Contribute below
Breaking News: just found this humble tool in the source code of the fine Dovado UMR router, which they publish in compliance with the GPL. So if you want the power of your Wireless Broadband across your local network, but without the "fun" of setting up your own Linux router (as I did), consider investing in such a machine.

Download

The latest release version is 1.0.2/b>. The tar archive contains the source and a i586 binary (32 bit, GCC 4.3.2). I used libusb-0.1.12.
There are changes and updates to the config file more often than new releases; most of the valuable knowledge about devices is contained in this file. So you better use the latest version linked here.
  • Download usb_modeswitch-1.0.2.tar.bz2, dated from 2009-06-10; a Debian (Xandros/Ubuntu) package should be available soon at the Debian Repository. Many architectures are supported there (like amd64 or ia64)
  • Load the latest usb_modeswitch.conf; the default place is "/etc". Last updated 2009-06-10
  • Don't forget libusb if you don't have it. In your distribution, there is most likely a package named "libusb-dev" or "libusb-devel"

How to install

Unpack and run "make install". Edit "/etc/usb_modeswitch.conf" according to your hardware (it's heavily commented and should tell you what to do).
If you want to compile it for yourself, just delete the binary, then run "make" or type on the shell:
$ gcc -l usb -o usb_modeswitch usb_modeswitch.c
That's as easy as it gets. And it should be as portable as libusb itself (some limitations on FreeBSD based systems are known).
If installing manually, take the executable "usb_modeswitch" and put it into your path (preferably "/sbin" or "/usr/sbin").
Put "usb_modeswitch.conf" into "/etc" and don't forget to edit it.
Alternatively you can use the command line interface to tell USB_ModeSwitch the things it needs to know; try "usb_modeswitch -h" to list the parameters. This way you can handle multiple configurations. If any command line parameters except -W and -q are used, the default config file is NOT read.
For a command line parameter reference, you have to consult /etc/usb_modeswitch.conf at the moment. Until I decide to put up a fight with groff and provide a man page.
Important: USB_ModeSwitch - like all programs with libusb routines - has to be run as root. Otherwise strange error messages come up ...

How to use and to automate

If your device was switched successfully, there are three possible outcomes:
  1. It changed to a CDC ACM device and was recognized by the "cdc-acm" driver. If you run "dmesg", you should see that new device files were generated starting from "/dev/ttyACM0". These are your new serial ports to use, most likely the one with the lowest number.
  2. It changed to a serial device and was recognized by the "option" driver. If you run "dmesg", you should see that new device files were generated starting from "/dev/ttyUSB0". These are your new serial ports to use, most likely the one with the lowest number.
  3. It changed to a serial device, but no driver was loaded. If you run "dmesg", it says something of a "new fullspeed device" but nothing more happened. To use it immediately, you have to load the driver manually and tell it to bind to your specific device. You need the (new) target IDs for this. Enter in a terminal (as root!):
    # modprobe usbserial vendor=<YourTargetVendID> product=<YourTargetProdID>
    Run "dmesg" again and you should see the changes as in 2.
    The use of usbserial is not recommended as the best solution by the Linux USB maintainers. Instead, new modems should have their IDs added to the "option" driver which is optimized for high speed wireless devices. I will try to turn in kernel patches for that purpose once in a while. If you know how to recompile your kernel you can add just a slight modification to "option.c" and make it work for you. Details follow soon.
Please note that further steps of using the modem to connect are outside the scope of this site. There is plenty of information on that subject, distribution-specific and in general.
Mind that you have to run USB_ModeSwitch every time you plug your device or boot with it. If you have "udev" in your distribution it's really not hard to automate this and just forget about it, once you figured how to switch your device manually.
Note however that timing might be an issue with some of the more recent setups. If your automatic switching is unreliable the delayed execution of USB_ModeSwitch might help (see the special script below).
That said, since version 0.9.4 there have been very few reports of timing issues.
You should have a folder named "/etc/udev" or similar. Somewhere in there (I have a folder "rules.d") you find some files with the extension ".rules". Create a new one (or edit an existing one, but by convention not the default "50-something.rules"). I chose one named "45-hotplug.rules" since hotplugging is what USB is about after all.
In the chosen/new file add the line
SUBSYSTEM=="usb", SYSFS{idProduct}=="<YourDefaultProdID>", SYSFS{idVendor}=="<YourDefaultVendID>", RUN+="<YourPathToUSB_ModeSwitch>"
That's basically it.
From here, there are several ways to continue. If your GSM device is recognized by a recent version of the "option" driver you shouldn't have to do anything but to load the module (most certainly handled by udev automatically). Some devices switch to the ACM class and are bound to the module "cdc-acm" ("USB Abstract Control Model driver for USB modems and ISDN adapters"). The created serial devices are named "ttyACM0", "..1", etc. instead of "ttyUSB0" ...
If your (serial) device is not supported by the modules mentioned you can always use "usbserial", but it needs to be told the device IDs (plus a performance-related option):
SUBSYSTEM=="usb", SYSFS{idProduct}=="<YourTargetProdID>", SYSFS{idVendor}=="<YourTargetVendID>",
  RUN+="/sbin/modprobe usbserial vendor=<YourTargetVendID> product=<YourTargetProdID> maxSize=4096"
As for the difference between "usbserial" and "option", here is a quote from option.c:
  This driver exists because the "normal" serial driver doesn't work too well
  with GSM modems. Issues:
  - data loss -- one single Receive URB is not nearly enough
  - nonstandard flow (Option devices) control
  - controlling the baud rate doesn't make sense
Following that, I'd recommend trying the "option" driver if you can. In recent kernels it recognizes several Option, Huawei and Novatel devices (among others) out of the box. And following kernel developers mail traffic it looks like this driver is becoming the standard for GSM devices as more models are added. In the latest kernels the kernel config entry reads "USB driver for GSM and CDMA modems" (Device Drivers / USB support / USB Serial Converter support).
Devices supported by the "option" driver that don't change their IDs after switching might run into problems because of the driver trying to attach before the switching happened. In this case it could help to blacklist it and to load it manually via the helper script after execution of usb_modeswitch. In newer kernels (definitely in 2.6.28) this problem is handled by probing for the device class before binding.
Anyway, if your device works O.K. with "usbserial", and you are not afraid to edit kernel sources, why not just add the vendor and product ID ( after switching of course) to the "option" driver? I just did that with my cell phone, and now the "option" module is bound to it automatically when plugging in. Look at the other devices included in "option.c" and just add your IDs the same way - that's it. Two or three lines in most cases. Recompile, add your device to one of the udev rules (see above) and enjoy!
For plain serial devices that keep their ID after switching a script "/sbin/mydevice_switch.sh" can be created:
#!/bin/sh
/sbin/usb_modeswitch
sleep <SomeSeconds>  # probably not necessary, try out
/sbin/modprobe usbserial vendor=<YourDefaultVendID> product=<YourDefaultProdID> maxSize=4096
And then add this rule:
SUBSYSTEM=="usb", SYSFS{idProduct}=="<YourDefaultProdID>", SYSFS{idVendor}=="<YourDefaultVendID>", RUN+="/sbin/mydeviceswitch.sh"
If timing is an issue with your device or setup it might help to delay the execution of USB_ModeSwitch, to allow other drivers like "usb-storage" to finish their activation. Again, use the helper script - called "/sbin/mydevice_switch.sh" here - and fill it like this:
#!/bin/sh
sh -c "sleep 4; /usr/bin/usb_modeswitch" &
exit 0
Luigi Iotti reported problems on some systems (RHEL 5, CentOS 5) of udev always waiting for background scripts to finish. Here is his solution for a changed "/sbin/mydevice_switch.sh":
#!/bin/sh 
# close these FDs to detach from udev 
exec 1<&- 2<&- 5<&- 7<&- 
sh -c "sleep 4; /usr/bin/usb_modeswitch" & 
exit 0

Known working hardware

Very important note:
Personally, I could only test my Option Icon and the S.E. MD400; the list here - as well as all the necessary data - relies on reports from third parties (people, that is). So don't be surprised if you hit sudden obstacles even with your device listed here. You have been warned.
There are hitherto three known methods for initiating the switching process:
1. sending a rarely used or seemingly weird standard storage command (equivalent to those of SCSI) to the storage device ("eject" for example)
2. actively removing (rather detaching) the storage driver from the device
3. sending a certain control message to the device
  • All Option devices
    All known Option devices use the USB storage command REZERO UNIT for switching (inherited from SCSI). Older devices change vendor and product ID, newer ones don't (just their device class). These newer sticks have a special interface after switching (HSO) for which there is a special driver. Some older devices are able to be loaded with the new HSO firmware which changes their behaviour.
    Note: for HSO driver questions and HowTos consult the fine Pharscape site!
    If you have a newer Option device not listed here there is a good chance to get it working by using any HSO driven device entry and just adapting your vendor/product ID.
    There is a switching routine for Option devices in the kernel driver usb-storage (since beginning of 2009). It works only for devices entered in "unusual_devs.h". More to that below.
  • Option GlobeSurfer iCON (aka "Vodafone EasyBox")
    The thing that started it all, because I wanted it to work on my Linux router.
  • Option GlobeSurfer iCON 7.2
    If you get hardware lockups of this thing when plugging in (flashing LEDs), update the firmware. You can probably update it to the new HSO interface
  • Option GlobeTrotter HSUPA Modem (aka "T-Mobile wnw Card Compact III")
    HSO interface
  • Option GlobeTrotter GT MAX 3.6 (aka "T-Mobile wnw Card Compact II")
  • Option GlobeTrotter EXPRESS 7.2 (aka "T-Mobile wnw Card Express II")
  • Option GlobeTrotter GT MAX "7.2 Ready"
  • Option iCON 210
    Not sure if this is a generic Option design (see PROLiNK A600)
  • Option iCON 225 HSDPA (aka "T-Mobile web'n'walk Stick")
    HSO interface
  • Option iCON 401 and AT&T Quicksilver
    HSO interface; has additional Micro SD.
    The Quicksilver looks exactly like the 401 but the product ID is different.
  • Vodafone K3760 (an Option device, original name yet unknown)
    HSO interface
  • All Huawei devices
    We have two options (no pun intended!) for Huawei devices: 1. detaching of "usb-storage" 2. the special control message found by Miroslav Bobovsky. The latter is independent of "usb-storage" and even leaves the storage portion of the device functional. Both methods leave other USB storage devices alone (compared to removing the storage module completely, which works as well).
    Newer kernels try to switch Huawei devices from the driver (special treatment in usb-storage), which does not seem to work all the time. Read last paragraph of Troubleshooting
    If you have a more recent Huawei device not listed here, just try and adapt your vendor/product ID. The switching method is the same for all known devices so far.
  • Huawei E220 (aka "Vodafone EasyBox II", aka "T-Mobile wnw Box Micro")
  • Huawei E160, Huawei E160G, Huawei E169, Huawei E180, Huawei E230, Huawei E270, Huawei E280
  • Huawei E630
    There are reportedly modem-only variants around (without the storage part); for these no switching is required.
  • Novatel Wireless Ovation MC950D HSUPA, Ovation 930D and Merlin XU950D
    They use the USB storage command START/STOP (Eject) for switching. Should switch with "eject <cd device>" as well
  • Novatel Wireless U727, Novatel Wireless U760
    Similar setup as the MC950D, different product IDs
  • Novatel MC990D
    Uses new feature of 0.9.5
  • All ZTE devices
    Some ZTE devices can be switched by issueing the "eject" command to the "CD-ROM" device as well.
    Please read the last paragraph in Troubleshooting!
  • ZTE MF620 (aka "Onda MH600HS")
    Uses the USB storage command TEST UNIT READY for switching.
  • ZTE MF622 (aka "Onda MDC502HS")
    Detachment of storage driver
  • ZTE MF626, ZTE MF628, ZTE MF628+
  • ZTE MF636 (aka "Telstra / BigPond 7.2 Mobile Card")
  • ZTE MF638 (aka "Onda MDC525UP")
  • ZTE AC8710, ZTE AC2710 (EVDO, featured by PTCL)
  • ZTE 6535-Z (featured by SFR)
  • ONDA MT503HS (most likely a ZTE model)
  • ONDA MT505UP (most likely a ZTE model)
  • Alcatel One touch X020 (aka OT-X020, aka "MBD-100HU", aka "Nuton 3.5G", works with "Emobile D11LC")
  • Alcatel One touch X030 (aka OT-X030, aka "Nuton NT36HD")
  • Alcatel X200
  • AnyDATA ADU-500A, AnyDATA ADU-510A, AnyDATA ADU-510L, AnyDATA ADU-520A
  • BandLuxe C120
    Special treatment reportedly necessary. See Forum Entry
  • Solomon S3Gm-660
    Same notes apply as with the BandLuxe C120 above
  • C-motech D-50 (aka "CDU-680")
    Important notes at this Forum Entry
  • C-motech CGU-628 (aka "Franklin Wireless CGU-628A" aka "4G Systems XS Stick W12")
  • Toshiba G450
  • UTStarcom UM175 (distributor "Alltel")
  • Hummer DTM5731
  • A-Link 3GU
  • Quanta MU-Q101, also referred to as "Quanta (NU) MU-Q101"
    You probably need to do the "power suspend" trick (see Troubleshooting) to make it usable
  • Sierra Wireless AirCard 881U (most likely 880U too)
    Supported by newer kernels. If you are stuck with an older one, use this
  • Sierra Wireless Compass 597
    Supported by newer kernels. If you are stuck with an older one, use this
  • Sony Ericsson MD400
    Special handling, takes around 25 seconds to switch
  • LG LDU-1900D EV-DO (Rev. A)
  • Samsung SGH-Z810 USB (with microSD card)
  • MobiData MBD-200HU
  • MyWave SW006 Sport Phone/Modem Combination
  • Hyundai Mobile MB-810
    Same parameters as Option iCON 210
  • PROLiNK PHS100 (various looks)
    Same parameters as Option iCON 210
  • Cricket A600
    Switches to ACM device. Might need a ResetUSB after switching - or not
  • EpiValley SEC-7089 (featured by Alegro and Starcomms / iZAP)
  • ST Mobile Connect HSUPA USB Modem

Troubleshooting

Note: if you still need support after having followed the advice on this page, please use the forum!
If you're next to certain that you have the right values for your device, followed all the hints (see Known working hardware), and USB_ModeSwitch seems to do something run after run but to no effect, there are most likely system issues involved. Almost all distributions today are using "udev" as a device and hotplug manager, and in some cases this daemon is not able to "release" the established connection of a switched device and to see it as a freshly plugged one (after all, this is something outside the USB specs).
There are several ways to analyze and tackle these problems:
  • To see what udev is doing, run udevmonitor in one console and watch what happens if you plug the device and run USB_ModeSwitch. "lsusb" and "dmesg" can give additional information
  • If you suspect timing issues, try to run USB_ModeSwitch with a defined delay after plugging
  • Find the device's sysfs access. It's in the file system under /sys/bus/usb/devices. "dmesg" tells you what bus address it got after plugging; should look like "1-2" or "2-4" or similar. Then - after doing the switch - set it's power level to suspend mode. For example like this:
    $ echo suspend > /sys/bus/usb/devices/1-2/power/level
    Mind that the USB powersaving option must have been configured in your kernel. Thanks to mixmaxtw for this neat trick
  • Try the ResetUSB option with your device. This is somewhat brutal and may also reset an internally switched device back to storage mode
  • Sometimes it is recommended to use the latest firmware available as there have been issues in the past with at least one device (Icon 7.2, resolved now). In other cases devices have stopped working with the usb-serial driver after a firmware update. So the advice is simple: update if not working, otherwise leave alone

Kernel related issues

In newer kernels, some device families (Huawei, ZTE since 2.6.26) get a special treatment in the usb-storage code to enable switching right away. You don't even need USB_ModeSwitch anymore; on the other hand you have no choice of accessing the "CD-ROM" part of your device. Plus, there were cases when the special treatment obviously brought no results and even prevented USB_ModeSwitch to work properly afterwards (happened with ZTE devices, error "-2").
In case of trouble, look into "unusual_devs.h" in the "drivers/usb/storage" folder of your kernel source. If your default ID (vendor and product ID of the storage part) can be found there and you get errors when running USB_ModeSwitch, try first to blacklist "usb-storage". If that helps, you should consider rebuilding your kernel with the entry in "unusual_devs.h" deactivated. The only thing that will happen is that usb-storage works in the default way afterwards.
I found a tip in the Russian Gentoo wiki to do exactly what I just suggested for the ZTE MF626.
Annother way of influencing the kernel behaviour is the parameter "delay_use" of "usb-storage" which sets the time in seconds after plugging when the storage device will actually be used (and mounted). The default value is 5; this might affect the switching result in some way, especially when using an udev rule. I'd be interested to learn about good or bad results of playing around with it.
Add in /etc/modprobe.conf:
options usb-storage delay_use=1 (or 10, or other)

Kernel Support

Standby for more content ...

Contribute

USB_ModeSwitch comes quite handy for experimenting with your own hardware if not supported yet. You could try this approach:
Note the device's Vendor and Product ID from /proc/bus/usb/devices (or from the output of "lsusb"); the assigned driver is usually "usb-storage". Then try spying out the USB communication to the device with the same ID inside M$ Windoze.
I recommend this tool: "SniffUSB" ( http://www.pcausa.com/Utilities/UsbSnoop/default.htm).
This is the extremely short version. There is a very good case example from Mark A. Ziesemer here:
Alltel UM175AL USB EVDO under Ubuntu Hardy Heron
Please post any improvements, new device information and/or bug reports to the ModeSwitchForum !
If you know about a new device configuration you can send me an old-fashioned - and at your demand confidential - e-mail (see below).

Whodunit

Copyright (C) 2007, 2008, 2009 Josua Dietze (usb_admin at this domain)
Command line parsing, decent usage/config output and handling, bugfixes added by:
  • Joakim Wennergren (jokedst) (gmail.com)
TargetClass parameter implementation to support new Option devices/firmware:
  • Paul Hardwick (http://www.pharscape.org)
Created with initial help from:
  • "usbsnoop2libusb.pl" by Timo Lindfors (http://iki.fi/lindi/usb/usbsnoop2libusb.pl)
Config file parsing stuff borrowed from:
  • Guillaume Dargaud (http://www.gdargaud.net/Hack/SourceCode.html)
Hexstr2bin function borrowed from:
  • Jouni Malinen (http://hostap.epitest.fi/wpa_supplicant, from "common.c")
Code, ideas and other input from:
  • Aki Makkonen
  • Denis Sutter
  • Lucas Benedičič
  • Roman Laube
  • Luigi Iotti
  • Vincent Teoh
  • Tommy Cheng
  • Daniel Cooper
  • Andrew Bird
More contributors (device specific) are listed in the config file. Thanks to everyone at the forum too!

History

Version 1.0.2, 2009/06/08
    Some output bugs fixed
Version 1.0.1, 2009/06/08
    Added output of descriptor strings for further identification
Version 1.0.0, 2009/06/03
Attention: possible incompatibilities for command line control! On/off flags don't require arguments anymore (-H, -S, -O, -d, -R, -n, new: -I), meaning "-R 0" does a reset like "-R 1" or "-R"; long option names changed to standard format (e.g. --HuaweiMode to --huawei-mode); added device inquiry, for future help with device identification; catch error -19 as possible success; send and response endpoints now autoselected (consequently NeedResponse is back); code cleanup; new devices
Version 0.9.7, 2009/04/15
    Updated SonyMode, MD 400 now stable; automatic default endpoint detection from Andrew Bird
Version 0.9.7beta, 2009/03/15
    Major code clean up, optional success control (both suggested by Daniel Cooper), new devices
Version 0.9.6, 2009/01/08
    Special modes added for Sierra and Sony Ericsson, new devices
Version 0.9.5, 2008/10/27
    New options for USB tuning added (jokedst), lots of new devices, clean up
Version 0.9.4, 2008/06/09
    Compat fix for libusb on FreeBSD quirks, more devices
Version 0.9.4beta2, 2008/03/19
    Udev 'release' fix
Version 0.9.4beta, 2008/03/16
    Multiple device support
Version 0.9.3, 2008/03/09
    More devices, no other changes from 0.9.3beta
Version 0.9.3beta, 2007/12/30
    New TargetClass parameter for recent Option firmware (Paul Hardwick), more devices
Version 0.9.2, 2007/11/02
    New Huawei mode (code from Miroslav Bobovsky, added by Denis Sutter), more devices
Version 0.9.1beta, 2007/09/11
    Added command line parsing (jokedst), cleaned up config stuff (jokedst), bug fixes, doc updates
Version 0.9beta, 2007/08/12
    Name change from "icon_switch", parameter file and generalizing
Version 0.2, 2006/09/25
    Code cleaning, more messages
Version 0.1, 2006/09/24
    Just very basic functionality ...

Legal

This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details:
http://www.gnu.org/licenses/gpl.txt
 
分享至
一键收藏,随时查看,分享好友!
0人
了这篇文章
类别: 3G┆阅读( 0)┆评论( 0) ┆ 返回博主首页┆ 返回博客首页
上一篇 用wvdial和ppp轻松上网 下一篇 华为E180在linux下使用3G的注意事项(linux in ..

职位推荐

  • 网络运维主管工程师 - 无线领域
  • 网络运维工程师
  • Linux系统运维工程师
  • 运维工程师
  • 信息安全实习生
  • 初级运维工程师
  • 系统运维工程师
  • 前台兼人事助理
  • 高级运维工程师
  • 运维工程师

文章评论

 
 

发表评论            

昵  称:
登录  快速注册
验证码:

点击图片可刷新验证码请点击后输入验证码博客过2级,无需填写验证码

内  容:

同时赞一个

每日博报 精彩不止一点关闭

你可能感兴趣的:(linux,职场,休闲)