Internet Access using a Mobile Phone over Bluetooth

Scope
Here is how I got my laptop connected to the Interweb using my Nokia N95 in the UK. I simply have to turn on the Bluetooth system on my phone. Within a few seconds I am connected.

Update - 09 Aug 2009 - Bluez 4.39 is on my smart new laptop and its rather different! It seems you only need the bluez package and not bluez-utils and -libs. The pin handling is different. There are several other HOWTOs on this wiki that give the information needed to pair up so I wont repeat them. As it turns out these instructions work for my N79 once I'd got the pairing to work.

This method of connecting makes use of the extremely sophisticated network handling built into "baselayout" in Gentoo which is (in my not so humble opinion) easily the best in any distro I have ever used. However as with most things Gentoo it just needs a little reading up on to make the most of it.

Before you start all this make sure you can get a GPRS connection to the web on your phone. I'm not an expert on the ways that phones get to the web but I do know that my N95 can get there and that this all works regardless of whether the little 3G icon is displayed or not. I just need the two little left and right arrows displayed. WAP and all the rest of it means little to me!

(Time passes) Having used this way of doing things for a while now, a few problems have emerged: I have not got to the bottom of why yet but it seems that after the box has been up for a while you end up having to restart the Bluetooth and net.ppp{n} services to get a connection. You may be better off with something like kppp or whatever Gnome has for a dialer.

Software
net-wireless/bluez-utils-3.11-r2 net-dialup/ppp-2.4.4-r4 sys-apps/baselayout-1.12.10-r4 Kernel support for Bluetooth sys-apps/ifplugd-0.28-r8

The above list is what I am using at the moment (06 July 2007) with ~x86 but I suspect pretty much any current versions will suffice. I can't remember when baselayout started supporting ppp properly but have a look in /etc/conf.d/net.example on your system and make sure there is a lot of talk about ppp. If you are not already using ifplugd or equivalent then you really should be. Even on a permannently connected system. It allows you to define exactly what happens when something is plugged in or not (oooh it's just like Windows (TM) but better)

Hardware
I have a "no name" laptop (well actually its a Time Computers job bought off QVC - "Three Easy Payments"!) and I've stuffed a Bluetooth dongle that I bought from Maplins into a USB port. I have a Nokia N95 mobile blower with T-Mobile as the supplier.

Procedure
As with anything to do with networking, start at the bottom and work your way "up the stack". That is start with the wires and work up to the application. In this case the wires don't really exist.

Kernel
You'll need Bluetooth enabled in your kernel. I just compiled everything under "Networking -> Bluetooth subsystem support" as modules and relied on UDEV etc to sort things out. After rebooting you should find something like this in:

Bluetooth: HCI device and connection manager initialized Bluetooth: HCI socket layer initialized Bluetooth: L2CAP ver 2.8 Bluetooth: L2CAP socket layer initialized Bluetooth: RFCOMM socket layer initialized Bluetooth: RFCOMM TTY layer initialized Bluetooth: RFCOMM ver 1.8 Bluetooth: BNEP (Ethernet Emulation) ver 1.2 Bluetooth: BNEP filters: protocol multicast
 * 1) dmesg | grep -i bluetooth

Bluez
Bluez configuration is held in /etc/bluetooth/

Here are my config files.

options { autoinit yes; security auto; pairing multi; passkey "1234"; } device { name "jglaptop"; class 0x3e0100; iscan enable; pscan enable; lm accept; lp rswitch,hold,sniff,park; } rfcomm0 { bind yes; device 00:18:42:EC:FC:92; channel 4; comment "Jon's N95 (Jonny)"; } rfcomm1 { bind yes; device 00:18:42:F0:E9:E3; channel 4; comment "Rose's N95 (Rosie)"; }
 * 1) hcid.conf:
 * 1) rfcomm.conf:

Bluez is capable of a lot more than just connecting you up to the web but I will only deal with the bits relevant to that. I have removed the comments from the above for brevity.

hcid.conf is the main configuration file and rfcomm.conf is the bit that creates the "modem" for use to dial out to the web with. You will need to change some settings from mine: In hcid.conf name your system under the device section. This is what the phone will see on a Bluetooth scan. Also change the passkey to taste (numeric only).

