Home | Linux |     Share This Page
Mobile Internet Access Using Linux

Completely rewritten 10/2007

— All content Copyright © 2007, P. LutusMessage Page

History | The Details | Conclusion

(double-click any word to see its definition)

History
My cell phone collection, newest at the right

I have to say I don't particularly like cell phones. I only own them out of necessity, and a small bit of curiosity. Their lives are too short, they cost too much, and even if you never pick up the phone, you have to pay a monthly fee.

Notwithstanding this antipathy, I have owned four cell phones, and I keep the old ones in my junk box (see picture this page). My main reason for having a cell phone has been to access the Internet and download e-mails while traveling in the lower 48, and while on my boat in Alaska.

I just got a new cell phone (picture, right) to replace a phone I managed to wear out by taking it on my boat to Alaska, constantly connecting and disconnecting a special data cable, and generally abusing it. The new phone (Motorola Maxx Ve) has a simple mini-USB connector for data connections (it also has Bluetooth). A suitable data cable has a mini-USB connector on one end and a standard USB connector on the other — this is a cable one can acquire nearly anywhere. Don't let a cell phone vendor sell you a "special" data cable at a "special" price, because it isn't special. In this article I'll be describing how to use this phone with Linux for Internet access.

When I travel by road in the lower 48, Verizon (my service provider) offers a low-speed Internet connection (14.4 kbps), which is adequate for my modest goal of keeping up-to-date by way of plain-text e-mails. There are more details on this service below.

In the past, while traveling in Canada and Alaska, areas not covered by Verizon's cell network, I was able to switch my older cell phones into analog mode and dial up my home ISP as though I was connected to a regular terrestrial phone line. Unfortunately, this mode of operation has pretty much disappeared — as time passes, fewer locations have cell systems that support analog mode, and fewer phones support it. So this year, as part of the new cell phone purchase, I realized I had to give up trying to connect by way of analog mode.

This is a bit off our topic, but while I am in Alaska, instead of relying on the cellular analog mode, I have started connecting by way of the wireless access points now available in most of the marinas I visit. These access point are nearly everywhere now, they are relatively inexpensive on a per-day basis, and they offer a much faster connection than the cell phone connection I had been using.

But I can still use my cell phone for low-speed Internet access while I am traveling in the lower 48. In the next section I explain how.

The Details
How Windows reacts to a new peripheral

I created this procedure on Fedora 7. It should work without changes on those distributions that resemble Fedora (Fedora, Red Hat, Mandrake, Yellow Dog, etc.). Readers using other distributions, or older kernels, may have to change certain parts of the procedure.

In modern times, it seems to be a principle that your computer won't recognize your new hi-tech peripheral, regardless of whether you are running Linux or Windows. You plug it in and the operating system either ignores it (Linux) or it hurls chunks (Windows: see picture at right).

If this happens to you, you have options. If you're running Windows, you can sit in a corner and bang your head against the wall until they come and take you away. If you're running Linux and if you are willing to create some plain-text configuration files, these instructions are for you.

This section is organized by issues, in a natural temporal sequence.

These examples deal specifically with my cell phone, but the method can be applied to nearly any unrecognized peripheral.

Recognition, Association
First we need to get Linux to recognize a peripheral and associate it with a driver. The first step is to plug the peripheral in and make sure it isn't recognized already, in which case you can skip this section.

Typically, for a device that hasn't been on the market very long, on plugging in the device you will see a message more or less like this in /var/log/messages:

Oct  5 11:32:20 pl-alpha kernel: usb 4-1.4: new full speed USB device using ehci_hcd and address 18
Oct  5 11:32:20 pl-alpha kernel: usb 4-1.4: configuration #1 chosen from 1 choice

If this is the last log entry for the device, it means the Linux kernel couldn't find a driver that recognized the device, but we can easily arrange for this to happen.

Vendor/Product ID

