Blogs | Srijan

Bluetooth GPS devices with Linux

Written by Team Srijan | Jan 18, 2008 8:00:00 AM

A. Talking to Bluetooth GPS devices with Linux

This is a guide for communicating with Bluetooth GPS devices on a Linux platform. As there are a wide range of GPS Bluetooth devices, and a fair number of Linux distributions, we focus on the GL50-BT device from San Jose Navigation on an Ubuntu Gutsy (7.10) distribution. However, the ideas should be generally applicable to other Bluetooth devices, and to other recent Linux distributions. Much of this information is gleaned from a thread on Ubuntu forums, but is made specific here to Bluetooth GPS devices.

B. For the impatient

Impatience being one of the cardinal virtues of a FOSS programmer, if you do not have the time to go through the entire article, here is a minimal set of steps for getting your Bluetooth GPS device working:

  1. Get Bluetooth working on your computer: You will need to install the appropriate packages. On some machines, such as Acer laptops, you might also need to install a kernel module. Check that Bluetooth is working, with:
  •   hcitool dev This should display the ID of the Bluetooth device on your computer, something like: hci0      00:16:CE:DE:3C:B1
  •   hcitool scan will now scan for other devices that are in range. Make sure that Bluetooth on the GPS device       is on, as some devices are discoverable only at startup, or when a button is pressed. You can also check that         the scan is working by having another Bluetooth device, such as a mobile phone, within range. You should           see something like: 00:01:53:02:DF:A5 GL50BT If you have trouble detecting the device, one thing to                 ensure is that the batteries are in good shape. Bluetooth uses up a fair bit of power, and II have had trouble           connecting when the batteries are low.
  1. Set up /etc/bluetooth/hcid.conf
  2. Set up /etc/bluetooth/rfcomm.conf
  3. Establish RF communications: sdptool add --channel=1 OPUSH sudo rfcomm bind /dev/rfcomm0 00:01:53:02:DF:A5 Use the channel no. specified in /etc/bluetooth/rfcomm.conf, and the Bluetooth ID for the GPS device as reported by "hcitool scan".
  4. Read data fom the GPS device:
  • cat /dev/rfcomm0 will read realtime NMEA data from the device, but included with this will be binary data in the device buffer
  • sudo gpsd /dev/rfcomm0 will start gpsd using the proper device node, and gpspipe -r will show you properly formatted NMEA sentences.

On to the detailed instructions.

C. Packages to install

This is what I have installed, though I am not sure if all packages are needed, nor if I have missed some that are not included by default in Gutsy. Please let me know of any required modifications:

  • bluez-gnome
  • bluez-utils
  • gnome-bluetooth
  • kdebluetooth
  • Also, useful are
  • cutecom
  • gpsd
  • gpsd-clients
  • gpsdrive
  • gpsd seems to work with the GL50-BT, though I did have some problems, and am not yet completely satisfied.

D. Get bluetooth working on your laptop

This might involve having the proper drivers, and the appropriate kernel modules. For an Acer laptop, you should use the acerhk kernel module. Thus, sudo modprobe acerhk echo on > /proc/driver/acerhk/blueled The blue LED on the front should now come on. "hcitool dev" should also show you something like hci0 00:16:CE:DE:3C:B1 Check http://www.xmarks.com/site/www.cakey.de/acerhk/ for supported model numbers. If you do not see your model number, and the above instructions do not work, you can often force the series to the closest model number lower than the actual model number. Thus, for the unsupported Acer Travelmate 4200, use: sudo rmmod acerhk sudo modprobe acerhk force_series=4000 echo on > /proc/driver/acerhk/blueled Likewise, the Acer Aspire 5550 can be coerced into working with sudo modprobe acerhk force_series=5020 The documentation for this driver in the Linux kernel source has more details.

E. Check device visibility

