How to install a Huawei E1762 USB/GSM modem on Gentoo

(27.Feb.2010)

Introduction

Installing a USB modem, especially the Huawei E1762 in Gentoo Linux, was quite difficult - especially for me as so far I never fiddled around with "ppp" or AT-commands in Linux.
In the end I tried out quite many ways to make it work, and what I describe here is the one that worked the best.

Update 29.Dec.2012
This device now works out of the box when using Ubuntu 11.10 or Fedora 16 (I did not test other distributions).

Update 09.Nov.2014
Ralf from Germany sent me some remarks/notes => I have posted them at the bottom.


HRDW and provider

As I mention below, I bought a "Huawei E1762" USB modem, but I am actually not 100% sure if the "E1762" is really correct.
I originally wanted to get a "E180v" (as by reading some blogs I got the impression that it was better supported in Linux) but unluckily it wasn't available anymore for the kind of subscription I wanted to have.

The subscription type is the "NATEL(R) data easy" of Swisscom, which is a prepaid one.
Once the modem works the data transfer rate is not bad - I was downloading with 174KB/s, which I think is the maximum I can reach here.

The USB modem has a slot where I have to insert my prepaid card - I think it will therefore accept as well other SIM cards when I am abroad or if I just change provider - but I didn't try this out yet.


Assumptions

  • You already installed the USB modem in a Windows PC and checked that everything is working and that the connection was working. I say this because it might be that the proprietary drivers have to do something "special" during the first connection to activate your subscription.
  • I suppose that in Linux you're logged in as "root". Once it works for root you can always switch back to your normal user.
  • Pls. refer to other guides to know how to do specific tasks, like setting up and compiling a kernel, installing packages, etc... .
  • This guide is specific for Gentoo, and if it works with it, it should be easy to do more or less the same for other distributions. The packages I mention might be called differently in other distributions (e.g. "usb_modeswitch" might be called "usb_modemswitch").
  • If you're using another distribution, the modules I mention below will probably be already available and you therefore won't have to touch the kernel.
  • I am using for this article the kernel version 2.6.32-r3. Not sure if things will work with an older version, but it should work with newer ones.

1- Kernel configuration

First of all make sure that your kernel is ready to work with your USB modem.

Copied from the post of Michael Li:

Device drivers --->
    Network device support --->
        [M] PPP (point-to-point protocol) support
        [M] PPP support for async serial ports
    USB support --->
        [M] OHCI HCD support
        [M] USB Mass Storage support (provides usb-storage so it can be unloaded)
        [M] USB Serial Converter support (provides usbserial, very important)
            [*] USB Generic Serial Driver
            [M] USB driver for GSM and CDMA modems (provides 'option' module, v. important)

About the "OHCI"-line/module: your PC might need another one (EHCI, UHCI, OHCI). To see which one you have to use issue "lspci | grep -i hci" (package "pciutils"). Ignore "AHCI" if you have it as it doesn't have anything to do with USB.

What I did was to select as well...

(under "[M] USB Serial Converter support")
       [M] USB FTDI Single Port Serial Driver
       [M] USB driver for GSM and CDMA modems

...and under "Device drivers => Network device support...

[*]   Universal TUN/TAP device driver support
(under "[M] PPP (point-to-point protocol) support")
    [ ]     PPP multilink support (EXPERIMENTAL)
    [ ]     PPP filtering
    [M]   PPP support for async serial ports
    [M]    PPP support for sync tty ports
    [M]   PPP Deflate compression
    [M]   PPP BSD-Compress compression
    [M]   PPP MPPE compression (encryption) (EXPERIMENTAL)
    [M]   PPP over Ethernet (EXPERIMENTAL)

...as I wasn't sure if my model/provider needed some additional drivers.

Once you have changed the kernel settings, compile & install it and reboot as usual.


2- Which modem do I have?

After rebooting run "lsusb" (package "usbutils"). On my EeePC it looks like this:

~ # lsusb
Bus 001 Device 002: ID 13d3:5108 IMC Networks
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 002: ID 0b05:b700 ASUSTek Computer, Inc. Broadcom Bluetooth 2.1
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

If you now stick the modem into the PC and run again the same command you should see that a new device was recognized:

~ # lsusb
Bus 001 Device 004: ID 12d1:1446 Huawei Technologies Co., Ltd. E1552 (HSPA modem)
Bus 001 Device 002: ID 13d3:5108 IMC Networks
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 002: ID 0b05:b700 ASUSTek Computer, Inc. Broadcom Bluetooth 2.1
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

You see that in my case the device is displayed as a Huawei Technologies Co., Ltd. E1552 (HSPA modem).
Actually these labels change from time to time - run the command "update-usbids" to install the latest ones.