Each USB device has a specific and unique pair of numbers: vendor ID and product ID. To get your peripheral's numbers, open a command shell and enter this command (the "$" symbol at the left is the shell prompt, you don't type it).
$ /sbin/lsusb
As entered, this command will list all attached USB peripherals, including hubs. This can sometimes be a long list. At the right of each entry in the list will be a plain-English name. You should be able to identify your peripheral in this list of names. To list only the peripheral you are interested in, type this command, including the name of your peripheral:
$ /sbin/lsusb | grep -i "motorola pcs"

Bus 004 Device 018: ID 22b8:2b24 Motorola PCS
In this example, I filtered the list by entering the name of the device I am interested in. I want the two numbers to the right of "ID" — these are the vendor and product numbers I mentioned earlier. In this example they are 22b8 and 2b24 respectively (these are hexadecimal numbers). Keep these numbers for the next step.

Modprobe

Now we'll tell the kernel which driver to associate with this USB device, then we'll tell the driver to recognize it as well. I happen to know this device can be recognized and configured as a USB serial modem, so I know which driver to use. On that basis, I create the following file:

File: /etc/modprobe.d/motorola_ve.options
Contents:
alias usb:v22B8p2B24* usbserial
options usbserial vendor=0x22b8 product=0x2b24

The purpose of this file is to (1) tell the kernel to associate a particular USB device with the "usbserial" driver, and (2) tell the "usbserial" driver to recognize and configure the device when it is plugged in. I recommend that such files be given the peripheral's name, to avoid confusion if there are several peripherals that need to be identified in this ad hoc way.

Notice something important about the file's contents — in the first appearance of the vendor and product numbers, the hexadecimal letters are UPPERCASE (v22B8p2B24), and in the second appearance they are lowercase (vendor=0x22b8 product=0x2b24). Don't let this detail escape your attention, or the entire process will fail.

This file can be prepared by any user, but it needs to be copied into its destination directory with root authority. After the file has been moved to its destination, reboot your system to make the change effective (or "modprobe -r" the usbserial module if you're in a hurry).

After reboot, test the change. On plugging in the device, you should see something like this in /var/log/messages:
Oct  5 13:17:08 pl-alpha kernel: usb 4-1.4: new full speed USB device using ehci_hcd and address 18
Oct  5 13:17:08 pl-alpha kernel: usb 4-1.4: configuration #1 chosen from 1 choice
Oct  5 13:17:08 pl-alpha kernel: usbserial_generic 4-1.4:1.0: generic converter detected
Oct  5 13:17:08 pl-alpha kernel: usb 4-1.4: generic converter now attached to ttyUSB1
Oct  5 13:17:08 pl-alpha kernel: usbserial_generic 4-1.4:1.1: generic converter detected
Oct  5 13:17:08 pl-alpha kernel: usb 4-1.4: generic converter now attached to ttyUSB2

For some reasons I won't be elaborating on, this particular cell phone becomes configured as two USB ports. Just remember, for this project, we're interested in the first listed USB port (and your port won't necessarily have the same number).

Saying Hello

Now we'll test to see if the phone is alive. Did you notice that the first of the two ports above was named "ttyUSB1"? This is the port we're interested in (and your port number may differ). It is actually located at /dev/ttyUSB1. Here is a test to see if the phone is really present:

$ echo -e "ATi\r" > /dev/ttyUSB1
$ tr -s "\n" < /dev/ttyUSB1
ATi
Manufacturer: I: Motorola CE, Copyright 2000
Model: I: Motorola CDMA Ve Phone
Revision: I: 20.1_013606S1
ESN: I: 0xNNNNNNNN
I: +GCAP: +CIS707-A, CIS-856, +MS, +ES, +DS, +FCLASS
OK

You will need to press Ctrl+C to break out of the "tr" command, which will continue to try to read from the port. If you saw a result like the above (remember to replace "ttyUSB1" with your own port number), everything is OK.

Network Configuration

Now we can set up a network connection for the Verizon slow-speed network, which has the advantage that it is not an extra-cost service (you only pay for online minutes, like a regular cellphone call).

if you are certain that you will always be getting the same port identifier, which by default will be "/dev/ttyUSB0" in the absence of any other usb-serial peripherals, you can make a symlink in the /dev directory to identify the phone for the network configuration scripts (as root):
# ln -s /dev/ttyUSB0 /dev/cellphone
But this is not typical. It's more likely that every time you connect the phone, you will get a different, random identifier, and it would be really nice to be able to have a unique, unchanging device name for the cell phone. Here is how this is done.

ifup-pre-local

There is an optional executable shell script with the path "/sbin/ifup-pre-local" that, if it is present, will always be executed in advance of a network connection being made. This script can do all sorts of useful things. I will add a section to the file (and create it if need be) to assure that the cell phone has a consistent identifier.

The reason this idea works is because the system directory /sys contains lots of information about connected peripherals, including which peripherals were assigned to which device names.

Here is the content that needs to be placed in /sbin/ifup-pre-local (it doesn't have to be the only content):

# create symlink to cellphone device port

tag="/dev/cellphone"

modemport=`/bin/grep MODEMPORT $1`
modemport=${modemport#*=}

# if this connection needs the cell phone pseudo-device
if [ "x$modemport" == "x$tag" ]
then
	# if the cell phone is connected
	if usb_data=($(/sbin/lsusb | grep "Motorola PCS"))
	then
		# convert bus,dev to ttyUSB device ID
		bus=${usb_data[1]#0}
		bus=${bus#0}
		dev=${usb_data[3]#0}
		dev=${dev#0}
		dev=${dev%:}
		# get the current USB port from its name in the /sys path
		usb_port=$(ls /sys/class/usb_device/usbdev${bus}.${dev}/device/*:1.0 | grep ttyUSB)
		# create cellphone symlink
		ln -nsf /dev/$usb_port $tag
	fi

fi

Click Here to see the shell script content in plain-text form. Place this content in /sbin/ifup-pre-local. If this file doesn't already exist, create it, give it a first line of "#!/bin/sh", and make it executable . Although it will probably continue to work from now on, this shell script is very much dependent on a system with a kernel version >= 2.6.

NOTE: The file /sbin/ifup-pre-local can be used to solve all sorts of problems. At present, mine deals with a quirk in a new wireless interface card that prevented it from working at all, sets up WPA encryption in a convenient way, creates the cellphone symlink as described above, and a number of other things. Just remember it is executed in advance any time you or the system issues the "ifup" command to bring up a network interface.

ifcfg-Verizon_USB

Now we need to create a network profile for the Verizon service. Here are the details:

File: /etc/sysconfig/networking/devices/ifcfg-Verizon_USB

Content:
ONBOOT=no
USERCTL=yes
PEERDNS=yes
TYPE=Modem
DEVICE=ppp0
BOOTPROTO=dialup
CCP=on
PC=on
AC=on
BSDCOMP=on
VJ=on
VJCCOMP=on
LINESPEED=115200
MODEMPORT=/dev/cellphone
PROVIDER=VerizonQNC
DEFROUTE=yes
PERSIST=no
PAPNAME=qnc
WVDIALSECT=Verizon_USB
MODEMNAME=Modem_USB
DEMAND=no
Click Here to get a plain-text copy of this content. Not all these options need to be set, but most of them do. Just create a file named "ifcfg-Verizon_USB" and put the above content into it. Then, as root, copy it to the location indicated above.

wvdial.conf

Now we add content to one more file (this isn't necessarily the only content in the file):

File: /etc/wvdial.conf

Content:

[Modem_USB]
	Modem = /dev/cellphone
	Baud = 115200
	SetVolume = 2
	Dial Command = ATDT
	Init1 = ATZ
	FlowControl = Hardware (CRTSCTS)

[Dialer Verizon_USB]
	Username = qnc
	Password = qnc
	Phone = #777
	Stupid Mode = 1
	Init1 = ATZ
	Init2 = ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
	Init3 = at$qcmdr=2
	Inherits = Modem_USB

Click Here to get a plain-text copy of this content. This is another file that needs to be created or edited using root authority.

Network Operation

At this point the system should recognize the cell phone when it is plugged in, and you should have a complete, working network configuration.

Typical Linux users want to use the "Network Control" applet (system-control-network), but for the first experiment we need to use the "Network Configuration" applet (system-config-network). The reason is we need to make our new configuration part of the default network profile. Activate the "Network Configuration" applet by way of the desktop menus, or open a root command shell and type:
# system-config-network
In this applet, find the item named "Verizon_USB" and click the box under "Profile" to make this configuration part of the default network profile. Then, with the phone connected to a USB port, try bringing it up. If you have been careful about these instructions (and if I have not made any mistakes), you should see something like this in /var/log/messages:
Oct  5 15:00:23 pl-alpha ifup-ppp: pppd started for Verizon_USB on /dev/cellphone at 19200
Oct  5 15:00:23 pl-alpha kernel: PPP generic driver version 2.4.2
Oct  5 15:00:23 pl-alpha pppd[28441]: pppd 2.4.4 started by root, uid 0
Oct  5 15:00:24 pl-alpha wvdial[28466]: WvDial: Internet dialer version 1.54.0
Oct  5 15:00:24 pl-alpha wvdial[28466]: Initializing modem.
Oct  5 15:00:24 pl-alpha wvdial[28466]: Sending: ATZ
Oct  5 15:00:25 pl-alpha wvdial[28466]: ATZ
Oct  5 15:00:25 pl-alpha wvdial[28466]: OK
Oct  5 15:00:25 pl-alpha wvdial[28466]: Sending: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Oct  5 15:00:25 pl-alpha wvdial[28466]: ATQ0 V1 E1 S0=0 &C1 &D2 +FCLASS=0
Oct  5 15:00:25 pl-alpha wvdial[28466]: OK
Oct  5 15:00:25 pl-alpha wvdial[28466]: Sending: at$qcmdr=2
Oct  5 15:00:25 pl-alpha wvdial[28466]: at$qcmdr=2
Oct  5 15:00:25 pl-alpha wvdial[28466]: OK
Oct  5 15:00:25 pl-alpha wvdial[28466]: Modem initialized.
Oct  5 15:00:25 pl-alpha wvdial[28466]: Sending: ATDT#777
Oct  5 15:00:25 pl-alpha wvdial[28466]: Waiting for carrier.
Oct  5 15:00:25 pl-alpha wvdial[28466]: ATDT#777
Oct  5 15:00:27 pl-alpha wvdial[28466]: CONNECT
Oct  5 15:00:27 pl-alpha wvdial[28466]: Carrier detected.  Chatmode finished.
Oct  5 15:00:27 pl-alpha pppd[28441]: Serial connection established.
Oct  5 15:00:27 pl-alpha pppd[28441]: Using interface ppp0
Oct  5 15:00:27 pl-alpha pppd[28441]: Connect: ppp0 <--> /dev/cellphone
Oct  5 15:00:30 pl-alpha pppd[28441]: CHAP authentication succeeded
Oct  5 15:00:30 pl-alpha pppd[28441]: CHAP authentication succeeded
Oct  5 15:00:30 pl-alpha kernel: PPP Deflate Compression module registered
Oct  5 15:00:30 pl-alpha pppd[28441]: local  IP address 151.144.40.64
Oct  5 15:00:30 pl-alpha pppd[28441]: remote IP address 151.144.40.65
Oct  5 15:00:30 pl-alpha pppd[28441]: primary   DNS address 66.174.92.14
Oct  5 15:00:30 pl-alpha pppd[28441]: secondary DNS address 66.174.95.44
Oct  5 15:00:31 pl-alpha NET[28532]: /etc/sysconfig/network-scripts/ifup-post : updated /etc/resolv.conf
This indicates a successful connection on the Verizon low-speed Internet service.
Conclusion

I want to emphasize this procedure can be used for all sorts of peripherals, not just a certain cell phone. Pay particular attention to the method for telling the kernel about peripherals it doesn't already know about, and for telling kernel drivers about your new peripheral. I can't tell you how many times I've needed to get a Linux system to recognize a new, unheard-of peripheral, months or years before the current kernel began to recognize it by default.

 

Home | Linux |     Share This Page