I was a bit afraid that getting an UMTS USB stick to work under Linux would be an impossible task. Turns out to be reasonably simple. These notes are for a Huawei K4505 HSPA+ USB stick, as provided by Proximus (Vodaphone group).

This stick employs the “ZeroCD technology”, also called “flip flop devices”. When plugged in, it presents itself as a mass storage device with its (Windows) installer. It then needs a switching command, which is normally send by the driver once it’s installed. Only after this switching command, the modem is presented to the OS.

So the first step is to get the USB device into the correct mode. This can be done with usb_modeswitch (called usb-modeswitch on ubuntu). The Ubuntu package automatically installs the needed udev-rules to make things work automagically. Seconds after plugging in the device, I can see (via dmesg) the switch and see /dev/ttyUSB0 added.

The modem is now visible. Next up is making the actual connection with the network. I’ve found this guide for ArchLinux, which works on Ubuntu with almost no changes. For redundancy reasons, I’ll summarize the steps below:

# cat > /etc/ppp/options-mobile <<EOT
ttyUSB0         # Use this device
921600          # at high speed
lock            # create lockfile
crtscts         # use hardware (CTS/RTS) flow control with the modem
modem           # use modem control lines
passive         # don't exit if no LCD reply is received
novj            # no TCP header compression
defaultroute    # use this connection as default route
noipdefault     # use IPCP to get IP, don't try to guess one
usepeerdns      # Use supplied DNS servers
hide-password   # don't log passwords (if used)
persist         # reopen connection if closed
holdoff 10      # but wait 10 seconds between reconnects
maxfail 0       # and keep trying forever
debug           # tell me what's going on

# cat > /etc/ppp/peers/mobile-auth <<EOT
file /etc/ppp/options-mobile
user "your_usr"
password "your_pass"
connect "/usr/sbin/chat -v -t15 -f /etc/ppp/chatscripts/mobile-modem.chat"
# cat > /etc/ppp/peers/mobile-noauth <<EOT
file /etc/ppp/options-mobile
connect "/usr/sbin/chat -v -t15 -f /etc/ppp/chatscripts/mobile-modem.chat"
# ln -fs mobile-noauth /etc/ppp/peers/provider

# mkdir /etc/ppp/chatscripts
# cat > /etc/ppp/chatscripts/mobile-modem.chat <<EOT
'' 'ATQ0'
'OK' @/etc/ppp/chatscripts/pin
'OK\d-AT-OK' 'ATI'
'OK' 'ATZ'
'OK' 'ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0'
'OK' @/etc/ppp/chatscripts/mode
'OK-AT-OK' @/etc/ppp/chatscripts/apn
'OK' 'ATDT*99***1#'

# cat > /etc/ppp/chatscripts/apn.be.proximus <<EOT
# ln -fs apn.be.proximus /etc/ppp/chatscripts/apn

# cat > /etc/ppp/chatscripts/pin.CODE <<EOT
# cat > /etc/ppp/chatscripts/pin.NONE <<EOT
# ln -fs pin.CODE /etc/ppp/chatscripts/pin

# cat > /etc/ppp/chatscripts/mode.3G-only <<EOT
# cat > /etc/ppp/chatscripts/mode.3G-pref <<EOT
# cat > /etc/ppp/chatscripts/mode.GPRS-only <<EOT
# cat > /etc/ppp/chatscripts/mode.GPRS-pref <<EOT
# cat > /etc/ppp/chatscripts/mode.NONE <<EOT
# ln -fs mode.3G-pref /etc/ppp/chatscripts/mode

These instructions set up a set of files with symlinks to easily switch between configs. Simply changing the symlinks in /etc/ppp/chatscripts allows you to change the APN or the (preferred) mode.

Once these configuration files are in place, a simple pon brings up the connection.

Other useful AT commands