For rfcomm.conf we need the device's MAC address and channel number. Also, is your phone really capable of doing this. Run the following command after switching on your mobile phone's Bluetooth (you don't need the Bluetooth service running)

Inquiring ... Searching for DUN on 00:18:42:EC:FC:92 ... Service Name: Dial-Up Networking Service RecHandle: 0x10051 Service Class ID List: "Dialup Networking" (0x1103) Protocol Descriptor List: "L2CAP" (0x0100) "RFCOMM" (0x0003) Channel: 4 Language Base Attr List: code_ISO639: 0x454e encoding:   0x6a base_offset: 0x100 Profile Descriptor List: "Dialup Networking" (0x1103) Version: 0x0100
 * 1) sdptool search DUN

If you don't see Dialup Networking in the output, then your mileage might vary. We now have the MAC address from searching for DUN on nn:nn:nn:nn:nn:nn and the channel. These can be entered in the rtcomm.conf.

Note that I have two entries, one for my phone and one for my wife's. They will cause a device called /dev/rfcomm0 or /etc/rfcomm1 to be a modem on this machine when they are connected.

Assuming all is well, startup the daemon:


 * 1) /etc/init.d/bluetooth

You should see something like this in /var/log/messages:

Jul 6 23:42:47 jglaptop hcid[13944]: Bluetooth HCI daemon Jul 6 23:42:47 jglaptop hcid[13944]: HCI dev 0 registered Jul 6 23:42:47 jglaptop hcid[13944]: HCI dev 0 already up  Jul  6 23:42:47 jglaptop hcid[13944]: Device hci0 has been added Jul 6 23:42:47 jglaptop hcid[13944]: Starting security manager 0 Jul 6 23:42:47 jglaptop hcid[13944]: Device hci0 has been activated Jul 6 23:42:47 jglaptop hcid[13944]: Starting SDP server

Now is probably a good time to pair your phone with the system.

ppp
In /etc/conf.d/net, add the following

config_ppp0=( "ppp" ) link_ppp0="/dev/rfcomm0" phone_number_ppp0=( "*99***1#" ) username_ppp0='web' password_ppp0='web' pppd_ppp0=(       "maxfail 10"        "noauth"        "lcp-echo-interval 5"        "lcp-echo-failure 12"        "debug"        "noipdefault"        "defaultroute"        "usepeerdns"        "ipcp-accept-remote"        "ipcp-accept-local"        "holdoff 3"        "noaccomp noccp nobsdcomp nodeflate nopcomp novj novjccomp"        "912600"        "lock"        "nocrtscts" ) chat_ppp0=(      'ABORT' 'BUSY'       'ABORT' 'ERROR'       'ABORT' 'NO ANSWER'       'ABORT' 'NO CARRIER'       'ABORT' 'NO DIALTONE'       'ABORT' 'Invalid Login'       'ABORT' 'Login incorrect'       'TIMEOUT' '5'       &#39;&#39; 'ATZ'       'OK' 'ATM0'       'OK' 'ATDT\T'       'TIMEOUT' '60'       'CONNECT' &#39;&#39;       'TIMEOUT' '5'       '~--' &#39;&#39; )

Also do this:


 * 1) ln -s /etc/init.d/net.lo /etc/init.d/net.ppp0

If you already have a ppp0 device, then simply use ppp1 etc. Now there are a few things to note. the username and password I use here are possibly specific to T-Mobile and possibly not even required. The phone number is also rather interesting. It is a special number built into the phone which means "dial up the GPRS connection using profile 1 (the 1# bit)".

You may have to use a different profile however I created this setup following: http://www.bless.li/articles/bluetooth-gprs/, so I suspect this is pretty generic. To debug this if you have problems would involve a visit again to /var/log/messages (note the "debug" above and see "man pppd").

The "defaultroute" option will change the default route on your system to this connection.

Start it all up:


 * 1) /etc/init.d/net.ppp0 start

Nothing will happen until you try to "go outside" You get something like this:

* Service net.ppp0 starting * WARNING: net.ppp0 has started but is inactive
 * 1) /etc/init.d/net.ppp0 start

So ping something external to your network (eg 1.1.1.1) or if you have ntpd running, it will soon cause a connection.