Turn the GL50-BT off, start "hcitool scan", turn it on, hold the little white button, labelled "connection", down for a couple of seconds, and release. The connection button can also be used to re-establish a dropped connection while the GPS is running, but this does not seem entirely reliablehcitool scan should show you something like: 00:01:53:02:DF:A5 GL50BT 00:1D:FD:EC:AC:44 Rahul The GPS device here is the one labelled GL50BT, while the other one is a Bluetooth-enabled mobile phone that was in range. The first string of digits is a device-specific ID.

F. Edit /etc/bluetooth/hcid.conf

Mine looks like: # # HCI daemon configuration file. # # HCId options options { # Automatically initialize new devices autoinit yes; # Security Manager mode # none - Security manager disabled # auto - Use local PIN for incoming connections # user - Always ask user for a PIN # security none; # Pairing mode # none - Pairing disabled # multi - Allow pairing with already paired devices # once - Pair once and deny successive attempts pairing multi; # Default PIN code for incoming connections passkey "1234"; } # Default settings for HCI devices device { # Local device name # %d - device id # %h - host name name "%h-%d"; # Local device class class 0x3e0100; # Default packet type #pkt_type DH1,DM1,HV1; # Inquiry and Page scan iscan enable; pscan enable; discovto 0; # Default link mode # none - no specific policy # accept - always accept incoming connections # master - become master on incoming connections, # deny role switch on outgoing connections lm accept; # Default link policy # none - no specific policy # rswitch - allow role switch # hold - allow hold mode # sniff - allow sniff mode # park - allow park mode lp rswitch,hold,sniff,park; } From my incomplete understanding of the file format:

  1. The "autoinit yes" and "security none" options are important.
  2. In the device section, the "lm master" is what is recommended, though things seemed to work for me with "lm accept". Not sure what the difference is.
  3. In the device section, the "class 0x3e0100" is important. Part of the bit settings in the class indicate that this is a location device. However, there are apparently other ways (sdptool) of setting up communications.

G. Edit /etc/bluetooth/rfcomm.conf

Mine now is: # # RFCOMM configuration file. # rfcomm0 { # Automatically bind the device at startup bind no; # Bluetooth address of the device device 00:01:53:02:DF:A5; # RFCOMM channel for the connection channel 1; # Description of the connection comment "GL50BT GPS device"; } Notes:

  1. The device ID string in "device 00:01:53:02:DF:A5" is specific to a GPS unit. Use the one reported for the GL50-BT by "hcitool scan".
  2. The comment string is arbitrary.

H. Establish the RF communication

sdptool add --channel=1 OPUSH should return something like, OBEX Object Push service registered and, sudo rfcomm bind /dev/rfcomm0 00:01:53:02:DF:A5 should set up /dev/rfcomm0 for communication with the device. Again, the last string is the device bluetooth ID, e.g., as reported by "hcitool scan".

I. Read data from the device

You can check quickly that things are working with: cat /dev/rfcomm0 Be warned that binary characters in the output might be interpreted as ANSI escape sequences, and scramble your terminal settings. Pipe output into less. (For gnome-terminal, you can recover from a scrambled terminal with Terminal > Reset and Clear, followed by hitting keyboard return.) A better way is to use gpsd. E.g., sudo gpsd /dev/rfcomm0 will set it running in daemon mode. You can examine NMEA sentences from the GL50-BT with gpspipe -r One can also run cutecom, using device /dev/rfcomm0. All the usual GL50 device-specific commands, @PCgs, @PCsr, @PCrr, etc., work as expected. Programmatic readout of stored data should also work, but I have not tried that as of yet.

J. Resuming connection, and data reading

Note that once the above commands (C-H) are done, there is no need to redo them unless the machine is rebooted. Thus, one can turn off the GPS device, turn it on again (maybe checking that it is visible with "hcitool scan"), and reading GPS data from /dev/rfcomm0 should still be possible. Likewise, gpsd should still be running, so that rerunning "gpspipe -r" should start showing NMEA sentences.