Setting up Nokia phone as modem under Linux

Linux: Guide on configuring Nokia phone as GPRS / 3G / EDGE / HSDPA modem

NOTE: Some parts of this tutorial is probably outdated.

This tutorial will cover steps that needs to be done to enabled your shiny new Nokia (almost any recent brand that have data connectivity, including N80, N81, N95, N93, 6680, 6630, etc.) to work as modem under Linux. I am using Ubuntu "Dapper Drake" for this guide. But it should be easily adapted to whatever Linux distribution your are using. Basically, your Nokia phone will be automatically detected using the cdc-acm driver. But this driver have some drawback for me. Up until kernel 2.6.15, I am experiencing problems with cdc-acm such as:

  • I cannot get full data transfer speed using cdc-acm driver. My 3G download rate stuck at around 144 kbps. This problem only manifest itself when you use the USB sync cable to connect to your Linux box. Using Bluetooth, you get full 384 kbps speed. Go figure...

  • It oops (crash) just to often. Unplug the USB cable, bang it crash. Battery flat, bang it crash again. After a while, it becomes rather tiring.

So, not willing to give up my Ubuntu, I started digging. Eventually I realized I can use the usbserial driver for my Nokia. And turns out, the usbserial is at least much better when used with my Nokia 6630 and 6680 when connected to USB sync cable compared to cdc-acm.

  • I get full 384 kbps on my Celcom 3G connection. Way to go!

  • More stable, and not prone to oops compared to cdc-acm. I can plug and unplug the USB cable for all that I care, the driver just gracefully recover.

Enough background, lets start working.

1. I am using kernel 2.6.15 provided in the stock Dapper. It should work with other 2.6 kernel. No idea whether it will work on 2.4 kernel though.

2. Make sure you have ppp package installed. Execute the following if you do not have ppp installed.

sudo apt-get install ppp

3. "Blacklist" your cdc-acm driver. Under Ubuntu, this can be easily achieved by this command:

sudo echo "blacklist cdc-acm" >> /etc/modprobe.d/blacklist

4. Tell Ubuntu to automatically load the usbserial module.

sudo echo "usbserial" >> /etc/modules

5. Now trickiest part, setting your phone device ID as the usbserial parameter. Issue the command lsusb.

bitubique@bitubique:~/$ lsusb 
Bus 005 Device 006: ID 04cf:8818 Myson Century, Inc. Fast 3.5" External Storage 
Bus 005 Device 001: ID 0000:0000 

Bus 006 Device 001: ID 0000:0000 
Bus 003 Device 001: ID 0000:0000 
Bus 004 Device 001: ID 0000:0000 
Bus 001 Device 005: ID 0a81:0101 Chesen Electronics Corp. Keyboard 
Bus 001 Device 004: ID 1241:1177 Belkin F8E842-DL Mouse 
Bus 001 Device 001: ID 0000:0000 Bus 002 Device 002: ID 0421:041e Nokia Mobile Phones <-- my Nokia 6680!
Bus 002 Device 001: ID 0000:0000

If you have your phone plugged with the USB sync cable, it should appear here with description "Nokia Mobile Phones". Notice the vendor ID and the product ID, 0421:041e. Vendor ID is 0421, product ID is 041e for Nokia 6680. We need to put these IDs into out modprobe options. This can be done with this command:

sudo echo "options usbserial vendor=0x0421 product=0x041e" >> /etc/modprobe.d/options

Notice you need to prefix the IDs with "0x" qualifier, since the ID is specified in hex.

6. Now load the module. Ensure we have unloaded the cdc-acm driver first. As root, execute the following.

rmmod cdc-acm
modprobe usbserial

7. Copy the following text and save it with name /etc/ppp/peers/provider. Especially, you need to change the line user "celcom3g" to the user name that your mobile operator assigned to use their GPRS / 3G Internet access. You probably need to become root user in order to write to /etc directory.

/dev/ttyUSB0    # Serial device to which the GPRS phone is connected 
debug        # Comment this off, if you don't need more info 
# scripts to initialize the 3G / EDGE / GPRS modem 

connect /etc/ppp/peers/connect-chat 
# AT commands used to 'hangup' the connection 
disconnect /etc/ppp/peers/disconnect-chat
460800      # Serial port line speed 
crtscts    # hardware flow control for cable 
local        # Ignore carrier detect signal from the modem: 
lcp-echo-failure 0 
lcp-echo-interval 0
# IP addresses: 