Wait awhile and you'll get this (you are using iproute2 aren't you). Note the ppp0 inet address which I have been allocated by the ISP. Here I am getting an address which is in the 10 network. This is not direct to the Internet and implies that they are NAT'ing me. Some things will not work over this, so be careful. Your ISP may block certain things but I have been able to use web, rsync and RDP.

1: lo:  mtu 16436 qdisc noqueue link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 brd 127.255.255.255 scope host lo 2: fire0:  mtu 1500 qdisc pfifo_fast qlen 1000 link/ieee1394 00:00:0a:e6:ff:2a:15:1f brd ff:ff:ff:ff:ff:ff:ff:ff 3: lan0:  mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:11:5b:ab:0d:17 brd ff:ff:ff:ff:ff:ff 4: wlan0:  mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:11:09:08:19:0f brd ff:ff:ff:ff:ff:ff 19: ppp0:  mtu 1500 qdisc pfifo_fast qlen 3 link/ppp inet 10.34.168.95 peer 10.6.6.6/32 scope global ppp0
 * 1) ip a

... and as you can see my ppp0 is wired up to the web.

10.6.6.6 dev ppp0 proto kernel  scope link  src 10.34.183.4 127.0.0.0/8 dev lo scope link default via 10.6.6.6 dev ppp0
 * 1) ip r

Now start up a browser.

Debugging
Here is a successfull connection according to my log:

