Linux + Mobile Phone + Bluetooth
OR: WHY WAS THE DOCUMENTATION THIS BAD???
2005-04-17
(updated 2006-07-03)
Walter Stanish
walter@pratyeka.org
Introduction / Synopsis ( SKIP TO GOODIES )
I wasted a lot of time recently (April 2005) at a Chinese second-hand
mobile phone market trying to find an old phone with which I could
establish an AT-style command-line connection over RS232. Having
worked previously with GSM modems, GPS, etc. and having one such cable
(for old Nokias) I figured such a find would be easy. Not
so! Here in 2005, such an old beast is near impossible to find
... even in China! Most phones are USB, due to MP3/camera mass-storage type features.
In the end I managed to acquire a new RS232 cable that connected OK to
a Sony Ericsson T68 phone, which I then bargained down to 300RMB (28
euro). Included was the old (2nd-hand) battery, a new (spare)
battery (though apparently an 'old' model), the data cable, the phone
and a new charger. I soon realised it had bluetooth, and some
searching online convinced me that I should try to get it
working. Actually, the killer was that the phone charger and data
cable couldn't both be plugged in together - which meant my server's
new SMS-drone would not be viable. I picked up a cheap USB
bluetooth dongle for 120RMB (11 euro, or almost half the cost of the
phone!) on the chance I'd get it working. I did, but bluetooth
was a real hassle.
Getting
bluetooth working
First, a gripe: Linux bluetooth documentation sux.
OK, now that's over, here's what you need.
- 2.6 kernel with the bluetooth, rfcomm, rfcomm tty options all compiled in
'hard'. Also compile in all USB dongles drivers.
Actually, compiling as modules should be possible, but apparently in
some kernel versions compiling as a module reportedly causes silent
failure - so to eliminate one potential problem, don't do this!
If your kernel isn't up to date, get a new kernel from kernel.org/mirrors. I used
2.6.11.7
WARNING:
Sort this out before going ahead. Without a recent kernel, nobody
will help you with your coming problems. :)
- Recentish bluez-utils,
bluez-libs packages. Get bluez-hcidump too, to be sure.
You can get the latest from bluez.org/download.html.
To confuse the matter, whenever you look up bluetooth for linux you
will have to wade through garbage about different stacks.
Virtually nobody except hardcore embedded systems developers should
probably care much anymore. In recent 2.6 kernels, the stack
previously known as bluez has
now been included as default, and is just 'bluetooth support' (which
you have already, or will compile in as per the above note!)
WARNING:
Install these before going ahead. They provide the tools required
to use the kernel drivers and/or debug your connection.
1. First steps
So, what to do next? Basically you should have your bluetooth
adapter in (if USB - plug in now!). Type hciconfig. If you don't see
info regarding hci0 pop up,
you've got driver problems. Check your kernel source again,
making sure you have compiled in your adapter's driver hard (not as
module). If you do it as a module, you might need to add lines to
/etc/modules.conf or something
similar - not worth the effort.
If you see hci0 pop up, you probably need to activate it. Type hciconfig hci0 up to get the
interface up 'n active. Verify this with another hciconfig
Once you've got the hci0 interface up, get your bluetooth phone (mine
was T68), or other bluetooth device, ready. If it has a discoverable mode, then activate
it. Now go back to your system and type hcitool scan. You should see
an entry pop up about your hardware. If not, double check your
other bluetooth device is in discoverable mode.
NOTE: If
you are (paranoid or) interested then at this point you might wish to
use the hci-dump tool to check out wireless activity.
The scan results should show your device's name (I guess this is
usually user-configurable, in my case it defaulted to the phone model
name - T68) as well as the device's
address. This will look like some sort of 12:12:12:12:12:12
number. Copy it with your mouse, or write it down - you'll need
it. I'll refer to it below as <address>.
NOTE: The
fact that you need to use a difficult to remember address for almost
every subsequent is silly, but there's no established / generally
accepted solution, so as the saying goes "eat it or wear it".
Now, type l2ping <address> - you should
see ping replies. If not, you've got issues (hooray!). I
guess you'd use hci-dump and hcitool to sort them out.
After seeing ping replies, you are potentially 'connected' to your
phone. Basically now, as I understand, there are a few types of
higher-level connections that you can make. The one of these you
probably want is RFCOMM, which
is what we'll focus on. It is based upon emulating a serial line
(think RS232 - /dev/ttyS0 or whatever), over bluetooth.
Note: The
other connection types (OBEX, etc.) are used for doing things like
getting access to phone filesystems. I haven't tried 'em, but
there's plenty of info out there on google.
Before you continue, check that you have a /dev/rfcomm0 - if not, make it like
this: mknod --mode=666 /dev/rfcomm0 c 216 0
Now that your /dev/rfcomm0 is good, type the following: rfcomm connect 0 <address>
1 This will probably fail. If not, you're in
business, so what are you waiting for? Go away!
Otherwise, you might get to the frustrating point that I and many other
users have - receiving a message like rfcomm0:
Connection refused .. debugging this with your hcidump tool might just show
something like 'connection terminated by peer'. Confusing!
The reason is, as I eventually figured out, you're not 'peered' with
the device yet. To enable peering, you need a PIN. Edit /etc/bluetooth/pin and change the
content to your desired pin number. I used four digits, which
worked with my T68, but I've read elsewhere some guy used five digits
with his Nokia. Use whatever floats your boat (or
rfcomm...). to test it, use the phone or other device to 'add
peer'.
When adding the computer as a peer, you will need to have hcid,
the HCI daemon, running.
Use hcidump and the
phone's screen to debug this step. If it fails, try
again. For some reason, the default pin in the file was BlueZ -
very annoying, as it suggests a BlueZ:1234 pin format - THIS IS
WRONG. Just add the pin, like '1234'. There should be
nothing else in the file. Keep playing until your device peers OK.
Now, once your phone is 'peered', go back and run the rfcomm command
again - rfcomm connect 0 <address> 1.
You should see it connect and say 'press Ctrl+C to disconnect',
and you're set!
Note that with some old kernels you can get to this stage but
communications will not function, with either no error or some
kind of IO related error appearing when you try to access the newly
bound device (/dev/rfcomm0). If this happens, upgrade your kernel.
To test, simply fire up minicom (minicom
-s) and set /dev/rfcomm0 as your device.
I used 115200 baud but
perhaps other values will work for you. Type AT, you should see
OK. ATI will give you your phone or device ID. Now you are
right to send SMS, back up your phonebook, dial out for GPRS 'net
access, etc. That means it's time to check out some tools like gnokii.
If you want to do some lower-level coding instead of using a pre-packaged
solution, check out AT+C commands, a reference on the differences of AT+C command set implementation of various GSM devices. Other than ETSI standardized commands are not listed although there are a tons of manufacturer specific commands in many implementations.
- Walter Stanish (walter@pratyeka.org)
Hosted @ pratyeka