Well. at this point I was already very happy as I thought that the device was already recognized as being a modem and not a normal USB-stick (storage). This because the modem has a "dual personality" - it's a memory card and a modem.
Unluckily I needed a couple of hours to understand that I was just being tricked! :oP . I mention the reason in the next chapter.

What is important in the output you get from "lsusb" is the ID, which is in my case 12d1 (the "vendor") and 1446 (the "product" of that vendor).
It's funny but under the productID "1446" my modem is shown in Linux being a E1552 (as you see in my lsusb-output), but my provider (Swisscom) sells it as E1762. I found in Internet many other blogs/forums where the productID 1446 corresponded apparently to even other models e.g. E1550.

So, which type of Huawei modem do I have? I don't know, but I'm sure that its productID is "1446" respectively "140c" (read below why) :oP


3- Switch mode from storage to modem

Why was I wrong about thinking that my USB modem was already recognized?

Because if at this point I issue a "lsusb -vvv | less" command and scroll down to the line where "Huawei" appears, I see that after all its "Interface Descriptor" sections the entry "bInterfaceClass" shows "Mass Storage" which is what I don't want. I want to see a modem!

To make it switch from the "storage" to "modem" mode you need the utility "usb_modeswitch".
After that you "emerged"/installed it, edit the file "/etc/usb_modeswitch.conf" and add the following:

#CUSTOMIZED
########################################################
;DefaultVendor=  0x12d1
;DefaultProduct= 0x1446

MessageEndpoint = 0x01
MessageContent = "55534243000000000000000000000011060000000000000000000000000000"
########################################################

Check that you don't have already any other sections for "0x1446" (there weren't any as of now - if you already find such a section, that one might actually be better that the one I state).
I have no clue what the last two lines do, but without them it the switch did not work (or it did not work because of some other reason which I wrongly associated to this change ;o) ).

So, now that you know 1) your "vendor" ID, 2) your "product" ID and 3) have edited "/etc/usb_modeswitch.conf" you can try to switch to the modem mode:

usb_modeswitch -v 0x12d1 -p 0x1446 -H -s 5 -c /etc/usb_modeswitch.conf

The "-v" defines the vendor, the "-p" the product, "-H" is for "Huawei"-stuff, the "-s" is a sleep timer and the "-c" defines the configuration file we just edited.

If you now run again "lsusb" you'll see that the productID changed. In my case it looks like this:

~ # lsusb
Bus 001 Device 005: ID 12d1:140c Huawei Technologies Co., Ltd.
Bus 001 Device 002: ID 13d3:5108 IMC Networks
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 002: ID 0b05:b700 ASUSTek Computer, Inc. Broadcom Bluetooth 2.1
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

I don't have a "1446" anymore but a "140c"!
And "lsusb -vvv | less" now does not show anymore the "Mass Storage" entry, but "Vendor Specific Class", which is not great but better than nothing :o)


4- Discover the modem

You can now check if you did your homework when you configured your kernel ;o)

First of all, to avoid interferences, unload the modules "usb_storage" and "option" (and other ones) if you have them already loaded (I have compiled them all as modules, and they get loaded automatically as soon as I plug in the modem - not sure if this works if you have "usb_storage" compiled directly in the kernel):

modprobe -r option
modprobe -r usb_storage
modprobe -r usbserial

After that run:

modprobe usbserial vendor=0x12d1 product=0x140c

Please note that I am using the new vendorID which popped up when I ran "usb_modeswitch".

Now, in my case, if I run "lsmod" I see that the system loaded the module "usbserial".
AND: if I issue a "ls /dev/ttyU*" I see that 6 new interfaces appeared - "ttyUSB0" to ttyUSB5. Great! Ok, sometimes they're just 4, but that might work too.


5- Prepare the dialer

In order to be able to establish a connection you will need a few more utilities:
I remember "ppp" and "wvdial" (and maybe "dhcpcd"?) - emerge/install them if you don't have them yet.

Once you have installed all packages first run "wvdialconf" and then edit "/etc/wvdial.conf".
In my case I modified that file and now it looks like this (!!!change the PIN to the one you have!!!):

[Dialer Defaults]
Modem = /dev/ttyUSB0
Baud = 9600

#Config 1
#Init = ATZ+CPIN="1234"
#Init1 = ATH
#Init2 = ATE1
#Init3 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
#Phone = *99***1#

#Config 2
#First eventually issue a "echo "ATZ+CPIN=\"1234\"" > /dev/ttyUSB0" to
#unlock the modem, if it needs a "PIN".
Init = ATZ
Init1 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Dial Command = ATM1L3DT
Phone = *99***1#
Stupid Mode = 1

Modem Type = Analog Modem
ISDN = 0
Username = gprs
Password = gprs