Jul 7 00:15:58 jglaptop pppd[14665]: Plugin passwordfd.so loaded. Jul 7 00:15:58 jglaptop pppd[14666]: pppd 2.4.4 started by root, uid 0 Jul 7 00:15:58 jglaptop rc-scripts: WARNING:  net.ppp0 has started but is inactive Jul 7 00:15:59 jglaptop hcid[13944]: link_key_request (sba=00:0D:18:11:47:3E, dba=00:18:42:EC:FC:92) Jul 7 00:15:59 jglaptop pppd[14666]: speed 912600 not supported Jul 7 00:16:00 jglaptop chat[14676]: abort on (BUSY) Jul 7 00:16:00 jglaptop chat[14676]: abort on (ERROR) Jul 7 00:16:00 jglaptop chat[14676]: abort on (NO ANSWER) Jul 7 00:16:00 jglaptop chat[14676]: abort on (NO CARRIER) Jul 7 00:16:00 jglaptop chat[14676]: abort on (NO DIALTONE) Jul 7 00:16:00 jglaptop chat[14676]: abort on (Invalid Login) Jul 7 00:16:00 jglaptop chat[14676]: abort on (Login incorrect) Jul 7 00:16:00 jglaptop chat[14676]: timeout set to 5 seconds Jul 7 00:16:00 jglaptop chat[14676]: send (ATZ^M) Jul 7 00:16:00 jglaptop chat[14676]: expect (OK) Jul 7 00:16:00 jglaptop chat[14676]: ATZ^M^M Jul 7 00:16:00 jglaptop chat[14676]: OK  Jul  7 00:16:00 jglaptop chat[14676]: -- got it Jul  7 00:16:00 jglaptop chat[14676]: send (ATM0^M) Jul 7 00:16:00 jglaptop chat[14676]: expect (OK) Jul 7 00:16:00 jglaptop chat[14676]: ^M Jul 7 00:16:00 jglaptop chat[14676]: ATM0^M^M Jul 7 00:16:00 jglaptop chat[14676]: OK  Jul  7 00:16:00 jglaptop chat[14676]: -- got it Jul  7 00:16:00 jglaptop chat[14676]: send (ATDT*99***1#^M) Jul 7 00:16:01 jglaptop chat[14676]: timeout set to 60 seconds Jul 7 00:16:01 jglaptop chat[14676]: expect (CONNECT) Jul 7 00:16:01 jglaptop chat[14676]: ^M Jul 7 00:16:02 jglaptop chat[14676]: ATDT*99***1#^M^M Jul 7 00:16:02 jglaptop chat[14676]: CONNECT Jul 7 00:16:02 jglaptop chat[14676]: -- got it Jul  7 00:16:02 jglaptop chat[14676]: send (^M) Jul 7 00:16:02 jglaptop chat[14676]: timeout set to 5 seconds Jul 7 00:16:02 jglaptop chat[14676]: expect (~) Jul 7 00:16:02 jglaptop chat[14676]: ^M Jul 7 00:16:02 jglaptop chat[14676]: ~ Jul 7 00:16:02 jglaptop chat[14676]: -- got it Jul  7 00:16:02 jglaptop chat[14676]: send (^M) Jul 7 00:16:02 jglaptop pppd[14666]: Serial connection established. Jul 7 00:16:02 jglaptop pppd[14666]: speed 912600 not supported Jul 7 00:16:02 jglaptop pppd[14666]: using channel 17 Jul 7 00:16:02 jglaptop pppd[14666]: Using interface ppp0 Jul 7 00:16:02 jglaptop pppd[14666]: Connect: ppp0 <--> /dev/rfcomm0 Jul 7 00:16:03 jglaptop pppd[14666]: rcvd [LCP ConfReq id=0x0   ] Jul 7 00:16:03 jglaptop pppd[14666]: sent [LCP ConfReq id=0x1  ] Jul 7 00:16:03 jglaptop pppd[14666]: sent [LCP ConfAck id=0x0   ] Jul 7 00:16:03 jglaptop pppd[14666]: rcvd [LCP ConfRej id=0x1 ] Jul 7 00:16:03 jglaptop pppd[14666]: sent [LCP ConfReq id=0x2 ] Jul 7 00:16:03 jglaptop pppd[14666]: rcvd [LCP ConfAck id=0x2 ] Jul 7 00:16:03 jglaptop pppd[14666]: sent [LCP EchoReq id=0x0 magic=0x0] Jul 7 00:16:03 jglaptop pppd[14666]: sent [PAP AuthReq id=0x1 user="web" password= ] Jul 7 00:16:03 jglaptop pppd[14666]: rcvd [LCP EchoRep id=0x0 magic=0x0] Jul 7 00:16:03 jglaptop pppd[14666]: rcvd [PAP AuthAck id=0x1 ""] Jul 7 00:16:03 jglaptop pppd[14666]: PAP authentication succeeded Jul 7 00:16:03 jglaptop pppd[14666]: sent [IPCP ConfReq id=0x1   ] Jul 7 00:16:03 jglaptop pppd[14666]: rcvd [IPCP ConfReq id=0x0 ] Jul 7 00:16:03 jglaptop pppd[14666]: sent [IPCP ConfAck id=0x0 ] Jul 7 00:16:06 jglaptop pppd[14666]: rcvd [IPCP ConfNak id=0x1   ] Jul 7 00:16:06 jglaptop pppd[14666]: sent [IPCP ConfReq id=0x2   ] Jul 7 00:16:06 jglaptop pppd[14666]: rcvd [IPCP ConfAck id=0x2 <addr 10.34.168.95> <ms-dns1 149.254.1.14> <ms-dns3 149.254.1.15>] Jul 7 00:16:06 jglaptop pppd[14666]: local IP address 10.34.168.95 Jul 7 00:16:06 jglaptop pppd[14666]: remote IP address 10.6.6.6 Jul 7 00:16:06 jglaptop pppd[14666]: primary  DNS address 149.254.1.14 Jul 7 00:16:06 jglaptop pppd[14666]: secondary DNS address 149.254.1.15 Jul 7 00:16:06 jglaptop pppd[14666]: Script /etc/ppp/ip-up started (pid 14682) Jul 7 00:16:07 jglaptop pppd[14666]: Script /etc/ppp/ip-up finished (pid 14682), status = 0x1 Jul 7 00:16:56 jglaptop ntpd[7669]: Listening on interface #7 ppp0, 10.34.168.95#123 Enabled

The way to read PPP messages is like this: sent [LCP ConfReq ... ] means "I would like to do this setting" You then see a ConfAck which means "OK" or a ConfRej which means "No, this is what I'd like you to do". You may see another ConfReq with changed parameters fitting in with the suggestions accompanying the ConfReg. It's a negotiation process and you should be able to follow it along and see where problems arise.

Finale
Finish it all off with:


 * 1) rc-update add bluetooth default
 * 2) rc-update add net.ppp0 default

You may decide to not do the second line above and instead start the interface manually, otherwise whenever your system is running and you turn on the Bluetooth interface on your phone, you system will connect to the web on it. *sigh* the price of convenience. If you are using a Bluetooth dongle rather than a built in one, then you can just remove the dongle. The choice is yours.