I’ve found the AT command specification for a Huawei Modem (local copy) which listed some other interesting AT-commands:

  • AT+CSQ returns the current RSSI (received signal strength indicator). The first number indicates the Rx power = (-113 + <num>*2) dBm. You can convert this to the more usual “bars” unit, this site lists some value-to-bars conversions (local copy).
  • AT^SYSINFO tells you what mode is currently used (GPRS, EDGE, UMTS, …) in the 7th field:
    • 0: No service
    • 1: GSM mode
    • 2: GPRS mode
    • 3: EDGE mode
    • 4: WCDMA mode
    • 5: HSDPA mode
    • 6: HSUPA mode
    • 7: HSDPA mode and HSUPA mode
    • 8: TD_SCDMA mode
    • 9: HSPA+ mode
    • 17: HSPA+(64QAM) mode
    • 18: HSPA+(MIMO) mode
  • AT+CREG=2 and AT+CGREG=2 when used on /dev/ttyUSB2 return the cellID of the current cell (on a periodic basis).


  1. Thibaut says:

    Can it be done on Raspbian too?
    On my Raspberry Pi the switchover seems to happen (sometimes) after unplugging and replugging the modem (E5331s) on a live Raspberry Pi. I have no luck yet with using usb-modeswitch on Raspbian.

  2. Niobos says:

    Hi Thibaut,

    I’m pretty sure it can be done on Raspbian as well.

    Can you elaborate what you have already tried and what the result was: Did you get any log messages about usb-modeswitch attempting to switch the device? In what configuration did you get (intermittent) success?


  3. Thibaut says:

    Hi Niobos,

    The log messages (I’ve put a selection of it with attention to the USB devices) are below at the end.
    Raspbian recognises a Mass-storage drive in the Huawei Dongle

    With or without usb-modeswitch, Raspbian does not make a ttyUSB for it in the /dev folder. Without that I can’t settup the wvdial configuration file.
    The targetproduct should be the modem although nor the logs or lsusb make clear which what is.

    My setup for the usb_modeswitch.conf file is:
    # Configuration for the usb_modeswitch package, a mode switching tool for

    # USB devices providing multiple states or modes


    # Evaluated by the wrapper script /usr/sbin/usb_modeswitch_dispatcher


    # To enable an option, set it to “1”, “yes” or “true” (case doesn’t matter)

    # Everything else counts as “disable”

    # Disable automatic mode switching globally (e.g. to access the original

    # install storage)


    # Enable logging (results in a extensive report file in /var/log, named

    # “usb_modeswitch_” and probably others


    # T-Mobile NL (Huawei E352)

    DefaultVendor= 0x12d1


    TargetVendor= 0x12d1

    TargetProduct= 0x1c20


    RPi Logs:
    [ 2.792963] usb 1-1: New USB device found, idVendor=0424, idProduct=9512

    [ 2.802520] usb 1-1: New USB device strings: Mfr=0, Product=0, SerialNumber=0

    [ 2.813531] hub 1-1:1.0: USB hub found

    [ 2.819687] hub 1-1:1.0: 3 ports detected

    [ 3.102570] usb 1-1.1: new high-speed USB device number 3 using dwc_otg

    [ 3.213096] usb 1-1.1: New USB device found, idVendor=0424, idProduct=ec00

    [ 3.221995] usb 1-1.1: New USB device strings: Mfr=0, Product=0, SerialNumber=0

    [ 3.249812] smsc95xx v1.0.4

    [ 3.330735] smsc95xx 1-1.1:1.0 eth0: register ‘smsc95xx’ at usb-bcm2708_usb-1.1, smsc95xx USB 2.0 Ethernet, b8:27:eb:0d:09:65

    [ 4.256492] udevd[159]: starting version 175

    [ 5.642682] usb 1-1.3: new high-speed USB device number 4 using dwc_otg

    [ 5.773500] usb 1-1.3: New USB device found, idVendor=12d1, idProduct=1c20

    [ 5.792482] usb 1-1.3: New USB device strings: Mfr=2, Product=1, SerialNumber=0

    [ 5.801840] usb 1-1.3: Product: HUAWEI Mobile

    [ 5.823284] usb 1-1.3: Manufacturer: HUAWEI

    [ 5.844907] usb-storage 1-1.3:1.0: USB Mass Storage device detected

    [ 5.872515] scsi host0: usb-storage 1-1.3:1.0

    [ 6.873591] scsi 0:0:0:0: CD-ROM HUAWEI Mass Storage 2.31 PQ: 0 ANSI: 2

    [ 7.739479] usbcore: registered new interface driver uas

    [ 7.825190] sr 0:0:0:0: [sr0] scsi-1 drive

    [ 7.831178] cdrom: Uniform CD-ROM driver Revision: 3.20

    [ 7.844063] sr 0:0:0:0: Attached scsi CD-ROM sr0

    [ 7.872815] sr 0:0:0:0: Attached scsi generic sg0 type 5

    [ 7.986266] random: nonblocking pool is initialized

    [ 10.846517] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)

    [ 11.329606] EXT4-fs (mmcblk0p2): re-mounted. Opts: (null)

    [ 21.163233] smsc95xx 1-1.1:1.0 eth0: hardware isn’t capable of remote wakeup

    [ 22.863815] smsc95xx 1-1.1:1.0 eth0: link up, 100Mbps, full-duplex, lpa 0x41E1

    [ 27.001666] ip_tables: (C) 2000-2006 Netfilter Core Team

    [ 27.062641] nf_conntrack version 0.5.0 (6964 buckets, 27856 max)

    [ 28.058836] Adding 102396k swap on /var/swap. Priority:-1 extents:2 across:2134012k SSFS

  4. Niobos says:

    I believe you have your usb_modeswitch config the wrong way around.

    From the logs, I see 12d1:1c20 as being the CD-ROM & mass storage mode. From the man page of usb_modeswitch, these should go in the Default… variables. The Target… variables should contain the USB-IDs that you want to achieve.

    You can also try to run usb_modeswitch by hand, optionally in verbose mode.

  5. Thibaut says:

    Hi Niobos,

    After restarting the modem the number 12d1:1506 showed up, which is the Dongle in 3g mode. It first connects to ttyUSB0, then less than a second later it connects to ttyUSB1. So the USB conundrum is solved now.

    In order to make the connection with 3g to the internet I use wvdial with the following config-file. I’m sure that things like the APN, Modem, login and password are correct. I’m less sure about the Phone (is it the landcode ??) and the baudrate. I googled for the right settings for this ISP (carrefourdata.be in this case) but as far as I can see the ISP doesn’t provide these settings. I see you found the settings for pppd for your ISP (proximus). Do some ISPs provide these and others not?

    [Dialer BASE]

    Init1 = ATZ

    Init2 = AT+CSQ

    Init3 = AT^SYSINFO

    Init4 = AT+CGDCONT=1,”IP”,”carrefourdata.be”

    Stupid Mode = 1

    Modem Type = Analog
    ISDN = 0

    Phone = *99#

    Modem = /dev/ttyUSB1

    Username = carrefour

    Password = carrefour

    Baud = 460800

  6. Niobos says:

    Hi Thibaut,

    For the TTY-issue: These flip-flop devices just have two configurations, and a few devices (modem, monitorport, CDROM, SD-card, …). You can (re)configure it to set which device is shown in which configuration. It’s perfectly possible that the modem is already visible in “initial” mode, and that no switch is needed. (Google for AT^GETPORTMODE).

    Phone number looks good. This is the default phone number. If this doesn’t work, you can try *99***1# as well. All ISPs should provide these, but most don’t… There are lists on the internet to help you out.

    Baudrate shoud be as high as your virtual port supports. I use 921600, but I don’t think it matters since the serial port is virtual and doesn’t exist anyway.

Leave a Reply

Anti-Spam Quiz: