Saturday, 5 December 2009

Using skypephone modem in Linux

I've been having a frustrating few days trying to get the 3G modem in my mobile phone to work with my Linux boxes. For anyone with similar issues, I'm documenting here what I did.

The phone I have is made by the Chinese company Amoi, marketed in the UK by 3 as a skypephone, currently version 2 of this. Basically, this was the cheapest 3G phone/modem I could find. 3 include 150MB of internet access in their topup charge, either used via the internet programs on the phone itself (there are various apps including a browser which uses Google Wireless Transcoder to try and render full-size webpages for the mobile form factor), or by using the phone as a modem. The modem can be used via either bluetooth or a usb cable provided with the phone. My Asus netbook does not have a bluetooth connection ootb, so I wanted to use usb.

Like most of these setups, the usb interface is heavily oriented to Windows users, to such an extent that it presents a cdrom drive which automatically installs Windows drivers when you initially plug the cable in. When you do so, the cdrom drive disappears and you can access the modem. As usual with Linux, there's no need for any drivers as these are already provided either in the kernel or as separate modules. So the main question is how to ignore the cdrom and access the modem. The best documentation I've found of this process, which varies depending on the device, is on the website for usb_modeswitch, a program which attempts to do this.

  1. The first thing to do is to switch on the phone and plug in the usb cable (a pitfall I fell into was that when you plug in the cable the phone immediately starts charging, which can give the impression that the phone is on even if it isn't - so make sure the phone's operating system is running).

  2. Then run lsusb on Linux. This should show the Amoi device, with an id of either 1614:1000 or 1614:0407. If the latter, you're in luck: that is the modem - proceed to the next step. If not, try unplugging the usb cable and plugging it back in again. With luck, it should now show 1614:0407. 'dmesg | tail' will show "Product: USB MMC Storage" for 1614:1000, or "Product: S2" for 1614:0407. I've found that you get different results depending on distro: according to the last post on this thread, both Ubuntu and Fedora find 0407 straightaway, my Debian testing/squeeze partition may need unplugging/replugging one or more times, and my Slackware partition doesn't seem able to find the modem at all, no matter how many times I replug the cable. Presumably, this is due to the way the kernel is configured, so if anyone can tell me what I have to configure on my Slackware kernel to enable this I'd be grateful. Fortunately, once the modem is set up it stays that way until you reinitialise the phone by switching it off or unplugging the cable, so once I have it set up in Debian I can then reboot in Slackware and it will then show as 1614:0407.

  3. Once you have 1614:0407, you can then load the driver. There are 2 possibilities: the old standard usbserial module and the newer option module, which it seems is now recommended for these kind of phone modems (tho IMHO it would be better if they renamed it).

    usbserial can be loaded with "modprobe usbserial vendor=0x1614 product=0x0407". option does not have the vendor/product (er) options, but thanks to a tip from usb_modeswitch, you can set them directly on sys bus:
    modprobe option
    echo "1614 0407" >/sys/bus/usb-serial/drivers/option1/new_id

    In both cases, udev then creates /dev/ttyUSB0 which pppd can use.

  4. For completeness, here is my pppd control file, which I put in /etc/ppp/peers/3:

    idle 7200
    user three
    password three
    connect-delay 20000
    connect "/usr/sbin/chat -V -f /etc/ppp/chat3"

    I don't believe the modem speed has any effect for these devices, and I don't think user and password are used either.

    Here is /etc/ppp/chat3, the chatscript I use:
    ABORT        BUSY
    TIMEOUT 10
    "" ATZ
    OK 'ATE0V1Q0S0=0&C1&D2+FCLASS=0'
    OK 'AT+CGDCONT=1,"IP",""'
    SAY "Calling..."
    TIMEOUT 60
    OK 'ATDT*99#'
    CONNECT \c

    The important thing here is "", the APN, which is the important part of user validation; it will not work without this.

  5. The alert will notice that I do not have 'usepeerdns'. This is because, rather bizarrely, 3's nameservers do not appear to work. When I used 'usepeerdns' I got a connection and could do, for example, 'ping' (one of Google's servers, if you don't know) but no dns resolution was working. So I set up /etc/resolv.conf with OpenDNS's servers instead:

  6. You then start ppp with 'pppd call 3' and wait for the connection to be set up. You can monitor this from the logfile, /var/log/messages in the case of Slackware: when 'tail /var/log/messages' shows the local and remote IP addresses, the connection should be ready. On my setup, this takes about 30 seconds.

  7. When you have finished, you can kill pppd with "kill `cat /var/run/`". And, as pppd also logs how much data transfer there was, you can do something like "cat /var/log/messages | grep 'bytes, received'" to find out how much of the 150MB you used during that connection.