The lines I commented with "#" after the section "Config 1" were very unreliable for me - I managed to establish a connection only once every second day.
The lines of "Config 2" seem to work each time :o)

You might find a hint about the username/password and phone number you have to use here.
For the phone number of my provider ("Swisscom" - was mentioned being "*99#") I am using as you see "*99***1#", so I don't really know if the informations stated there are really correct.


6- Dial in!

So, I think we're ready to dial in.
Issue (!!!change the PIN to the one you have!!!)...

echo "ATZ+CPIN=\"1234\"" > /dev/ttyUSB0

...to unlock the modem and afterwards...

vwdial

...and I hope that you will see "wvdial" managing to get your IP address and DNS entries and that a "ppp0"-interface will pop up (run the command "ifconfig"). This might not happen if you already have an active eth/wlan connection when you issue the "wvdial" command as the IP-configuration retrieved by "wvdial" will conflict with the one of the other network.


7- Superscript

Hoping that at least the first steps above worked, we can merge everything into a single script.
Here some of the "sleep" commands are very important as things need some time to wake up/react.

#1- Unload everything that is already loaded
echo Unload all modules
modprobe -r ppp_async
modprobe -r crc_ccitt
modprobe -r ppp_generic
modprobe -r slhc

modprobe -r option
sleep 2
modprobe -r usb_storage
modprobe -r usbserial

#2- Switch the mode of the USB-modem from storage to modem
echo Wait and switch mode to modem
sleep 10
usb_modeswitch -v 0x12d1 -p 0x1446 -H -s 5 -c /etc/usb_modeswitch.conf

#3- Again, if after the switch some modules get loaded automatically, unload
#them and load usbserial with the correct module parameters.
echo Reload usbserial with the correct parameters
sleep 5
modprobe -r option
modprobe -r usb_storage
modprobe -r usbserial
sleep 5
modprobe usbserial vendor=0x12d1 product=0x140c

#4- Send the PIN to unlock the modem - will return an error (and just
#do nothing even if no error is displayed) if the modem was already unlocked.
echo Sleep and unlock modem
sleep 5
echo "ATZ+CPIN=\"1234\"" > /dev/ttyUSB0
sleep 10 #Very important

#5- Start wvdial and let's hope for the best.
echo Start wvdial
wvdial

#6- After I quit wvdial I unload again all modules.
echo Sleep and unload modules
sleep 5
modprobe -r ppp_async
modprobe -r crc_ccitt
modprobe -r ppp_generic
modprobe -r slhc

modprobe -r option
modprobe -r usb_storage
modprobe -r usbserial

You will possibly have to review the part about un/loading the modules as it might be slightly different in your case.


Ralf's remarks (thank you!)

Your problem "works only every second day" is explained in
http://superuser.com/questions/527543/randomly-getting-no-carrier-from-huawei-3g-modem-under-linux/

It seems to be a non-deterministic problem that the MoDem gets the dial command while still initialising, making it "cough".
I found another solution using both sources:

[Dialer Defaults]
Init1 = ATZ
Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
#Init4 = AT+CGDCONT=1,"IP","surfo2"
#Init5 = AT^SYSCFG=2,2,3FFFFFFF,2,4
Modem Type = Analog Modem
#ISDN = 0
#Modem = /dev/ttyUSB_utps_modem
#Modem = /dev/gsmmodem
Modem = /dev/ttyUSB0
Baud = 9600
Carrier Check = On
apn = internet
Dial Command = ATM1L3D
Check Def Route = on
Abort on No Dialtone = on
Stupid Mode = on
Idle Seconds = 0
Auto DNS = on

[Dialer pin]
Init3 = AT+CPIN=1234

[Dialer o2]
Phone = *99#
Username = surfo2
Password = surfo2
Ask Password = off

Notes:

  • The other init strings seem to work, but it also works without them. So I left them commented out as they didn't make it work.
  • Dial Command = ATM1L3D
    You don't need the "T", as it means Tone dialing. Obviously, our MoDems don't dial pulse or tone, but digitally. On an analog MoDem, you have a preference that can be overridden with either ATDT or ATDP; ATD is the "use the preference and dial"-command
  • The flesh is in that NO phone, password and username are given in the Default section; wvdial initialises the MoDem, wvdial pin sends the PIN to the MoDem, and wvdial o2 connects to this provider (o2 Germany). Between wvdial pin and wvdial o2, the MoDem has "time" to initialise and accept the PIN.

On the command line, wvdial and wvdial pin give a "no phone number....."-output; for as long as it is not possible to "sleep" inside wvdial.conf, that cannot be helped.

In a script, it would look something like
#!/bin/sh
usb_modeswitch -c /etc/usb_modeswitch.conf
sleep 12
wvdial pin
sleep 6
wvdial o2

On the command line, it works well.


References