@@ -38,6 +38,8 @@
#include <qofonoextmodemmanager.h>
+#include <android-config.h>
+
#include <strings.h>
#include <sys/time.h>
@@ -71,6 +73,9 @@
const QString LocationSettingsOldAgpsEnabledKey = QStringLiteral("location/agreement_accepted");
const QString LocationSettingsOldAgpsAgreementAcceptedKey = QStringLiteral("location/here_agreement_accepted");
+const int MaxXtraServers = 3;
+const QString XtraConfigFile = QStringLiteral("/etc/gps_xtra.ini");
+
void locationCallback(GpsLocation *location)
{
Location loc;
@@ -139,6 +144,53 @@
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;
@@ -229,6 +281,14 @@
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;
@@ -236,7 +296,7 @@
QByteArray ssid;
QByteArray password;
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2
+#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) {
@@ -281,7 +341,7 @@
QMetaObject::invokeMethod(staticProvider, "xtraDownloadRequest", Qt::QueuedConnection);
}
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
ApnIpType fromContextProtocol(const QString &protocol)
{
if (protocol == QLatin1String("ip"))
@@ -315,12 +375,19 @@
locationCallback,
statusCallback,
svStatusCallback,
+#ifdef USE_GPS_VENDOR_EXTENSION
+ gnssSvStatusCallback_custom,
+#endif
nmeaCallback,
setCapabilitiesCallback,
acquireWakelockCallback,
releaseWakelockCallback,
createThreadCallback,
- requestUtcTimeCallback
+ requestUtcTimeCallback,
+#if GEOCLUE_ANDROID_GPS_INTERFACE == 3
+ gnssSetSystemInfoCallback,
+ gnssSvStatusCallback,
+#endif
};
AGpsCallbacks agpsCallbacks = {
@@ -428,12 +495,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_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),
m_ofonoExtModemManager(new QOfonoExtModemManager(this)),
m_connectionManager(new QOfonoConnectionManager(this)), m_connectionContext(0), m_ntpSocket(0),
- m_agpsEnabled(false), m_agpsOnlineEnabled(false)
+ m_agpsEnabled(false), m_agpsOnlineEnabled(false), m_useForcedXtraInject(false), m_xtraUserAgent("")
{
if (staticProvider)
qFatal("Only a single instance of HybrisProvider is supported.");
@@ -454,6 +521,7 @@
m_manager = new QNetworkAccessManager(this);
connect(m_networkManager, SIGNAL(technologiesChanged()), this, SLOT(technologiesChanged()));
+ connect(m_networkManager, SIGNAL(stateChanged(QString)), this, SLOT(stateChanged(QString)));
technologiesChanged();
@@ -483,6 +551,48 @@
m_idleTimer.start(QuitIdleTime, this);
}
+ QString xtraUserAgentFileName;
+ QSettings settings(XtraConfigFile, QSettings::IniFormat);
+ QString xtraServer;
+
+ for (int i = 0; i < MaxXtraServers; i++) {
+ QString key = QString("xtra/XTRA_SERVER_%1").arg(i);
+ xtraServer = settings.value(key, "").toString();
+ if (xtraServer != "") {
+ m_xtraServers.enqueue(xtraServer);
+ }
+ }
+
+ m_useForcedXtraInject = settings.value("xtra/XTRA_FORCE_INJECT", "").toBool();
+
+ xtraUserAgentFileName = settings.value("xtra/XTRA_USERAGENT_FILE", "").toString();
+ if (xtraUserAgentFileName != "") {
+ QFile xtraUserAgentFile(xtraUserAgentFileName);
+ if (xtraUserAgentFile.open(QIODevice::ReadOnly)) {
+ m_xtraUserAgent = xtraUserAgentFile.readLine();
+ }
+ }
+
+ if (m_xtraServers.isEmpty()) {
+ QFile gpsConf(QStringLiteral("/system/etc/gps.conf"));
+ if (gpsConf.open(QIODevice::ReadOnly)) {
+
+ while (!gpsConf.atEnd()) {
+ const QByteArray line = gpsConf.readLine().trimmed();
+ if (line.startsWith('#'))
+ continue;
+
+ const QList<QByteArray> split = line.split('=');
+ if (split.length() != 2)
+ continue;
+
+ const QByteArray key = split.at(0).trimmed();
+ if (key == "XTRA_SERVER_1" || key == "XTRA_SERVER_2" || key == "XTRA_SERVER_3")
+ m_xtraServers.enqueue(QUrl::fromEncoded(split.at(1).trimmed()));
+ }
+ }
+ }
+
const hw_module_t *hwModule;
int error = hw_get_module(GPS_HARDWARE_MODULE_ID, &hwModule);
@@ -949,36 +1059,26 @@
qCDebug(lcGeoclueHybris) << "xtra download requested";
- QFile gpsConf(QStringLiteral("/system/etc/gps.conf"));
- if (!gpsConf.open(QIODevice::ReadOnly))
- return;
-
- while (!gpsConf.atEnd()) {
- const QByteArray line = gpsConf.readLine().trimmed();
- if (line.startsWith('#'))
- continue;
-
- const QList<QByteArray> split = line.split('=');
- if (split.length() != 2)
- continue;
-
- const QByteArray key = split.at(0).trimmed();
- if (key == "XTRA_SERVER_1" || key == "XTRA_SERVER_2" || key == "XTRA_SERVER_3")
- m_xtraServers.enqueue(QUrl::fromEncoded(split.at(1).trimmed()));
- }
+ m_xtraServerIndex = 0;
xtraDownloadRequestSendNext();
}
void HybrisProvider::xtraDownloadRequestSendNext()
{
- if (m_xtraServers.isEmpty())
+ if (m_xtraServerIndex >= m_xtraServers.count())
return;
qCDebug(lcGeoclueHybris) << m_xtraServers;
- m_xtraDownloadReply = m_manager->get(QNetworkRequest(m_xtraServers.dequeue()));
+ QNetworkRequest network_request(m_xtraServers[m_xtraServerIndex]);
+ if (m_xtraUserAgent != "") {
+ network_request.setRawHeader("User-Agent", m_xtraUserAgent.toUtf8());
+ }
+ m_xtraDownloadReply = m_manager->get(network_request);
connect(m_xtraDownloadReply, SIGNAL(finished()), this, SLOT(xtraDownloadFinished()));
+
+ m_xtraServerIndex++;
}
void HybrisProvider::xtraDownloadFinished()
@@ -1002,9 +1102,9 @@
QByteArray xtraData = m_xtraDownloadReply->readAll();
m_xtra->inject_xtra_data(xtraData.data(), xtraData.length());
- m_xtraDownloadReply = 0;
+ qCDebug(lcGeoclueHybris) << "injected " << xtraData.length() << " bytes of xtra data";
- m_xtraServers.clear();
+ m_xtraDownloadReply = 0;
}
}
@@ -1022,7 +1122,7 @@
qCDebug(lcGeoclueHybris) << "type:" << type << "status:" << status;
if (!m_agpsEnabled) {
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2 || GEOCLUE_ANDROID_GPS_INTERFACE == 1
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
m_agps->data_conn_failed();
#else
m_agps->data_conn_failed(AGPS_TYPE_SUPL);
@@ -1041,7 +1141,7 @@
break;
case GPS_RELEASE_AGPS_DATA_CONN:
// Immediately inform that connection is closed.
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2 || GEOCLUE_ANDROID_GPS_INTERFACE == 1
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
m_agps->data_conn_closed();
#else
m_agps->data_conn_closed(AGPS_TYPE_SUPL);
@@ -1090,7 +1190,7 @@
qCDebug(lcGeoclueHybris) << path << error;
if (path.contains(QStringLiteral("cellular")))
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2 || GEOCLUE_ANDROID_GPS_INTERFACE == 1
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
m_agps->data_conn_failed();
#else
m_agps->data_conn_failed(AGPS_TYPE_SUPL);
@@ -1102,7 +1202,7 @@
if (!selected) {
qCDebug(lcGeoclueHybris) << "User aborted mobile data connection";
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2 || GEOCLUE_ANDROID_GPS_INTERFACE == 1
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
m_agps->data_conn_failed();
#else
m_agps->data_conn_failed(AGPS_TYPE_SUPL);
@@ -1170,6 +1270,15 @@
}
}
+void HybrisProvider::stateChanged(const QString &state)
+{
+ if (state == "online") {
+ if (m_gpsStarted && m_useForcedXtraInject) {
+ gpsXtraDownloadRequest();
+ }
+ }
+}
+
void HybrisProvider::defaultDataModemChanged(const QString &modem)
{
qCDebug(lcGeoclueHybris) << "Default data modem changed to" << modem;
@@ -1203,7 +1312,7 @@
m_connectionContext->deleteLater();
m_connectionContext = 0;
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2
+#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
@@ -1310,6 +1419,10 @@
}
m_gpsStarted = true;
+
+ if (m_useForcedXtraInject && m_networkManager->state() == "online") {
+ gpsXtraDownloadRequest();
+ }
}
void HybrisProvider::stopPositioningIfNeeded()
@@ -1401,7 +1514,7 @@
if (!m_agpsOnlineEnabled) {
qCDebug(lcGeoclueHybris) << "Online aGPS not enabled, not starting data connection.";
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2 || GEOCLUE_ANDROID_GPS_INTERFACE == 1
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
m_agps->data_conn_failed();
#else
m_agps->data_conn_failed(AGPS_TYPE_SUPL);
@@ -1493,7 +1606,7 @@
delete m_connectionContext;
m_connectionContext = 0;
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2 || GEOCLUE_ANDROID_GPS_INTERFACE == 1
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 1
m_agps->data_conn_failed();
#else
m_agps->data_conn_failed(AGPS_TYPE_SUPL);
|
[-]
[+]
|
Changed |
_service:tar_git:geoclue-provider-hybris-0.2.17.tar.gz/main.cpp
^
|
@@ -55,7 +55,22 @@
supplementaryGroups[numberGroups++] = group->gr_gid;
-#if GEOCLUE_ANDROID_GPS_INTERFACE == 2
+ // remove audio, radio and bluetooth groups to avoid confusion in BSP
+ char *groups_to_remove[] = {"bluetooth", "radio", "audio", NULL};
+
+ int idx = 0;
+ while (groups_to_remove[idx]) {
+ group = getgrnam(groups_to_remove[idx]);
+ idx++;
+
+ if (idx + 1 < numberGroups) {
+ memmove((void*)&supplementaryGroups[idx], (void*)&supplementaryGroups[idx + 1], (numberGroups - idx - 1) * sizeof(gid_t));
+ }
+
+ numberGroups--;
+ }
+
+#if GEOCLUE_ANDROID_GPS_INTERFACE >= 2
group = getgrnam("net_raw");
if (group) {
if (numberGroups + 1 > NGROUPS_MAX)
@@ -69,7 +84,7 @@
if (numberGroups == -1)
qFatal("Failed to set supplementary groups, %s", strerror(errno));
-#if GEOCLUE_ANDROID_GPS_INTERFACE != 2
+#if GEOCLUE_ANDROID_GPS_INTERFACE == 1
// Drop privileges.
result = setuid(realUid);
if (result == -1)
|