@@ -0,0 +1,14 @@ | |||
image: alpine:latest | |||
pages: | |||
stage: deploy | |||
script: | |||
- apk update && apk add python xmlto asciidoc scons rsync | |||
- mkdir .pages; WEBSITE=.public scons website=.pages website; mv .public public | |||
- find public -type f -regex '.*\.\(htm\|html\|txt\|text\|js\|css\)$' -exec gzip -f -k {} \; | |||
- ls -lR public | |||
artifacts: | |||
paths: | |||
- public | |||
only: | |||
- master |
@@ -6,13 +6,13 @@ language: generic | |||
# context, we disable the C++ builds in the clang case. | |||
env: | |||
- TRAVIS_DEBIAN_DISTRIBUTION=unstable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev libdbus-glib-1-dev makedev libbluetooth-dev qtbase5-dev qt5-default lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd python-serial" | |||
- TRAVIS_DEBIAN_DISTRIBUTION=unstable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev libdbus-glib-1-dev makedev libbluetooth-dev libqt4-dev lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd python-serial" | |||
- TRAVIS_DEBIAN_DISTRIBUTION=unstable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh libgpsmm=no qt=no" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev libdbus-glib-1-dev makedev libbluetooth-dev libqt4-dev lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd clang python-serial" TRAVIS_DEBIAN_BUILD_ENVIRONMENT="CC=clang CXX=clang++" | |||
- TRAVIS_DEBIAN_DISTRIBUTION=stable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev libdbus-glib-1-dev makedev libbluetooth-dev libqt4-dev lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd python-serial" | |||
- TRAVIS_DEBIAN_DISTRIBUTION=unstable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev makedev libbluetooth-dev qtbase5-dev qt5-default lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd python-serial" | |||
- TRAVIS_DEBIAN_DISTRIBUTION=unstable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev makedev libbluetooth-dev libqt4-dev lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd python-serial" | |||
- TRAVIS_DEBIAN_DISTRIBUTION=unstable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh libgpsmm=no qt=no" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev makedev libbluetooth-dev libqt4-dev lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd clang python-serial" TRAVIS_DEBIAN_BUILD_ENVIRONMENT="CC=clang CXX=clang++" | |||
- TRAVIS_DEBIAN_DISTRIBUTION=stable TRAVIS_DEBIAN_BUILD_COMMAND="/bin/bash .travis/build.sh" TRAVIS_DEBIAN_BUILD_DEPENDENCIES="build-essential debhelper po-debconf python-all-dev python-all-dbg xsltproc docbook-xsl docbook-xml asciidoc libncurses-dev libusb-1.0-0-dev libdbus-1-dev libglib2.0-dev makedev libbluetooth-dev libqt4-dev lsb-release bc dpkg-dev scons chrpath dh-buildinfo pps-tools dh-systemd python-serial" | |||
services: | |||
- docker | |||
script: | |||
- wget -O- http://build-in-debian.bzed.at/script.sh | sh - | |||
- wget -O- https://build-in-debian.bzed.at/script.sh | sh - |
@@ -0,0 +1,243 @@ | |||
cc_binary { | |||
name: "gps_test", | |||
vendor: true, | |||
srcs: [ | |||
"android/gps_test.c" | |||
], | |||
shared_libs: [ | |||
"libutils", | |||
"liblog", | |||
"libcutils" | |||
], | |||
static_libs: [ | |||
"libgps_static" | |||
], | |||
cflags: [ | |||
"-Wno-unused-variable", | |||
"-Wno-unused-parameter", | |||
"-Wno-missing-field-initializers", | |||
] | |||
} | |||
cc_binary { | |||
name: "gpsd", | |||
vendor: true, | |||
required: ["gpsd_wrapper"], | |||
generated_headers: [ | |||
"gpsd_timebase_h", | |||
"gpsd_revision_h", | |||
"gpsd_config_h", | |||
"gpsd_packet_names_h" | |||
], | |||
srcs: [ | |||
"dbusexport.c", | |||
"gpsd.c", | |||
"shmexport.c", | |||
"timehint.c" | |||
], | |||
static_libs: [ | |||
"libgpsd", | |||
"libgps_static", | |||
], | |||
cflags: [ | |||
"-Wno-unused-variable", | |||
"-Wno-unused-parameter", | |||
"-Wno-missing-field-initializers", | |||
] | |||
} | |||
cc_binary { | |||
name: "gpsd_wrapper", | |||
vendor: true, | |||
init_rc: ["android/gpsd.rc"], | |||
srcs: ["android/gpsd_wrapper.c"], | |||
shared_libs: [ | |||
"liblog", | |||
"libcutils" | |||
] | |||
} | |||
cc_library_shared { | |||
name: "libgps", | |||
vendor: true, | |||
export_include_dirs: ["."], | |||
generated_headers: [ | |||
"gpsd_timebase_h", | |||
"gpsd_revision_h", | |||
"gpsd_config_h", | |||
"gpsd_packet_names_h" | |||
], | |||
generated_sources: ["gps_maskdump_c"], | |||
srcs: [ | |||
"bits.c", | |||
"gpsdclient.c", | |||
"gpsutils.c", | |||
"hex.c", | |||
"json.c", | |||
"libgps_core.c", | |||
"libgps_dbus.c", | |||
"libgps_json.c", | |||
"libgps_shm.c", | |||
"libgps_sock.c", | |||
"netlib.c", | |||
"os_compat.c", | |||
"rtcm2_json.c", | |||
"rtcm3_json.c", | |||
"shared_json.c" | |||
], | |||
cflags: [ | |||
"-Wno-unused-variable", | |||
"-Wno-unused-parameter", | |||
"-Wno-missing-field-initializers", | |||
], | |||
} | |||
cc_library_static { | |||
name: "libgps_static", | |||
vendor: true, | |||
export_include_dirs: ["."], | |||
generated_headers: [ | |||
"gpsd_timebase_h", | |||
"gpsd_revision_h", | |||
"gpsd_config_h", | |||
"gpsd_packet_names_h" | |||
], | |||
generated_sources: ["gps_maskdump_c"], | |||
srcs: [ | |||
"bits.c", | |||
"gpsdclient.c", | |||
"gpsutils.c", | |||
"hex.c", | |||
"json.c", | |||
"libgps_core.c", | |||
"libgps_dbus.c", | |||
"libgps_json.c", | |||
"libgps_shm.c", | |||
"libgps_sock.c", | |||
"netlib.c", | |||
"os_compat.c", | |||
"rtcm2_json.c", | |||
"rtcm3_json.c", | |||
"shared_json.c" | |||
], | |||
cflags: [ | |||
"-Wno-unused-variable", | |||
"-Wno-unused-parameter", | |||
"-Wno-missing-field-initializers", | |||
], | |||
} | |||
genrule { | |||
name: "gpsd_packet_names_h", | |||
cmd: "rm -f $(out); sed -e '/^ *\\([A-Z][A-Z0-9_]*\\)," + | |||
"/s// \"\\1\",/' < $(in) > $(out)", | |||
srcs: ["packet_states.h"], | |||
out: ["packet_names.h"] | |||
} | |||
genrule { | |||
name: "gpsd_config_h", | |||
cmd: "cat $(in)/android/gpsd_config.in > $(out);" + | |||
"grep \"^gpsd_version\" $(in)/SConstruct | " + | |||
"cut -d\\= -f2 | sed -e 's/^/#define VERSION/'" + | |||
">> $(out)", | |||
srcs: [""], | |||
out: ["gpsd_config.h"] | |||
} | |||
genrule { | |||
name: "gpsd_revision_h", | |||
cmd: "grep \"^gpsd_version\" $(in) | cut -d\\= -f2 " + | |||
"| sed -e 's/^/#define REVISION/' > $(out)", | |||
srcs: ["SConstruct"], | |||
out: ["revision.h"] | |||
} | |||
python_binary_host { | |||
name: "leapsecond", | |||
main: "leapsecond.py", | |||
srcs: ["leapsecond.py"], | |||
} | |||
genrule { | |||
name: "gpsd_timebase_h", | |||
tools: ["leapsecond"], | |||
cmd: "$(location leapsecond) -H $(in) > $(out)", | |||
srcs: ["leapseconds.cache"], | |||
out: ["timebase.h"] | |||
} | |||
python_binary_host { | |||
name: "maskaudit", | |||
main: "maskaudit.py", | |||
srcs: ["maskaudit.py"] | |||
} | |||
genrule { | |||
name: "gps_maskdump_c", | |||
tools: ["maskaudit"], | |||
cmd: "$(location maskaudit) -c $(in) > $(out)", | |||
out: ["gps_maskdump.c"], | |||
srcs: [""] | |||
} | |||
cc_library_static { | |||
name: "libgpsd", | |||
vendor: true, | |||
export_include_dirs: ["."], | |||
generated_headers: [ | |||
"gpsd_timebase_h", | |||
"gpsd_revision_h", | |||
"gpsd_config_h", | |||
"gpsd_packet_names_h" | |||
], | |||
srcs: [ | |||
"bsd_base64.c", | |||
"crc24q.c", | |||
"driver_ais.c", | |||
"driver_evermore.c", | |||
"driver_garmin.c", | |||
"driver_garmin_txt.c", | |||
"driver_geostar.c", | |||
"driver_greis.c", | |||
"driver_greis_checksum.c", | |||
"driver_italk.c", | |||
"driver_navcom.c", | |||
"driver_nmea0183.c", | |||
"driver_nmea2000.c", | |||
"driver_oncore.c", | |||
"driver_rtcm2.c", | |||
"driver_rtcm3.c", | |||
"drivers.c", | |||
"driver_sirf.c", | |||
"driver_skytraq.c", | |||
"driver_superstar2.c", | |||
"driver_tsip.c", | |||
"driver_ubx.c", | |||
"driver_zodiac.c", | |||
"geoid.c", | |||
"gpsd_json.c", | |||
"isgps.c", | |||
"libgpsd_core.c", | |||
"matrix.c", | |||
"net_dgpsip.c", | |||
"net_gnss_dispatch.c", | |||
"net_ntrip.c", | |||
"ntpshmread.c", | |||
"ntpshmwrite.c", | |||
"packet.c", | |||
"ppsthread.c", | |||
"pseudoais.c", | |||
"pseudonmea.c", | |||
"serial.c", | |||
"subframe.c", | |||
"timebase.c", | |||
"timespec_str.c" | |||
], | |||
cflags: [ | |||
"-Wno-unused-variable", | |||
"-Wno-unused-parameter", | |||
"-Wno-missing-field-initializers", | |||
"-Wno-uninitialized" | |||
], | |||
} |
@@ -1,4 +1,4 @@ | |||
COPYRIGHTS | |||
COPYRIGHTS | |||
Compilation copyright is held by the GPSD project. All rights reserved. | |||
@@ -8,28 +8,25 @@ Eric S. Raymond. Other portions of the GPSD code are Copyright (c) | |||
Copyright (c) 2005 by Eric S. Raymond. For other copyrights, see | |||
individual files. | |||
BSD LICENSE | |||
LICENSE | |||
(SPDX short identifier: BSD-2-Clause) | |||
Redistribution and use in source and binary forms, with or without | |||
modification, are permitted provided that the following conditions | |||
are met:<P> | |||
are met: | |||
Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer.<P> | |||
1. Redistributions of source code must retain the above copyright | |||
notice, this list of conditions and the following disclaimer. | |||
Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in the | |||
documentation and/or other materials provided with the distribution.<P> | |||
Neither name of the GPSD project nor the names of its contributors | |||
may be used to endorse or promote products derived from this software | |||
without specific prior written permission. | |||
2. Redistributions in binary form must reproduce the above copyright | |||
notice, this list of conditions and the following disclaimer in the | |||
documentation and/or other materials provided with the distribution. | |||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |||
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |||
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR | |||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER | |||
OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |||
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |||
@@ -96,7 +96,7 @@ various additional features have additional prerequisites: | |||
|Qt + qmake | libQgpsmm depends on this | |||
|python2.x(x>=6) or 3.y(y>=2) | required for various clients and utilities | |||
|python-GI bindings | the test clients xgps and xgpsspeed, need this | |||
|pyserial | ubxtool and zerk need this | |||
|pyserial | for ubxtool and zerk in direct-serial mode | |||
|=============================================================================== | |||
Some ncurses packages contain the terminfo library; some break it out | |||
@@ -183,16 +183,19 @@ GPSD Time Service HOWTO in the distribution or on the web. | |||
== Special Notes for OS X Installation == | |||
gpsd will build, install and run on OS X. The easiest way to do so is | |||
to first install the MacPorts package. Follow their install procedure | |||
at: http://www.macports.org/install.php | |||
gpsd will build, install and run on OS X (osX). The easiest way to | |||
do so is to first install the MacPorts package. Follow their install | |||
procedure at: http://www.macports.org/install.php | |||
Then use their port command to install scons, and optionally git if you | |||
want to access the development source. | |||
Then use their port command to install scons. Optionally git if you | |||
want to access the development source. Optionally install libxslt and | |||
xmlto to build the documentation. | |||
-------------------------------------------------------------- | |||
# port install scons | |||
# port install git | |||
# port install libxslt | |||
# port install xmlto | |||
-------------------------------------------------------------- | |||
While running gpsd, or scons check, you may run out of shared memory | |||
@@ -273,7 +276,7 @@ and testing gpsd: | |||
You need scons at 2.3.0 or higher to build. | |||
If your scons is less than 2.3.0 you will need to get a newer scons | |||
from wheezy-backport. Partial instructions are detailed here: | |||
http://backports.debian.org/Instructions/ | |||
https://backports.debian.org/Instructions/ | |||
Basically you need to add this line to /etc/apt/sources.list: | |||
@@ -399,12 +402,53 @@ fudge 127.127.28.2 refid PPS | |||
Now proceed as for any other operating system to use gpsd. | |||
Warning, the pps_gpio driver in all linux kernels up to the current | |||
3.19 only reports one edge. Be sure to validate that your PPS signal | |||
is not offset by the pulse width. | |||
Be sure to validate that your PPS signal is not offset by the pulse | |||
width. That would mean gpsd is using the wrong edge. | |||
Detailed instructions are available from their web site: | |||
https://learn.adafruit.com/adafruit-ultimate-gps-hat-for-raspberry-pi/ | |||
You will need to dig deeper to make the PPS work, here is a good reference: | |||
http://www.satsignal.eu/ntp/Raspberry-Pi-NTP.html | |||
== Special Notes for FreeBSD Installation == | |||
gpsd will build, install and run on FreeBSD. | |||
Use their pkg command to install scons, and optionally git if you | |||
want to access the development source. | |||
-------------------------------------------------------------- | |||
# pkg install scons | |||
# pkg install git | |||
# git clone ssh://git@gitlab.com/gpsd/gpsd.git | |||
# cd gpsd | |||
# scons --config=force && scons install | |||
-------------------------------------------------------------- | |||
== Special Notes for CentOS 7 Installation == | |||
gpsd currently will build, install and run on CentOS 7. | |||
Install the gcc compiler and tools. Install EPEL. | |||
Note: there is no EPEL for i386. | |||
Use the yum command to install git if you | |||
want to access the development source. | |||
-------------------------------------------------------------- | |||
# yum group install "Development Tools" | |||
# yum install git | |||
# yum install \ | |||
https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm | |||
# yum install scons | |||
# yum install python-devel | |||
# yum install ncurses-devel | |||
# yum install pps-tools-devel | |||
# git clone https://gitlab.com/gpsd/gpsd.git | |||
# cd gpsd | |||
# scons | |||
-------------------------------------------------------------- | |||
@@ -1,6 +1,20 @@ | |||
GPSD project news | |||
3.19: not released yet | |||
3.19: 2019-07-01 | |||
Rearrange rawdata_t. Bump the API because gps_data_t changed. | |||
Report sequence-ID fields in type 7 and 13 AIS messages. | |||
Preliminary support for SiRFstar V | |||
Improve error modeling. | |||
Update pseudo NMEA to v3.0, with fractional time. | |||
Improve cycle detection, mostly for NMEA. | |||
Move epe from gps_data_t to be near its friends in gps_fix_t. | |||
Preliminary u-blox 9 support. | |||
Add qErr in gps_data_t to store PPS quantization error. | |||
Add Android (AOSP) support | |||
Improved multi gnss and multi signal support. | |||
NMEA 4.10 multi gnss multi signal support. | |||
The arguments to "ubxtool -p P" have been expanded and changed. | |||
New options, -g, -x, -z, added to ubxtool for u-blox 9 support. | |||
3.18.1: 2018-10-19 (Gary E. Miller <gem@rellim.com>) | |||
Fix some installation issues. | |||
@@ -12,7 +12,7 @@ the "Upstream Bugs" page on the project website. | |||
Improve the uninstall target. Remove library syminks. | |||
Make libdir conform to new Gentoo layout: 32bit in lib/ and 64bit in | |||
Make libdir conform to new FHS layout: 32bit in lib/ and 64bit in | |||
lib64/. Doing that also makes the uninstall more complex. | |||
** Documentation ** | |||
@@ -27,16 +27,14 @@ the calibration process less annoying? | |||
** Things to do when we can break compatibility ** | |||
In gps_data_t add more string like subtype for HW version, SW version, etc. | |||
------------------------------------------------------------------------- | |||
In gps_data_t, save PPS precision; this will require creating a pps struct. | |||
Where would PPS precision come from? | |||
Convert all the time_t (double) and timeval (usec) to timespec (nsec). | |||
Convert all the timestamp_t (double) timespec (nsec). | |||
That could be done one small step at a time. | |||
Add MMSI sequence number fields to AIS type 7. | |||
Make the Python JSON client as smart as the C JSON client. Gonna be | |||
a big job. The C client checks all the JSON classes for completeness | |||
and correctness. For example, a missing JSON field will be replaced | |||
@@ -47,19 +45,12 @@ client uses a generic validator function, fed with templates for each | |||
JSON message. Initially harder than a simple procedural parser, Once | |||
running it is very robust and easy to tweak. | |||
Handle mutifrequency GNSS (B1, E1, L1, L2, B3, L3, L5, L2C, E5, E6, | |||
etc.) | |||
Handle raw measurements, like UBX-RXM-RAW. With an uploader for | |||
postprocessing. | |||
add u-blox IMU (UBX-ESF-RAW) and qErr (UBX-TIM-TP) support. | |||
Add u-blox IMU (UBX-ESF-RAW) support. Nothing we can do without | |||
samples or a u-blox IMU. | |||
Adding a sample Go client (gpspipe -> pytogo -> Go ?). | |||
Add RTCM3, RINEX, and/or RAW message forwarders. | |||
Move webgps.py out of contrib. It needs a man page and light cleanup. | |||
Move webgps.py out of contrib. It needs a man page and light cleanup. | |||
** Bugs in gpsd and its clients: | |||
@@ -115,10 +106,16 @@ message 6 and 8 subtypes - specifically, 6/23, 8/21, 8/22, 8/24, and | |||
** New features ** | |||
** Qt ** | |||
Add a sample client | |||
*** Time tracking | |||
Our goal is to be independent of the system clock. | |||
Create a CLI tool to convert UTC to GPS week/tow and back. | |||
**** Maybe apply wraparound compensation **** | |||
See <http://www.febo.com/pipermail/time-nuts/2013-August/079271.html> | |||
@@ -6,15 +6,16 @@ | |||
* Modifications : ilham@mit.edu (July 10 '90) | |||
* Cleaned up and simplified by Eric S. Raymond, December 2004. | |||
* | |||
* This file is Copyright (c) 2010 by the GPSD project | |||
* This file is Copyright (c) 2004-2018 by the GPSD project | |||
* SPDX-License-Identifier: BSD-2-clause | |||
*/ | |||
#include "gpsd_config.h" /* must be before all includes */ | |||
#include <X11/IntrinsicP.h> | |||
#include <X11/StringDefs.h> | |||
#include <TachometerP.h> | |||
#include <math.h> | |||
#include "gpsd_config.h" | |||
#include "gps.h" | |||
#define D2R 0.0174532925199432957692369076848861271 /* radians = pi/180 */ | |||
@@ -7,8 +7,12 @@ DESCRIPTION | |||
This module uses the generic JSON parser to get data from AIS | |||
representations to libgps structures. | |||
This file is Copyright (c)2010-2018 by the GPSD project | |||
SPDX-License-Identifier: BSD-2-clause | |||
***************************************************************************/ | |||
#include "gpsd_config.h" /* must be before all includes */ | |||
#include <stdio.h> | |||
#include <string.h> | |||
#include <stdbool.h> | |||
@@ -16,7 +20,6 @@ representations to libgps structures. | |||
#include <stddef.h> | |||
#include <time.h> | |||
#include "gpsd_config.h" | |||
#include "gps.h" | |||
#include "json.h" | |||
#ifdef SOCKET_EXPORT_ENABLE | |||
@@ -411,6 +411,14 @@ | |||
.dflt.uinteger = 0}, | |||
{"mmsi4", t_uinteger, .addr.uinteger = &ais->type7.mmsi4, | |||
.dflt.uinteger = 0}, | |||
{"seqno1", t_uinteger, .addr.uinteger = &ais->type7.seqno1, | |||
.dflt.uinteger = 0}, | |||
{"seqno2", t_uinteger, .addr.uinteger = &ais->type7.seqno2, | |||
.dflt.uinteger = 0}, | |||
{"seqno3", t_uinteger, .addr.uinteger = &ais->type7.seqno3, | |||
.dflt.uinteger = 0}, | |||
{"seqno4", t_uinteger, .addr.uinteger = &ais->type7.seqno4, | |||
.dflt.uinteger = 0}, | |||
{NULL} | |||
}; | |||
@@ -0,0 +1,157 @@ | |||
GPSd on Android/AOSP: | |||
--------------------- | |||
The files in this path, as well as the Android.bp in the path below, | |||
are used for building the GPSd client as a platform library for AOSP. | |||
Five components are currently implemented; | |||
gpsd executable, | |||
Shared library, libgps (builds libgps.so) | |||
Static library, libgps_static | |||
Test client, gps_test (builds executable gps_test) | |||
Android GNSS 1.1 HAL, (builds android.hardware.gnss@1.1-service.gpsd) | |||
Build instructions: | |||
------------------- | |||
1) clone gpsd into your Android build tree at; | |||
platform/external/gpsd | |||
2) initialize your build environment for your target device; | |||
cd platform/ | |||
. build/envsetup.sh | |||
lunch | |||
3) build the component; | |||
m libgps | |||
or | |||
m gps_test | |||
This will build the component and output it at; | |||
platform/out/target/product/<device name>/vendor/ | |||
As a platform dependency: | |||
------------------------- | |||
You can add the components to your device's dependency list by adding | |||
it to the PRODUCT_PACKAGES variable in one of your device's makefiles. | |||
For example; | |||
PRODUCT_PACKAGES += libgps gps_test | |||
Following this, performing a full build for your device will | |||
incorporate the component(s) into the vendor partition image for | |||
your device. | |||
Note that for the HAL, you also have to include some additional | |||
components; | |||
PRODUCT_PACKAGES += android.hardware.gnss@1.1 \ | |||
android.hardware.gnss@1.1-impl \ | |||
android.hardware.gnss@1.1-service.gpsd | |||
Running gps_test: | |||
----------------- | |||
gps_test is an extremely simple test client that continually prints | |||
fix and SV details to the console. | |||
It accepts one parameter, which is the IP address or hostname of | |||
a running instance of GPSd. | |||
Building other components using libgps: | |||
--------------------------------------- | |||
gps_test is a good starting point for building other components using | |||
libgps. libgps can be added either as a shared object or static | |||
linked. For use as a shared object, add "libgps" to the list of | |||
shared_libs that your module depends on. For static, use | |||
"libgps_static" in the list of static_libs. | |||
GPSd: | |||
----- | |||
The only configuration needed for GPSd is to set a system property | |||
with the launch parameters to use. This should be appended to the | |||
PRODUCT_PROPERTY_OVERRIDES variable in an appropriate device specific | |||
makefile. This is a comma-separated list of parameters. | |||
For example (note that this is the default if unspecified); | |||
PRODUCT_PROPERTY_OVERRIDES += \ | |||
service.gpsd.parameters=-Nn,-D2,/dev/ttyACM0,/dev/ttyACM1 | |||
GNSS 1.1 HAL for Android: | |||
------------------------- | |||
This is the part that wraps everything together on Android. It makes | |||
it possible for location services on Android to be fed location data | |||
by gpsd. | |||
The HAL is able to operate with or without gpsd running on the same | |||
device. By default, the HAL will look to localhost:2947 for gpsd, | |||
however, it is possible to change both the host and port by setting | |||
the system properties "service.gpsd.host" and "service.gpsd.port" | |||
to reflect the hostname or ip address of the gpsd host, and the | |||
port number it is listening on. | |||
The HAL also has a special automotive mode that can be activated | |||
by setting the system property "service.gpsd.automotive" to any | |||
value. When the automotive mode is activated, the HAL will feed | |||
the location services with the last known fix coordinates until | |||
the first valid fix has been received. If the fix is later lost, | |||
it will correctly NOT continue to feed a fix. The updated fix will | |||
be stored in persistent system properties every 30 seconds while | |||
there is a valid fix. | |||
The purpose of automotive mode is to make it possible to immediately | |||
input a destination into navigation software without having to wait | |||
for a valid fix. A valid fix can take minutes to establish, even with | |||
a clear view of the sky, but worse, a fix can even be impossible if | |||
the vehicle is parked underground or in any structure that | |||
effectively blocks the signals. The consequence is that without | |||
automotive mode, it would be necessary to drive the vehicle from | |||
its current location to somewhere with a clear view of the sky, | |||
and then wait potentially several minutes for a valid fix before | |||
being able to enter a destination. With automotive mode, it is | |||
possible to immediately enter a destination, and begin driving. | |||
Once a fix has been established, the navigation software will | |||
update to the current location on the route. | |||
Note that in addition to including the components, it is also | |||
necessary to make adjustments to the device's selinux policy in | |||
order for the HAL to properly interact with the network. A typical | |||
policy file will be provided. | |||
VERY IMPORTANT: SEPOLICY! | |||
------------------------- | |||
In the old days prior to Android 8, it was possible to achieve full | |||
system functionality by simply disabling selinux enforcement. This | |||
is no longer enough with Android 8+, since the init process does | |||
its own selinux checks before it will even attempt to launch a daemon. | |||
And not only this, but it is also very important to enforce a certain | |||
degree of security. As such, appropriate policy for the GPSd process | |||
and the GNSS HAL are included, however, it is necessary for it to be | |||
included in the device configuration. | |||
Add the following to an appropriate device specific makefile; | |||
BOARD_SEPOLICY_DIRS += external/gpsd/android/sepolicy | |||
Putting it all together: | |||
------------------------ | |||
Adding the following to your device's makefile will build and install | |||
GPSd and its GNSS HAL: | |||
PRODUCT_PACKAGES += android.hardware.gnss@1.1 \ | |||
android.hardware.gnss@1.1-impl \ | |||
android.hardware.gnss@1.1-service.gpsd \ | |||
gpsd | |||
PRODUCT_PROPERTY_OVERRIDES += \ | |||
service.gpsd.parameters=-Nn,-G,/dev/ttyACM0 | |||
BOARD_SEPOLICY_DIRS += external/gpsd/android/sepolicy | |||
Contact: Adam Serbinski <aserbinski@gmail.com> |
@@ -0,0 +1,104 @@ | |||
/* | |||
* This file is Copyright (c) 2019 by the GPSD project | |||
* SPDX-License-Identifier: BSD-2-clause | |||
*/ | |||
#include <stdlib.h> | |||
#include <time.h> | |||
#include <stdio.h> | |||
#include <unistd.h> | |||
#include <errno.h> | |||
#include <string.h> | |||
#include "gps.h" | |||
int main (int argc, char **argv) { | |||
struct gps_data_t gps_data; | |||
int gpsopen = -2; | |||
/* debug | |||
* FILE *fp = fopen("/data/bin/gpslog", "a+"); | |||
* gps_enable_debug(3, fp); | |||
*/ | |||
printf("Usage: gpsdtest [host]\n\n"); | |||
memset(&gps_data, 0, sizeof(gps_data)); | |||
while (1) { | |||
if (gpsopen < 0) { | |||
gpsopen = gps_open((argc == 1 ? "localhost" : argv[1]), | |||
"2947", &gps_data); | |||
if (0 == gpsopen) { | |||
printf("gps_open returned 0 (success)\n"); | |||
gps_stream(&gps_data, WATCH_ENABLE, NULL); | |||
} else { | |||
printf("gps_open failed, returned: %d\n", gpsopen); | |||
gpsopen = -1; | |||
sleep(5); | |||
continue; | |||
} | |||
} | |||
if (gps_waiting (&gps_data, 2000000)) { | |||
errno = 0; | |||
if (gps_read (&gps_data, NULL, 0) != -1) { | |||
if (gps_data.status >= 1 && gps_data.fix.mode >= 2){ | |||
printf("\nHave a fix: "); | |||
if (gps_data.fix.mode == 2) | |||
printf("2D\n"); | |||
else | |||
printf("3D\n"); | |||
printf("Latitude: %f\n", gps_data.fix.latitude); | |||
printf("Longitude: %f\n", gps_data.fix.longitude); | |||
printf("Speed: %f\n", gps_data.fix.speed); | |||
printf("Bearing: %f\n", gps_data.fix.track); | |||
printf("H Accuracy: %f\n", gps_data.fix.eph); | |||
printf("S Accuracy: %f\n", gps_data.fix.eps); | |||
printf("B Accuracy: %f\n", gps_data.fix.epd); | |||
printf("Time: %ld\n", (long) gps_data.fix.time); | |||
printf("Altitude: %f\n", gps_data.fix.altitude); | |||
printf("V Accuracy: %f\n\n", gps_data.fix.epv); | |||
} | |||
printf("Satellites visible: %d\n", | |||
gps_data.satellites_visible); | |||
for (int i = 0; i < gps_data.satellites_visible; i++) { | |||
printf("SV type: "); | |||
switch (gps_data.skyview[i].gnssid) { | |||
case 0: | |||
printf("GPS, "); | |||
break; | |||
case 1: | |||
printf("SBAS, "); | |||
break; | |||
case 2: | |||
printf("Galileo, "); | |||
break; | |||
case 3: | |||
printf("Beidou, "); | |||
break; | |||
case 4: | |||
printf("Unknown, "); | |||
break; | |||
case 5: | |||
printf("QZSS, "); | |||
break; | |||
case 6: | |||
printf("Glonass, "); | |||
break; | |||
} | |||
printf("SVID: %d, SNR: %d, Elevation: %d, " | |||
"Azimuth: %d, Used: %d\n", | |||
gps_data.skyview[i].svid, | |||
(int)gps_data.skyview[i].ss, | |||
gps_data.skyview[i].elevation, | |||
gps_data.skyview[i].azimuth, | |||
gps_data.skyview[i].used); | |||
} | |||
} | |||
} | |||
} | |||
} |
@@ -0,0 +1,5 @@ | |||
service gpsd /vendor/bin/gpsd_wrapper | |||
class main | |||
user root | |||
group root | |||
oneshot |
@@ -0,0 +1,81 @@ | |||
/* | |||
* The Android build system is unable to make use of scons, | |||
* therefore this configuration file has to be prepopulated. | |||
* | |||
* This file is Copyright (c) 2019 by the GPSD project | |||
* SPDX-License-Identifier: BSD-2-clause | |||
*/ | |||
#define GPSD_URL "https://gpsd.gitlab.io/gpsd" | |||
#define HAVE_LIBRT 1 | |||
#define HAVE_LINUX_CAN_H 1 | |||
#define HAVE_STDATOMIC_H 1 | |||
#define HAVE_BUILTIN_ENDIANNESS 1 | |||
#define HAVE_SYS_SOCKET_H 1 | |||
#define HAVE_SYS_SELECT_H 1 | |||
#define HAVE_NETDB_H 1 | |||
#define HAVE_NETINET_IN_H 1 | |||
#define HAVE_NETINET_IP_H 1 | |||
#define HAVE_ARPA_INET_H 1 | |||
#define HAVE_SYSLOG_H 1 | |||
#define HAVE_TERMIOS_H 1 | |||
#define HAVE_DAEMON 1 | |||
#define HAVE_CLOCK_GETTIME 1 | |||
#define HAVE_STRPTIME 1 | |||
#define HAVE_GMTIME_R 1 | |||
#define HAVE_INET_NTOP 1 | |||
#define HAVE_FCNTL 1 | |||
#define HAVE_FORK 1 | |||
#define ASHTECH_ENABLE 1 | |||
#define CLIENTDEBUG_ENABLE 1 | |||
#define CONTROL_SOCKET_ENABLE 1 | |||
#define CONTROLSEND_ENABLE 1 | |||
#define EARTHMATE_ENABLE 1 | |||
#define EVERMORE_ENABLE 1 | |||
#define FURY_ENABLE 1 | |||
#define FV18_ENABLE 1 | |||
#define GARMIN_ENABLE 1 | |||
#define GARMINTXT_ENABLE 1 | |||
#define GEOSTAR_ENABLE 1 | |||
#define GPSCLOCK_ENABLE 1 | |||
#define GPSD_ENABLE 1 | |||
#define GPSD_USER "nobody" | |||
#define GPSDCLIENTS_ENABLE 1 | |||
#define GREIS_ENABLE 1 | |||
#define IMPLICIT_LINK_ENABLE 1 | |||
#define IPV6_ENABLE 1 | |||
#define ISYNC_ENABLE 1 | |||
#define ITRAX_ENABLE 1 | |||
#define LEAPFETCH_ENABLE 1 | |||
#define LIBGPSMM_ENABLE 1 | |||
#define MAX_CLIENTS 64 | |||
#define MAX_DEVICES 4 | |||
#define MTK3301_ENABLE 1 | |||
#define NAVCOM_ENABLE 1 | |||
#define NETFEED_ENABLE 1 | |||
#define NMEA0183_ENABLE 1 | |||
#define NTP_ENABLE 1 | |||
#define NTPSHM_ENABLE 1 | |||
#define NTRIP_ENABLE 1 | |||
#define OCEANSERVER_ENABLE 1 | |||
#define ONCORE_ENABLE 1 | |||
#define OSCILLATOR_ENABLE 1 | |||
#define PASSTHROUGH_ENABLE 1 | |||
#define PPS_ENABLE 1 | |||
#define QT_ENABLE 1 | |||
#define RECONFIGURE_ENABLE 1 | |||
#define RTCM104V2_ENABLE 1 | |||
#define RTCM104V3_ENABLE 1 | |||
#define SHARED_ENABLE 1 | |||
#define SHM_EXPORT_ENABLE 1 | |||
#define SIRF_ENABLE 1 | |||
#define SKYTRAQ_ENABLE 1 | |||
#define SOCKET_EXPORT_ENABLE 1 | |||
#define SUPERSTAR2_ENABLE 1 | |||
#define SYSCONFDIR "vendor/etc" | |||
#define TNT_ENABLE 1 | |||
#define TRIPMATE_ENABLE 1 | |||
#define TSIP_ENABLE 1 | |||
#define UBLOX_ENABLE 1 | |||
#define UDEVDIR "/lib/udev" | |||
#define USB_ENABLE 1 |
@@ -0,0 +1,24 @@ | |||
#include <stdio.h> | |||
#include <stdlib.h> | |||
#include <android/log.h> | |||
#include <cutils/properties.h> | |||
#include <sys/system_properties.h> | |||
int main (){ | |||
char gpsd_params[PROP_VALUE_MAX]; | |||
char cmd[1024]; | |||
int i = 0; | |||
property_get("service.gpsd.parameters", gpsd_params, "-Nn,-D2,/dev/ttyACM0,/dev/ttyACM1"); | |||
while (gpsd_params[i] != 0){ | |||
if (gpsd_params[i] == ',') gpsd_params[i] = ' '; | |||
i++; | |||
} | |||
sprintf(cmd, "/vendor/bin/logwrapper /vendor/bin/gpsd %s", gpsd_params); | |||
__android_log_print(ANDROID_LOG_DEBUG, "gpsd_wrapper", "Starting gpsd: %s", cmd); | |||
system(cmd); | |||
return 0; | |||
} | |||
@@ -0,0 +1,29 @@ | |||
cc_binary { | |||
name: "android.hardware.gnss@1.1-service.gpsd", | |||
overrides: ["android.hardware.gnss@1.0-impl"], | |||
vintf_fragments: ["android.hardware.gnss@1.1-service.gpsd.xml"], | |||
init_rc: ["android.hardware.gnss@1.1-service.gpsd.rc"], | |||
relative_install_path: "hw", | |||
vendor: true, | |||
srcs: [ | |||
"Gnss.cpp", | |||
"GnssConfiguration.cpp", | |||
"GnssMeasurement.cpp", | |||
"service.cpp", | |||
], | |||
shared_libs: [ | |||
"libhidlbase", | |||
"libhidltransport", | |||
"libutils", | |||
"liblog", | |||
"libcutils", | |||
"android.hardware.gnss@1.1", | |||
"android.hardware.gnss@1.0", | |||
], | |||
static_libs: [ | |||
"libgps_static" | |||
], | |||
cflags: [ | |||
"-Wno-register" | |||
] | |||
} |
@@ -0,0 +1,389 @@ | |||
#define LOG_TAG "GPSd_HAL" | |||
#include <android/hardware/gnss/1.0/types.h> | |||
#include <log/log.h> | |||
#include <cutils/properties.h> | |||
#include <stdlib.h> | |||
#include <time.h> | |||
#include "Gnss.h" | |||
#include "GnssMeasurement.h" | |||
namespace android { | |||
namespace hardware { | |||
namespace gnss { | |||
namespace V1_1 { | |||
namespace implementation { | |||
using GnssSvFlags = IGnssCallback::GnssSvFlags; | |||
const uint32_t MIN_INTERVAL_MILLIS = 100; | |||
sp<::android::hardware::gnss::V1_1::IGnssCallback> Gnss::sGnssCallback = nullptr; | |||
Gnss::Gnss() : mMinIntervalMs(1000), mGnssConfiguration{new GnssConfiguration()} {} | |||
Gnss::~Gnss() { | |||
stop(); | |||
} | |||
// Methods from ::android::hardware::gnss::V1_0::IGnss follow. | |||
Return<bool> Gnss::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssCallback>&) { | |||
// Mock handles only new callback (see setCallback1_1) coming from Android P+ | |||
return false; | |||
} | |||
Return<bool> Gnss::start() { | |||
if (mIsActive) { | |||
ALOGW("Gnss has started. Restarting..."); | |||
stop(); | |||
} | |||
mIsActive = true; | |||
mThread = std::thread([this]() { | |||
struct gps_data_t gps_data; | |||
int gpsopen = -1; | |||
char gpsdhost[PROP_VALUE_MAX]; | |||
char gpsdport[PROP_VALUE_MAX]; | |||
char gpsdauto[PROP_VALUE_MAX]; | |||
int is_automotive; | |||
char gpslat[PROP_VALUE_MAX]; | |||
char gpslon[PROP_VALUE_MAX]; | |||
long last_recorded_fix = 0; | |||
char dtos[100]; | |||
GnssLocation location; | |||
// Normally, GPSd will be running on localhost, but we can set a system property | |||
// "service.gpsd.host" to some other hostname in order to open a GPSd instance | |||
// running on a different host. | |||
property_get("service.gpsd.host", gpsdhost, "localhost"); | |||
property_get("service.gpsd.port", gpsdport, "2947"); | |||
is_automotive = (property_get("service.gpsd.automotive", gpsdauto, "") > 0); | |||
// Load coordinates stored in persist properties as current location | |||
// This is to provide instantaneous fix to the last good location | |||
// in order to provide instantaneous ability to begin navigator routing. | |||
if (is_automotive && property_get("persist.service.gpsd.latitude", gpslat, "") > 0 | |||
&& property_get("persist.service.gpsd.longitude", gpslon, "") > 0){ | |||
location = { | |||
.gnssLocationFlags = 0xDD, | |||
.latitudeDegrees = atof(gpslat), | |||
.longitudeDegrees = atof(gpslon), | |||
.speedMetersPerSec = 0.0, | |||
.bearingDegrees = 0.0, | |||
.horizontalAccuracyMeters = 0.0, | |||
.speedAccuracyMetersPerSecond = 0.0, | |||
.bearingAccuracyDegrees = 0.0, | |||
.timestamp = (long) time(NULL) | |||
}; | |||
this->reportLocation(location); | |||
} | |||
memset(&gps_data, 0, sizeof(gps_data)); | |||
while (mIsActive == true) { | |||
// If the connection to GPSd is not open, try to open it. | |||
// If the attempt to open it fails, sleep 5 seconds and try again. | |||
// Note the continue; statement that will skip the reading in the | |||
// event that the connection to GPSd cannot be established. | |||
if (gpsopen != 0){ | |||
ALOGD("%s: gpsd_host: %s, gpsd_port: %s", __func__, gpsdhost, gpsdport); | |||
if ((gpsopen = gps_open(gpsdhost, gpsdport, &gps_data)) == 0){ | |||
ALOGD("%s: gps_open SUCCESS", __func__); | |||
gps_stream(&gps_data, WATCH_ENABLE, NULL); | |||
} else { | |||
ALOGD("%s: gps_open FAIL (%d). Trying again in 5 seconds.", __func__, gpsopen); | |||
sleep(5); | |||
continue; | |||
} | |||
} | |||
// Wait for data from gpsd, then process it. | |||
if (gps_waiting (&gps_data, 2000000)) { | |||
errno = 0; | |||
if (gps_read (&gps_data, NULL, 0) != -1) { | |||
if (gps_data.status >= 1 && gps_data.fix.mode >= 2){ | |||
// Every 30 seconds, store current coordinates to persist property. | |||
if (is_automotive && ((long) gps_data.fix.time) > last_recorded_fix + 30){ | |||
last_recorded_fix = (long) gps_data.fix.time; | |||
sprintf(dtos, "%lf", gps_data.fix.latitude); | |||
property_set("persist.service.gpsd.latitude", dtos); | |||
sprintf(dtos, "%lf", gps_data.fix.longitude); | |||
property_set("persist.service.gpsd.longitude", dtos); | |||
} | |||
unsigned short flags = | |||
V1_0::GnssLocationFlags::HAS_LAT_LONG | | |||
V1_0::GnssLocationFlags::HAS_SPEED | | |||
V1_0::GnssLocationFlags::HAS_BEARING | | |||
V1_0::GnssLocationFlags::HAS_HORIZONTAL_ACCURACY | | |||
V1_0::GnssLocationFlags::HAS_SPEED_ACCURACY | | |||
V1_0::GnssLocationFlags::HAS_BEARING_ACCURACY; | |||
location = { | |||
.latitudeDegrees = (double) gps_data.fix.latitude, | |||
.longitudeDegrees = (double) gps_data.fix.longitude, | |||
.speedMetersPerSec = (float) gps_data.fix.speed, | |||
.bearingDegrees = (float) gps_data.fix.track, | |||
.horizontalAccuracyMeters = (float) gps_data.fix.eph, | |||
.speedAccuracyMetersPerSecond = (float) gps_data.fix.eps, | |||
.bearingAccuracyDegrees = (float) gps_data.fix.epd, | |||
.timestamp = (long) gps_data.fix.time | |||
}; | |||
if (gps_data.fix.mode == 3){ | |||
flags |= V1_0::GnssLocationFlags::HAS_ALTITUDE | | |||
V1_0::GnssLocationFlags::HAS_VERTICAL_ACCURACY; | |||
location.altitudeMeters = gps_data.fix.altitude; | |||
location.verticalAccuracyMeters = gps_data.fix.epv; | |||
} | |||
location.gnssLocationFlags = flags; | |||
this->reportLocation(location); | |||
} else if (is_automotive && last_recorded_fix == 0){ | |||
location.timestamp = (long) time(NULL); | |||
this->reportLocation(location); | |||
} | |||
GnssSvStatus svStatus = {.numSvs = (uint32_t) gps_data.satellites_visible}; | |||
for (int i = 0; i < gps_data.satellites_visible; i++){ | |||
GnssConstellationType constellation_type = GnssConstellationType::UNKNOWN; | |||
switch (gps_data.skyview[i].gnssid){ | |||
case 0: | |||
constellation_type = GnssConstellationType::GPS; | |||
break; | |||
case 1: | |||
constellation_type = GnssConstellationType::SBAS; | |||
break; | |||
case 2: | |||
constellation_type = GnssConstellationType::GALILEO; | |||
break; | |||
case 3: | |||
constellation_type = GnssConstellationType::BEIDOU; | |||
break; | |||
case 4: | |||
constellation_type = GnssConstellationType::UNKNOWN; | |||
break; | |||
case 5: | |||
constellation_type = GnssConstellationType::QZSS; | |||
break; | |||
case 6: | |||
constellation_type = GnssConstellationType::GLONASS; | |||
break; | |||
} | |||
svStatus.gnssSvList[i] = getSvInfo( | |||
gps_data.skyview[i].svid, | |||
constellation_type, | |||
gps_data.skyview[i].ss, | |||
gps_data.skyview[i].elevation, | |||
gps_data.skyview[i].azimuth, | |||
gps_data.skyview[i].used | |||
); | |||
svStatus.gnssSvList[i].svFlag = 0; | |||
if (gps_data.skyview[i].used == 1) svStatus.gnssSvList[i].svFlag |= GnssSvFlags::USED_IN_FIX; | |||
if (gps_data.skyview[i].elevation > -91 && gps_data.skyview[i].azimuth > -1){ | |||
svStatus.gnssSvList[i].svFlag |= GnssSvFlags::HAS_ALMANAC_DATA; | |||
if (gps_data.skyview[i].ss > 0) | |||
svStatus.gnssSvList[i].svFlag |= GnssSvFlags::HAS_EPHEMERIS_DATA; | |||
} | |||
} | |||
this->reportSvStatus(svStatus); | |||
} | |||
} | |||
} | |||
// Close the GPS | |||
gps_stream(&gps_data, WATCH_DISABLE, NULL); | |||
gps_close (&gps_data); | |||
}); | |||
return true; | |||
} | |||
Return<bool> Gnss::stop() { | |||
mIsActive = false; | |||
if (mThread.joinable()) { | |||
mThread.join(); | |||
} | |||
return true; | |||
} | |||
Return<void> Gnss::cleanup() { | |||
// TODO implement | |||
return Void(); | |||
} | |||
Return<bool> Gnss::injectTime(int64_t, int64_t, int32_t) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<bool> Gnss::injectLocation(double, double, float) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<void> Gnss::deleteAidingData(::android::hardware::gnss::V1_0::IGnss::GnssAidingData) { | |||
return Void(); | |||
} | |||
Return<bool> Gnss::setPositionMode(::android::hardware::gnss::V1_0::IGnss::GnssPositionMode, | |||
::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence, | |||
uint32_t, uint32_t, uint32_t) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IAGnssRil>> Gnss::getExtensionAGnssRil() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IAGnssRil>{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssGeofencing>> Gnss::getExtensionGnssGeofencing() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IGnssGeofencing>{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IAGnss>> Gnss::getExtensionAGnss() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IAGnss>{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssNi>> Gnss::getExtensionGnssNi() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IGnssNi>{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssMeasurement>> Gnss::getExtensionGnssMeasurement() { | |||
// TODO implement | |||
return new GnssMeasurement(); | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>> | |||
Gnss::getExtensionGnssNavigationMessage() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssXtra>> Gnss::getExtensionXtra() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IGnssXtra>{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssConfiguration>> | |||
Gnss::getExtensionGnssConfiguration() { | |||
// TODO implement | |||
return new GnssConfiguration(); | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> Gnss::getExtensionGnssDebug() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IGnssDebug>{}; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> Gnss::getExtensionGnssBatching() { | |||
// TODO implement | |||
return ::android::sp<::android::hardware::gnss::V1_0::IGnssBatching>{}; | |||
} | |||
// Methods from ::android::hardware::gnss::V1_1::IGnss follow. | |||
Return<bool> Gnss::setCallback_1_1( | |||
const sp<::android::hardware::gnss::V1_1::IGnssCallback>& callback) { | |||
if (callback == nullptr) { | |||
ALOGE("%s: Null callback ignored", __func__); | |||
return false; | |||
} | |||
sGnssCallback = callback; | |||
uint32_t capabilities = 0x0; | |||
auto ret = sGnssCallback->gnssSetCapabilitesCb(capabilities); | |||
if (!ret.isOk()) { | |||
ALOGE("%s: Unable to invoke callback", __func__); | |||
} | |||
IGnssCallback::GnssSystemInfo gnssInfo = {.yearOfHw = 2018}; | |||
ret = sGnssCallback->gnssSetSystemInfoCb(gnssInfo); | |||
if (!ret.isOk()) { | |||
ALOGE("%s: Unable to invoke callback", __func__); | |||
} | |||
auto gnssName = "GPSd GNSS Implementation v1.1"; | |||
ret = sGnssCallback->gnssNameCb(gnssName); | |||
if (!ret.isOk()) { | |||
ALOGE("%s: Unable to invoke callback", __func__); | |||
} | |||
return true; | |||
} | |||
Return<bool> Gnss::setPositionMode_1_1( | |||
::android::hardware::gnss::V1_0::IGnss::GnssPositionMode, | |||
::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence, uint32_t minIntervalMs, | |||
uint32_t, uint32_t, bool) { | |||
mMinIntervalMs = (minIntervalMs < MIN_INTERVAL_MILLIS) ? MIN_INTERVAL_MILLIS : minIntervalMs; | |||
return true; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>> | |||
Gnss::getExtensionGnssConfiguration_1_1() { | |||
return mGnssConfiguration; | |||
} | |||
Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>> | |||
Gnss::getExtensionGnssMeasurement_1_1() { | |||
// TODO implement | |||
return new GnssMeasurement(); | |||
} | |||
Return<bool> Gnss::injectBestLocation(const GnssLocation&) { | |||
return true; | |||
} | |||
Return<GnssSvInfo> Gnss::getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz, | |||
float elevationDegrees, float azimuthDegrees, int16_t used) const { | |||
GnssSvInfo svInfo = {.svid = svid, | |||
.constellation = type, | |||
.cN0Dbhz = cN0DbHz, | |||
.elevationDegrees = elevationDegrees, | |||
.azimuthDegrees = azimuthDegrees, | |||
.svFlag = 0}; | |||
if (used) | |||
svInfo.svFlag |= GnssSvFlags::USED_IN_FIX; | |||
if (elevationDegrees > 0 && azimuthDegrees > 0) | |||
svInfo.svFlag |= GnssSvFlags::HAS_EPHEMERIS_DATA | GnssSvFlags::HAS_ALMANAC_DATA; | |||
return svInfo; | |||
} | |||
Return<void> Gnss::reportLocation(const GnssLocation& location) const { | |||
std::unique_lock<std::mutex> lock(mMutex); | |||
if (sGnssCallback == nullptr) { | |||
ALOGE("%s: sGnssCallback is null.", __func__); | |||
return Void(); | |||
} | |||
sGnssCallback->gnssLocationCb(location); | |||
return Void(); | |||
} | |||
Return<void> Gnss::reportSvStatus(const GnssSvStatus& svStatus) const { | |||
std::unique_lock<std::mutex> lock(mMutex); | |||
if (sGnssCallback == nullptr) { | |||
ALOGE("%s: sGnssCallback is null.", __func__); | |||
return Void(); | |||
} | |||
sGnssCallback->gnssSvStatusCb(svStatus); | |||
return Void(); | |||
} | |||
} // namespace implementation | |||
} // namespace V1_1 | |||
} // namespace gnss | |||
} // namespace hardware | |||
} // namespace android |
@@ -0,0 +1,107 @@ | |||
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSS_H | |||
#define ANDROID_HARDWARE_GNSS_V1_1_GNSS_H | |||
#include <android/hardware/gnss/1.1/IGnss.h> | |||
#include <hidl/MQDescriptor.h> | |||
#include <hidl/Status.h> | |||
#include <atomic> | |||
#include <mutex> | |||
#include <thread> | |||
#include "GnssConfiguration.h" | |||
#include "gps.h" | |||
namespace android { | |||
namespace hardware { | |||
namespace gnss { | |||
namespace V1_1 { | |||
namespace implementation { | |||
using ::android::hardware::hidl_array; | |||
using ::android::hardware::hidl_memory; | |||
using ::android::hardware::hidl_string; | |||
using ::android::hardware::hidl_vec; | |||
using ::android::hardware::Return; | |||
using ::android::hardware::Void; | |||
using ::android::sp; | |||
using GnssConstellationType = V1_0::GnssConstellationType; | |||
using GnssLocation = V1_0::GnssLocation; | |||
using GnssSvInfo = V1_0::IGnssCallback::GnssSvInfo; | |||
using GnssSvStatus = V1_0::IGnssCallback::GnssSvStatus; | |||
/** | |||
* Unlike the gnss/1.0/default implementation, which is a shim layer to the legacy gps.h, this | |||
* default implementation serves as a mock implementation for emulators | |||
*/ | |||
struct Gnss : public IGnss { | |||
Gnss(); | |||
~Gnss(); | |||
// Methods from ::android::hardware::gnss::V1_0::IGnss follow. | |||
Return<bool> setCallback( | |||
const sp<::android::hardware::gnss::V1_0::IGnssCallback>& callback) override; | |||
Return<bool> start() override; | |||
Return<bool> stop() override; | |||
Return<void> cleanup() override; | |||
Return<bool> injectTime(int64_t timeMs, int64_t timeReferenceMs, | |||
int32_t uncertaintyMs) override; | |||
Return<bool> injectLocation(double latitudeDegrees, double longitudeDegrees, | |||
float accuracyMeters) override; | |||
Return<void> deleteAidingData( | |||
::android::hardware::gnss::V1_0::IGnss::GnssAidingData aidingDataFlags) override; | |||
Return<bool> setPositionMode( | |||
::android::hardware::gnss::V1_0::IGnss::GnssPositionMode mode, | |||
::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence recurrence, | |||
uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, | |||
uint32_t preferredTimeMs) override; | |||
Return<sp<::android::hardware::gnss::V1_0::IAGnssRil>> getExtensionAGnssRil() override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssGeofencing>> getExtensionGnssGeofencing() | |||
override; | |||
Return<sp<::android::hardware::gnss::V1_0::IAGnss>> getExtensionAGnss() override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssNi>> getExtensionGnssNi() override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssMeasurement>> getExtensionGnssMeasurement() | |||
override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssNavigationMessage>> | |||
getExtensionGnssNavigationMessage() override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssXtra>> getExtensionXtra() override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssConfiguration>> getExtensionGnssConfiguration() | |||
override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssDebug>> getExtensionGnssDebug() override; | |||
Return<sp<::android::hardware::gnss::V1_0::IGnssBatching>> getExtensionGnssBatching() override; | |||
// Methods from ::android::hardware::gnss::V1_1::IGnss follow. | |||
Return<bool> setCallback_1_1( | |||
const sp<::android::hardware::gnss::V1_1::IGnssCallback>& callback) override; | |||
Return<bool> setPositionMode_1_1( | |||
::android::hardware::gnss::V1_0::IGnss::GnssPositionMode mode, | |||
::android::hardware::gnss::V1_0::IGnss::GnssPositionRecurrence recurrence, | |||
uint32_t minIntervalMs, uint32_t preferredAccuracyMeters, uint32_t preferredTimeMs, | |||
bool lowPowerMode) override; | |||
Return<sp<::android::hardware::gnss::V1_1::IGnssConfiguration>> | |||
getExtensionGnssConfiguration_1_1() override; | |||
Return<sp<::android::hardware::gnss::V1_1::IGnssMeasurement>> getExtensionGnssMeasurement_1_1() | |||
override; | |||
Return<bool> injectBestLocation( | |||
const ::android::hardware::gnss::V1_0::GnssLocation& location) override; | |||
// Methods from ::android::hidl::base::V1_0::IBase follow. | |||
private: | |||
Return<GnssSvInfo> getSvInfo(int16_t svid, GnssConstellationType type, float cN0DbHz, | |||
float elevationDegress, float azimuthDegress, int16_t used) const; | |||
Return<void> reportLocation(const GnssLocation&) const; | |||
Return<void> reportSvStatus(const GnssSvStatus&) const; | |||
static sp<IGnssCallback> sGnssCallback; | |||
std::atomic<long> mMinIntervalMs; | |||
sp<GnssConfiguration> mGnssConfiguration; | |||
std::atomic<bool> mIsActive; | |||
std::thread mThread; | |||
mutable std::mutex mMutex; | |||
}; | |||
} // namespace implementation | |||
} // namespace V1_1 | |||
} // namespace gnss | |||
} // namespace hardware | |||
} // namespace android | |||
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSS_H |
@@ -0,0 +1,84 @@ | |||
#define LOG_TAG "GnssConfiguration" | |||
#include "GnssConfiguration.h" | |||
#include <log/log.h> | |||
namespace android { | |||
namespace hardware { | |||
namespace gnss { | |||
namespace V1_1 { | |||
namespace implementation { | |||
// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow. | |||
Return<bool> GnssConfiguration::setSuplEs(bool) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<bool> GnssConfiguration::setSuplVersion(uint32_t) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<bool> GnssConfiguration::setSuplMode(hidl_bitfield<SuplMode>) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<bool> GnssConfiguration::setGpsLock(hidl_bitfield<GpsLock>) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<bool> GnssConfiguration::setLppProfile(hidl_bitfield<LppProfile>) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<bool> GnssConfiguration::setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol>) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
Return<bool> GnssConfiguration::setEmergencySuplPdn(bool) { | |||
// TODO implement | |||
return bool{}; | |||
} | |||
// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow. | |||
Return<bool> GnssConfiguration::setBlacklist(const hidl_vec<BlacklistedSource>& sourceList) { | |||
std::unique_lock<std::recursive_mutex> lock(mMutex); | |||
mBlacklistedConstellationSet.clear(); | |||
mBlacklistedSourceSet.clear(); | |||
for (auto source : sourceList) { | |||
if (source.svid == 0) { | |||
// Wildcard blacklist, i.e., blacklist entire constellation. | |||
mBlacklistedConstellationSet.insert(source.constellation); | |||
} else { | |||
mBlacklistedSourceSet.insert(source); | |||
} | |||
} | |||
return true; | |||
} | |||
Return<bool> GnssConfiguration::isBlacklisted(const GnssSvInfo& gnssSvInfo) const { | |||
std::unique_lock<std::recursive_mutex> lock(mMutex); | |||
if (mBlacklistedConstellationSet.find(gnssSvInfo.constellation) != | |||
mBlacklistedConstellationSet.end()) { | |||
return true; | |||
} | |||
BlacklistedSource source = {.constellation = gnssSvInfo.constellation, .svid = gnssSvInfo.svid}; | |||
return (mBlacklistedSourceSet.find(source) != mBlacklistedSourceSet.end()); | |||
} | |||
std::recursive_mutex& GnssConfiguration::getMutex() const { | |||
return mMutex; | |||
} | |||
// Methods from ::android::hidl::base::V1_0::IBase follow. | |||
} // namespace implementation | |||
} // namespace V1_1 | |||
} // namespace gnss | |||
} // namespace hardware | |||
} // namespace android |
@@ -0,0 +1,73 @@ | |||
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H | |||
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H | |||
#include <android/hardware/gnss/1.1/IGnssCallback.h> | |||
#include <android/hardware/gnss/1.1/IGnssConfiguration.h> | |||
#include <hidl/MQDescriptor.h> | |||
#include <hidl/Status.h> | |||
#include <mutex> | |||
#include <unordered_set> | |||
namespace android { | |||
namespace hardware { | |||
namespace gnss { | |||
namespace V1_1 { | |||
namespace implementation { | |||
using ::android::hardware::hidl_array; | |||
using ::android::hardware::hidl_memory; | |||
using ::android::hardware::hidl_string; | |||
using ::android::hardware::hidl_vec; | |||
using ::android::hardware::Return; | |||
using ::android::hardware::Void; | |||
using ::android::sp; | |||
using BlacklistedSource = ::android::hardware::gnss::V1_1::IGnssConfiguration::BlacklistedSource; | |||
using GnssConstellationType = V1_0::GnssConstellationType; | |||
using GnssSvInfo = V1_0::IGnssCallback::GnssSvInfo; | |||
struct BlacklistedSourceHash { | |||
inline int operator()(const BlacklistedSource& source) const { | |||
return int(source.constellation) * 1000 + int(source.svid); | |||
} | |||
}; | |||
struct BlacklistedSourceEqual { | |||
inline bool operator()(const BlacklistedSource& s1, const BlacklistedSource& s2) const { | |||
return (s1.constellation == s2.constellation) && (s1.svid == s2.svid); | |||
} | |||
}; | |||
using BlacklistedSourceSet = | |||
std::unordered_set<BlacklistedSource, BlacklistedSourceHash, BlacklistedSourceEqual>; | |||
using BlacklistedConstellationSet = std::unordered_set<GnssConstellationType>; | |||
struct GnssConfiguration : public IGnssConfiguration { | |||
// Methods from ::android::hardware::gnss::V1_0::IGnssConfiguration follow. | |||
Return<bool> setSuplEs(bool enabled) override; | |||
Return<bool> setSuplVersion(uint32_t version) override; | |||
Return<bool> setSuplMode(hidl_bitfield<SuplMode> mode) override; | |||
Return<bool> setGpsLock(hidl_bitfield<GpsLock> lock) override; | |||
Return<bool> setLppProfile(hidl_bitfield<LppProfile> lppProfile) override; | |||
Return<bool> setGlonassPositioningProtocol(hidl_bitfield<GlonassPosProtocol> protocol) override; | |||
Return<bool> setEmergencySuplPdn(bool enable) override; | |||
// Methods from ::android::hardware::gnss::V1_1::IGnssConfiguration follow. | |||
Return<bool> setBlacklist(const hidl_vec<BlacklistedSource>& blacklist) override; | |||
Return<bool> isBlacklisted(const GnssSvInfo& gnssSvInfo) const; | |||
std::recursive_mutex& getMutex() const; | |||
private: | |||
BlacklistedSourceSet mBlacklistedSourceSet; | |||
BlacklistedConstellationSet mBlacklistedConstellationSet; | |||
mutable std::recursive_mutex mMutex; | |||
}; | |||
} // namespace implementation | |||
} // namespace V1_1 | |||
} // namespace gnss | |||
} // namespace hardware | |||
} // namespace android | |||
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSCONFIGURATION_H |
@@ -0,0 +1,35 @@ | |||
#include "GnssMeasurement.h" | |||
namespace android { | |||
namespace hardware { | |||
namespace gnss { | |||
namespace V1_1 { | |||
namespace implementation { | |||
// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow. | |||
Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus> | |||
GnssMeasurement::setCallback(const sp<::android::hardware::gnss::V1_0::IGnssMeasurementCallback>&) { | |||
// TODO implement | |||
return ::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus{}; | |||
} | |||
Return<void> GnssMeasurement::close() { | |||
// TODO implement | |||
return Void(); | |||
} | |||
// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow. | |||
Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus> | |||
GnssMeasurement::setCallback_1_1( | |||
const sp<::android::hardware::gnss::V1_1::IGnssMeasurementCallback>&, bool) { | |||
// TODO implement | |||
return ::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus{}; | |||
} | |||
// Methods from ::android::hidl::base::V1_0::IBase follow. | |||
} // namespace implementation | |||
} // namespace V1_1 | |||
} // namespace gnss | |||
} // namespace hardware | |||
} // namespace android |
@@ -0,0 +1,42 @@ | |||
#ifndef ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H | |||
#define ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H | |||
#include <android/hardware/gnss/1.1/IGnssMeasurement.h> | |||
#include <hidl/MQDescriptor.h> | |||
#include <hidl/Status.h> | |||
namespace android { | |||
namespace hardware { | |||
namespace gnss { | |||
namespace V1_1 { | |||
namespace implementation { | |||
using ::android::hardware::hidl_array; | |||
using ::android::hardware::hidl_memory; | |||
using ::android::hardware::hidl_string; | |||
using ::android::hardware::hidl_vec; | |||
using ::android::hardware::Return; | |||
using ::android::hardware::Void; | |||
using ::android::sp; | |||
struct GnssMeasurement : public IGnssMeasurement { | |||
// Methods from ::android::hardware::gnss::V1_0::IGnssMeasurement follow. | |||
Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus> setCallback( | |||
const sp<::android::hardware::gnss::V1_0::IGnssMeasurementCallback>& callback) override; | |||
Return<void> close() override; | |||
// Methods from ::android::hardware::gnss::V1_1::IGnssMeasurement follow. | |||
Return<::android::hardware::gnss::V1_0::IGnssMeasurement::GnssMeasurementStatus> | |||
setCallback_1_1(const sp<::android::hardware::gnss::V1_1::IGnssMeasurementCallback>& callback, | |||
bool enableFullTracking) override; | |||
// Methods from ::android::hidl::base::V1_0::IBase follow. | |||
}; | |||
} // namespace implementation | |||
} // namespace V1_1 | |||
} // namespace gnss | |||
} // namespace hardware | |||
} // namespace android | |||
#endif // ANDROID_HARDWARE_GNSS_V1_1_GNSSMEASUREMENT_H |
@@ -0,0 +1,4 @@ | |||
service gnss-gpsd /vendor/bin/hw/android.hardware.gnss@1.1-service.gpsd | |||
class hal | |||
user root | |||
group system gps radio |
@@ -0,0 +1,11 @@ | |||
<manifest version="1.0" type="device"> | |||
<hal format="hidl"> | |||
<name>android.hardware.gnss</name> | |||
<transport>hwbinder</transport> | |||
<version>1.1</version> | |||
<interface> | |||
<name>IGnss</name> | |||
<instance>default</instance> | |||
</interface> | |||
</hal> | |||
</manifest> |
@@ -0,0 +1,25 @@ | |||
#define LOG_TAG "android.hardware.gnss@1.1-service.gpsd" | |||
#include <hidl/HidlSupport.h> | |||
#include <hidl/HidlTransportSupport.h> | |||
#include "Gnss.h" | |||
using ::android::hardware::configureRpcThreadpool; | |||
using ::android::hardware::gnss::V1_1::implementation::Gnss; | |||
using ::android::hardware::gnss::V1_1::IGnss; | |||
using ::android::hardware::joinRpcThreadpool; | |||
using ::android::OK; | |||
using ::android::sp; | |||
int main(int /* argc */, char* /* argv */ []) { | |||
sp<IGnss> gnss = new Gnss(); | |||
configureRpcThreadpool(1, true /* will join */); | |||
if (gnss->registerAsService() != OK) { | |||
ALOGE("Could not register gnss 1.1 service."); | |||
return 1; | |||
} | |||
joinRpcThreadpool(); | |||
ALOGE("Service exited!"); | |||
return 1; | |||
} |
@@ -0,0 +1,3 @@ | |||
/vendor/bin/hw/android\.hardware\.gnss@1\.1-service\.gpsd u:object_r:hal_gnss_default_exec:s0 | |||
/vendor/bin/gpsd u:object_r:gpsd_exec:s0 | |||
/vendor/bin/gpsd_wrapper u:object_r:gpsd_exec:s0 |
@@ -0,0 +1,17 @@ | |||
type gpsd, domain; | |||
type gpsd_exec, exec_type, vendor_file_type, file_type; | |||
init_daemon_domain(gpsd) | |||
net_domain(gpsd) | |||
allow gpsd gpsd:capability { net_raw }; | |||
allow gpsd serial_device:chr_file rw_file_perms; | |||
# The following are needed by logwrapper to get gpsd's output | |||
# to Android's logs. | |||
typeattribute gpsd vendor_executes_system_violators; | |||
allow gpsd shell_exec:file { execute execute_no_trans read open getattr }; | |||
allow gpsd vendor_file:file { execute execute_no_trans read open getattr }; | |||
allow gpsd devpts:chr_file { read write open getattr }; | |||
allow gpsd gpsd_exec:file { execute execute_no_trans read open getattr }; | |||
allow gpsd vendor_shell_exec:file { execute execute_no_trans read open getattr }; |
@@ -0,0 +1,7 @@ | |||
# Hijack hostapd domain and attribute to gain network access | |||
hal_server_domain(hal_gnss_default, hal_wifi_hostapd); | |||
typeattribute hal_gnss_default hal_wifi_hostapd_server; | |||
net_domain(hal_gnss_default) | |||
allow hal_gnss_default hal_gnss_default:capability { net_raw }; | |||
allow hal_gnss_default property_socket:sock_file { write }; |
@@ -1,6 +1,6 @@ | |||
/* bits.c - bitfield extraction code | |||
* | |||
* This file is Copyright (c)2010 by the GPSD project | |||
* This file is Copyright (c)2010-2018 by the GPSD project | |||
* SPDX-License-Identifier: BSD-2-clause | |||
* | |||
* Bitfield extraction functions. In each, start is a bit index - not | |||
@@ -10,6 +10,8 @@ | |||
* The sbits() function assumes twos-complement arithmetic. ubits() | |||
* and sbits() assume no padding in integers. | |||
*/ | |||
#include "gpsd_config.h" /* must be before all includes */ | |||
#include <assert.h> | |||
#include <stdint.h> | |||
#include <stdbool.h> | |||
@@ -41,6 +41,8 @@ | |||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES. | |||
*/ | |||
#include "gpsd_config.h" /* must be before all includes */ | |||
#include <stdlib.h> | |||
#include <sys/types.h> | |||
#include <ctype.h> | |||
@@ -9,6 +9,9 @@ Some hints for people building binary packages are in packaging/readme.txt. | |||
== Quick start == | |||
You can download the most recent development snapshot from: | |||
https://gitlab.com/gpsd/gpsd/tree/master | |||
You can download the lastest gpsd tarball from: | |||
http://download.savannah.gnu.org/releases/gpsd/ | |||
@@ -72,6 +75,12 @@ Necessary components for any build: | |||
|Python2.x(x>=6) or 3.y(y>=2) | for scons and some helper scripts | |||
|============================================================================ | |||
On Gentoo, a basic build only requires this package: | |||
|============================================================================ | |||
|dev-util/scons | for executing the build recipe | |||
|============================================================================ | |||
=== C compiler === | |||
C99 conformance is required in the compiler. The C code depends on one | |||
@@ -121,13 +130,24 @@ extensions are installed: | |||
|python-gi-cairo | Python bindings for Cairo toolkit under GI | |||
|=========================================================================== | |||
The ubxtool and zerk clients will only be installed if this Python | |||
extensions is installed: | |||
On Gentoo systems those packages are named: | |||
|============================================================================ | |||
|dev-python/pygobject | |||
|dev-python/pycairo | |||
|============================================================================ | |||
The ubxtool and zerk clients will only be usable in direct-serial mode | |||
if this Python extension is installed: | |||
|============================================================================ | |||
|pyserial | Python Serial Port extension | |||
|=========================================================================== | |||
On Gentoo systems that package is named: | |||
|============================================================================ | |||
|dev-python/pyserial | |||
|============================================================================ | |||
=== Scons === | |||
You will need scons version 2.3.0 (from 2013-03-02) or later to build the code. | |||
@@ -140,8 +160,21 @@ various additional capabilities and extensions: | |||
|============================================================================ | |||
|C++ compiler | allows building libgpsmm C++ wrapper for client library | |||
|Qt 4.53+ | allows building libQgpsmm C++ wrapper for client library | |||
|libcap | Capabilities library, allows 1PPS support under Linux | |||
|libcap | Capabilities library, improved security under Linux | |||
|(n)curses | curses screen-painting library, used by cgps and gpsmon | |||
|pps-tools | adds support for the KPPS API, for improved timing | |||
|libusb | Userspace access to USB devices | |||
|============================================================================ | |||
On Gentoo systems those packages are named: | |||
|============================================================================ | |||
|dev-qt/qtcore | Basic Qt | |||
|dev-qt/qtnetwork | Qt network components | |||
|sys-libs/libcap | Capabilities library | |||
|sys-libs/ncurses | curses screen-painting library, used by cgps and gpsmon | |||
|net-misc/pps-tools | adds support for the KPPS API, for improved timing | |||
|virtual/libusb | Userspace access to USB devices | |||
|============================================================================ | |||
If you have libusb-1.0.0 or later, the GPSD build will autodetect | |||
@@ -157,8 +190,8 @@ http://qt.nokia.com/doc/4.6/platform-specific.html for platform | |||
specific building documentation | |||
For working with DBUS, you'll need the DBUS development | |||
headers and libraries installed. Under Debian/Ubuntu these | |||
are the packages libdbus-1-dev and libdbus-glib-1-dev. | |||
headers and libraries installed. Under Debian/Ubuntu this | |||
is the package libdbus-1-dev. | |||
Under Ubuntu, the ncurses package you want is libncurses5-dev. Under | |||
Fedora, it's ncurses-devel. Depending on how your distribution | |||
@@ -174,6 +207,12 @@ We've seen a report that compiling on the Raspberry Pi fails with | |||
a complaint about curses.h not being found. You need to install | |||
Raspbian's curses development library if this happens. | |||
If your kernel provides the RFC 2783 KPPS (kernel PPS) API, gpsd will | |||
use that for extra accuracy. Many Linux distributions have a package | |||
called "pps-tools" that will install KPPS support and the timepps.h | |||
header file. We recommend you do that. If your kernel is built in | |||
the normal modular way, this package installation will suffice. | |||
For building from the source tree, or if you change the man page | |||
source, xslt and docbook xsl style files are used to generate nroff | |||
-man source from docbook xml. The following packages are used in this | |||
@@ -186,6 +225,15 @@ process: | |||
|asciidoc | DocBook front end with lighter markup | |||
|============================================================================ | |||
On Gentoo systems those packages are named: | |||
|============================================================================ | |||
|app-text/xmlto | DocBook formatter program | |||
|app-text/asciidoc | DocBook front end with lighter markup | |||
|dev-libs/libxslt | pulled in by asciidoc | |||
|app-text/docbook-xsl-stylesheets | pulled in by asciidoc | |||
|============================================================================ | |||
The build degrades gracefully in the absence of any of these. You should | |||
be able to tell from scons messages which extensions you will get. | |||
@@ -198,12 +246,15 @@ If you are custom-building a Linux kernel for embedded deployment, you | |||
will need some subset of the following modules: | |||
|============================================================================ | |||
|pl2303 | Prolific Technology, Inc. PL2303 Serial Port | |||
|ftdi_sio | FTDI 8U232AM / FT232 | |||
|cypress_m8 | M8/CY7C64013 | |||
|cp210x | Cygnal Integrated Products devices | |||
|garmin_gps | Garmin USB mice including GPS-18 | |||
|cdc_am | USB Communication Device Class Abstract Control Model interface | |||
|pl2303 | Prolific Technology, Inc. PL2303 Serial Port | |||
|ftdi_sio | FTDI 8U232AM / FT232 | |||
|cypress_m8 | M8/CY7C64013 | |||
|cp210x | Cygnal Integrated Products devices | |||
|garmin_gps | Garmin USB mice including GPS-18 | |||
|cdc_am | USB Communication Device Class Abstract Control Model interface | |||
|pps-gpio | For KPPS support on ARM systems | |||
|pps-ldisc | For KPPS support with RS-232 ports | |||
|pps_parport | For KPPS support with a parallel port | |||
|============================================================================ | |||
These are listed in rough order of devices covered as of 2013; the | |||