[ Back to Kevin's Homepage | Technical Computer Stuff ]

Connecting via Bluetooth through my Treo 650 to the Internet

Before we start configuring pppd, make sure that your bluetooth dongle works and that you've already paired your Treo with your laptop.

My system

I am performing this installation on Kubuntu 6.06 LTS Linux distribution, up-to-date as of 2008.01.19. My Treo 650 is of Cingular AT&T descent, software version Treo650-1.17-CNG .

Basic configuration

Before we configure pppd, we should make sure that the Treo is ready to act as a dialup modem. Start by going into the Bluetooth Prefs panel and make sure that "Dial-up Networking:" is set to "On".

IMPORTANT: DUN mode drains your battery very very fast. If it is left in DUN mode, your battery will be dead in about 24 hours. Second, if you are constantly transmitting and receiving (eg downloading something large) your battery will be dead in less than an hour! Therefore, you will need a charger of some sort. Even the lowly USB charging cables should be sufficient to keep the phone from draining.

Once the Treo is in DUN mode, check that /dev/rfcomm0 shows up:

$ TREO_MAC=00:07:E0:63:2C:78
$ sudo hcitool cc $TREO_MAC
$ sudo hcitool auth $TREO_MAC
$ ls -l /dev/rfcomm0
crw-rw---- 1 root dialout 216, 0 Jan 20 18:53 /dev/rfcomm0
If you get the error "No such file or directory", try rebooting your Treo.

Get used to rebooting your Treo. Sometimes, it'll spontaneously reboot after staying connected for a few hours. I'd say that I probably reboot 2-3 times a day when using DUN heavily.

Create the config files you need as root

cat >/etc/ppp/peers/BluetoothDialup <<'_EOF_'
# tty name
/dev/rfcomm0
# speed
115200
# options
hide-password
debug
noauth
connect "/usr/sbin/chat -v -f /etc/chatscripts/BluetoothDialup"
usepeerdns
defaultroute
crtscts
lcp-echo-failure 0
novj
user "ISP@CINGULARGPRS.COM"
remotename BluetoothDialup
ipparam BluetoothDialup
_EOF_

cat >/etc/chatscripts/BluetoothDialup <<'_EOF_'
TIMEOUT 35
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
OK 'AT&f&d2&c1+cgdcont=1,"IP","isp.cingular"'
OK ATD*99***1#
CONNECT ""
_EOF_

echo '"ISP@CINGULARGPRS.COM" BluetoothDialup "CINGULAR1"'>>/etc/ppp/pap-secrets

Activating your Internet connection

The first time you bring the connection up, you should monitor your syslog messages to make sure it's doing what you think it's doing. In a separate window, run sudo tail -f /var/log/messages To start your Internet connection, execute this command: sudo pppd call BluetoothDialup which should dump the following information into /var/log/messages:

Jan 19 23:00:47 pocketeer pppd[2654]: pppd 2.4.4b1 started by root, uid 0
Jan 19 23:00:49 pocketeer chat[2655]: timeout set to 35 seconds
Jan 19 23:00:49 pocketeer chat[2655]: abort on (\nBUSY\r)
Jan 19 23:00:49 pocketeer chat[2655]: abort on (\nERROR\r)
Jan 19 23:00:49 pocketeer chat[2655]: abort on (\nNO ANSWER\r)
Jan 19 23:00:49 pocketeer chat[2655]: abort on (\nNO CARRIER\r)
Jan 19 23:00:49 pocketeer chat[2655]: abort on (\nNO DIALTONE\r)
Jan 19 23:00:49 pocketeer chat[2655]: abort on (\nRINGING\r\n\r\nRINGING\r)
Jan 19 23:00:49 pocketeer chat[2655]: send (^MAT^M)
Jan 19 23:00:49 pocketeer chat[2655]: expect (OK)
Jan 19 23:00:49 pocketeer chat[2655]: *MRDY: 1^M
Jan 19 23:00:49 pocketeer chat[2655]: ^MAT^M^M
Jan 19 23:00:49 pocketeer chat[2655]: OK
Jan 19 23:00:49 pocketeer chat[2655]:  -- got it
Jan 19 23:00:49 pocketeer chat[2655]: send (AT&f&d2&c1+cgdcont=1,"IP","isp.cingular"^M)
Jan 19 23:00:50 pocketeer chat[2655]: expect (OK)
Jan 19 23:00:50 pocketeer chat[2655]: ^M
Jan 19 23:00:50 pocketeer chat[2655]: AT&f&d2&c1+cgdcont=1,"IP","isp.cingular"^M^M
Jan 19 23:00:50 pocketeer chat[2655]: OK
Jan 19 23:00:50 pocketeer chat[2655]:  -- got it
Jan 19 23:00:50 pocketeer chat[2655]: send (ATD*99***1#^M)
Jan 19 23:00:50 pocketeer chat[2655]: expect (CONNECT)
Jan 19 23:00:50 pocketeer chat[2655]: ^M
Jan 19 23:00:50 pocketeer chat[2655]: ATD*99***1#^M^M
Jan 19 23:00:50 pocketeer chat[2655]: CONNECT
Jan 19 23:00:50 pocketeer chat[2655]:  -- got it
Jan 19 23:00:50 pocketeer chat[2655]: send (^M)
Jan 19 23:00:50 pocketeer pppd[2654]: Serial connection established.
Jan 19 23:00:50 pocketeer pppd[2654]: Using interface ppp0
Jan 19 23:00:50 pocketeer pppd[2654]: Connect: ppp0 <--> /dev/rfcomm0
Jan 19 23:00:55 pocketeer pppd[2654]: Remote message: PAP access OK
Jan 19 23:00:55 pocketeer pppd[2654]: PAP authentication succeeded
Jan 19 23:00:56 pocketeer pppd[2654]: local  IP address 166.217.86.87
Jan 19 23:00:56 pocketeer pppd[2654]: remote IP address 166.217.86.0
Jan 19 23:00:56 pocketeer pppd[2654]: primary   DNS address 66.209.10.202
Jan 19 23:00:56 pocketeer pppd[2654]: secondary DNS address 66.102.163.232
Test your connection with nslookup google.com and ping yahoo.com

Once your connection is up and working, there are a few things you can do to make the link more usable. The first thing you probably want is a ping to keep your link from hanging up on you from lack of use. You could simply run "ping -i 15 yahoo.com" but because bandwidth is at an extreme premium here, you can more intelligently check your connection for lack of use and only ping in those cases. The script below does this. Currently I'm manually launching the script, since I'm not finished tweaking it yet.

cat >/root/keepalive <<'_EOF_'
#!/bin/bash
#########################
## begin configuration ##
# PING_TARGET = hostname that you can successfully ping
PING_TARGET=yahoo.com
# VERBOSE = (true|false)
# true = echo bandwidth usage statistics, filtered ping output
VERBOSE=true
# DEBUG = (true|false)
# true = echo full ping output, some debugging statements below
DEBUG=false
##  end configuration  ##
#########################

IF=ppp0
if [ -n "$1" ] ; then
  IF=$1
  fi

xb()
{
ifconfig $IF 2>/dev/null | fgrep "$1" | sed -e "s/^.*${1}:\\([0-9]*\\).*$/\\1/"
}

LAST_TX=0
LAST_TXB=`xb 'TX bytes'`
LAST_RXB=`xb 'RX bytes'`
NO_RX_COUNT=0
sleep 8
# run until the interface disappears (eg pppd dies)
while ifconfig $IF >/dev/null 2>&1 ; do
  ($DEBUG || $TARGET) && date
  TX=`ifconfig $IF 2>/dev/null | fgrep 'TX packets' | cut -f2 -d: | cut -f1 -d' '`
  if [ "$LAST_TX" = "$TX" ] ; then
    echo "Firing ping..."
    if $DEBUG ; then
      ping -c 1 $PING_TARGET
    elif $VERBOSE ; then
      ping -c 1 $PING_TARGET | fgrep 'bytes from'
    else
      ping -c 1 $PING_TARGET >/dev/null
      fi
  elif $DEBUG ; then
    echo "$LAST_TX != $TX"
  fi
  LAST_TX=$TX
  RXB=`xb 'RX bytes'`
  TXB=`xb 'TX bytes'`
  TX=`expr $TXB - $LAST_TXB`
  RX=`expr $RXB - $LAST_RXB`
  TXr=`echo $TX / 8 | bc -l | cut -c1-8`
  RXr=`echo $RX / 8 | bc -l | cut -c1-8`
  $VERBOSE && echo "tx $TX Bytes / 8 sec = $TXr Bps"
  $VERBOSE && echo "rx $RX Bytes / 8 sec = $RXr Bps"
  LAST_RXB=$RXB
  if [ 0 = $RX ] ; then
    NO_RX_COUNT=`expr $NO_RX_COUNT + 1`
    if [ $NO_RX_COUNT -gt 30 ] ; then
      echo "ERROR, no rx for 30 loops!"
      echo "killall pppd"
      fi
  else
    NO_RX_COUNT=0
    fi
  LAST_TXB=$TXB
  sleep 8
  done
echo Exited at `date`
_EOF_
chmod +x /root/keepalive
You may notice that there's a message in the middle that reads "ERROR, no rx for 30 loops!". There is an occasional problem where the Dial-Up Networking will stay connected, but no data packets flow in or out. This script is still under development, so right now the only thing it does is echo out "killall pppd" which is the command that should be run as root to kill the DUN connection.

Further advanced topics

Optimize your bluetooth connection with local DNS cache and traffic prioritization

Turn your bluetooth connected machine into a router


KJW - kjw@rightsock.com