How to use Android phone as GPS sensor in Linux
Typically, desktop computers and laptops are sold without a GPS chip. This can be explained by the fact that the stationary device does not need to determine the coordinates. Nevertheless, there are several specialized applications for which GPS is needed, for example: compiling a list of Wi-Fi Access Points with their exact coordinates. Of course, you can buy an external GPS receiver, which will cost you literally a few dollars (start from three dollars with delivery). But there is an even more free option – use the GPS sensor of your Android phone.
In this article I will tell you how to transfer GPS data from a phone to Linux in real time and how to use the phone’s GPS to get the exact geographical coordinates, to draw up a travel route and in any other applications for working with GPS signals on Linux.
NMEA protocol and daemon for GPS receivers
Let's start with a small piece of equipment.
As follows from Wikipedia:
NMEA 0183 is a combined electrical and data specification for communication between marine electronics such as echo sounder, sonars, anemometer, gyrocompass, autopilot, GPS receivers and many other types of instruments. It has been defined by, and is controlled by, the National Marine Electronics Association. It replaces the earlier NMEA 0180 and NMEA 0182 standards.[1] In marine applications, it is slowly being phased out in favor of the newer NMEA 2000 standard.
In simple terms, NMEA is a way of transmitting coordinates and other related information in the form of specially organized data, being transmitted in plain text. Example NMEA lines:
$GPGGA,042554.000,1227.4487,N,09958.6233,E,1,24,0.4,-0.6,M,-25.8,M,,*55 $GPGLL,1227.4487,N,09958.6233,E,042554.000,A,A*5B $GPVTG,148.6,T,,M,0.0,N,0.0,K,A*06 $GPGSV,3,1,09,02,24,116,35,05,15,050,30,13,33,033,35,15,65,006,32*75 $GPGSV,3,2,09,20,16,295,35,21,21,328,32,24,37,155,40,25,10,213,38*7E $GPGSV,3,3,09,29,63,257,33*4E $GLGSV,2,1,05,66,14,021,27,67,42,330,28,81,78,124,14,82,43,340,28*69 $GLGSV,2,2,05,88,29,149,35*51 $BDGSV,4,1,13,201,42,103,29,203,74,126,30,204,21,097,37,206,68,014,26*63 $BDGSV,4,2,13,207,14,160,33,208,56,077,35,209,76,251,23,210,17,187,33*62 $BDGSV,4,3,13,213,61,021,31,214,18,265,32,216,74,359,29,221,41,358,26*69 $BDGSV,4,4,13,222,09,043,28*6C $GPGSA,A,3,15,29,24,13,02,21,20,05,25,,,,0.8,0.4,0.6*32 $GNGSA,A,3,66,67,82,88,,,,,,,,,0.8,0.4,0.6*2D $BDGSA,A,3,204,206,207,208,209,210,213,214,216,221,222,,0.8,0.4,0.6*1D $GPRMC,042554.000,A,1227.4487,N,09958.6233,E,0.0,148.6,301019,,,A*6D $PSAMCLK,2077,27517200,24,9693359,70115239,275172000*4F $GPGGA,042555.000,1227.4487,N,09958.6233,E,1,24,0.4,-0.6,M,-25.8,M,,*54 $GPGLL,1227.4487,N,09958.6233,E,042555.000,A,A*5A $GPVTG,148.6,T,,M,0.0,N,0.0,K,A*06 $GPGSV,3,1,09,02,24,116,35,05,15,050,30,13,33,033,35,15,65,006,32*75 $GPGSV,3,2,09,20,16,295,35,21,21,328,32,24,37,155,40,25,10,213,38*7E $GPGSV,3,3,09,29,63,257,33*4E $GLGSV,2,1,05,66,14,021,27,67,42,330,28,81,78,124,13,82,43,340,28*6E $GLGSV,2,2,05,88,29,149,35*51 $BDGSV,4,1,13,201,42,103,29,203,74,126,30,204,21,097,37,206,68,014,26*63 $BDGSV,4,2,13,207,14,160,33,208,56,077,35,209,76,251,23,210,17,187,33*62 $BDGSV,4,3,13,213,61,021,31,214,18,265,32,216,74,359,29,221,41,358,26*69 $BDGSV,4,4,13,222,09,043,28*6C $GPGSA,A,3,15,29,24,13,02,21,20,05,25,,,,0.8,0.4,0.6*32 $GNGSA,A,3,66,67,82,88,,,,,,,,,0.8,0.4,0.6*2D $BDGSA,A,3,204,206,207,208,209,210,213,214,216,221,222,,0.8,0.4,0.6*1D $GPRMC,042555.000,A,1227.4487,N,09958.6233,E,0.0,148.6,301019,,,A*6C $PSAMCLK,2077,27517300,24,9693366,70176767,275173000*48 $PSAMDLOK,88,0x00F,0x000*59 $PSAMDLOK,152,0x3FF,0x000*1A $PSAMDLOK,67,0x00F,0x000*58 $PSAMDLOK,160,0x3FF,0x000*1B $PSAMDLOK,82,0x00F,0x00F*25 $PSAMDLOK,66,0x000,0x00F*59 $PSAMDLOK,159,0x3F8,0x3FF*6C $GPGGA,042556.000,1227.4487,N,09958.6233,E,1,24,0.4,-0.6,M,-25.8,M,,*57 $GPGLL,1227.4487,N,09958.6233,E,042556.000,A,A*59 $GPVTG,148.6,T,,M,0.0,N,0.0,K,A*06 ........................................... ........................................... ........................................... ........................................... ...........................................
Using this protocol we will send GPS coordinates from a phone to a computer.
gpsd is interface daemon for GPS receivers. The fact is that GPS receivers output data in a very different formats: some of them support the NMEA protocol, and some use their own binary formats. If programs work directly with GPS receivers, then each of them would need to implement support for each device. To simplify this situation, gpsd is also used, this service listens for incoming data from GPS receivers, and it supports many formats and devices. The gpsd service automatically determines the format of incoming data, recognizes them and makes them available on the tcp://localhost:2947 socket (the port can be changed in the settings) for any programs in the operating system. That is, if you want the program to be able to receive a stream of GPS data, then it is enough to implement it to receive data from tcp://localhost:2947 and an understanding of the gpsd format, and after that the program will be able to work with most GPS receivers!
In my distribution, the following driver types are compiled into gpsd:
NMEA0183 Ashtech Delorme TripMate Pre-2003 Delorme EarthMate Furuno Electric GH-79L4 n Garmin NMEA c MTK-3301 OceanServer OS5000 San Jose Navigation FV18 b True North c Jackson Labs Fury * AIVDM n b c * EverMore n * Garmin Serial binary * Garmin USB binary n b * GeoStar b * GREIS * iTalk * Motorola Oncore b * Navcom NCT n b * SiRF * Skytraq n b * SuperStarII n b * Trimble TSIP iSync n b c * u-blox b * Zodiac * NMEA2000 * RTCM104V2 * RTCM104V3 * Garmin Simple Text * JSON slave driver PPS
Legents:
- n: mode switch
- b: speed switch
- c: rate switch
- *: non-NMEA packet type.
Features:
- Socket export enabled.
- Shared memory export enabled.
- DBUS export enabled
- Time service features enabled.
- PPS enabled.
As you can see, many devices transmit packet types other than NMEA. For some devices, additional functions for adjusting the switching of mode, speed and rate are implemented.
How can I transfer GPS data to a computer in real time?
There are different ways to transfer data from the phone to the computer:
- Bluetooth
- USB
- over the network (Wi-Fi, Internet)
The easiest way is over the network. Bluetooth and USB require additional configuration.
For transmission over the network, the phone must have an IP address accessible from the computer – in a Wi-Fi local area network, this is quite simple. If you are far from a Wi-Fi router, then you can use the phone itself as an Access Point – in this case it will also be accessible via IP from a laptop. Even if the phone is far from the computer, it can still transmit GPS data without a white IP – but this requires that both devices are connected to the same VPN.
Programs for transferring GPS from phone to computer
The following table is taken from here. I don’t know how relevant it is – it is quite possible that when I write it and even more so when you read it, new programs for this function appear – by the way, share them in the comments if you know other programs.
Name | Via | TCP port | License |
---|---|---|---|
ShareGPS | Bluetooth, USB | 50000 | Free |
BlueNMEA | Bluetooth, USB | 4352 | Free |
Solidsync Network/Bluetooth GPS | Bluetooth, Wifi | 25010 | 2.99 USD |
Symarctic ExtGPS | Bluetooth | Free | |
Bluetooth GPS Output | Bluetooth | 10 minute trial or 0.92 USD | |
GPS 2 Bluetooth v.4 | Bluetooth | Free, just a widget |
I will use the Share GPS program – just because it was the first on the list and everything worked out with it. Although it should be noted, the program is rather shareware: you can create only one connection for free, only one device can connect to this one connection, some advanced functions are available only in the premium version. But for our purposes there are plenty of free features.
How to find out the IP address of a phone
When sending GPS data, the phone can act as a server to which we connect, or it can be a client and connect to the service to transmit GPS stream to it. The first option, when the phone works as a server, is simpler. We only need to know the local IP address of the phone.
If your phone and computer are on the same local network, for example, are connected to the same router via Wi-Fi, or the phone is connected via Wi-Fi, and the laptop is connected by wire, then the local IP of the phone can be viewed by going to the Wi-Fi connection properties:
If you are away from the router, then you can use the phone as an Access Point – in this case:
- phone and laptop will be again in the same local network
- the laptop will be able to use the phone’s Internet connection (for example, to download maps)
In this case, the easiest way to know the IP address of the phone is to run the command on the laptop:
ip route show default
Output Example:
default via 192.168.43.1 dev wlo1 proto dhcp metric 20600
That is, the phone in this situation acts as a router, and by the previous command we looked at the IP address of this router, which turned out to be 192.168.43.1.
How to set up Share GPS
On the GPS STATUS tab, you can view the current status and GPS coordinates.
Go to CONNECTIONS and press the ADD button
Uncheck Setup by Activity
Click on Data Type
and select Standard NMEA format
Click OK.
Click on Connection Method and select Use TCP/IP to send NMEA GPS to PC. The IP addresses of the devices are known:
Enter any name for the connection:
Press the NEXT button.
Here you can change the port, which is set to 50000 by default. I am satisfied with the standard port, so I just click OK.
When everything is ready, click on the connection to activate it. If the connection has switched to Listening status, then your phone is ready to send GPS information. If the status is Idle, then the connection is not active (it is not used and does not listen on the port).
If you do not receive data from the program, then in the Share GPS settings, enable the “Create NMEA” option.
Checking incoming GPS data using NMEA
In fact, the phone will work as a simple web server that will send a data stream in plain text. Therefore, you can check the work, for example, with the curl command (specify the IP of your phone, and also specify the correct port if you changed the default port, or use another program):
curl 192.168.1.3:50000
The previous command failed:
curl: (1) Received HTTP/0.9 when not allowed
To fix this error, simply add the --http0.9 option to your command:
curl --http0.9 192.168.1.3:50000
If the data stream appears, then everything works.
On the phone, the status has changed to Connected.
How to run gpsd to get GPS from your phone
We stop the previous cURL command if you have not done so already, since in the free version the program allows only one connection.
Now you need to install gpsd.
In Debain, Kali Linux, Linux Mint, Ubuntu and their derivatives, the installation is done with the following command:
sudo apt install gpsd gpsd-clients
In Arch Linux, BlackArch and their derivatives, the installation is done like this:
sudo pacman -S gpsd
To start gpsd, use the command (in it, replace the IP address and port with your values):
gpsd -N tcp://192.168.1.3:50000
The -N option is needed so that the service does not go into the background (does not turn into a daemon). After debugging, when you make sure that everything works, the -N option can be omitted.
If something is wrong – the program immediately exits, or works, but other applications do not receive GPS information, then use the -D option, after which specify a number to increase debug level. For example, -D 1 for a brief output or -D 10 for a very detailed output:
gpsd -N -D 10 tcp://192.168.1.3:50000
How to check if gpsd works
Even after the successful launch of gpsd, visually nothing happens. To check if data is coming from gpsd, run the program:
gpsmon
This program will show coordinates, time, speed, status and other related information.
Map on Linux for GPS. Recording a motion track on Linux via GPS
As an application that accepts GPS coordinates and shows the location on the map, and also records the path of movement, I will use FoxtrotGPS – an easy and lightweight mapping application.
FoxtrotGPS is an easy-to-use free open source GPS/GIS application that works well on small screens and is especially suitable for touch input. FoxtrotGPS is freely available for public use, distribution and modification in accordance with the terms of the GNU General Public License 2.0 (GPLv2).
To install FoxtrotGPS on Debain, Kali Linux, Linux Mint, Ubuntu and their derivatives, run the command:
sudo apt install foxtrotgps
To install foxtrotgps on Arch Linux, BlackArch and their derivatives, run the following commands:
gpg --recv-keys 894EF3C0A2C08D8B git clone https://aur.archlinux.org/foxtrotgps.git cd foxtrotgps/ makepkg -si
Run the program:
foxtrotgps
If the gpsd service is running, the program will immediately show your location:
Program Menu:
1. Settings
2. Full screen mode (F11)
3. Zoom in map
4. Zoom out map
5. Auto center at your location
6. Next map repository (several free maps are supported at once!)
7. Previous map repository
8. Enable route recording
Configuring FoxtrotGPS
The first settings tab shows
- current speed
- average speed
- maximum speed
- path length
- track recording time
- GPS data (coordinates and time)
- number of visible satellites
On the next tab, you can enable or disable tracks logging. If you click the Split button, the recording will continue to a new file.
On the third settings tab, you can select a map, a system of units, connect a heart rate sensor, and change the address and port of the GPSD service if you want to use non-standard values.
The default map in FoxtrotGPS looks like this:
In FoxtrotGPS you can choose satellite view from Google:
One more option:
And one of the maps shows the need to use the API on watermarks:
GPS receiver simulation
Some programs, for example, Google Earth, for reasons known only to them, do not work with GPSD – they try to scan the system in search of a GPS receiver.
Examples of such devices:
- /dev/ttyS0 (serial device)
- /dev/ttyUSB0 (USB devices)
- /dev/gpsd0 (Generic GPS device 0)
You can simulate the operation of such devices using socat with commands of the form (IP, port numbers, as well as device numbers, change to your own):
sudo socat pty,link=/dev/ttyS0,raw tcp:192.168.1.3:50000 sudo socat pty,link=/dev/ttyUSB0,raw tcp:192.168.1.3:50000
In principle, it becomes possible to read data from such devices – I checked using the cat and bettercap programs.
sudo cat /dev/ttyUSB0
But Google Earth didn’t work for me.
If you saw some kind of error in my socat commands, or you were able to successfully work with such virtual devices in any programs, please write about this in the comments.
To make the /dev/ttyUSB0 device available to non-elevated users, run the following command:
sudo chown $USER /dev/pts/1
GPS in Bettercap
By default, Bettercap uses the device /dev/ttyUSB0 (can be changed in the settings). In order to pretend that GPS information comes from the device /dev/ttyUSB0, I run the following command:
sudo socat pty,link=/dev/ttyUSB0,raw tcp:192.168.1.3:50000
Then run Bettercap
sudo bettercap
Inside the Bettercap session, turn on the GPS module and display the current coordinates:
gps on; sleep 5; gps.show
On my system, this command successfully displayed information on the coordinates, quality and number of visible satellites.
latitude:12.457478 longitude:99.977055 quality:1 satellites:24 altitude:-0.600000
GPS in Kismet
Kismet has become known as a program for mapping wireless access points, including with their binding to GPS coordinates. Currently, the program is developing rapidly and supports many sources of radio signals, including:
- Wifi
- Bluetooth
- SDR
Kismet can work with various GPS sources, including directly with GPS receivers or receiving data over the network.
Supported GPS types:
- serial
- tcp
- gpsd
- web
- virtual
Example setup for receiving data from a serial device:
gps=serial:device=/dev/ttyACM0,reconnect=true,name=LaptopSerial
Example settings for receiving data directly from the network (you can connect to the phone instead of GPSD and get a stream of GPS coordinates):
gps=tcp:host=192.168.1.3,port=50000
Example settings for reading data from the GPSD service:
gps=gpsd:host=localhost,port=2947,reconnect=true
More information at: https://www.kismetwireless.net/docs/readme/gps/
GPS receivers for laptop
If you need an external GPS receiver for your laptop or computer, which you can connect via USB and get the current coordinates regardless of the phone, then you can choose any of the following devices, since the prices are low:
- BEITIAN BS-71U (supprots NMEA-0183)
- BEITIAN BS-70U (supprots NMEA-0183)
- BN-808 USB GPS Receiver (supprots NMEA-0183)
- BT-708 GPS Receiver (supprots NMEA-0183)
- BU353S4 (supprots NMEA-0183)
- VK-172
- VK-162
- gps usb receiver
Automatically launch GPSD service with options and on a specific device
If desired, you can configure the GPSD service in the /etc/default/gpsd file:
# Default settings for gpsd. START_DAEMON="true" GPSD_OPTIONS="" DEVICES="" USBAUTO="true"
Specify options as GPSD_OPTIONS value, and specify the desired device (it is possible to use tcp://* type), as DEVICES value.
To start in the background of the service:
sudo systemctl start gpsd.service
To enable gpsd to start automatically every time you boot your computer:
sudo systemctl enable gpsd.service
Related articles:
- How in Windows view the contents of a Linux disk and copy files from it (50.7%)
- How to brute-force passwords using GPU and CPU in Linux (50.7%)
- Linux kernel modules (50.7%)
- How to install NVIDIA drivers, CUDA and Bumblebee on Arch Linux / BlackArch (50%)
- How to unbrick HackRF. How to restore HackRF after failed device flashing (50%)
- Basics of working with a web server for a pentester (RANDOM - 5.4%)