[-]
[+]
|
Changed |
_service:tar_git:geoclue-provider-hybris.changes
|
|
[-]
[+]
|
Changed |
_service:tar_git:geoclue-providers-hybris.spec
^
|
|
[-]
[+]
|
Deleted |
_service:tar_git:geoclue-provider-hybris-0.2.17.tar.gz/geoclue-providers-hybris.pro
^
|
@@ -1,54 +0,0 @@
-TARGET = geoclue-hybris
-CONFIG += console
-CONFIG -= app_bundle
-TEMPLATE = app
-
-target.path = /usr/libexec
-
-QT = core dbus network
-
-CONFIG += link_pkgconfig
-PKGCONFIG += libhardware android-headers connman-qt5 qofono-qt5 qofonoext systemsettings
-
-LIBS += -lrt
-
-dbus_geoclue.files = \
- org.freedesktop.Geoclue.xml \
- org.freedesktop.Geoclue.Position.xml \
- org.freedesktop.Geoclue.Velocity.xml \
- org.freedesktop.Geoclue.Satellite.xml
-dbus_geoclue.header_flags = "-l HybrisProvider -i hybrisprovider.h"
-dbus_geoclue.source_flags = "-l HybrisProvider"
-
-DBUS_ADAPTORS = \
- dbus_geoclue
-
-DBUS_INTERFACES = \
- com.jollamobile.Connectiond.xml \
- com.jolla.lipstick.ConnectionSelector.xml
-
-session_dbus_service.files = org.freedesktop.Geoclue.Providers.Hybris.service
-session_dbus_service.path = /usr/share/dbus-1/services
-
-system_dbus_conf.files = com.jollamobile.gps.conf
-system_dbus_conf.path = /etc/dbus-1/system.d
-
-geoclue_provider.files = geoclue-hybris.provider
-geoclue_provider.path = /usr/share/geoclue-providers
-
-HEADERS += \
- hybrisprovider.h \
- locationtypes.h
-
-SOURCES += \
- main.cpp \
- hybrisprovider.cpp
-
-OTHER_FILES = \
- $${session_dbus_service.files} \
- $${system_dbus_service.files} \
- $${system_dbus_conf.files} \
- $${geoclue_provider.files} \
- rpm/geoclue-providers-hybris.spec
-
-INSTALLS += target session_dbus_service system_dbus_conf geoclue_provider
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/binder/binderlocationbackend.cpp
^
|
@@ -0,0 +1,1158 @@
+/*
+ Copyright (C) 2015 Jolla Ltd.
+ Copyright (C) 2018 Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ Contact: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
+
+ This file is part of geoclue-hybris.
+
+ Geoclue-hybris is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License.
+*/
+
+#include "binderlocationbackend.h"
+
+#include "hybrisprovider.h"
+
+#include <QtNetwork/QHostAddress>
+
+#include <strings.h>
+#include <sys/time.h>
+
+#define GNSS_BINDER_DEFAULT_DEV "/dev/hwbinder"
+
+HybrisLocationBackend *getLocationBackend()
+{
+ return qobject_cast<HybrisLocationBackend *>(new BinderLocationBackend());
+}
+
+enum GnssFunctions {
+ GNSS_SET_CALLBACK = 1,
+ GNSS_START = 2,
+ GNSS_STOP = 3,
+ GNSS_CLEANUP = 4,
+ GNSS_INJECT_TIME = 5,
+ GNSS_INJECT_LOCATION = 6,
+ GNSS_DELETE_AIDING_DATA = 7,
+ GNSS_SET_POSITION_MODE = 8,
+ GNSS_GET_EXTENSION_AGNSS_RIL = 9,
+ GNSS_GET_EXTENSION_GNSS_GEOFENCING = 10,
+ GNSS_GET_EXTENSION_AGNSS = 11,
+ GNSS_GET_EXTENSION_GNSS_NI = 12,
+ GNSS_GET_EXTENSION_GNSS_MEASUREMENT = 13,
+ GNSS_GET_EXTENSION_GNSS_NAVIGATION_MESSAGE = 14,
+ GNSS_GET_EXTENSION_XTRA = 15,
+ GNSS_GET_EXTENSION_GNSS_CONFIGURATION = 16,
+ GNSS_GET_EXTENSION_GNSS_DEBUG = 17,
+ GNSS_GET_EXTENSION_GNSS_BATCHING = 18
+};
+
+enum GnssCallbacks {
+ GNSS_LOCATION_CB = 1,
+ GNSS_STATUS_CB = 2,
+ GNSS_SV_STATUS_CB = 3,
+ GNSS_NMEA_CB = 4,
+ GNSS_SET_CAPABILITIES_CB = 5,
+ GNSS_ACQUIRE_WAKELOCK_CB = 6,
+ GNSS_RELEASE_WAKELOCK_CB = 7,
+ GNSS_REQUEST_TIME_CB = 8,
+ GNSS_SET_SYSTEM_INFO_CB = 9
+};
+
+enum GnssDebudFunctions {
+ GNSS_DEBUG_GET_DEBUG_DATA = 1
+};
+
+enum GnssNiFunctions {
+ GNSS_NI_SET_CALLBACK = 1,
+ GNSS_NI_RESPOND = 2
+};
+
+enum GnssNiCallbacks {
+ GNSS_NI_NOTIFY_CB = 1
+};
+
+enum GnssXtraFunctions {
+ GNSS_XTRA_SET_CALLBACK = 1,
+ GNSS_XTRA_INJECT_XTRA_DATA = 2
+};
+
+enum GnssXtraCallbacks {
+ GNSS_XTRA_DOWNLOAD_REQUEST_CB = 1
+};
+
+enum AGnssFunctions {
+ AGNSS_SET_CALLBACK = 1,
+ AGNSS_DATA_CONN_CLOSED = 2,
+ AGNSS_DATA_CONN_FAILED = 3,
+ AGNSS_SET_SERVER = 4,
+ AGNSS_DATA_CONN_OPEN = 5
+};
+
+enum AGnssCallbacks {
+ AGNSS_STATUS_IP_V4_CB = 1,
+ AGNSS_STATUS_IP_V6_CB = 2
+};
+
+enum AGnssRilFunctions {
+ AGNSS_RIL_SET_CALLBACK = 1,
+ AGNSS_RIL_SET_REF_LOCATION = 2,
+ AGNSS_RIL_SET_ID = 3,
+ AGNSS_RIL_UPDATE_NETWORK_STATE = 4,
+ AGNSS_RIL_UPDATE_NETWORK_AVAILABILITY = 5
+};
+
+enum AGnssRilCallbacks {
+ AGNSS_RIL_REQUEST_REF_ID_CB = 1,
+ AGNSS_RIL_REQUEST_REF_LOC_CB = 2
+};
+
+enum HybrisApnIpTypeEnum {
+ HYBRIS_APN_IP_INVALID = 0,
+ HYBRIS_APN_IP_IPV4 = 1,
+ HYBRIS_APN_IP_IPV6 = 2,
+ HYBRIS_APN_IP_IPV4V6 = 3
+};
+
+#define GNSS_IFACE(x) "android.hardware.gnss@1.0::" x
+#define GNSS_REMOTE GNSS_IFACE("IGnss")
+#define GNSS_CALLBACK GNSS_IFACE("IGnssCallback")
+#define GNSS_DEBUG_REMOTE GNSS_IFACE("IGnssDebug")
+#define GNSS_NI_REMOTE GNSS_IFACE("IGnssNi")
+#define GNSS_NI_CALLBACK GNSS_IFACE("IGnssNiCallback")
+#define GNSS_XTRA_REMOTE GNSS_IFACE("IGnssXtra")
+#define GNSS_XTRA_CALLBACK GNSS_IFACE("IGnssXtraCallback")
+#define AGNSS_REMOTE GNSS_IFACE("IAGnss")
+#define AGNSS_CALLBACK GNSS_IFACE("IAGnssCallback")
+#define AGNSS_RIL_REMOTE GNSS_IFACE("IAGnssRil")
+#define AGNSS_RIL_CALLBACK GNSS_IFACE("IAGnssRilCallback")
+
+
+/*==========================================================================*
+ * Implementation
+ *==========================================================================*/
+
+HybrisApnIpType fromContextProtocol(const QString &protocol)
+{
+ if (protocol == QLatin1String("ip"))
+ return HYBRIS_APN_IP_IPV4;
+ else if (protocol == QLatin1String("ipv6"))
+ return HYBRIS_APN_IP_IPV6;
+ else if (protocol == QLatin1String("dual"))
+ return HYBRIS_APN_IP_IPV4V6;
+ else
+ return HYBRIS_APN_IP_INVALID;
+}
+
+static const void *geoclue_binder_gnss_decode_struct1(
+ GBinderReader *in,
+ guint size)
+{
+ const void *result = Q_NULLPTR;
+ GBinderBuffer *buf = gbinder_reader_read_buffer(in);
+
+ if (buf && buf->size == size) {
+ result = buf->data;
+ }
+ gbinder_buffer_free(buf);
+ return result;
+}
+
+#define geoclue_binder_gnss_decode_struct(type,in) \
+ ((const type*)geoclue_binder_gnss_decode_struct1(in, sizeof(type)))
+
+bool nmeaChecksumValid(const QByteArray &nmea)
+{
+ unsigned char checksum = 0;
+ for (int i = 1; i < nmea.length(); ++i) {
+ if (nmea.at(i) == '*') {
+ if (nmea.length() < i+3)
+ return false;
+
+ checksum ^= nmea.mid(i+1, 2).toInt(0, 16);
+
+ break;
+ }
+
+ checksum ^= nmea.at(i);
+ }
+
+ return checksum == 0;
+}
+
+void parseRmc(const QByteArray &nmea)
+{
+ QList<QByteArray> fields = nmea.split(',');
+ if (fields.count() < 12)
+ return;
+
+ bool ok;
+ double variation = fields.at(10).toDouble(&ok);
+ if (ok) {
+ if (fields.at(11) == "W")
+ variation = -variation;
+
+ QMetaObject::invokeMethod(staticProvider, "setMagneticVariation", Qt::QueuedConnection,
+ Q_ARG(double, variation));
+ }
+}
+
+void processNmea(gint64 timestamp, const char *nmeaData)
+{
+ int length = strlen(nmeaData);
+ while (length > 0 && isspace(nmeaData[length-1]))
+ --length;
+
+ if (length == 0)
+ return;
+
+ QByteArray nmea = QByteArray::fromRawData(nmeaData, length);
+
+ qCDebug(lcGeoclueHybrisNmea) << timestamp << nmea;
+
+ if (!nmeaChecksumValid(nmea))
+ return;
+
+ // truncate checksum and * from end of sentence
+ nmea.truncate(nmea.length()-3);
+
+ if (nmea.startsWith("$GPRMC"))
+ parseRmc(nmea);
+}
+
+static GBinderLocalReply *geoclue_binder_gnss_callback(
+ GBinderLocalObject *obj,
+ GBinderRemoteRequest *req,
+ guint code,
+ guint flags,
+ int *status,
+ void *user_data)
+{
+ Q_UNUSED(flags)
+ Q_UNUSED(user_data)
+ const char *iface = gbinder_remote_request_interface(req);
+
+ if (!g_strcmp0(iface, GNSS_CALLBACK)) {
+ GBinderReader reader;
+
+ gbinder_remote_request_init_reader(req, &reader);
+ switch (code) {
+ case GNSS_LOCATION_CB:
+ {
+ Location loc;
+
+ const GnssLocation *location = geoclue_binder_gnss_decode_struct
+ (GnssLocation, &reader);
+
+ loc.setTimestamp(location->timestamp);
+
+ if (location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_LAT_LONG) {
+ loc.setLatitude(location->latitudeDegrees);
+ loc.setLongitude(location->longitudeDegrees);
+ }
+
+ if (location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_ALTITUDE)
+ loc.setAltitude(location->altitudeMeters);
+
+ if (location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_SPEED)
+ loc.setSpeed(location->speedMetersPerSec);
+
+ if (location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_BEARING)
+ loc.setDirection(location->bearingDegrees);
+
+ if ((location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_HORIZONTAL_ACCURACY) ||
+ (location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_VERTICAL_ACCURACY)) {
+ Accuracy accuracy;
+ if (location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_HORIZONTAL_ACCURACY) {
+ accuracy.setHorizontal(location->horizontalAccuracyMeters);
+ }
+ if (location->gnssLocationFlags & HYBRIS_GNSS_LOCATION_HAS_VERTICAL_ACCURACY) {
+ accuracy.setVertical(location->verticalAccuracyMeters);
+ }
+ loc.setAccuracy(accuracy);
+ }
+
+ QMetaObject::invokeMethod(staticProvider, "setLocation", Qt::QueuedConnection,
+ Q_ARG(Location, loc));
+ }
+ break;
+ case GNSS_STATUS_CB:
+ {
+ guint32 stat;
+ if (gbinder_reader_read_uint32(&reader, &stat)) {
+ if (stat == HYBRIS_GNSS_STATUS_ENGINE_ON) {
+ QMetaObject::invokeMethod(staticProvider, "engineOn", Qt::QueuedConnection);
+ }
+ if (stat == HYBRIS_GNSS_STATUS_ENGINE_OFF) {
+ QMetaObject::invokeMethod(staticProvider, "engineOff", Qt::QueuedConnection);
+ }
+ }
+ }
+ break;
+ case GNSS_SV_STATUS_CB:
+ {
+ const GnssSvStatus *svStatus = geoclue_binder_gnss_decode_struct
+ (GnssSvStatus, &reader);
+
+ QList<SatelliteInfo> satellites;
+ QList<int> usedPrns;
+
+ for (int i = 0; i < svStatus->numSvs; ++i) {
+ SatelliteInfo satInfo;
+ GnssSvInfo svInfo = svStatus->gnssSvList.data[i];
+ satInfo.setSnr(svInfo.cN0Dbhz);
+ satInfo.setElevation(svInfo.elevationDegrees);
+ satInfo.setAzimuth(svInfo.azimuthDegrees);
+ int prn = svInfo.svid;
+ // From https://github.com/barbeau/gpstest
+ // and https://github.com/mvglasow/satstat/wiki/NMEA-IDs
+ if (svInfo.constellation == GnssConstellationType::SBAS) {
+ prn -= 87;
+ } else if (svInfo.constellation == GnssConstellationType::GLONASS) {
+ prn += 64;
+ } else if (svInfo.constellation == GnssConstellationType::BEIDOU) {
+ prn += 200;
+ } else if (svInfo.constellation == GnssConstellationType::GALILEO) {
+ prn += 300;
+ }
+ satInfo.setPrn(prn);
+ satellites.append(satInfo);
+
+ if (svInfo.svFlag & HYBRIS_GNSS_SV_FLAGS_USED_IN_FIX)
+ usedPrns.append(svInfo.svid);
+ }
+
+ QMetaObject::invokeMethod(staticProvider, "setSatellite", Qt::QueuedConnection,
+ Q_ARG(QList<SatelliteInfo>, satellites),
+ Q_ARG(QList<int>, usedPrns));
+ }
+ break;
+ case GNSS_NMEA_CB:
+ {
+ gint64 timestamp;
+ if (gbinder_reader_read_int64(&reader, ×tamp)) {
+ char *nmeaData = gbinder_reader_read_hidl_string(&reader);
+ if (nmeaData) {
+ processNmea(timestamp, nmeaData);
+ g_free(nmeaData);
+ }
+ }
+ }
+ break;
+ case GNSS_SET_CAPABILITIES_CB:
+ {
+ guint32 capabilities;
+ if (gbinder_reader_read_uint32(&reader, &capabilities)) {
+ qCDebug(lcGeoclueHybris) << "capabilities" << showbase << hex << capabilities;
+ }
+ }
+ break;
+ case GNSS_ACQUIRE_WAKELOCK_CB:
+ case GNSS_RELEASE_WAKELOCK_CB:
+ break;
+ case GNSS_REQUEST_TIME_CB:
+ qCDebug(lcGeoclueHybris) << "GNSS request UTC time";
+ QMetaObject::invokeMethod(staticProvider, "injectUtcTime", Qt::QueuedConnection);
+ break;
+ case GNSS_SET_SYSTEM_INFO_CB:
+ qCDebug(lcGeoclueHybris) << "GNSS set system info";
+ break;
+ default:
+ qWarning("Failed to decode callback %u\n", code);
+ break;
+ }
+ *status = GBINDER_STATUS_OK;
+ return gbinder_local_reply_append_int32(gbinder_local_object_new_reply(obj), 0);
+ } else {
+ qWarning("Unknown interface %s and code %u\n", iface, code);
+ *status = GBINDER_STATUS_FAILED;
+ }
+ return Q_NULLPTR;
+}
+
+static GBinderLocalReply *geoclue_binder_gnss_xtra_callback(
+ GBinderLocalObject *obj,
+ GBinderRemoteRequest *req,
+ guint code,
+ guint flags,
+ int *status,
+ void *user_data)
+{
+ Q_UNUSED(flags)
+ Q_UNUSED(user_data)
+ const char *iface = gbinder_remote_request_interface(req);
+
+ if (!g_strcmp0(iface, GNSS_XTRA_CALLBACK)) {
+ GBinderReader reader;
+
+ gbinder_remote_request_init_reader(req, &reader);
+ switch (code) {
+ case GNSS_XTRA_DOWNLOAD_REQUEST_CB:
+ QMetaObject::invokeMethod(staticProvider, "xtraDownloadRequest", Qt::QueuedConnection);
+ break;
+ default:
+ qWarning("Failed to decode callback %u\n", code);
+ break;
+ }
+ *status = GBINDER_STATUS_OK;
+ return gbinder_local_reply_append_int32(gbinder_local_object_new_reply(obj), 0);
+ } else {
+ qWarning("Unknown interface %s and code %u\n", iface, code);
+ *status = GBINDER_STATUS_FAILED;
+ }
+ return Q_NULLPTR;
+}
+
+static GBinderLocalReply *geoclue_binder_agnss_callback(
+ GBinderLocalObject *obj,
+ GBinderRemoteRequest *req,
+ guint code,
+ guint flags,
+ int *status,
+ void *user_data)
+{
+ Q_UNUSED(flags)
+ Q_UNUSED(user_data)
+ const char *iface = gbinder_remote_request_interface(req);
+
+ if (!g_strcmp0(iface, AGNSS_CALLBACK)) {
+ GBinderReader reader;
+
+ gbinder_remote_request_init_reader(req, &reader);
+ switch (code) {
+ case AGNSS_STATUS_IP_V4_CB:
+ {
+ QHostAddress ipv4;
+ QHostAddress ipv6;
+ QByteArray ssid;
+ QByteArray password;
+
+ const AGnssStatusIpV4 *status = geoclue_binder_gnss_decode_struct
+ (AGnssStatusIpV4, &reader);
+
+ ipv4.setAddress(status->ipV4Addr);
+
+ QMetaObject::invokeMethod(staticProvider, "agpsStatus", Qt::QueuedConnection,
+ Q_ARG(qint16, status->type), Q_ARG(quint16, status->status),
+ Q_ARG(QHostAddress, ipv4), Q_ARG(QHostAddress, ipv6),
+ Q_ARG(QByteArray, ssid), Q_ARG(QByteArray, password));
+ }
+ break;
+ case AGNSS_STATUS_IP_V6_CB:
+ {
+ QHostAddress ipv4;
+ QHostAddress ipv6;
+ QByteArray ssid;
+ QByteArray password;
+
+ const AGnssStatusIpV6 *status = geoclue_binder_gnss_decode_struct
+ (AGnssStatusIpV6, &reader);
+
+ ipv6.setAddress(status->ipV6Addr.data);
+
+ QMetaObject::invokeMethod(staticProvider, "agpsStatus", Qt::QueuedConnection,
+ Q_ARG(qint16, status->type), Q_ARG(quint16, status->status),
+ Q_ARG(QHostAddress, ipv4), Q_ARG(QHostAddress, ipv6),
+ Q_ARG(QByteArray, ssid), Q_ARG(QByteArray, password));
+ }
+ break;
+ default:
+ qWarning("Failed to decode callback %u\n", code);
+ break;
+ }
+ *status = GBINDER_STATUS_OK;
+ return gbinder_local_reply_append_int32(gbinder_local_object_new_reply(obj), 0);
+ } else {
+ qWarning("Unknown interface %s and code %u\n", iface, code);
+ *status = GBINDER_STATUS_FAILED;
+ }
+ return Q_NULLPTR;
+}
+
+
+static GBinderLocalReply *geoclue_binder_agnss_ril_callback(
+ GBinderLocalObject *obj,
+ GBinderRemoteRequest *req,
+ guint code,
+ guint flags,
+ int *status,
+ void *user_data)
+{
+ Q_UNUSED(flags)
+ Q_UNUSED(user_data)
+ const char *iface = gbinder_remote_request_interface(req);
+
+ if (!g_strcmp0(iface, AGNSS_RIL_CALLBACK)) {
+ GBinderReader reader;
+
+ gbinder_remote_request_init_reader(req, &reader);
+ switch (code) {
+ case AGNSS_RIL_REQUEST_REF_ID_CB:
+ qCDebug(lcGeoclueHybris) << "AGNSS RIL request ref ID";
+ break;
+ case AGNSS_RIL_REQUEST_REF_LOC_CB:
+ qCDebug(lcGeoclueHybris) << "AGNSS RIL request ref location";
+ break;
+ default:
+ qWarning("Failed to decode callback %u\n", code);
+ break;
+ }
+ *status = GBINDER_STATUS_OK;
+ return gbinder_local_reply_append_int32(gbinder_local_object_new_reply(obj), 0);
+ } else {
+ qWarning("Unknown interface %s and code %u\n", iface, code);
+ *status = GBINDER_STATUS_FAILED;
+ }
+ return Q_NULLPTR;
+}
+
+
+static GBinderLocalReply *geoclue_binder_gnss_ni_callback(
+ GBinderLocalObject *obj,
+ GBinderRemoteRequest *req,
+ guint code,
+ guint flags,
+ int *status,
+ void *user_data)
+{
+ Q_UNUSED(flags)
+ Q_UNUSED(user_data)
+ const char *iface = gbinder_remote_request_interface(req);
+
+ if (!g_strcmp0(iface, GNSS_NI_CALLBACK)) {
+ GBinderReader reader;
+
+ gbinder_remote_request_init_reader(req, &reader);
+ switch (code) {
+ case GNSS_NI_NOTIFY_CB:
+ qCDebug(lcGeoclueHybris) << "GNSS NI notify";
+ break;
+ default:
+ qWarning("Failed to decode callback %u\n", code);
+ break;
+ }
+ *status = GBINDER_STATUS_OK;
+ return gbinder_local_reply_append_int32(gbinder_local_object_new_reply(obj), 0);
+ } else {
+ qWarning("Unknown interface %s and code %u\n", iface, code);
+ *status = GBINDER_STATUS_FAILED;
+ }
+ return Q_NULLPTR;
+}
+
+static void geoclue_binder_gnss_gnss_died(
+ GBinderRemoteObject */*obj*/,
+ void *user_data)
+{
+ BinderLocationBackend *self = (BinderLocationBackend *)user_data;
+ self->dropGnss();
+}
+
+
+/*==========================================================================*
+ * Backend class
+ *==========================================================================*/
+
+BinderLocationBackend::BinderLocationBackend(QObject *parent)
+: HybrisLocationBackend(parent), m_death_id(0), m_fqname(Q_NULLPTR), m_sm(Q_NULLPTR),
+ m_clientGnss(Q_NULLPTR), m_remoteGnss(Q_NULLPTR), m_callbackGnss(Q_NULLPTR),
+ m_clientGnssDebug(Q_NULLPTR), m_remoteGnssDebug(Q_NULLPTR),
+ m_clientGnssNi(Q_NULLPTR), m_remoteGnssNi(Q_NULLPTR), m_callbackGnssNi(Q_NULLPTR),
+ m_clientGnssXtra(Q_NULLPTR), m_remoteGnssXtra(Q_NULLPTR), m_callbackGnssXtra(Q_NULLPTR),
+ m_clientAGnss(Q_NULLPTR), m_remoteAGnss(Q_NULLPTR), m_callbackAGnss(Q_NULLPTR),
+ m_clientAGnssRil(Q_NULLPTR), m_remoteAGnssRil(Q_NULLPTR), m_callbackAGnssRil(Q_NULLPTR)
+{
+}
+
+BinderLocationBackend::~BinderLocationBackend()
+{
+ dropGnss();
+}
+
+void BinderLocationBackend::dropGnss()
+{
+ if (m_callbackGnss) {
+ gbinder_local_object_drop(m_callbackGnss);
+ m_callbackGnss = Q_NULLPTR;
+ }
+ if (m_remoteGnss) {
+ gbinder_remote_object_remove_handler(m_remoteGnss, m_death_id);
+ gbinder_remote_object_unref(m_remoteGnss);
+ m_death_id = 0;
+ m_remoteGnss = Q_NULLPTR;
+ }
+ if (m_remoteGnssDebug) {
+ gbinder_remote_object_unref(m_remoteGnssDebug);
+ m_remoteGnssDebug = Q_NULLPTR;
+ }
+ if (m_callbackGnssNi) {
+ gbinder_local_object_drop(m_callbackGnssNi);
+ m_callbackGnssNi = Q_NULLPTR;
+ }
+ if (m_remoteGnssNi) {
+ gbinder_remote_object_unref(m_remoteGnssNi);
+ m_remoteGnssNi = Q_NULLPTR;
+ }
+ if (m_callbackGnssXtra) {
+ gbinder_local_object_drop(m_callbackGnssXtra);
+ m_callbackGnssXtra = Q_NULLPTR;
+ }
+ if (m_remoteGnssXtra) {
+ gbinder_remote_object_unref(m_remoteGnssXtra);
+ m_remoteGnssXtra = Q_NULLPTR;
+ }
+ if (m_callbackAGnss) {
+ gbinder_local_object_drop(m_callbackAGnss);
+ m_callbackAGnss = Q_NULLPTR;
+ }
+ if (m_remoteAGnss) {
+ gbinder_remote_object_unref(m_remoteAGnss);
+ m_remoteAGnss = Q_NULLPTR;
+ }
+ if (m_callbackAGnssRil) {
+ gbinder_local_object_drop(m_callbackAGnssRil);
+ m_callbackAGnssRil = Q_NULLPTR;
+ }
+ if (m_remoteAGnssRil) {
+ gbinder_remote_object_unref(m_remoteAGnssRil);
+ m_remoteAGnssRil = Q_NULLPTR;
+ }
+}
+
+bool BinderLocationBackend::isReplySuccess(GBinderRemoteReply *reply)
+{
+ GBinderReader reader;
+ gint32 status;
+ gboolean result;
+ gbinder_remote_reply_init_reader(reply, &reader);
+
+ if (!gbinder_reader_read_int32(&reader, &status) || status != 0) {
+ return false;
+ }
+ if (!gbinder_reader_read_bool(&reader, &result) || !result) {
+ return false;
+ }
+
+ return true;
+}
+
+GBinderRemoteObject *BinderLocationBackend::getExtensionObject(GBinderRemoteReply *reply)
+{
+ GBinderReader reader;
+ gint32 status;
+ gbinder_remote_reply_init_reader(reply, &reader);
+
+ if (!gbinder_reader_read_int32(&reader, &status) || status != 0) {
+ qWarning("Failed to get extension object %d\n", status);
+ return Q_NULLPTR;
+ }
+
+ return gbinder_reader_read_object(&reader);
+}
+
+// Gnss
+bool BinderLocationBackend::gnssInit()
+{
+ bool ret = false;
+
+ qWarning("Initialising GNSS interface\n");
+
+ m_sm = gbinder_servicemanager_new(GNSS_BINDER_DEFAULT_DEV);
+ if (m_sm) {
+ int status = 0;
+
+ /* Fetch remote reference from hwservicemanager */
+ m_fqname = g_strconcat(GNSS_REMOTE "/default", Q_NULLPTR);
+ m_remoteGnss = gbinder_servicemanager_get_service_sync(m_sm,
+ m_fqname, &status);
+
+ if (m_remoteGnss) {
+ GBinderLocalRequest *req;
+ GBinderRemoteReply *reply;
+
+ /* get_service returns auto-released reference,
+ * we need to add a reference of our own */
+ gbinder_remote_object_ref(m_remoteGnss);
+ m_clientGnss = gbinder_client_new(m_remoteGnss, GNSS_REMOTE);
+ m_death_id = gbinder_remote_object_add_death_handler
+ (m_remoteGnss, geoclue_binder_gnss_gnss_died, this);
+ m_callbackGnss = gbinder_servicemanager_new_local_object
+ (m_sm, GNSS_CALLBACK, geoclue_binder_gnss_callback, this);
+
+ /* IGnss::setCallback */
+ req = gbinder_client_new_request(m_clientGnss);
+ gbinder_local_request_append_local_object(req, m_callbackGnss);
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_SET_CALLBACK, req, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ gbinder_local_request_unref(req);
+ gbinder_remote_reply_unref(reply);
+ }
+ }
+
+ if (!ret) {
+ qWarning("Failed to initialise GNSS interface\n");
+ }
+ return ret;
+}
+
+bool BinderLocationBackend::gnssStart()
+{
+ bool ret = false;
+
+ if (m_clientGnss) {
+ int status = 0;
+ GBinderRemoteReply *reply;
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_START, Q_NULLPTR, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ gbinder_remote_reply_unref(reply);
+ }
+
+ if (!ret) {
+ qWarning("Failed to start positioning\n");
+ }
+ return ret;
+}
+
+bool BinderLocationBackend::gnssStop()
+{
+ bool ret = false;
+
+ if (m_clientGnss) {
+ int status = 0;
+ GBinderRemoteReply *reply;
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_STOP, Q_NULLPTR, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ gbinder_remote_reply_unref(reply);
+ }
+
+ if (!ret) {
+ qWarning("Failed to stop positioning\n");
+ }
+ return ret;
+}
+
+void BinderLocationBackend::gnssCleanup()
+{
+ if (m_clientGnss) {
+ const int status = gbinder_client_transact_sync_oneway(m_clientGnss,
+ GNSS_CLEANUP, Q_NULLPTR);
+
+ if (status) {
+ qWarning("Failed to cleanup\n");
+ }
+ }
+}
+
+bool BinderLocationBackend::gnssInjectLocation(double latitudeDegrees, double longitudeDegrees, float accuracyMeters)
+{
+ bool ret = false;
+
+ if (m_clientGnss) {
+ int status = 0;
+
+ GBinderLocalRequest *req;
+ GBinderRemoteReply *reply;
+ GBinderWriter writer;
+
+ req = gbinder_client_new_request(m_clientGnss);
+ gbinder_local_request_init_writer(req, &writer);
+ gbinder_writer_append_double(&writer, latitudeDegrees);
+ gbinder_writer_append_double(&writer, longitudeDegrees);
+ gbinder_writer_append_float(&writer, accuracyMeters);
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_INJECT_LOCATION, req, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+ if (!ret) {
+ qWarning("Failed to inject location\n");
+ }
+
+ gbinder_local_request_unref(req);
+ gbinder_remote_reply_unref(reply);
+ }
+ return ret;
+}
+
+bool BinderLocationBackend::gnssInjectTime(HybrisGnssUtcTime timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs)
+{
+ bool ret = false;
+
+ if (m_clientGnss) {
+ int status = 0;
+ GBinderLocalRequest *req;
+ GBinderRemoteReply *reply;
+ GBinderWriter writer;
+
+ req = gbinder_client_new_request(m_clientGnss);
+ gbinder_local_request_init_writer(req, &writer);
+ gbinder_writer_append_int64(&writer, timeMs);
+ gbinder_writer_append_int64(&writer, timeReferenceMs);
+ gbinder_writer_append_int32(&writer, uncertaintyMs);
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_INJECT_TIME, req, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ if (!ret) {
+ qWarning("Failed to inject time\n");
+ }
+ gbinder_local_request_unref(req);
+ gbinder_remote_reply_unref(reply);
+ }
+ return ret;
+}
+
+void BinderLocationBackend::gnssDeleteAidingData(HybrisGnssAidingData aidingDataFlags)
+{
+ if (m_clientGnss) {
+ GBinderLocalRequest *req;
+
+ req = gbinder_client_new_request(m_clientGnss);
+ gbinder_local_request_append_int32(req, aidingDataFlags);
+ gbinder_client_transact_sync_oneway(m_clientGnss,
+ GNSS_DELETE_AIDING_DATA, req);
+
+ gbinder_local_request_unref(req);
+ }
+}
+
+bool BinderLocationBackend::gnssSetPositionMode(HybrisGnssPositionMode mode, HybrisGnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs)
+{
+ bool ret = false;
+
+ if (m_clientGnss) {
+ int status = 0;
+ GBinderLocalRequest *req;
+ GBinderRemoteReply *reply;
+ GBinderWriter writer;
+
+ req = gbinder_client_new_request(m_clientGnss);
+ gbinder_local_request_init_writer(req, &writer);
+ gbinder_writer_append_int32(&writer, mode);
+ gbinder_writer_append_int32(&writer, recurrence);
+ gbinder_writer_append_int32(&writer, minIntervalMs);
+ gbinder_writer_append_int32(&writer, preferredAccuracyMeters);
+ gbinder_writer_append_int32(&writer, preferredTimeMs);
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_SET_POSITION_MODE, req, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ if (!ret) {
+ qWarning("GNSS set position mode failed\n");
+ }
+ gbinder_local_request_unref(req);
+ gbinder_remote_reply_unref(reply);
+ }
+ return ret;
+}
+
+// GnssDebug
+void BinderLocationBackend::gnssDebugInit()
+{
+ GBinderRemoteReply *reply;
+ int status = 0;
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_GET_EXTENSION_GNSS_DEBUG, Q_NULLPTR, &status);
+
+ if (!status) {
+ m_remoteGnssDebug = getExtensionObject(reply);
+ if (m_remoteGnssDebug) {
+ qWarning("Initialising GNSS Debug interface\n");
+ m_clientGnssDebug = gbinder_client_new(m_remoteGnssDebug, GNSS_DEBUG_REMOTE);
+ }
+ }
+ gbinder_remote_reply_unref(reply);
+}
+
+// GnnNi
+void BinderLocationBackend::gnssNiInit()
+{
+ GBinderRemoteReply *reply;
+ int status = 0;
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_GET_EXTENSION_GNSS_NI, Q_NULLPTR, &status);
+
+ if (!status) {
+ m_remoteGnssNi = getExtensionObject(reply);
+
+ if (m_remoteGnssNi) {
+ qWarning("Initialising GNSS NI interface\n");
+ GBinderLocalRequest *req;
+ m_clientGnssNi = gbinder_client_new(m_remoteGnssNi, GNSS_NI_REMOTE);
+ m_callbackGnssNi = gbinder_servicemanager_new_local_object
+ (m_sm, GNSS_NI_CALLBACK, geoclue_binder_gnss_ni_callback, this);
+
+ gbinder_remote_reply_unref(reply);
+
+ /* IGnssNi::setCallback */
+ req = gbinder_client_new_request(m_clientGnssNi);
+ gbinder_local_request_append_local_object(req, m_callbackGnssNi);
+ reply = gbinder_client_transact_sync_reply(m_clientGnssNi,
+ GNSS_NI_SET_CALLBACK, req, &status);
+
+ if (!status) {
+ if (!gbinder_remote_reply_read_int32(reply, &status) || status != 0) {
+ qWarning("Initialising GNSS NI interface failed %d\n", status);
+ }
+ }
+ gbinder_local_request_unref(req);
+ }
+ }
+ gbinder_remote_reply_unref(reply);
+}
+
+void BinderLocationBackend::gnssNiRespond(int32_t notifId, HybrisGnssUserResponseType userResponse)
+{
+ if (m_clientGnssNi) {
+ int status = 0;
+ GBinderLocalRequest *req;
+ GBinderRemoteReply *reply;
+ GBinderWriter writer;
+
+ req = gbinder_client_new_request(m_clientGnssNi);
+ gbinder_local_request_init_writer(req, &writer);
+ gbinder_writer_append_int32(&writer, notifId);
+ gbinder_writer_append_int32(&writer, userResponse);
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnssNi,
+ GNSS_NI_RESPOND, req, &status);
+
+ if (!status) {
+ if (!gbinder_remote_reply_read_int32(reply, &status) || status != 0) {
+ qWarning("GNSS NI respond failed %d\n", status);
+ }
+ }
+
+ gbinder_local_request_unref(req);
+ gbinder_remote_reply_unref(reply);
+ }
+}
+
+// GnssXtra
+void BinderLocationBackend::gnssXtraInit()
+{
+ GBinderRemoteReply *reply;
+ int status = 0;
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_GET_EXTENSION_XTRA, Q_NULLPTR, &status);
+
+ if (!status) {
+ m_remoteGnssXtra = getExtensionObject(reply);
+
+ if (m_remoteGnssXtra) {
+ qWarning("Initialising GNSS Xtra interface\n");
+ GBinderLocalRequest *req;
+ m_clientGnssXtra = gbinder_client_new(m_remoteGnssXtra, GNSS_XTRA_REMOTE);
+ m_callbackGnssXtra = gbinder_servicemanager_new_local_object
+ (m_sm, GNSS_XTRA_CALLBACK, geoclue_binder_gnss_xtra_callback, this);
+
+ gbinder_remote_reply_unref(reply);
+
+ /* IGnssXtra::setCallback */
+ req = gbinder_client_new_request(m_clientGnssXtra);
+ gbinder_local_request_append_local_object(req, m_callbackGnssXtra);
+ reply = gbinder_client_transact_sync_reply(m_clientGnssXtra,
+ GNSS_XTRA_SET_CALLBACK, req, &status);
+
+ if (status || !isReplySuccess(reply)) {
+ qWarning("Initialising GNSS Xtra interface failed\n");
+ }
+ gbinder_local_request_unref(req);
+ }
+ }
+ gbinder_remote_reply_unref(reply);
+}
+
+bool BinderLocationBackend::gnssXtraInjectXtraData(QByteArray &xtraData)
+{
+ bool ret = false;
+ if (m_clientGnssXtra) {
+ int status = 0;
+
+ GBinderLocalRequest *req;
+ GBinderRemoteReply *reply;
+
+ req = gbinder_client_new_request(m_clientGnssXtra);
+ gbinder_local_request_append_hidl_string(req, xtraData.constData());
+ reply = gbinder_client_transact_sync_reply(m_clientGnssXtra,
+ GNSS_XTRA_INJECT_XTRA_DATA, req, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ if (!ret) {
+ qWarning("GNSS Xtra inject xtra data failed\n");
+ }
+ gbinder_local_request_unref(req);
+ gbinder_remote_reply_unref(reply);
+ }
+ return ret;
+}
+
+// AGnss
+void BinderLocationBackend::aGnssInit()
+{
+ GBinderRemoteReply *reply;
+ int status = 0;
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_GET_EXTENSION_AGNSS, Q_NULLPTR, &status);
+
+ if (!status) {
+ m_remoteAGnss = getExtensionObject(reply);
+
+ if (m_remoteAGnss) {
+ qWarning("Initialising AGNSS interface\n");
+ GBinderLocalRequest *req;
+ m_clientAGnss = gbinder_client_new(m_remoteAGnss, AGNSS_REMOTE);
+ m_callbackAGnss = gbinder_servicemanager_new_local_object
+ (m_sm, AGNSS_CALLBACK, geoclue_binder_agnss_callback, this);
+
+ gbinder_remote_reply_unref(reply);
+
+ /* IAGnss::setCallback */
+ req = gbinder_client_new_request(m_clientAGnss);
+ gbinder_local_request_append_local_object(req, m_callbackAGnss);
+ reply = gbinder_client_transact_sync_reply(m_clientAGnss,
+ AGNSS_SET_CALLBACK, req, &status);
+
+ if (!status) {
+ if (!gbinder_remote_reply_read_int32(reply, &status) || status != 0) {
+ qWarning("Initialising AGNSS interface failed %d\n", status);
+ }
+ }
+ gbinder_local_request_unref(req);
+ }
+ }
+ gbinder_remote_reply_unref(reply);
+}
+
+bool BinderLocationBackend::aGnssDataConnClosed()
+{
+ int status = 0;
+ bool ret = false;
+ GBinderRemoteReply *reply;
+
+ reply = gbinder_client_transact_sync_reply(m_clientAGnss,
+ AGNSS_DATA_CONN_CLOSED, Q_NULLPTR, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ gbinder_remote_reply_unref(reply);
+ return ret;
+}
+
+bool BinderLocationBackend::aGnssDataConnFailed()
+{
+ int status = 0;
+ bool ret = false;
+ GBinderRemoteReply *reply;
+
+ reply = gbinder_client_transact_sync_reply(m_clientAGnss,
+ AGNSS_DATA_CONN_FAILED, Q_NULLPTR, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ gbinder_remote_reply_unref(reply);
+ return ret;
+}
+
+bool BinderLocationBackend::aGnssDataConnOpen(const QByteArray &apn, const QString &protocol)
+{
+ int status = 0;
+ bool ret = false;
+ GBinderLocalRequest *req;
+ GBinderRemoteReply *reply;
+ GBinderWriter writer;
+
+ req = gbinder_client_new_request(m_clientAGnss);
+
+ gbinder_local_request_init_writer(req, &writer);
+ gbinder_writer_append_hidl_string(&writer, apn.constData());
+ gbinder_writer_append_int32(&writer, fromContextProtocol(protocol));
+ reply = gbinder_client_transact_sync_reply(m_clientAGnss,
+ AGNSS_DATA_CONN_OPEN, req, &status);
+
+ if (!status) {
+ ret = isReplySuccess(reply);
+ }
+
+ gbinder_local_request_unref(req);
+ gbinder_remote_reply_unref(reply);
+
+ return ret;
+}
+
+// AGnssRil
+void BinderLocationBackend::aGnssRilInit()
+{
+ GBinderRemoteReply *reply;
+ int status = 0;
+
+ reply = gbinder_client_transact_sync_reply(m_clientGnss,
+ GNSS_GET_EXTENSION_AGNSS_RIL, Q_NULLPTR, &status);
+
+ if (!status) {
+ m_remoteAGnssRil = getExtensionObject(reply);
+
+ if (m_remoteAGnssRil) {
+ qWarning("Initialising AGNSS RIL interface\n");
+ GBinderLocalRequest *req;
+ m_clientAGnssRil = gbinder_client_new(m_remoteAGnssRil, AGNSS_RIL_REMOTE);
+ m_callbackAGnssRil = gbinder_servicemanager_new_local_object
+ (m_sm, AGNSS_RIL_CALLBACK, geoclue_binder_agnss_ril_callback, this);
+
+ gbinder_remote_reply_unref(reply);
+
+ /* IAGnssRil::setCallback */
+ req = gbinder_client_new_request(m_clientAGnssRil);
+ gbinder_local_request_append_local_object(req, m_callbackAGnssRil);
+ reply = gbinder_client_transact_sync_reply(m_clientAGnssRil,
+ AGNSS_RIL_SET_CALLBACK, req, &status);
+
+ if (!status) {
+ if (!gbinder_remote_reply_read_int32(reply, &status) || status != 0) {
+ qWarning("Initialising AGNSS RIL interface failed %d\n", status);
+ }
+ }
+ gbinder_local_request_unref(req);
+ }
+ }
+ gbinder_remote_reply_unref(reply);
+}
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/binder/binderlocationbackend.h
^
|
@@ -0,0 +1,105 @@
+/*
+ Copyright (C) 2015 Jolla Ltd.
+ Copyright (C) 2018 Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ Contact: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
+
+ This file is part of geoclue-hybris.
+
+ Geoclue-hybris is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License.
+*/
+
+#ifndef BINDERLOCATIONBACKEND_H
+#define BINDERLOCATIONBACKEND_H
+
+#include "hybrislocationbackend.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QBasicTimer>
+#include <QtCore/QQueue>
+#include <QtDBus/QDBusContext>
+#include <QtNetwork/QNetworkReply>
+
+#include <gbinder.h>
+#include <locationsettings.h>
+
+#include "gnss-binder-types.h"
+#include "locationtypes.h"
+
+class BinderLocationBackend : public HybrisLocationBackend
+{
+ Q_OBJECT
+public:
+ BinderLocationBackend(QObject *parent = 0);
+ ~BinderLocationBackend();
+
+ void dropGnss();
+
+ // Gnss
+ bool gnssInit();
+ bool gnssStart();
+ bool gnssStop();
+ void gnssCleanup();
+ bool gnssInjectTime(HybrisGnssUtcTime timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs);
+ bool gnssInjectLocation(double latitudeDegrees, double longitudeDegrees, float accuracyMeters);
+ void gnssDeleteAidingData(HybrisGnssAidingData aidingDataFlags);
+ bool gnssSetPositionMode(HybrisGnssPositionMode mode, HybrisGnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs);
+
+ // GnssDebug
+ void gnssDebugInit();
+
+ // GnnNi
+ void gnssNiInit();
+ void gnssNiRespond(int32_t notifId, HybrisGnssUserResponseType userResponse);
+
+ // GnssXtra
+ void gnssXtraInit();
+ bool gnssXtraInjectXtraData(QByteArray &xtraData);
+
+ // AGnss
+ void aGnssInit();
+ bool aGnssDataConnClosed();
+ bool aGnssDataConnFailed();
+ bool aGnssDataConnOpen(const QByteArray &apn, const QString &protocol);
+
+ // AGnssRil
+ void aGnssRilInit();
+
+private:
+ bool isReplySuccess(GBinderRemoteReply *reply);
+ GBinderRemoteObject *getExtensionObject(GBinderRemoteReply *reply);
+
+ gulong m_death_id;
+ char *m_fqname;
+ GBinderServiceManager *m_sm;
+
+ GBinderClient *m_clientGnss;
+ GBinderRemoteObject *m_remoteGnss;
+ GBinderLocalObject *m_callbackGnss;
+
+ GBinderClient *m_clientGnssDebug;
+ GBinderRemoteObject *m_remoteGnssDebug;
+
+ GBinderClient *m_clientGnssNi;
+ GBinderRemoteObject *m_remoteGnssNi;
+ GBinderLocalObject *m_callbackGnssNi;
+
+ GBinderClient *m_clientGnssXtra;
+ GBinderRemoteObject *m_remoteGnssXtra;
+ GBinderLocalObject *m_callbackGnssXtra;
+
+ GBinderClient *m_clientAGnss;
+ GBinderRemoteObject *m_remoteAGnss;
+ GBinderLocalObject *m_callbackAGnss;
+
+ GBinderClient *m_clientAGnssRil;
+ GBinderRemoteObject *m_remoteAGnssRil;
+ GBinderLocalObject *m_callbackAGnssRil;
+};
+
+#endif // BINDERLOCATIONBACKEND_H
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/binder/binderlocationbackend.pro
^
|
@@ -0,0 +1,9 @@
+include($$PWD/../geoclue-providers-hybris.pri)
+
+HEADERS += \
+ binderlocationbackend.h
+
+SOURCES += \
+ binderlocationbackend.cpp
+
+PKGCONFIG += libgbinder libglibutil gobject-2.0 glib-2.0
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/binder/gnss-binder-types.h
^
|
@@ -0,0 +1,154 @@
+/*
+ Copyright (C) 2015 Jolla Ltd.
+ Copyright (C) 2018 Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ Contact: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
+
+ This file is part of geoclue-hybris.
+
+ Geoclue-hybris is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License.
+*/
+
+#ifndef GNSS_BINDER_TYPES_H
+#define GNSS_BINDER_TYPES_H
+
+#include <gutil_types.h>
+
+#define ALIGNED(x) __attribute__ ((aligned(x)))
+
+typedef struct hidl_string {
+ union {
+ guint64 value;
+ const char *str;
+ } data;
+ guint32 len;
+ guint8 owns_buffer;
+} ALIGNED(4) HidlString;
+
+typedef struct hidl_vector {
+ union {
+ guint64 value;
+ const void *ptr;
+ } data;
+ guint32 count;
+ guint8 owns_buffer;
+} ALIGNED(4) HidlVector;
+
+template<typename T, size_t SIZE1>
+struct HidlArray {
+ T data[SIZE1];
+};
+
+typedef struct geoclue_binder_gnss GeoclueBinderGnss;
+
+typedef enum gnss_max {
+ SVS_COUNT = 64u,
+} GnssMax;
+
+typedef int64_t GnssUtcTime;
+
+enum class GnssConstellationType : guint8 {
+ UNKNOWN = 0,
+ GPS = 1,
+ SBAS = 2,
+ GLONASS = 3,
+ QZSS = 4,
+ BEIDOU = 5,
+ GALILEO = 6,
+};
+
+enum class GnssLocationFlags : guint16 {
+ HAS_LAT_LONG = 1, // 0x0001
+ HAS_ALTITUDE = 2, // 0x0002
+ HAS_SPEED = 4, // 0x0004
+ HAS_BEARING = 8, // 0x0008
+ HAS_HORIZONTAL_ACCURACY = 16, // 0x0010
+ HAS_VERTICAL_ACCURACY = 32, // 0x0020
+ HAS_SPEED_ACCURACY = 64, // 0x0040
+ HAS_BEARING_ACCURACY = 128, // 0x0080
+};
+
+enum {
+ HYBRIS_GNSS_SV_FLAGS_NONE = 0,
+ HYBRIS_GNSS_SV_FLAGS_HAS_EPHEMERIS_DATA = 1, //(1 << 0)
+ HYBRIS_GNSS_SV_FLAGS_HAS_ALMANAC_DATA = 2, //(1 << 1)
+ HYBRIS_GNSS_SV_FLAGS_USED_IN_FIX = 4, //(1 << 2)
+ HYBRIS_GNSS_SV_FLAGS_HAS_CARRIER_FREQUENCY = 8, //(1 << 3)
+};
+
+typedef struct gnss_location {
+ guint16 gnssLocationFlags ALIGNED(2);
+ gdouble latitudeDegrees ALIGNED(8);
+ gdouble longitudeDegrees ALIGNED(8);
+ gdouble altitudeMeters ALIGNED(8);
+ gfloat speedMetersPerSec ALIGNED(4);
+ gfloat bearingDegrees ALIGNED(4);
+ gfloat horizontalAccuracyMeters ALIGNED(4);
+ gfloat verticalAccuracyMeters ALIGNED(4);
+ gfloat speedAccuracyMetersPerSecond ALIGNED(4);
+ gfloat bearingAccuracyDegrees ALIGNED(4);
+ gint64 timestamp ALIGNED(8);
+} ALIGNED(8) GnssLocation;
+
+G_STATIC_ASSERT(sizeof(GnssLocation) == 64);
+
+typedef struct gnss_sv_info {
+ gint16 svid ALIGNED(2);
+ GnssConstellationType constellation ALIGNED(1);
+ gfloat cN0Dbhz ALIGNED(4);
+ gfloat elevationDegrees ALIGNED(4);
+ gfloat azimuthDegrees ALIGNED(4);
+ gfloat carrierFrequencyHz ALIGNED(4);
+ guint8 svFlag ALIGNED(1);
+} ALIGNED(4) GnssSvInfo;
+
+G_STATIC_ASSERT(sizeof(GnssSvInfo) == 24);
+
+typedef struct gnss_sv_status {
+ gint32 numSvs ALIGNED(4);
+ HidlArray<GnssSvInfo, 64> gnssSvList ALIGNED(4);
+} ALIGNED(4) GnssSvStatus;
+
+G_STATIC_ASSERT(sizeof(GnssSvStatus) == 1540);
+
+typedef uint8_t AGnssType;
+typedef uint8_t AGnssStatusValue;
+
+enum {
+ HYBRIS_GNSS_STATUS_NONE = 0,
+ HYBRIS_GNSS_STATUS_SESSION_BEGIN = 1,
+ HYBRIS_GNSS_STATUS_SESSION_END = 2,
+ HYBRIS_GNSS_STATUS_ENGINE_ON = 3,
+ HYBRIS_GNSS_STATUS_ENGINE_OFF = 4,
+};
+
+enum {
+ HYBRIS_GNSS_LOCATION_HAS_LAT_LONG = 1, // 0x0001
+ HYBRIS_GNSS_LOCATION_HAS_ALTITUDE = 2, // 0x0002
+ HYBRIS_GNSS_LOCATION_HAS_SPEED = 4, // 0x0004
+ HYBRIS_GNSS_LOCATION_HAS_BEARING = 8, // 0x0008
+ HYBRIS_GNSS_LOCATION_HAS_HORIZONTAL_ACCURACY = 16, // 0x0010
+ HYBRIS_GNSS_LOCATION_HAS_VERTICAL_ACCURACY = 32, // 0x0020
+ HYBRIS_GNSS_LOCATION_HAS_SPEED_ACCURACY = 64, // 0x0040
+ HYBRIS_GNSS_LOCATION_HAS_BEARING_ACCURACY = 128, // 0x0080
+};
+
+typedef struct agnss_status_ip_v4 {
+ AGnssType type ALIGNED(1);
+ AGnssStatusValue status ALIGNED(1);
+ gint32 ipV4Addr ALIGNED(4);
+} ALIGNED(4) AGnssStatusIpV4;
+
+G_STATIC_ASSERT(sizeof(AGnssStatusIpV4) == 8);
+
+typedef struct agnss_status_ip_v6 {
+ AGnssType type ALIGNED(1);
+ AGnssStatusValue status ALIGNED(1);
+ HidlArray<uint8_t, 16> ipV6Addr ALIGNED(1);
+} ALIGNED(1) AGnssStatusIpV6;
+
+G_STATIC_ASSERT(sizeof(AGnssStatusIpV6) == 18);
+
+#endif // GNSS_BINDER_TYPES_H
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/geoclue-providers-hybris.pri
^
|
@@ -0,0 +1,55 @@
+TARGET = geoclue-hybris
+CONFIG += console
+CONFIG -= app_bundle
+TEMPLATE = app
+
+target.path = /usr/libexec
+
+QT = core dbus network
+
+CONFIG += link_pkgconfig
+PKGCONFIG += connman-qt5 qofono-qt5 qofonoext systemsettings
+
+LIBS += -lrt
+
+dbus_geoclue.files = \
+ org.freedesktop.Geoclue.xml \
+ org.freedesktop.Geoclue.Position.xml \
+ org.freedesktop.Geoclue.Velocity.xml \
+ org.freedesktop.Geoclue.Satellite.xml
+dbus_geoclue.header_flags = "-l HybrisProvider -i hybrisprovider.h"
+dbus_geoclue.source_flags = "-l HybrisProvider"
+
+DBUS_ADAPTORS = \
+ dbus_geoclue
+
+DBUS_INTERFACES = \
+ com.jollamobile.Connectiond.xml \
+ com.jolla.lipstick.ConnectionSelector.xml
+
+session_dbus_service.files = org.freedesktop.Geoclue.Providers.Hybris.service
+session_dbus_service.path = /usr/share/dbus-1/services
+
+system_dbus_conf.files = com.jollamobile.gps.conf
+system_dbus_conf.path = /etc/dbus-1/system.d
+
+geoclue_provider.files = geoclue-hybris.provider
+geoclue_provider.path = /usr/share/geoclue-providers
+
+HEADERS += \
+ hybrislocationbackend.h \
+ hybrisprovider.h \
+ locationtypes.h
+
+SOURCES += \
+ main.cpp \
+ hybrisprovider.cpp
+
+OTHER_FILES = \
+ $${session_dbus_service.files} \
+ $${system_dbus_service.files} \
+ $${system_dbus_conf.files} \
+ $${geoclue_provider.files} \
+ rpm/geoclue-providers-hybris.spec
+
+INSTALLS += target session_dbus_service system_dbus_conf geoclue_provider
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/hal/hallocationbackend.cpp
^
|
@@ -0,0 +1,625 @@
+/*
+ Copyright (C) 2015 Jolla Ltd.
+ Contact: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
+
+ This file is part of geoclue-hybris.
+
+ Geoclue-hybris is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License.
+*/
+
+#include "hallocationbackend.h"
+
+#include "hybrisprovider.h"
+
+#include <QtNetwork/QHostAddress>
+
+#include <android-config.h>
+
+#include <strings.h>
+#include <sys/time.h>
+
+// Define versions of the Android GPS interface supported.
+#if ANDROID_VERSION_MAJOR >= 7
+ #define GEOCLUE_ANDROID_GPS_INTERFACE 3
+#elif ANDROID_VERSION_MAJOR >= 5
+ #define GEOCLUE_ANDROID_GPS_INTERFACE 2
+#elif ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR >= 2
+ #define GEOCLUE_ANDROID_GPS_INTERFACE 1
+#else
+ // By default expects Android 4.1
+#endif
+
+HybrisLocationBackend *getLocationBackend()
+{
+ return qobject_cast<HybrisLocationBackend *>(new HalLocationBackend());
+}
+
+namespace
+{
+
+const double KnotsToMps = 0.514444;
+
+void locationCallback(GpsLocation *location)
+{
+ Location loc;
+
+ loc.setTimestamp(location->timestamp);
+
+ if (location->flags & GPS_LOCATION_HAS_LAT_LONG) {
+ loc.setLatitude(location->latitude);
+ loc.setLongitude(location->longitude);
+ }
+
+ if (location->flags & GPS_LOCATION_HAS_ALTITUDE)
+ loc.setAltitude(location->altitude);
+
+ if (location->flags & GPS_LOCATION_HAS_SPEED)
+ loc.setSpeed(location->speed / KnotsToMps);
+
+ if (location->flags & GPS_LOCATION_HAS_BEARING)
+ loc.setDirection(location->bearing);
+
+ if (location->flags & GPS_LOCATION_HAS_ACCURACY) {
+ Accuracy accuracy;
+ accuracy.setHorizontal(location->accuracy);
+ accuracy.setVertical(location->accuracy);
+ loc.setAccuracy(accuracy);
+ }
+
+ QMetaObject::invokeMethod(staticProvider, "setLocation", Qt::QueuedConnection,
+ Q_ARG(Location, loc));
+}
+
+void statusCallback(GpsStatus *status)
+{
+ switch (status->status) {
+ case GPS_STATUS_ENGINE_ON:
+ QMetaObject::invokeMethod(staticProvider, "engineOn", Qt::QueuedConnection);
+ break;
+ case GPS_STATUS_ENGINE_OFF:
+ QMetaObject::invokeMethod(staticProvider, "engineOff", Qt::QueuedConnection);
+ break;
+ default:
+ ;
+ }
+}
+
+void svStatusCallback(GpsSvStatus *svStatus)
+{
+ QList<SatelliteInfo> satellites;
+ QList<int> usedPrns;
+
+ for (int i = 0; i < svStatus->num_svs; ++i) {
+ SatelliteInfo satInfo;
+ GpsSvInfo &svInfo = svStatus->sv_list[i];
+ satInfo.setPrn(svInfo.prn);
+ satInfo.setSnr(svInfo.snr);
+ satInfo.setElevation(svInfo.elevation);
+ satInfo.setAzimuth(svInfo.azimuth);
+ satellites.append(satInfo);
+
+ if (svStatus->used_in_fix_mask & (1 << i))
+ usedPrns.append(svInfo.prn);
+ }
+
+ QMetaObject::invokeMethod(staticProvider, "setSatellite", Qt::QueuedConnection,
+ Q_ARG(QList<SatelliteInfo>, satellites),
+ Q_ARG(QList<int>, usedPrns));
+}
+
+#if GEOCLUE_ANDROID_GPS_INTERFACE == 3
+void gnssSvStatusCallback(GnssSvStatus *svStatus)
+{
+ QList<SatelliteInfo> satellites;
+ QList<int> usedPrns;
+
+ for (int i = 0; i < svStatus->num_svs; ++i) {
+ SatelliteInfo satInfo;
+ GnssSvInfo &svInfo = svStatus->gnss_sv_list[i];
+ satInfo.setSnr(svInfo.c_n0_dbhz);
+ satInfo.setElevation(svInfo.elevation);
+ satInfo.setAzimuth(svInfo.azimuth);
+ int prn = svInfo.svid;
+ // From https://github.com/barbeau/gpstest
+ // and https://github.com/mvglasow/satstat/wiki/NMEA-IDs
+ if (svInfo.constellation == GNSS_CONSTELLATION_SBAS) {
+ prn -= 87;
+ } else if (svInfo.constellation == GNSS_CONSTELLATION_GLONASS) {
+ prn += 64;
+ } else if (svInfo.constellation == GNSS_CONSTELLATION_BEIDOU) {
+ prn += 200;
+ } else if (svInfo.constellation == GNSS_CONSTELLATION_GALILEO) {
+ prn += 300;
+ }
+ satInfo.setPrn(prn);
+ satellites.append(satInfo);
+
+ if (svInfo.flags & GNSS_SV_FLAGS_USED_IN_FIX)
+ usedPrns.append(svInfo.svid);
+ }
+
+ QMetaObject::invokeMethod(staticProvider, "setSatellite", Qt::QueuedConnection,
+ Q_ARG(QList<SatelliteInfo>, satellites),
+ Q_ARG(QList<int>, usedPrns));
+}
+#endif
+
+#ifdef USE_GPS_VENDOR_EXTENSION
+void gnssSvStatusCallback_custom(GnssSvStatus *svStatus)
+{
+ QList<SatelliteInfo> satellites;
+ QList<int> usedPrns;
+
+ for (int i = 0; i < svStatus->num_svs; ++i) {
+ SatelliteInfo satInfo;
+ GnssSvInfo &svInfo = svStatus->sv_list[i];
+ satInfo.setPrn(svInfo.prn);
+ satInfo.setSnr(svInfo.snr);
+ satInfo.setElevation(svInfo.elevation);
+ satInfo.setAzimuth(svInfo.azimuth);
+ satellites.append(satInfo);
+ }
+
+ QMetaObject::invokeMethod(staticProvider, "setSatellite", Qt::QueuedConnection,
+ Q_ARG(QList<SatelliteInfo>, satellites),
+ Q_ARG(QList<int>, usedPrns));
+}
+#endif
+
+bool nmeaChecksumValid(const QByteArray &nmea)
+{
+ unsigned char checksum = 0;
+ for (int i = 1; i < nmea.length(); ++i) {
+ if (nmea.at(i) == '*') {
+ if (nmea.length() < i+3)
+ return false;
+
+ checksum ^= nmea.mid(i+1, 2).toInt(0, 16);
+
+ break;
+ }
+
+ checksum ^= nmea.at(i);
+ }
+
+ return checksum == 0;
+}
+
+void parseRmc(const QByteArray &nmea)
+{
+ QList<QByteArray> fields = nmea.split(',');
+ if (fields.count() < 12)
+ return;
+
+ bool ok;
+ double variation = fields.at(10).toDouble(&ok);
+ if (ok) {
+ if (fields.at(11) == "W")
+ variation = -variation;
+
+ QMetaObject::invokeMethod(staticProvider, "setMagneticVariation", Qt::QueuedConnection,
+ Q_ARG(double, variation));
+ }
+}
+
+void nmeaCallback(GpsUtcTime timestamp, const char *nmeaData, int length)
+{
+ // Trim trailing whitepsace
+ while (length > 0 && isspace(nmeaData[length-1]))
+ --length;
+
+ if (length == 0)
+ return;
+
+ QByteArray nmea = QByteArray::fromRawData(nmeaData, length);
+
+ qCDebug(lcGeoclueHybrisNmea) << timestamp << nmea;
+
+ if (!nmeaChecksumValid(nmea))
+ return;
+
+ // truncate checksum and * from end of sentence
+ nmea.truncate(nmea.length()-3);
+
+ if (nmea.startsWith("$GPRMC"))
+ parseRmc(nmea);
+}
+
+void setCapabilitiesCallback(uint32_t capabilities)
+{
+ qCDebug(lcGeoclueHybris) << "capabilities" << showbase << hex << capabilities;
+}
+
+void acquireWakelockCallback()
+{
+}
+
+void releaseWakelockCallback()
+{
+}
+
+pthread_t createThreadCallback(const char *name, void (*start)(void *), void *arg)
+{
+ Q_UNUSED(name)
+
+ pthread_t threadId;
+
+ int error = pthread_create(&threadId, 0, (void*(*)(void*))start, arg);
+
+ return error ? 0 : threadId;
+}
+
+void requestUtcTimeCallback()
+{
+ qCDebug(lcGeoclueHybris);
+
+ QMetaObject::invokeMethod(staticProvider, "injectUtcTime", Qt::QueuedConnection);
+}
+
+#if GEOCLUE_ANDROID_GPS_INTERFACE == 3
+void gnssSetSystemInfoCallback(const GnssSystemInfo *info)
+{
+ Q_UNUSED(info)
+ qCDebug(lcGeoclueHybris);
+}
+#endif
+
+void agpsStatusCallback(AGpsStatus *status)
+{
+ QHostAddress ipv4;
+ QHostAddress ipv6;
+ QByteArray ssid;
+ QByteArray password;
+
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
+ if (status->addr.ss_family == AF_INET) {
+ ipv4.setAddress(status->ipaddr);
+ } else if (status->addr.ss_family == AF_INET6) {
+ qDebug() << "IPv6 address extraction is untested";
+ ipv6.setAddress(reinterpret_cast<sockaddr *>(&status->addr));
+ qDebug() << "IPv6 address:" << ipv6;
+ }
+#elif GEOCLUE_ANDROID_GPS_INTERFACE == 1
+ ipv4.setAddress(status->ipaddr);
+#else
+ ipv4.setAddress(status->ipv4_addr);
+ ssid = QByteArray(status->ssid, SSID_BUF_SIZE);
+ password = QByteArray(status->password, SSID_BUF_SIZE);
+#endif
+
+ QMetaObject::invokeMethod(staticProvider, "agpsStatus", Qt::QueuedConnection,
+ Q_ARG(qint16, status->type), Q_ARG(quint16, status->status),
+ Q_ARG(QHostAddress, ipv4), Q_ARG(QHostAddress, ipv6),
+ Q_ARG(QByteArray, ssid), Q_ARG(QByteArray, password));
+}
+
+void gpsNiNotifyCallback(GpsNiNotification *notification)
+{
+ Q_UNUSED(notification)
+ qCDebug(lcGeoclueHybris);
+}
+
+void agpsRilRequestSetId(uint32_t flags)
+{
+ Q_UNUSED(flags)
+ qCDebug(lcGeoclueHybris) << "flags" << showbase << hex << flags;
+}
+
+void agpsRilRequestRefLoc(uint32_t flags)
+{
+ Q_UNUSED(flags)
+ qCDebug(lcGeoclueHybris) << "flags" << showbase << hex << flags;
+}
+
+void gnssXtraDownloadRequest()
+{
+ QMetaObject::invokeMethod(staticProvider, "xtraDownloadRequest", Qt::QueuedConnection);
+}
+
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
+HybrisApnIpType fromContextProtocol(const QString &protocol)
+{
+ if (protocol == QLatin1String("ip"))
+ return APN_IP_IPV4;
+ else if (protocol == QLatin1String("ipv6"))
+ return APN_IP_IPV6;
+ else if (protocol == QLatin1String("dual"))
+ return APN_IP_IPV4V6;
+ else
+ return APN_IP_INVALID;
+}
+#elif GEOCLUE_ANDROID_GPS_INTERFACE == 1
+#else
+HybrisAGpsBearerType fromContextProtocol(const QString &protocol)
+{
+ if (protocol == QLatin1String("ip"))
+ return AGPS_APN_BEARER_IPV4;
+ else if (protocol == QLatin1String("ipv6"))
+ return AGPS_APN_BEARER_IPV6;
+ else if (protocol == QLatin1String("dual"))
+ return AGPS_APN_BEARER_IPV4V6;
+ else
+ return AGPS_APN_BEARER_INVALID;
+}
+#endif
+
+}
+
+GpsCallbacks gpsCallbacks = {
+ sizeof(GpsCallbacks),
+ locationCallback,
+ statusCallback,
+ svStatusCallback,
+#ifdef USE_GPS_VENDOR_EXTENSION
+ gnssSvStatusCallback_custom,
+#endif
+ nmeaCallback,
+ setCapabilitiesCallback,
+ acquireWakelockCallback,
+ releaseWakelockCallback,
+ createThreadCallback,
+ requestUtcTimeCallback,
+#if GEOCLUE_ANDROID_GPS_INTERFACE == 3
+ gnssSetSystemInfoCallback,
+ gnssSvStatusCallback,
+#endif
+};
+
+AGpsCallbacks agpsCallbacks = {
+ agpsStatusCallback,
+ createThreadCallback
+};
+
+GpsNiCallbacks gpsNiCallbacks = {
+ gpsNiNotifyCallback,
+ createThreadCallback
+};
+
+AGpsRilCallbacks agpsRilCallbacks = {
+ agpsRilRequestSetId,
+ agpsRilRequestRefLoc,
+ createThreadCallback
+};
+
+// Work-around for compatibility, the public definition of GpsXtraCallbacks has only two members,
+// however, some hardware adaptation definitions contain an extra report_xtra_server_cb member.
+// Add extra pointer length padding and initialise it to nullptr to prevent crashes.
+struct GpsXtraCallbacksWrapper {
+ GpsXtraCallbacks callbacks;
+ void *padding;
+} gpsXtraCallbacks = {
+ { gnssXtraDownloadRequest, createThreadCallback },
+ 0
+};
+
+HalLocationBackend::HalLocationBackend(QObject *parent)
+: HybrisLocationBackend(parent), m_gps(Q_NULLPTR), m_agps(Q_NULLPTR), m_agpsril(Q_NULLPTR), m_gpsni(Q_NULLPTR), m_xtra(Q_NULLPTR), m_debug(Q_NULLPTR)
+{
+}
+
+HalLocationBackend::~HalLocationBackend()
+{
+}
+
+// Gnss
+bool HalLocationBackend::gnssInit()
+{
+ const hw_module_t *hwModule;
+
+ int error = hw_get_module(GPS_HARDWARE_MODULE_ID, &hwModule);
+ if (error) {
+ qWarning("Android GPS interface not found, error %d\n", error);
+ return false;
+ }
+
+ qWarning("Android GPS hardware module \"%s\" \"%s\" %u.%u\n", hwModule->id, hwModule->name,
+ hwModule->module_api_version, hwModule->hal_api_version);
+
+ error = hwModule->methods->open(hwModule, GPS_HARDWARE_MODULE_ID,
+ reinterpret_cast<hw_device_t **>(&m_gpsDevice));
+ if (error) {
+ qWarning("Failed to open GPS device, error %d\n", error);
+ return false;
+ }
+
+ m_gps = m_gpsDevice->get_gps_interface(m_gpsDevice);
+ if (!m_gps)
+ return false;
+
+ qWarning("Initialising GPS interface\n");
+
+ error = m_gps->init(&gpsCallbacks);
+ if (error) {
+ qWarning("Failed to initialise GPS interface, error %d\n", error);
+ return false;
+ }
+
+ return true;
+}
+
+bool HalLocationBackend::gnssStart()
+{
+ if (m_gps) {
+ int error = m_gps->start();
+ if (error) {
+ qWarning("Failed to start positioning, error %d\n", error);
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool HalLocationBackend::gnssStop()
+{
+ if (m_gps) {
+ int error = m_gps->stop();
+ if (error) {
+ qWarning("Failed to stop positioning, error %d\n", error);
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+void HalLocationBackend::gnssCleanup()
+{
+ if (m_gps)
+ m_gps->cleanup();
+
+ if (m_gpsDevice->common.close)
+ m_gpsDevice->common.close(reinterpret_cast<hw_device_t *>(m_gpsDevice));
+}
+
+bool HalLocationBackend::gnssInjectLocation(double latitudeDegrees, double longitudeDegrees, float accuracyMeters)
+{
+ if (m_gps) {
+ int error = m_gps->inject_location(latitudeDegrees, longitudeDegrees, accuracyMeters);
+ if (error) {
+ qWarning("Failed to inject location, error %d\n", error);
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+bool HalLocationBackend::gnssInjectTime(HybrisGnssUtcTime timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs)
+{
+ if (m_gps) {
+ int error = m_gps->inject_time(timeMs, timeReferenceMs, uncertaintyMs);
+ if (error) {
+ qWarning("Failed to inject time, error %d\n", error);
+ return false;
+ }
+ return true;
+ }
+ return false;
+}
+
+void HalLocationBackend::gnssDeleteAidingData(HybrisGnssAidingData aidingDataFlags)
+{
+ Q_UNUSED(aidingDataFlags)
+}
+
+bool HalLocationBackend::gnssSetPositionMode(HybrisGnssPositionMode mode, HybrisGnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs)
+{
+ int error = m_gps->set_position_mode(mode, recurrence, minIntervalMs,
+ preferredAccuracyMeters, preferredTimeMs);
+ if (error) {
+ qWarning("While updating the updateInterval, failed to set position mode, error %d\n", error);
+ return false;
+ }
+ return true;
+}
+
+// GnssDebug
+void HalLocationBackend::gnssDebugInit()
+{
+ m_debug = static_cast<const GpsDebugInterface *>(m_gps->get_extension(GPS_DEBUG_INTERFACE));
+}
+
+// GnnNi
+void HalLocationBackend::gnssNiInit()
+{
+ m_gpsni = static_cast<const GpsNiInterface *>(m_gps->get_extension(GPS_NI_INTERFACE));
+ if (m_gpsni) {
+ qWarning("Initialising GPS NI Interface\n");
+ m_gpsni->init(&gpsNiCallbacks);
+ }
+}
+
+void HalLocationBackend::gnssNiRespond(int32_t notifId, HybrisGnssUserResponseType userResponse)
+{
+ m_gpsni->respond(notifId, userResponse);
+}
+
+// GnssXtra
+void HalLocationBackend::gnssXtraInit()
+{
+ m_xtra = static_cast<const GpsXtraInterface *>(m_gps->get_extension(GPS_XTRA_INTERFACE));
+ if (m_xtra) {
+ qWarning("Initialising GPS Xtra Interface\n");
+ int error = m_xtra->init(&gpsXtraCallbacks.callbacks);
+ if (error)
+ qWarning("GPS Xtra Interface init failed, error %d\n", error);
+ }
+}
+
+bool HalLocationBackend::gnssXtraInjectXtraData(QByteArray &xtraData)
+{
+ if (!m_xtra->inject_xtra_data(xtraData.data(), xtraData.length())) {
+ return true;
+ }
+ return false;
+}
+
+// AGnss
+void HalLocationBackend::aGnssInit()
+{
+ m_agps = static_cast<const AGpsInterface *>(m_gps->get_extension(AGPS_INTERFACE));
+ if (m_agps) {
+ qWarning("Initialising AGPS Interface\n");
+ m_agps->init(&agpsCallbacks);
+ }
+}
+
+bool HalLocationBackend::aGnssDataConnClosed()
+{
+ if (
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
+ !m_agps->data_conn_closed()
+#else
+ !m_agps->data_conn_closed(AGPS_TYPE_SUPL)
+#endif
+ ) {
+ return true;
+ }
+ return false;
+}
+
+bool HalLocationBackend::aGnssDataConnFailed()
+{
+ if (
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
+ !m_agps->data_conn_failed()
+#else
+ !m_agps->data_conn_failed(AGPS_TYPE_SUPL)
+#endif
+ ) {
+ return true;
+ }
+ return false;
+}
+
+bool HalLocationBackend::aGnssDataConnOpen(const QByteArray &apn, const QString &protocol)
+{
+ int error;
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
+ if (m_agps->data_conn_open_with_apn_ip_type)
+ error = m_agps->data_conn_open_with_apn_ip_type(apn.constData(), fromContextProtocol(protocol));
+ else
+ error = m_agps->data_conn_open(apn.constData());
+#elif GEOCLUE_ANDROID_GPS_INTERFACE == 1
+ error = m_agps->data_conn_open(apn.constData());
+#else
+ error = m_agps->data_conn_open(AGPS_TYPE_SUPL, apn.constData(), fromContextProtocol(protocol));
+#endif
+ return !error;
+}
+
+// AGnssRil
+void HalLocationBackend::aGnssRilInit()
+{
+ m_agpsril = static_cast<const AGpsRilInterface *>(m_gps->get_extension(AGPS_RIL_INTERFACE));
+ if (m_agpsril) {
+ qWarning("Initialising AGPS RIL Interface\n");
+ m_agpsril->init(&agpsRilCallbacks);
+ }
+}
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/hal/hallocationbackend.h
^
|
@@ -0,0 +1,84 @@
+/*
+ Copyright (C) 2015 Jolla Ltd.
+ Contact: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
+
+ This file is part of geoclue-hybris.
+
+ Geoclue-hybris is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License.
+*/
+
+#ifndef HALLOCATIONBACKEND_H
+#define HALLOCATIONBACKEND_H
+
+#include "hybrislocationbackend.h"
+
+#include <QtCore/QObject>
+#include <QtCore/QStringList>
+#include <QtCore/QBasicTimer>
+#include <QtCore/QQueue>
+#include <QtDBus/QDBusContext>
+#include <QtNetwork/QNetworkReply>
+
+#include <android-version.h>
+#include <hardware/gps.h>
+
+#include <locationsettings.h>
+
+#include "locationtypes.h"
+
+class HalLocationBackend : public HybrisLocationBackend
+{
+ Q_OBJECT
+public:
+ HalLocationBackend(QObject *parent = 0);
+ ~HalLocationBackend();
+
+ // Gnss
+ bool gnssInit();
+ bool gnssStart();
+ bool gnssStop();
+ void gnssCleanup();
+ bool gnssInjectTime(HybrisGnssUtcTime timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs);
+ bool gnssInjectLocation(double latitudeDegrees, double longitudeDegrees, float accuracyMeters);
+ void gnssDeleteAidingData(HybrisGnssAidingData aidingDataFlags);
+ bool gnssSetPositionMode(HybrisGnssPositionMode mode, HybrisGnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs);
+
+ // GnssDebug
+ void gnssDebugInit();
+
+ // GnnNi
+ void gnssNiInit();
+ void gnssNiRespond(int32_t notifId, HybrisGnssUserResponseType userResponse);
+
+ // GnssXtra
+ void gnssXtraInit();
+ bool gnssXtraInjectXtraData(QByteArray &xtraData);
+
+ // AGnss
+ void aGnssInit();
+ bool aGnssDataConnClosed();
+ bool aGnssDataConnFailed();
+ bool aGnssDataConnOpen(const QByteArray &apn, const QString &protocol);
+
+ // AGnssRil
+ void aGnssRilInit();
+
+private:
+ gps_device_t *m_gpsDevice;
+
+ const GpsInterface *m_gps;
+
+ const AGpsInterface *m_agps;
+ const AGpsRilInterface *m_agpsril;
+ const GpsNiInterface *m_gpsni;
+ const GpsXtraInterface *m_xtra;
+
+ const GpsDebugInterface *m_debug;
+};
+
+#endif // HALLOCATIONBACKEND_H
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/hal/hallocationbackend.pro
^
|
@@ -0,0 +1,9 @@
+include($$PWD/../geoclue-providers-hybris.pri)
+
+HEADERS += \
+ hallocationbackend.h
+
+SOURCES += \
+ hallocationbackend.cpp
+
+PKGCONFIG += libhardware android-headers
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/hybrislocationbackend.h
^
|
@@ -0,0 +1,147 @@
+/*
+ Copyright (C) 2015 Jolla Ltd.
+ Copyright (C) 2018 Matti Lehtimäki <matti.lehtimaki@gmail.com>
+ Contact: Aaron McCarthy <aaron.mccarthy@jollamobile.com>
+
+ This file is part of geoclue-hybris.
+
+ Geoclue-hybris is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License.
+*/
+
+#ifndef HYBRIS_LOCATION_BACKEND_H
+#define HYBRIS_LOCATION_BACKEND_H
+
+#include <cstdint>
+
+#include <QtCore/QObject>
+#include <QtCore/QString>
+
+/** Milliseconds since January 1, 1970 */
+typedef int64_t HybrisGnssUtcTime;
+
+/** Requested operational mode for GPS operation. */
+typedef uint32_t HybrisGnssPositionMode;
+
+/** Requested recurrence mode for GPS operation. */
+typedef uint32_t HybrisGnssPositionRecurrence;
+
+/** GPS status event values. */
+typedef uint16_t HybrisGnssStatusValue;
+
+/** Flags to indicate which values are valid in a GpsLocation. */
+typedef uint16_t HybrisGnssLocationFlags;
+
+/**
+ * Flags used to specify which aiding data to delete when calling
+ * delete_aiding_data().
+ */
+typedef uint16_t HybrisGnssAidingData;
+
+/** AGPS type */
+typedef uint16_t HybrisAGnssType;
+
+typedef uint16_t HybrisAGnssSetIDType;
+
+typedef uint16_t HybrisApnIpType;
+
+typedef int16_t HybrisAGpsBearerType;
+
+/**
+ * HybrisGnssNiType constants
+ */
+typedef uint32_t HybrisGnssNiType;
+
+/**
+ * HybrisGnssNiNotifyFlags constants
+ */
+typedef uint32_t HybrisGnssNiNotifyFlags;
+
+/**
+ * GPS NI responses, used to define the response in
+ * NI structures
+ */
+typedef int HybrisGnssUserResponseType;
+
+/**
+ * NI data encoding scheme
+ */
+typedef int HybrisGnssNiEncodingType;
+
+/** AGPS status event values. */
+typedef uint16_t HybrisAGnssStatusValue;
+
+typedef uint16_t HybrisAGnssRefLocationType;
+
+typedef int HybrisNetworkType;
+
+enum {
+ HYBRIS_GNSS_POSITION_MODE_STANDALONE = 0,
+ HYBRIS_GNSS_POSITION_MODE_MS_BASED = 1,
+ HYBRIS_GNSS_POSITION_MODE_MS_ASSISTED = 2,
+};
+
+enum {
+ HYBRIS_GNSS_POSITION_RECURRENCE_PERIODIC = 0,
+ HYBRIS_GNSS_POSITION_RECURRENCE_SINGLE = 1,
+};
+
+enum {
+ HYBRIS_AGNSS_TYPE_SUPL = 1,
+ HYBRIS_AGNSS_TYPE_C2K = 2,
+};
+
+enum {
+ HYBRIS_GNSS_REQUEST_AGNSS_DATA_CONN = 1,
+ HYBRIS_GNSS_RELEASE_AGNSS_DATA_CONN = 2,
+ HYBRIS_GNSS_AGNSS_DATA_CONNECTED = 3,
+ HYBRIS_GNSS_AGNSS_DATA_CONN_DONE = 4,
+ HYBRIS_GNSS_AGNSS_DATA_CONN_FAILED = 5,
+};
+
+class HybrisLocationBackend : public QObject
+{
+ Q_OBJECT
+public:
+ explicit HybrisLocationBackend(QObject *parent = 0) : QObject(parent) {};
+ virtual ~HybrisLocationBackend() {}
+
+ // Gnss
+ virtual bool gnssInit() = 0;
+ virtual bool gnssStart() = 0;
+ virtual bool gnssStop() = 0;
+ virtual void gnssCleanup() = 0;
+ virtual bool gnssInjectTime(HybrisGnssUtcTime timeMs, int64_t timeReferenceMs, int32_t uncertaintyMs) = 0;
+ virtual bool gnssInjectLocation(double latitudeDegrees, double longitudeDegrees, float accuracyMeters) = 0;
+ virtual void gnssDeleteAidingData(HybrisGnssAidingData aidingDataFlags) = 0;
+ virtual bool gnssSetPositionMode(HybrisGnssPositionMode mode, HybrisGnssPositionRecurrence recurrence,
+ uint32_t minIntervalMs, uint32_t preferredAccuracyMeters,
+ uint32_t preferredTimeMs) = 0;
+
+ // GnssDebug
+ virtual void gnssDebugInit() = 0;
+
+ // GnnNi
+ virtual void gnssNiInit() = 0;
+ virtual void gnssNiRespond(int32_t notifId, HybrisGnssUserResponseType userResponse) = 0;
+
+ // GnssXtra
+ virtual void gnssXtraInit() = 0;
+ virtual bool gnssXtraInjectXtraData(QByteArray &xtraData) = 0;
+
+ // AGnss
+ virtual void aGnssInit() = 0;
+ virtual bool aGnssDataConnClosed() = 0;
+ virtual bool aGnssDataConnFailed() = 0;
+ virtual bool aGnssDataConnOpen(const QByteArray &apn, const QString &protocol) = 0;
+
+ // AGnssRil
+ virtual void aGnssRilInit() = 0;
+
+};
+
+HybrisLocationBackend *getLocationBackend();
+
+#endif // HYBRIS_LOCATION_BACKEND_H
|
[-]
[+]
|
Changed |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/hybrisprovider.cpp
^
|
@@ -20,7 +20,6 @@
#include "connectiond_interface.h"
#include "connectionselector_interface.h"
-#include <QtCore/QLoggingCategory>
#include <QtNetwork/QNetworkAccessManager>
#include <QtNetwork/QNetworkReply>
#include <QtNetwork/QHostAddress>
@@ -38,8 +37,6 @@
#include <qofonoextmodemmanager.h>
-#include <android-config.h>
-
#include <strings.h>
#include <sys/time.h>
@@ -49,11 +46,11 @@
Q_LOGGING_CATEGORY(lcGeoclueHybrisNmea, "geoclue.provider.hybris.nmea")
Q_LOGGING_CATEGORY(lcGeoclueHybrisPosition, "geoclue.provider.hybris.position")
+HybrisProvider *staticProvider = Q_NULLPTR;
+
namespace
{
-HybrisProvider *staticProvider = 0;
-
const int QuitIdleTime = 30000;
const int FixTimeout = 30000;
const quint32 MinimumInterval = 1000;
@@ -76,347 +73,11 @@
const int MaxXtraServers = 3;
const QString XtraConfigFile = QStringLiteral("/etc/gps_xtra.ini");
-void locationCallback(GpsLocation *location)
-{
- Location loc;
-
- loc.setTimestamp(location->timestamp);
-
- if (location->flags & GPS_LOCATION_HAS_LAT_LONG) {
- loc.setLatitude(location->latitude);
- loc.setLongitude(location->longitude);
- }
-
- if (location->flags & GPS_LOCATION_HAS_ALTITUDE)
- loc.setAltitude(location->altitude);
-
- if (location->flags & GPS_LOCATION_HAS_SPEED)
- loc.setSpeed(location->speed / KnotsToMps);
-
- if (location->flags & GPS_LOCATION_HAS_BEARING)
- loc.setDirection(location->bearing);
-
- if (location->flags & GPS_LOCATION_HAS_ACCURACY) {
- Accuracy accuracy;
- accuracy.setHorizontal(location->accuracy);
- accuracy.setVertical(location->accuracy);
- loc.setAccuracy(accuracy);
- }
-
- QMetaObject::invokeMethod(staticProvider, "setLocation", Qt::QueuedConnection,
- Q_ARG(Location, loc));
-}
-
-void statusCallback(GpsStatus *status)
-{
- switch (status->status) {
- case GPS_STATUS_ENGINE_ON:
- QMetaObject::invokeMethod(staticProvider, "engineOn", Qt::QueuedConnection);
- break;
- case GPS_STATUS_ENGINE_OFF:
- QMetaObject::invokeMethod(staticProvider, "engineOff", Qt::QueuedConnection);
- break;
- default:
- ;
- }
-}
-
-void svStatusCallback(GpsSvStatus *svStatus)
-{
- QList<SatelliteInfo> satellites;
- QList<int> usedPrns;
-
- for (int i = 0; i < svStatus->num_svs; ++i) {
- SatelliteInfo satInfo;
- GpsSvInfo &svInfo = svStatus->sv_list[i];
- satInfo.setPrn(svInfo.prn);
- satInfo.setSnr(svInfo.snr);
- satInfo.setElevation(svInfo.elevation);
- satInfo.setAzimuth(svInfo.azimuth);
- satellites.append(satInfo);
-
- if (svStatus->used_in_fix_mask & (1 << i))
- usedPrns.append(svInfo.prn);
- }
-
- QMetaObject::invokeMethod(staticProvider, "setSatellite", Qt::QueuedConnection,
- Q_ARG(QList<SatelliteInfo>, satellites),
- Q_ARG(QList<int>, usedPrns));
-}
-
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 3
-void gnssSvStatusCallback(GnssSvStatus *svStatus)
-{
- QList<SatelliteInfo> satellites;
- QList<int> usedPrns;
-
- for (int i = 0; i < svStatus->num_svs; ++i) {
- SatelliteInfo satInfo;
- GnssSvInfo &svInfo = svStatus->gnss_sv_list[i];
- satInfo.setPrn(svInfo.svid);
- satInfo.setSnr(svInfo.c_n0_dbhz);
- satInfo.setElevation(svInfo.elevation);
- satInfo.setAzimuth(svInfo.azimuth);
- satellites.append(satInfo);
-
- if (svInfo.flags & GNSS_SV_FLAGS_USED_IN_FIX)
- usedPrns.append(svInfo.svid);
- }
-
- QMetaObject::invokeMethod(staticProvider, "setSatellite", Qt::QueuedConnection,
- Q_ARG(QList<SatelliteInfo>, satellites),
- Q_ARG(QList<int>, usedPrns));
-}
-#endif
-
-#ifdef USE_GPS_VENDOR_EXTENSION
-void gnssSvStatusCallback_custom(GnssSvStatus *svStatus)
-{
- QList<SatelliteInfo> satellites;
- QList<int> usedPrns;
-
- for (int i = 0; i < svStatus->num_svs; ++i) {
- SatelliteInfo satInfo;
- GnssSvInfo &svInfo = svStatus->sv_list[i];
- satInfo.setPrn(svInfo.prn);
- satInfo.setSnr(svInfo.snr);
- satInfo.setElevation(svInfo.elevation);
- satInfo.setAzimuth(svInfo.azimuth);
- satellites.append(satInfo);
- }
-
- QMetaObject::invokeMethod(staticProvider, "setSatellite", Qt::QueuedConnection,
- Q_ARG(QList<SatelliteInfo>, satellites),
- Q_ARG(QList<int>, usedPrns));
-}
-#endif
-
-bool nmeaChecksumValid(const QByteArray &nmea)
-{
- unsigned char checksum = 0;
- for (int i = 1; i < nmea.length(); ++i) {
- if (nmea.at(i) == '*') {
- if (nmea.length() < i+3)
- return false;
-
- checksum ^= nmea.mid(i+1, 2).toInt(0, 16);
-
- break;
- }
-
- checksum ^= nmea.at(i);
- }
-
- return checksum == 0;
-}
-
-void parseRmc(const QByteArray &nmea)
-{
- QList<QByteArray> fields = nmea.split(',');
- if (fields.count() < 12)
- return;
-
- bool ok;
- double variation = fields.at(10).toDouble(&ok);
- if (ok) {
- if (fields.at(11) == "W")
- variation = -variation;
-
- QMetaObject::invokeMethod(staticProvider, "setMagneticVariation", Qt::QueuedConnection,
- Q_ARG(double, variation));
- }
-}
-
-void nmeaCallback(GpsUtcTime timestamp, const char *nmeaData, int length)
-{
- // Trim trailing whitepsace
- while (length > 0 && isspace(nmeaData[length-1]))
- --length;
-
- if (length == 0)
- return;
-
- QByteArray nmea = QByteArray::fromRawData(nmeaData, length);
-
- qCDebug(lcGeoclueHybrisNmea) << timestamp << nmea;
-
- if (!nmeaChecksumValid(nmea))
- return;
-
- // truncate checksum and * from end of sentence
- nmea.truncate(nmea.length()-3);
-
- if (nmea.startsWith("$GPRMC"))
- parseRmc(nmea);
-}
-
-void setCapabilitiesCallback(uint32_t capabilities)
-{
- qCDebug(lcGeoclueHybris) << "capabilities" << showbase << hex << capabilities;
-}
-
-void acquireWakelockCallback()
-{
-}
-
-void releaseWakelockCallback()
-{
-}
-
-pthread_t createThreadCallback(const char *name, void (*start)(void *), void *arg)
-{
- Q_UNUSED(name)
-
- pthread_t threadId;
-
- int error = pthread_create(&threadId, 0, (void*(*)(void*))start, arg);
-
- return error ? 0 : threadId;
-}
-
-void requestUtcTimeCallback()
-{
- qCDebug(lcGeoclueHybris);
-
- QMetaObject::invokeMethod(staticProvider, "injectUtcTime", Qt::QueuedConnection);
-}
-
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 3
-void gnssSetSystemInfoCallback(const GnssSystemInfo *info)
-{
- Q_UNUSED(info)
- qCDebug(lcGeoclueHybris);
-}
-#endif
-
-void agpsStatusCallback(AGpsStatus *status)
-{
- QHostAddress ipv4;
- QHostAddress ipv6;
- QByteArray ssid;
- QByteArray password;
-
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
- if (status->addr.ss_family == AF_INET) {
- ipv4.setAddress(status->ipaddr);
- } else if (status->addr.ss_family == AF_INET6) {
- qDebug() << "IPv6 address extraction is untested";
- ipv6.setAddress(reinterpret_cast<sockaddr *>(&status->addr));
- qDebug() << "IPv6 address:" << ipv6;
- }
-#elif GEOCLUE_ANDROID_GPS_INTERFACE == 1
- ipv4.setAddress(status->ipaddr);
-#else
- ipv4.setAddress(status->ipv4_addr);
- ssid = QByteArray(status->ssid, SSID_BUF_SIZE);
- password = QByteArray(status->password, SSID_BUF_SIZE);
-#endif
-
- QMetaObject::invokeMethod(staticProvider, "agpsStatus", Qt::QueuedConnection,
- Q_ARG(qint16, status->type), Q_ARG(quint16, status->status),
- Q_ARG(QHostAddress, ipv4), Q_ARG(QHostAddress, ipv6),
- Q_ARG(QByteArray, ssid), Q_ARG(QByteArray, password));
-}
-
-void gpsNiNotifyCallback(GpsNiNotification *notification)
-{
- Q_UNUSED(notification)
- qCDebug(lcGeoclueHybris);
-}
-
-void agpsRilRequestSetId(uint32_t flags)
-{
- Q_UNUSED(flags)
- qCDebug(lcGeoclueHybris) << "flags" << showbase << hex << flags;
-}
-
-void agpsRilRequestRefLoc(uint32_t flags)
-{
- Q_UNUSED(flags)
- qCDebug(lcGeoclueHybris) << "flags" << showbase << hex << flags;
-}
-
-void gpsXtraDownloadRequest()
+void gnssXtraDownloadRequest()
{
QMetaObject::invokeMethod(staticProvider, "xtraDownloadRequest", Qt::QueuedConnection);
}
-
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
-ApnIpType fromContextProtocol(const QString &protocol)
-{
- if (protocol == QLatin1String("ip"))
- return APN_IP_IPV4;
- else if (protocol == QLatin1String("ipv6"))
- return APN_IP_IPV6;
- else if (protocol == QLatin1String("dual"))
- return APN_IP_IPV4V6;
- else
- return APN_IP_INVALID;
-}
-#elif GEOCLUE_ANDROID_GPS_INTERFACE == 1
-#else
-AGpsBearerType fromContextProtocol(const QString &protocol)
-{
- if (protocol == QLatin1String("ip"))
- return AGPS_APN_BEARER_IPV4;
- else if (protocol == QLatin1String("ipv6"))
- return AGPS_APN_BEARER_IPV6;
- else if (protocol == QLatin1String("dual"))
- return AGPS_APN_BEARER_IPV4V6;
- else
- return AGPS_APN_BEARER_INVALID;
-}
-#endif
-
-}
-
-GpsCallbacks gpsCallbacks = {
- sizeof(GpsCallbacks),
- locationCallback,
- statusCallback,
- svStatusCallback,
-#ifdef USE_GPS_VENDOR_EXTENSION
- gnssSvStatusCallback_custom,
-#endif
- nmeaCallback,
- setCapabilitiesCallback,
- acquireWakelockCallback,
- releaseWakelockCallback,
- createThreadCallback,
- requestUtcTimeCallback,
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 3
- gnssSetSystemInfoCallback,
- gnssSvStatusCallback,
-#endif
-};
-
-AGpsCallbacks agpsCallbacks = {
- agpsStatusCallback,
- createThreadCallback
-};
-
-GpsNiCallbacks gpsNiCallbacks = {
- gpsNiNotifyCallback,
- createThreadCallback
-};
-
-AGpsRilCallbacks agpsRilCallbacks = {
- agpsRilRequestSetId,
- agpsRilRequestRefLoc,
- createThreadCallback
-};
-
-// Work-around for compatibility, the public definition of GpsXtraCallbacks has only two members,
-// however, some hardware adaptation definitions contain an extra report_xtra_server_cb member.
-// Add extra pointer length padding and initialise it to nullptr to prevent crashes.
-struct GpsXtraCallbacksWrapper {
- GpsXtraCallbacks callbacks;
- void *padding;
-} gpsXtraCallbacks = {
- { gpsXtraDownloadRequest, createThreadCallback },
- 0
-};
-
+}
QDBusArgument &operator<<(QDBusArgument &argument, const Accuracy &accuracy)
{
@@ -494,12 +155,12 @@
}
HybrisProvider::HybrisProvider(QObject *parent)
-: QObject(parent), m_gps(0), m_agps(0), m_agpsril(0), m_gpsni(0), m_xtra(0),
- m_status(StatusUnavailable), m_positionInjectionConnected(false), m_xtraDownloadReply(0), m_xtraServerIndex(0),
- m_requestedConnect(false), m_gpsStarted(false), m_locationSettings(0),
- m_networkManager(new NetworkManager(this)), m_cellularTechnology(0),
+: QObject(parent), m_backend(Q_NULLPTR),
+ m_status(StatusUnavailable), m_positionInjectionConnected(false), m_xtraDownloadReply(Q_NULLPTR), m_xtraServerIndex(0),
+ m_requestedConnect(false), m_gpsStarted(false), m_locationSettings(Q_NULLPTR),
+ m_networkManager(new NetworkManager(this)), m_cellularTechnology(Q_NULLPTR),
m_ofonoExtModemManager(new QOfonoExtModemManager(this)),
- m_connectionManager(new QOfonoConnectionManager(this)), m_connectionContext(0), m_ntpSocket(0),
+ m_connectionManager(new QOfonoConnectionManager(this)), m_connectionContext(Q_NULLPTR), m_ntpSocket(Q_NULLPTR),
m_agpsEnabled(false), m_agpsOnlineEnabled(false), m_useForcedXtraInject(false), m_xtraUserAgent("")
{
if (staticProvider)
@@ -593,74 +254,26 @@
}
}
- const hw_module_t *hwModule;
+ m_backend = getLocationBackend();
- int error = hw_get_module(GPS_HARDWARE_MODULE_ID, &hwModule);
- if (error) {
- qWarning("Android GPS interface not found, error %d\n", error);
- return;
- }
-
- qWarning("Android GPS hardware module \"%s\" \"%s\" %u.%u\n", hwModule->id, hwModule->name,
- hwModule->module_api_version, hwModule->hal_api_version);
-
- error = hwModule->methods->open(hwModule, GPS_HARDWARE_MODULE_ID,
- reinterpret_cast<hw_device_t **>(&m_gpsDevice));
- if (error) {
- qWarning("Failed to open GPS device, error %d\n", error);
- return;
- }
-
- m_gps = m_gpsDevice->get_gps_interface(m_gpsDevice);
- if (!m_gps) {
+ if (!m_backend || !m_backend->gnssInit()) {
m_status = StatusError;
return;
}
- qWarning("Initialising GPS interface\n");
- error = m_gps->init(&gpsCallbacks);
- if (error) {
- qWarning("Failed to initialise GPS interface, error %d\n", error);
- m_status = StatusError;
- return;
- }
-
- m_agps = static_cast<const AGpsInterface *>(m_gps->get_extension(AGPS_INTERFACE));
- if (m_agps) {
- qWarning("Initialising AGPS Interface\n");
- m_agps->init(&agpsCallbacks);
- }
-
- m_gpsni = static_cast<const GpsNiInterface *>(m_gps->get_extension(GPS_NI_INTERFACE));
- if (m_gpsni) {
- qWarning("Initialising GPS NI Interface\n");
- m_gpsni->init(&gpsNiCallbacks);
- }
-
- m_agpsril = static_cast<const AGpsRilInterface *>(m_gps->get_extension(AGPS_RIL_INTERFACE));
- if (m_agpsril) {
- qWarning("Initialising AGPS RIL Interface\n");
- m_agpsril->init(&agpsRilCallbacks);
- }
-
- m_xtra = static_cast<const GpsXtraInterface *>(m_gps->get_extension(GPS_XTRA_INTERFACE));
- if (m_xtra) {
- qWarning("Initialising GPS Xtra Interface\n");
- error = m_xtra->init(&gpsXtraCallbacks.callbacks);
- if (error)
- qWarning("GPS Xtra Interface init failed, error %d\n", error);
- }
-
- m_debug = static_cast<const GpsDebugInterface *>(m_gps->get_extension(GPS_DEBUG_INTERFACE));
+ m_backend->aGnssInit();
+ m_backend->gnssNiInit();
+ m_backend->aGnssRilInit();
+ m_backend->gnssXtraInit();
+ m_backend->gnssDebugInit();
}
HybrisProvider::~HybrisProvider()
{
- if (m_gps)
- m_gps->cleanup();
-
- if (m_gpsDevice->common.close)
- m_gpsDevice->common.close(reinterpret_cast<hw_device_t *>(m_gpsDevice));
+ if (m_backend) {
+ m_backend->gnssCleanup();
+ delete m_backend;
+ }
if (staticProvider == this)
staticProvider = 0;
@@ -753,13 +366,10 @@
quint32 updateInterval = minimumRequestedUpdateInterval();
- int error = m_gps->set_position_mode(m_agpsEnabled ? GPS_POSITION_MODE_MS_BASED
- : GPS_POSITION_MODE_STANDALONE,
- GPS_POSITION_RECURRENCE_PERIODIC, updateInterval,
- PreferredAccuracy, PreferredInitialFixTime);
- if (error) {
- qWarning("While updating the updateInterval, failed to set position mode, error %d\n", error);
- }
+ m_backend->gnssSetPositionMode(m_agpsEnabled ? HYBRIS_GNSS_POSITION_MODE_MS_BASED
+ : HYBRIS_GNSS_POSITION_MODE_STANDALONE,
+ HYBRIS_GNSS_POSITION_RECURRENCE_PERIODIC, updateInterval,
+ PreferredAccuracy, PreferredInitialFixTime);
}
}
@@ -911,7 +521,7 @@
qCDebug(lcGeoclueHybris) << fields << timestamp << latitude << longitude << altitude
<< accuracy.horizontal() << accuracy.vertical();
- m_gps->inject_location(latitude, longitude, accuracy.horizontal());
+ m_backend->gnssInjectLocation(latitude, longitude, accuracy.horizontal());
}
void HybrisProvider::injectUtcTime()
@@ -1043,7 +653,7 @@
qCDebug(lcGeoclueHybris) << "Injecting time" << time << reference << certainty;
- m_gps->inject_time(time, reference, certainty);
+ m_backend->gnssInjectTime(time, reference, certainty);
m_ntpRetryTimer.stop();
}
@@ -1100,7 +710,7 @@
xtraDownloadRequestSendNext();
} else {
QByteArray xtraData = m_xtraDownloadReply->readAll();
- m_xtra->inject_xtra_data(xtraData.data(), xtraData.length());
+ m_backend->gnssXtraInjectXtraData(xtraData);
qCDebug(lcGeoclueHybris) << "injected " << xtraData.length() << " bytes of xtra data";
@@ -1122,37 +732,29 @@
qCDebug(lcGeoclueHybris) << "type:" << type << "status:" << status;
if (!m_agpsEnabled) {
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
- m_agps->data_conn_failed();
-#else
- m_agps->data_conn_failed(AGPS_TYPE_SUPL);
-#endif
+ m_backend->aGnssDataConnFailed();
return;
}
- if (type != AGPS_TYPE_SUPL) {
+ if (type != HYBRIS_AGNSS_TYPE_SUPL) {
qWarning("Only SUPL AGPS is supported.");
return;
}
switch (status) {
- case GPS_REQUEST_AGPS_DATA_CONN:
+ case HYBRIS_GNSS_REQUEST_AGNSS_DATA_CONN:
startDataConnection();
break;
- case GPS_RELEASE_AGPS_DATA_CONN:
+ case HYBRIS_GNSS_RELEASE_AGNSS_DATA_CONN:
// Immediately inform that connection is closed.
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
- m_agps->data_conn_closed();
-#else
- m_agps->data_conn_closed(AGPS_TYPE_SUPL);
-#endif
+ m_backend->aGnssDataConnClosed();
stopDataConnection();
break;
- case GPS_AGPS_DATA_CONNECTED:
+ case HYBRIS_GNSS_AGNSS_DATA_CONNECTED:
break;
- case GPS_AGPS_DATA_CONN_DONE:
+ case HYBRIS_GNSS_AGNSS_DATA_CONN_DONE:
break;
- case GPS_AGPS_DATA_CONN_FAILED:
+ case HYBRIS_GNSS_AGNSS_DATA_CONN_FAILED:
break;
default:
qWarning("Unknown AGPS Status.");
@@ -1190,23 +792,14 @@
qCDebug(lcGeoclueHybris) << path << error;
if (path.contains(QStringLiteral("cellular")))
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
- m_agps->data_conn_failed();
-#else
- m_agps->data_conn_failed(AGPS_TYPE_SUPL);
-#endif
+ m_backend->aGnssDataConnFailed();
}
void HybrisProvider::connectionSelected(bool selected)
{
if (!selected) {
qCDebug(lcGeoclueHybris) << "User aborted mobile data connection";
-
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
- m_agps->data_conn_failed();
-#else
- m_agps->data_conn_failed(AGPS_TYPE_SUPL);
-#endif
+ m_backend->aGnssDataConnFailed();
}
}
@@ -1274,7 +867,7 @@
{
if (state == "online") {
if (m_gpsStarted && m_useForcedXtraInject) {
- gpsXtraDownloadRequest();
+ gnssXtraDownloadRequest();
}
}
}
@@ -1312,16 +905,7 @@
m_connectionContext->deleteLater();
m_connectionContext = 0;
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
- if (m_agps->data_conn_open_with_apn_ip_type)
- m_agps->data_conn_open_with_apn_ip_type(apn.constData(), fromContextProtocol(protocol));
- else
- m_agps->data_conn_open(apn.constData());
-#elif GEOCLUE_ANDROID_GPS_INTERFACE == 1
- m_agps->data_conn_open(apn.constData());
-#else
- m_agps->data_conn_open(AGPS_TYPE_SUPL, apn.constData(), fromContextProtocol(protocol));
-#endif
+ m_backend->aGnssDataConnOpen(apn.constData(), protocol);
} else {
processNextConnectionContext();
}
@@ -1385,7 +969,7 @@
m_idleTimer.stop();
- if (!m_gps)
+ if (!m_backend)
return;
// Listen to all PositionChanged signals from org.freedesktop.Geoclue.Position interfaces. Used
@@ -1398,22 +982,17 @@
this, SLOT(injectPosition(int,int,double,double,double,Accuracy)));
}
- int error = m_gps->set_position_mode(m_agpsEnabled ? GPS_POSITION_MODE_MS_BASED
- : GPS_POSITION_MODE_STANDALONE,
- GPS_POSITION_RECURRENCE_PERIODIC,
- minimumRequestedUpdateInterval(),
- PreferredAccuracy, PreferredInitialFixTime);
- if (error) {
- qWarning("Failed to set position mode, error %d\n", error);
- setStatus(StatusError);
+ if (!m_backend->gnssSetPositionMode(m_agpsEnabled ? HYBRIS_GNSS_POSITION_MODE_MS_BASED
+ : HYBRIS_GNSS_POSITION_MODE_STANDALONE,
+ HYBRIS_GNSS_POSITION_RECURRENCE_PERIODIC,
+ minimumRequestedUpdateInterval(),
+ PreferredAccuracy, PreferredInitialFixTime)) {
return;
}
qCDebug(lcGeoclueHybris) << "Starting positioning";
- error = m_gps->start();
- if (error) {
- qWarning("Failed to start positioning, error %d\n", error);
+ if (!m_backend->gnssStart()) {
setStatus(StatusError);
return;
}
@@ -1421,7 +1000,7 @@
m_gpsStarted = true;
if (m_useForcedXtraInject && m_networkManager->state() == "online") {
- gpsXtraDownloadRequest();
+ gnssXtraDownloadRequest();
}
}
@@ -1445,14 +1024,13 @@
m_positionInjectionConnected = false;
}
- if (m_gps) {
+ if (m_backend) {
qCDebug(lcGeoclueHybris) << "Stopping positioning";
- int error = m_gps->stop();
- if (error)
- qWarning("Failed to stop positioning, error %d\n", error);
+ m_backend->gnssStop();
m_gpsStarted = false;
setStatus(StatusUnavailable);
}
+
m_fixLostTimer.stop();
}
@@ -1514,11 +1092,7 @@
if (!m_agpsOnlineEnabled) {
qCDebug(lcGeoclueHybris) << "Online aGPS not enabled, not starting data connection.";
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
- m_agps->data_conn_failed();
-#else
- m_agps->data_conn_failed(AGPS_TYPE_SUPL);
-#endif
+ m_backend->aGnssDataConnFailed();
return;
}
@@ -1606,11 +1180,7 @@
delete m_connectionContext;
m_connectionContext = 0;
-#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
- m_agps->data_conn_failed();
-#else
- m_agps->data_conn_failed(AGPS_TYPE_SUPL);
-#endif
+ m_backend->aGnssDataConnFailed();
return;
}
|
[-]
[+]
|
Changed |
_service:tar_git:geoclue-provider-hybris-0.2.19.tar.gz/hybrisprovider.h
^
|
@@ -13,6 +13,7 @@
#ifndef HYBRISPROVIDER_H
#define HYBRISPROVIDER_H
+#include <QtCore/QLoggingCategory>
#include <QtCore/QObject>
#include <QtCore/QStringList>
#include <QtCore/QBasicTimer>
@@ -20,23 +21,15 @@
#include <QtDBus/QDBusContext>
#include <QtNetwork/QNetworkReply>
-#include <android-version.h>
-#include <hardware/gps.h>
+#include "hybrislocationbackend.h"
#include <locationsettings.h>
#include "locationtypes.h"
-// Define versions of the Android GPS interface supported.
-#if ANDROID_VERSION_MAJOR >= 7
- #define GEOCLUE_ANDROID_GPS_INTERFACE 3
-#elif ANDROID_VERSION_MAJOR >= 5
- #define GEOCLUE_ANDROID_GPS_INTERFACE 2
-#elif ANDROID_VERSION_MAJOR == 4 && ANDROID_VERSION_MINOR >= 2
- #define GEOCLUE_ANDROID_GPS_INTERFACE 1
-#else
- // By default expects Android 4.1
-#endif
+Q_DECLARE_LOGGING_CATEGORY(lcGeoclueHybris)
+Q_DECLARE_LOGGING_CATEGORY(lcGeoclueHybrisNmea)
+Q_DECLARE_LOGGING_CATEGORY(lcGeoclueHybrisPosition)
QT_FORWARD_DECLARE_CLASS(QFileSystemWatcher)
QT_FORWARD_DECLARE_CLASS(QDBusServiceWatcher)
@@ -57,6 +50,7 @@
class HybrisProvider : public QObject, public QDBusContext
{
+friend class HybrisBackend;
Q_OBJECT
public:
@@ -178,16 +172,7 @@
void processConnectionContexts();
void processNextConnectionContext();
- gps_device_t *m_gpsDevice;
-
- const GpsInterface *m_gps;
-
- const AGpsInterface *m_agps;
- const AGpsRilInterface *m_agpsril;
- const GpsNiInterface *m_gpsni;
- const GpsXtraInterface *m_xtra;
-
- const GpsDebugInterface *m_debug;
+ HybrisLocationBackend *m_backend;
Location m_currentLocation;
@@ -256,6 +241,8 @@
double m_magneticVariation;
};
+extern HybrisProvider *staticProvider;
+
Q_DECLARE_OPERATORS_FOR_FLAGS(HybrisProvider::PositionFields)
Q_DECLARE_OPERATORS_FOR_FLAGS(HybrisProvider::VelocityFields)
|
[-]
[+]
|
Added |
_service:tar_git:geoclue-providers-hybris.inc
^
|
@@ -0,0 +1,43 @@
+Name: geoclue-provider-hybris
+Version: 0.0.1
+Release: 1
+Summary: Geoinformation Service Hybris Provider
+Group: System/Libraries
+URL: https://bitbucket.org/jolla/base-geoclue-providers-hybris
+License: LGPLv2.1
+Source: %{name}-%{version}.tar.gz
+BuildRequires: pkgconfig(Qt5Core)
+BuildRequires: pkgconfig(Qt5DBus)
+BuildRequires: pkgconfig(Qt5Network)
+BuildRequires: pkgconfig(connman-qt5) >= 1.0.68
+BuildRequires: pkgconfig(qofono-qt5)
+BuildRequires: pkgconfig(qofonoext)
+BuildRequires: pkgconfig(systemsettings)
+Requires: connectionagent-qt5 >= 0.9.20
+
+Source100: geoclue-providers-hybris.inc
+
+%description
+%{summary}.
+
+
+%prep
+%setup -q -n %{name}-%{version}
+
+
+%build
+%{qmake_command}
+make %{?_smp_mflags}
+
+
+%install
+make INSTALL_ROOT=%{buildroot} install
+
+%files
+%defattr(04755,root,root,-)
+%{_libexecdir}/geoclue-hybris
+%defattr(-,root,root,-)
+%{_sysconfdir}/dbus-1
+%{_datadir}/dbus-1
+%{_datadir}/geoclue-providers/geoclue-hybris.provider
+
|