Update 2016-08-17: I’ve been through also 14.04 LTS and 16.04 LTS, see the comments below for the small differences in configuration.
Still out of office for the New Year I can think about Open Seas … As you all know (?) I am a long time fan of OpenCPN navigation tool and I have promoted its virtues on an Linux system in an article. Now, I have this new Clevo 270EM laptop with (C)Ubuntu 12.04.1 pre-installed and I would like to use my excellent Nokia LD-3W GPS Bluetooth Appliance with it (just for learning, for the future box which I would actually build for the maritime usage one day). Unfortunately not manufactured anymore, the Nokia LD-3W is some excellent small piece of hardware ! I use it everywhere, especially in my car. But it excels also in the city, being always available and accurate even when walking on narrow streets, beating easily any phone with built-in GPS device. The battery life is excellent. So why not maritime use, since it seems to resist well the humid conditions as proven by my multiple trekking trips.
There is no easy way (in this particular case)
Sorry about that. You may want to try the below, standard method which works for most of the Bluetooth devices (such as phones) like a dream. But we may find out that OpenCPN will not receive the NMEA data from Bluetooth GPS device this way. This said not to disappoint you at the end.
Now it should work with OpenCPN, right ?
I warned you, this is the dreaded annoyances.org speaking. Let’s give it a try, though.
Let’s not give up !
That’s why you are reading this article, right ? This international team (south-african-american-french-finnish-to-start-with) will beat any big monopoly closed system 4 – 0 (a soccer score) !! Sorry if it is getting a bit more complex from now on, though.
Which googled suggestions are NOT working
Dynamically created /dev/rfcomm0 device is not actually available for the non-root user : it looks like that it is reserved for some GPRS applications or such:
canne@clevo:~$ ls -l /dev/rfcomm0 crw-rw---- 1 root dialout 216, 0 Jan 2 10:11 /dev/rfcomm0
But setting this to /etc/group
dialout:x:20:root,ubuntu,canne,nobody
does not change anything. Also, the obvious solution of running OpenCPN with sudo (or otherwise as root) does not help, either.
Let’s cut in a bit deeper
The exact Linux kernel version matters, as well as the Linux distro, in my case (C)Ubuntu 12.04.1 LTS.
canne@clevo:~$ uname -a Linux clevo.homenet.org 3.5.0-18-generic #29-Ubuntu SMP Thu Oct 25 07:26:14 UTC 2012 x86_64 x86_64 x86_64 GNU/Linux
It is noteworthy that if you repeat the above procedure from scratch after a reboot (i.e. create the /dev/rfcomm0 device again), you can read the GPS device information as root, from the terminal.
canne@clevo:~$ sudo su - [sudo] password for canne: root@clevo:~# cat /dev/rfcomm0 $GPGGA,091145.000,435 ... C $GPGSA,A,3,22,03,06, ... *35 $GPGSV,3,1,12,19,84, ... *70 $GPGSV,3,2,12,11, ... *7B $GPGSV,3,3,12,18,18, ... *79 $GPRMC,091145.000,A, ... A*64 $GPGGA,091146.000,4350.1753,N, ... 0*5F $GPGSA,A,3,22,03, ... 2.9*35 ...
But you cannot read the /dev/rfcomm0 device as a normal user.
canne@clevo:~$ cat /dev/rfcomm0 cat: /dev/rfcomm0: Device or resource busy
Busy ?
root@clevo:/etc/udev/rules.d# fuser /dev/rfcomm0 /dev/rfcomm0: 1149 root@clevo:/etc/udev/rules.d# ps -ef | grep 1149 root 1149 1 0 09:51 ? 00:00:03 /usr/sbin/bluetoothd
Well, that makes sense, the device is used by the Bluetooth daemon. But maybe the serial line cannot be shared ? Let’s kill the device by removing it from the Bluez Bluetooth Manager. (right-click the icon).
The Suggested Solution
Using the above observations, I concluded that it is necessary to :
- Not to share the rfcomm device with anybody else, such as bluetoothd
- Address the non-root user access problem with udev ACL access rights
Creating a manually set-up device, say /dev/rfcomm9
The instructions are largely inspired by those which I found from blog.petrilopia.net. Add the following lines in the /etc/bluetooth/rfcomm.conf file with your favourite text editor :
root@clevo:/etc/bluetooth# vi rfcomm.conf ... rfcomm9 { # # Automatically bind the device at startup bind no; # # # Bluetooth address of the device (your device) device 00:02:76:c7:82:38; # # # RFCOMM channel for the connection (this is the default) channel 1; # # # Description of the connection comment "Nokia LD-3W"; } ...
Prepare the PIN-code (with your BT-address, of course) and test the connection :
root@clevo:~# mkdir -p /var/lib/bluetooth/00:02:76:c7:82:38 root@clevo:~# echo "00:02:76:c7:82:38 0000" \ >/var/lib/bluetooth/00:02:76:c7:82:38/pincodes root@clevo:~# rfcomm connect 9 Connected /dev/rfcomm9 to 00:02:76:C7:82:38 on channel 1 Press CTRL-C for hangup
Hangup and wait until you do not see anymore the /dev/rfcomm9 device (which was created dynamically and its binding will be removed). Remember, if it is not going away, use fuser(1) to find out the process (ex. OpenCPN) who is using it.
root@clevo:~# ls -l /dev/rfcomm* crw-rw---- 1 root dialout 216, 9 Jan 2 14:51 /dev/rfcomm9 ... root@clevo:~# ls -l /dev/rfcomm* ls: cannot access /dev/rfcomm*: No such file or directory
The next thing is to make the device node with adequate access rights by creating a udev rule, which is done by creating the below file (with canne replaced with your group – and not user name) :
/etc/udev/rules.d/60-extra-acl.rules KERNEL=="rfcomm[0-9]*", NAME="%k", GROUP="canne", TAG+="udev-acl", TAG+="uaccess"
Connect the device again (in Nokia LD-3W you can see from the three turning lights that it has got both the Bluetooth connection and a GPS satellite fix) :
root@clevo:~# rfcomm connect 9 Connected /dev/rfcomm9 to 00:02:76:C7:82:38 on channel 1 Press CTRL-C for hangup
This time leave the above connection running. In another shell as root (or with sudo), test that data is flowing in :
root@clevo:~# cat /dev/rfcomm9 $GPGGA,144009.780,, .. ... root@clevo:~#
Note that you are not left hanging, but you get a prompt again after the buffer is emptied. Now try the same thing as you :
canne@clevo:~$ cat /dev/rfcomm9 $GPGGA,144018.000,4350.1649,N... ... canne@clevo:~$
Looks promising ! Let’s test with OpenCPN, running it as ourselves, from the desktop button, but modifying in the configuration dialog (as above) /dev/rfcomm0 to /dev/rfcomm9.
The Final Touch – Let’s Make It Persistent
You do not probably want to go through all the mayhem every time you restart the application / your computer ? Let’s make it persistent !
root@clevo:/etc/bluetooth# vi rfcomm.conf ... rfcomm9 { # # Automatically bind the device at startup bind yes; ...
Restart your system. At next reboot the /dev/rfcomm9 device node is created automatically and the first application which opens the device gets the NMEA stream. If the stream is not there (i.e. the device is turned off) you will not get the connection back, automagically on the fly.
Practically, this means that you need to make sure that your Nokia LD-3W device (or other external Bluetooth GPS) is powered on, preferrably for sufficiently long time that it has got a satellite fix. Only then start OpenCPN. This is somewhat annoying but I do not have an answer for that. However, as the battery life of Nokia LD-3W allows it to be turned on all day long, that is perhaps not a big deal, although more in-depth analysis and testing would be required for serious navigation usage.
Happy And Precise Navigation for 2013 !! Be careful out there.
Sunday, March 24, 2013 at 23:06
[…] and PC based navigation. In my previous articles about OpenCPN on MeeGo/Ubuntu and how to use a Bluetooth GPS device with it I have shared some of my acquired insight. Now, I got yesterday with my favourite sailing magazine […]
Wednesday, June 11, 2014 at 05:07
Update : Nokia GPS LD-3W Bluetooth on Ubuntu 14.04 LTS (Trusty Tahr) for OpenCPN 3.3.1731 and gpsd / xgps for Marble based navigator on Samsung N150.
uname -a
Linux n150 3.13.0-29-generic #53-Ubuntu SMP Wed Jun 4 21:00:20 UTC 2014 x86_64 x86_64 x86_64 GNU/Linux
With generic Bluetooth USB dongle
canne@n150:~$ lsusb
Bus 002 Device 002: ID 0a12:0001 Cambridge Silicon Radio, Ltd Bluetooth Dongle (HCI mode
It is OpenCPN 3.3.1731 who requires me to be put in the group ‘dialout’ for serial line connected GPS device at startup, which I did:
canne@n150:~$ cat /etc/group
dialout:x:20:canne
The system up, LD-3W not powered:
canne@n150:~$ rfcomm
rfcomm9: 00:02:76:C7:82:38 channel 1 clean
When LD-3W powered on, no automatic connection but the state remains as above.
Now, with LD-3W powered, pne can start the OpenCPN and define the /dev/rfcomm9 as explained in the article and the communication works as explained and a fix is quickly achieved. The status is, while the OpenCPN is executing:
canne@n150:~$ rfcomm
rfcomm9: 00:02:76:C7:82:38 channel 1 connected [tty-attached]
When one stops the OpenCPN, the status of the Bluetooth connection is
canne@n150:~$ rfcomm
rfcomm9: 00:02:76:C7:82:38 channel 1 closed
Note, that one can test the output of LD-3W by simple dumping the output from the device (note: the permissions to the device must have been set, using the udev-rules as explained in the article):
canne@n150:~$ ls -l /dev/rfcomm*
crw-rw—-+ 1 root canne 216, 9 juin 11 05:48 /dev/rfcomm9
canne@n150:~$ cat /dev/rfcomm9
$GPGGA,035118.165,,,,,0,00,,,M,0.0,M,,0000*5A
$GPGSA,A,1,,,,,,,,,,,,,,,*1E
$GPGSV,3,1,11,13,73,035, ….
…
^C
canne@n150:~$ rfcomm
rfcomm9: 00:02:76:C7:82:38 channel 1 closed
gpsd works, equally (it can be tested with xgps-utility). Note the “-n” option, which is mandatory with LD-3W.
canne@n150:~/bin$ gpsd -N -D 2 -n /dev/rfcomm9
gpsd:INFO: launching (Version 3.9)
gpsd:INFO: listening on port gpsd
gpsd:INFO: NTPD ntpd_link_activate: 1
gpsd:INFO: stashing device /dev/rfcomm9 at slot 0
gpsd:INFO: opening GPS data source type 4 at ‘/dev/rfcomm9’
gpsd:INFO: speed 115200, 8N1
gpsd:INFO: speed 9600, 8O1
gpsd:INFO: speed 115200, 8N1
gpsd:INFO: gpsd_activate(): activated GPS (fd 6)
gpsd:INFO: device /dev/rfcomm9 activated
gpsd:INFO: running with effective group ID 1000
gpsd:INFO: running with effective user ID 1000
gpsd:INFO: startup at 2014-06-11T03:54:16.000Z (1402458856)
gpsd:INFO: /dev/rfcomm9 identified as type Generic NMEA (8.291276 sec @ 115200bps)
gpsd:WARN: can’t use GGA time until after ZDA or RMC has supplied a year.
Now, gpsd executing, all other applications using its services are available. My favourite in Ubuntu 14.04 is Marble, which is an excellent, lightweight and delightful navigation application as well, not just a Google Earth replacement (it is doing that well, too). In Settings -> Panels mark “Location”, if not yet done, and in the panel, select Position Tracking with gpsd. You can select also Gpsinfo plugin, first in Plugins tab of Settings -> Configure, then in View -> Info Boxes, which gives you some additional information.
Nice, Nokia LD-3W, cool Open Source community. Thanks !
Wednesday, August 5, 2015 at 14:33
Hi,
I am trying to follow the advice given, however after restarting the system I cannot get the GPS data on OpenCPN. I have to re-do the udev file (no changes required – just saved again) and connect the rfcomm9 manually. After that it workss, but not automatically after starting OpenCPN with the Nokia beneath the laptop and switched on.
Can anybody help?
Thanks,
Jan
Wednesday, August 5, 2015 at 17:27
Hello Jan,
if you are using Ubuntu LTS12.04 maybe you have not finalized the binding configuration steps (see “Let’s Make It Persistent” in the article). Another source of problem are the file permissions: once you work from command line, everything works (sudo or root, perhaps?). When you reboot, it is your user login who should have the permissions, /dev directory requires special privileges: for that, have you double checked that /etc/udev/rules.d/60-extra-acl.rules file contains your group name and not your user name (often they are the same, but better check) ? Think always: can I do this as ‘me’ and not with ‘sudo’ or ‘root’ , otherwise the automatic binding will not work.
OpenCPN has this specific requirement of having in /etc/group folder:
dialout:x:20:your_group
If you are using the Ubuntu LTS14.04 you should check comment #2 above, the behavior of Bluetooth serial devices is somewhat different. Using the rfcomm and gpsd utilities before using OpenCPN would allow you to test a bit further the connection after the boot.
I am using in my navigation a PC with Lubuntu LTS14.04, OpenCPN 4.0.0 with the above instructions and the Nokia GPS gets connected automatically after boot every time, very reliably (I use two connections, 1st priority of NMEA WiFi multiplexer which sends GPS+instrument data and Nokia GPS as backup with 2nd priority: when I switch off my navigation system, Nokia will take over as GPS source with no hands when in anchor or when just want to save some energy in long legs).
Best regards,
Canne
Wednesday, August 17, 2016 at 21:33
Update : Nokia GPS LD-3W Bluetooth on Ubuntu 16.04 LTS (Xenial Xerus) for OpenCPN 4.4.3-0 and gpsd / xgps on Samsung N150. Bluetooth dongle (CSR chipset):
Compared to the previous installation of 14.04 LTS (above) I found the following changes to be necessary:
1. Automatic binding of /dev/rfcomm9 (in my example) does not take place by some bug as intended. /etc/bluetooth/rfcomm.conf is ignored or at least its “bind yes” parameter is ignored. The automatic binding (necessary but only possible if you have set the pairing as defined above, or used bluetoothctl for that in advance) can take place in the good old /etc/rc.local : before “exit 0” write
/usr/bin/rfcomm bind /dev/rfcomm9 00:02:76:C7:82:38 1
where the 00:02:76:C7:82:38 is the address of my Nokia GPS LD-3W, of course.
Reboot your system with Nokia GPS turned on. You should see the Nokia GPS shortly to connect by LEDs blinking, then they go off. Type “ls -l /dev/rf*” (remember, being root, my instructions never refer to sudo(1) which is a brain damage in this type of operations). You should see /dev/rfcomm9 belonging to user root and group “dialout” (see above, why your own user account must be part of this group).
The second difference between the previous instructions and the Ubuntu 16.04 LTS installation is that udev has obviously changed and if you use the KERNEL argument, nothing happens. One can simplify the statement in /etc/udev/rules.d/60-extra-acl.rules to make the device available for your user group (see above):
SUBSYSTEM=”bluetooth”, NAME=”%k”, GROUP=”your_group”, TAG+=”uaccess”
Oh, if the gpsd launched in foreground does not work, then you cannot use gpsmon to check your installation (before moving to OpenCPN). Now, for this the reason can be that the gpsd is launched as system service. You do not want that:
systemctl stop gpsd
systemctl disable gpsd
systemctl status gpsd
then you can try: /usr/sbin/gpsd -N -D 2 -n /dev/rfcomm9
and gpsmon to read it.
That’s it. Long lifetime for my modest investment! (OK, I changed it to work on a SSD disk).