6#ifdef Q_LOCATION_GYPSY_DEBUG
14#define UPDATE_TIMEOUT_COLD_START 120000
18static const auto defaultGconfKey =
"/apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice";
22 GPtrArray *satellites,
25#ifdef Q_LOCATION_GYPSY_DEBUG
26 qDebug() <<
"QGeoSatelliteInfoSourceGypsy Gypsy satellites-changed -signal received.";
31SatelliteGypsyEngine::SatelliteGypsyEngine(QGeoSatelliteInfoSource *parent) :
35SatelliteGypsyEngine::~SatelliteGypsyEngine()
40gulong SatelliteGypsyEngine::eng_g_signal_connect(gpointer instance,
41 const gchar *detailed_signal,
45 return ::g_signal_connect(instance, detailed_signal, c_handler, data);
47guint SatelliteGypsyEngine::eng_g_signal_handlers_disconnect_by_func (gpointer instance,
51 return ::g_signal_handlers_disconnect_by_func(instance, func, data);
54void SatelliteGypsyEngine::eng_g_free(gpointer mem)
59GypsyControl *SatelliteGypsyEngine::eng_gypsy_control_get_default (
void)
61 return ::gypsy_control_get_default();
63char *SatelliteGypsyEngine::eng_gypsy_control_create (GypsyControl *control,
const char *device_name, GError **error)
65 return ::gypsy_control_create(control, device_name, error);
67GypsyDevice *SatelliteGypsyEngine::eng_gypsy_device_new (
const char *object_path)
69 return ::gypsy_device_new(object_path);
71GypsySatellite *SatelliteGypsyEngine::eng_gypsy_satellite_new (
const char *object_path)
73 return ::gypsy_satellite_new (object_path);
75gboolean SatelliteGypsyEngine::eng_gypsy_device_start (GypsyDevice *device, GError **error)
77 return ::gypsy_device_start(device, error);
79gboolean SatelliteGypsyEngine::eng_gypsy_device_stop (GypsyDevice *device, GError **error)
89GypsyDeviceFixStatus SatelliteGypsyEngine::eng_gypsy_device_get_fix_status (GypsyDevice *device, GError **error)
91 return ::gypsy_device_get_fix_status (device, error);
93GPtrArray *SatelliteGypsyEngine::eng_gypsy_satellite_get_satellites (GypsySatellite *satellite, GError **error)
95 return ::gypsy_satellite_get_satellites (satellite, error);
97void SatelliteGypsyEngine::eng_gypsy_satellite_free_satellite_array (GPtrArray *satellites)
99 return ::gypsy_satellite_free_satellite_array(satellites);
102GConfClient *SatelliteGypsyEngine::eng_gconf_client_get_default(
void)
104 return ::gconf_client_get_default();
106gchar *SatelliteGypsyEngine::eng_gconf_client_get_string(GConfClient *client,
const gchar *key, GError** err)
108 return ::gconf_client_get_string(client, key, err);
112 : QGeoSatelliteInfoSource(parent), m_engine(0), m_satellite(0), m_device(0),
113 m_requestTimer(
this), m_updatesOngoing(
false), m_requestOngoing(
false)
115 m_requestTimer.setSingleShot(
true);
116 QObject::connect(&m_requestTimer, SIGNAL(timeout()),
this, SLOT(requestUpdateTimeout()));
122 m_engine =
new SatelliteGypsyEngine(
this);
127 GError *error = NULL;
129 m_engine->eng_gypsy_device_stop (m_device, &error);
130 g_object_unref(m_device);
133 g_object_unref(m_satellite);
135 g_object_unref(m_control);
143 if (prn >= 1 && prn <= 32)
144 return QGeoSatelliteInfo::GPS;
145 if (prn >= 33 && prn <= 64)
146 return QGeoSatelliteInfo::SBAS;
147 else if (prn >= 65 && prn <= 96)
148 return QGeoSatelliteInfo::GLONASS;
149 else if (prn >= 193 && prn <= 200)
150 return QGeoSatelliteInfo::QZSS;
151 else if ((prn >= 201 && prn <= 235) || (prn >= 401 && prn <= 437))
152 return QGeoSatelliteInfo::BEIDOU;
153 else if (prn >= 301 && prn <= 336)
154 return QGeoSatelliteInfo::GALILEO;
155 return QGeoSatelliteInfo::Undefined;
159 GPtrArray *satellites)
161 if (!satellite || !satellites)
167 QList<QGeoSatelliteInfo> lastSatellitesInView;
168 QList<QGeoSatelliteInfo> lastSatellitesInUse;
171 for (i = 0; i < satellites->len; i++) {
172 GypsySatelliteDetails *details = (GypsySatelliteDetails *)satellites->pdata[i];
173 QGeoSatelliteInfo info;
174 info.setSatelliteIdentifier(details->satellite_id);
175 info.setSatelliteSystem(idToSystem(details->satellite_id));
176 info.setAttribute(QGeoSatelliteInfo::Elevation, details->elevation);
177 info.setAttribute(QGeoSatelliteInfo::Azimuth, details->azimuth);
178 info.setSignalStrength(details->snr);
180 lastSatellitesInUse.append(info);
181 lastSatellitesInView.append(info);
183 bool sendUpdates(
false);
185 if (m_requestOngoing) {
187 m_requestTimer.stop();
188 m_requestOngoing =
false;
190 if (!m_updatesOngoing) {
191 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
195 if (m_updatesOngoing)
199 emit satellitesInUseUpdated(lastSatellitesInUse);
200 emit satellitesInViewUpdated(lastSatellitesInView);
217 if (gconfKey.isEmpty())
223 GConfClient *client = m_engine->eng_gconf_client_get_default();
227 gchar *device_name = m_engine->eng_gconf_client_get_string(client,
228 gconfKey.toLatin1().constData(),
230 g_object_unref(client);
232 const QString deviceName = QString::fromLatin1(device_name);
233 m_engine->eng_g_free(device_name);
240 GError *error = NULL;
243#if !GLIB_CHECK_VERSION(2
, 36
, 0
)
248 const QString deviceName = extractDeviceNameFromParameters(parameters);
250 if (deviceName.isEmpty() ||
251 (deviceName.trimmed().at(0) ==
'/' && !QFile::exists(deviceName.trimmed()))) {
252 qWarning (
"QGeoSatelliteInfoSourceGypsy Empty/nonexistent GPS device name detected.");
253 qWarning(
"Use '%s' plugin parameter to specify device name directly",
deviceNameParameter);
254 qWarning(
"or use '%s' plugin parameter to specify a GConf key to extract the device name.",
256 qWarning (
"If the GConf key is used, the gconftool-2 tool can be used to set device name "
257 "for the selected key, e.g. on terminal:");
261 m_control = m_engine->eng_gypsy_control_get_default();
263 qWarning(
"QGeoSatelliteInfoSourceGypsy unable to create Gypsy control.");
267 path = m_engine->eng_gypsy_control_create(m_control, deviceName.toLatin1().constData(), &error);
269 qWarning (
"QGeoSatelliteInfoSourceGypsy error creating client.");
271 qWarning (
"error message: %s", error->message);
272 g_error_free (error);
276 m_device = m_engine->eng_gypsy_device_new (path);
277 m_satellite = m_engine->eng_gypsy_satellite_new (path);
278 m_engine->eng_g_free(path);
279 if (!m_device || !m_satellite) {
280 qWarning (
"QGeoSatelliteInfoSourceGypsy error creating satellite device.");
281 qWarning (
"Please check that the GPS device is specified correctly.");
282 qWarning(
"Use '%s' plugin parameter to specify device name directly",
deviceNameParameter);
283 qWarning(
"or use '%s' plugin parameter to specify a GConf key to extract the device name.",
285 qWarning (
"If the GConf key is used, the gconftool-2 tool can be used to set device name "
286 "for the selected key, e.g. on terminal:");
289 g_object_unref(m_device);
291 g_object_unref(m_satellite);
294 m_engine->eng_gypsy_device_start (m_device, &error);
296 qWarning (
"QGeoSatelliteInfoSourceGypsy error starting device: %s ",
299 g_object_unref(m_device);
300 g_object_unref(m_satellite);
318 if (m_updatesOngoing)
321 m_error = QGeoSatelliteInfoSource::NoError;
324 if (!m_requestTimer.isActive()) {
325 m_engine->eng_g_signal_connect (m_satellite,
"satellites-changed",
326 G_CALLBACK (satellites_changed),
this);
328 m_updatesOngoing =
true;
333 if (!m_updatesOngoing)
335 m_updatesOngoing =
false;
339 if (!m_requestTimer.isActive())
340 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
345 if (m_requestOngoing)
348 m_error = QGeoSatelliteInfoSource::NoError;
351 setError(QGeoSatelliteInfoSource::UpdateTimeoutError);
354 m_requestOngoing =
true;
357 GypsyDeviceFixStatus fixStatus = m_engine->eng_gypsy_device_get_fix_status(m_device, &error);
358 if (!error && (fixStatus != GYPSY_DEVICE_FIX_STATUS_INVALID &&
359 fixStatus != GYPSY_DEVICE_FIX_STATUS_NONE)) {
360#ifdef Q_LOCATION_GYPSY_DEBUG
361 qDebug() <<
"QGeoSatelliteInfoSourceGypsy fix available, requesting current satellite data";
363 GPtrArray *satelliteData = m_engine->eng_gypsy_satellite_get_satellites(m_satellite, &error);
366 satellitesChanged(m_satellite, satelliteData);
367 m_engine->eng_gypsy_satellite_free_satellite_array(satelliteData);
373 if (!m_updatesOngoing) {
374 m_engine->eng_g_signal_connect (m_satellite,
"satellites-changed",
375 G_CALLBACK (satellites_changed),
this);
377 m_requestTimer.start();
379#ifdef Q_LOCATION_GYPSY_DEBUG
380 qDebug() <<
"QGeoSatelliteInfoSourceGypsy error asking fix status or satellite data: " << error->message;
388#ifdef Q_LOCATION_GYPSY_DEBUG
389 qDebug(
"QGeoSatelliteInfoSourceGypsy request update timeout occurred.");
394 if (!m_updatesOngoing) {
395 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
397 m_requestOngoing =
false;
398 setError(QGeoSatelliteInfoSource::UpdateTimeoutError);
404 if (m_error != QGeoSatelliteInfoSource::NoError)
405 emit QGeoSatelliteInfoSource::errorOccurred(m_error);
void satellitesChanged(GypsySatellite *satellite, GPtrArray *satellites)
void requestUpdate(int timeout=5000) override
void stopUpdates() override
virtual void createEngine()
int init(const QVariantMap parameters)
~QGeoSatelliteInfoSourceGypsy()
int minimumUpdateInterval() const override
Error error() const override
Returns the last error that occurred.
Combined button and popup list for selecting options.
static const auto deviceNameParameter
static const auto gconfKeyParameter
static const auto defaultGconfKey
static void satellites_changed(GypsySatellite *satellite, GPtrArray *satellites, gpointer userdata)
static QGeoSatelliteInfo::SatelliteSystem idToSystem(int prn)
#define UPDATE_TIMEOUT_COLD_START