# - accept peers idea of our local address and set address peer as 
# (any address would do, since IPCP gives to it) 
# - if you use the 10. network at home or something and pppd rejects it, 
# change the address to something else 
noipdefault        # pppd must not propose any IP address to the peer! 
ipcp-accept-local    # Accept peers idea of our local address 
defaultroute        # Add the ppp interface as default route to the IP routing table 
replacedefaultroute    # New route should be our default route to Internet 

usepeerdns        # User DNS returned by server 
noauth            # The phone is not required to authenticate
# Most phone do not support compression, so turn it off. 
# Username and password: 

# If username and password are required by the APN, put here the username 
# and put the username-password combination to the secrets file: 
# /etc/ppp/pap-secrets for PAP and /etc/ppp/chap-secrets for CHAP 
# authentication. See pppd man pages for details. 
user "celcom3g"        # Change this if you are not using Celcom 3G!
persist            # Persistent connection 
maxfail 99999        # Retry and retry and retry if failed...

8. If your mobile operator requires you to give password to access the APN, then edit or create the file /etc/ppp/pap-secrets for PAP authentication or /etc/ppp/chap-secrets for CHAP authentication. The format should be as follows:

# Secrets for authentication using CHAP. Format: 
# client        server  secret                  IP addresses
"celcom3g" * "celcom3g"

9. Copy the following text and save it as /etc/ppp/peers/connect-chat.

exec chat                                               \
        TIMEOUT         5                               \
        ECHO            ON                              \
        ABORT           '\nBUSY\r'                      \

        ABORT           '\nERROR\r'                     \
        ABORT           '\nNO ANSWER\r'                 \
        ABORT           '\nNO CARRIER\r'                \
        ABORT           '\nNO DIALTONE\r'               \
        ABORT           '\nRINGING\r\n\r\nRINGING\r'    \
        ''              \rAT                            \
        TIMEOUT         12                              \
        SAY             "Press CTRL-C to close the connection at any stage!"    \

        SAY             "\ndefining PDP context...\n"   \
        OK              ATH                             \
        OK              ATE1                            \
        OK              ATD*99#                         \
        TIMEOUT         22                              \
        SAY             "\nwaiting for connect...\n"    \
        CONNECT         ""                              \
        SAY             "\nConnected." \
        SAY             "\nIf the following ppp negotiations fail,\n"   \

         SAY             "try restarting the phone.\n"

However, some network requires you to specify the APN. Thus, you need to add the following line after the "OK ATE1" line in the file /etc/ppp/peers/connect-chat.

OK              'AT+CGDCONT=1,"IP","your_apn_name","",0,0'   \

10. Copy the following text and save it as /etc/ppp/peers/disconnect-chat.

# send break exec /usr/sbin/chat -V -s -S    \
ABORT           "BUSY"          \
ABORT           "ERROR"         \
ABORT           "NO DIALTONE"   \
SAY             "\nSending break to the modem\n"        \
""              "\K"            \
""              "\K"            \

""              "\K"            \
""              "\d\d+++\d\dATH"        \
SAY             "\nPDP context detached\n"

11. Both the file /etc/ppp/peers/connect-chat and /etc/ppp/peers/disconnect-chat should have executable bit set. Thus, issue this command to set it as executable;

chmod a+x /etc/ppp/peers/connect-chat
chmod a+x /etc/ppp/peers/disconnect-chat

12. Test your connection. Issue the command as root to check whether you are successful.

# pppd call provider 
# ifconfig ppp0 
ppp0      Link encap:Point-to-Point Protocol
         inet addr:  P-t-P:  Mask:
          RX packets:38 errors:0 dropped:0 overruns:0 frame:0

          TX packets:41 errors:0 dropped:0 overruns:0 carrier:0
         collisions:0 txqueuelen:3
          RX bytes:7700 (7.5 KiB)  TX bytes:3148 (3.0 KiB)

Voila! However, if the result of ifconfig ppp0 is blank, then you need to check /var/log/messages output to figure out why it failed.

13. Make your changes permanent. Under Ubuntu, this can be achieved easily creating an empty file ppp_on_boot in the /etc/ppp/ directory. The next time you restart your machine, connection to the Internet will be automatically established.

touch /etc/ppp/ppp_on_boot

14. Enjoy your connectivity!