7#ifdef Q_LOCATION_GYPSY_DEBUG
15#define UPDATE_TIMEOUT_COLD_START 120000
19static const auto defaultGconfKey =
"/apps/geoclue/master/org.freedesktop.Geoclue.GPSDevice";
23 GPtrArray *satellites,
26#ifdef Q_LOCATION_GYPSY_DEBUG
27 qDebug() <<
"QGeoSatelliteInfoSourceGypsy Gypsy satellites-changed -signal received.";
32SatelliteGypsyEngine::SatelliteGypsyEngine(QGeoSatelliteInfoSource *parent) :
36SatelliteGypsyEngine::~SatelliteGypsyEngine()
41gulong SatelliteGypsyEngine::eng_g_signal_connect(gpointer instance,
42 const gchar *detailed_signal,
46 return ::g_signal_connect(instance, detailed_signal, c_handler, data);
48guint SatelliteGypsyEngine::eng_g_signal_handlers_disconnect_by_func (gpointer instance,
52 return ::g_signal_handlers_disconnect_by_func(instance, func, data);
55void SatelliteGypsyEngine::eng_g_free(gpointer mem)
60GypsyControl *SatelliteGypsyEngine::eng_gypsy_control_get_default (
void)
62 return ::gypsy_control_get_default();
64char *SatelliteGypsyEngine::eng_gypsy_control_create (GypsyControl *control,
const char *device_name, GError **error)
66 return ::gypsy_control_create(control, device_name, error);
68GypsyDevice *SatelliteGypsyEngine::eng_gypsy_device_new (
const char *object_path)
70 return ::gypsy_device_new(object_path);
72GypsySatellite *SatelliteGypsyEngine::eng_gypsy_satellite_new (
const char *object_path)
74 return ::gypsy_satellite_new (object_path);
76gboolean SatelliteGypsyEngine::eng_gypsy_device_start (GypsyDevice *device, GError **error)
78 return ::gypsy_device_start(device, error);
80gboolean SatelliteGypsyEngine::eng_gypsy_device_stop (GypsyDevice *device, GError **error)
90GypsyDeviceFixStatus SatelliteGypsyEngine::eng_gypsy_device_get_fix_status (GypsyDevice *device, GError **error)
92 return ::gypsy_device_get_fix_status (device, error);
94GPtrArray *SatelliteGypsyEngine::eng_gypsy_satellite_get_satellites (GypsySatellite *satellite, GError **error)
96 return ::gypsy_satellite_get_satellites (satellite, error);
98void SatelliteGypsyEngine::eng_gypsy_satellite_free_satellite_array (GPtrArray *satellites)
100 return ::gypsy_satellite_free_satellite_array(satellites);
103GConfClient *SatelliteGypsyEngine::eng_gconf_client_get_default(
void)
105 return ::gconf_client_get_default();
107gchar *SatelliteGypsyEngine::eng_gconf_client_get_string(GConfClient *client,
const gchar *key, GError** err)
109 return ::gconf_client_get_string(client, key, err);
113 : QGeoSatelliteInfoSource(parent), m_engine(0), m_satellite(0), m_device(0),
114 m_requestTimer(
this), m_updatesOngoing(
false), m_requestOngoing(
false)
116 m_requestTimer.setSingleShot(
true);
117 QObject::connect(&m_requestTimer, SIGNAL(timeout()),
this, SLOT(requestUpdateTimeout()));
123 m_engine =
new SatelliteGypsyEngine(
this);
128 GError *error = NULL;
130 m_engine->eng_gypsy_device_stop (m_device, &error);
131 g_object_unref(m_device);
134 g_object_unref(m_satellite);
136 g_object_unref(m_control);
144 if (prn >= 1 && prn <= 32)
145 return QGeoSatelliteInfo::GPS;
146 if (prn >= 33 && prn <= 64)
147 return QGeoSatelliteInfo::SBAS;
148 else if (prn >= 65 && prn <= 96)
149 return QGeoSatelliteInfo::GLONASS;
150 else if (prn >= 193 && prn <= 200)
151 return QGeoSatelliteInfo::QZSS;
152 else if ((prn >= 201 && prn <= 235) || (prn >= 401 && prn <= 437))
153 return QGeoSatelliteInfo::BEIDOU;
154 else if (prn >= 301 && prn <= 336)
155 return QGeoSatelliteInfo::GALILEO;
156 return QGeoSatelliteInfo::Undefined;
160 GPtrArray *satellites)
162 if (!satellite || !satellites)
168 QList<QGeoSatelliteInfo> lastSatellitesInView;
169 QList<QGeoSatelliteInfo> lastSatellitesInUse;
172 for (i = 0; i < satellites->len; i++) {
173 GypsySatelliteDetails *details = (GypsySatelliteDetails *)satellites->pdata[i];
174 QGeoSatelliteInfo info;
175 info.setSatelliteIdentifier(details->satellite_id);
176 info.setSatelliteSystem(idToSystem(details->satellite_id));
177 info.setAttribute(QGeoSatelliteInfo::Elevation, details->elevation);
178 info.setAttribute(QGeoSatelliteInfo::Azimuth, details->azimuth);
179 info.setSignalStrength(details->snr);
181 lastSatellitesInUse.append(info);
182 lastSatellitesInView.append(info);
184 bool sendUpdates(
false);
186 if (m_requestOngoing) {
188 m_requestTimer.stop();
189 m_requestOngoing =
false;
191 if (!m_updatesOngoing) {
192 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
196 if (m_updatesOngoing)
200 emit satellitesInUseUpdated(lastSatellitesInUse);
201 emit satellitesInViewUpdated(lastSatellitesInView);
218 if (gconfKey.isEmpty())
224 GConfClient *client = m_engine->eng_gconf_client_get_default();
228 gchar *device_name = m_engine->eng_gconf_client_get_string(client,
229 gconfKey.toLatin1().constData(),
231 g_object_unref(client);
233 const QString deviceName = QString::fromLatin1(device_name);
234 m_engine->eng_g_free(device_name);
241 GError *error = NULL;
244#if !GLIB_CHECK_VERSION(2
, 36
, 0
)
249 const QString deviceName = extractDeviceNameFromParameters(parameters);
251 if (deviceName.isEmpty() ||
252 (deviceName.trimmed().at(0) ==
'/' && !QFile::exists(deviceName.trimmed()))) {
253 qWarning (
"QGeoSatelliteInfoSourceGypsy Empty/nonexistent GPS device name detected.");
254 qWarning(
"Use '%s' plugin parameter to specify device name directly",
deviceNameParameter);
255 qWarning(
"or use '%s' plugin parameter to specify a GConf key to extract the device name.",
257 qWarning (
"If the GConf key is used, the gconftool-2 tool can be used to set device name "
258 "for the selected key, e.g. on terminal:");
262 m_control = m_engine->eng_gypsy_control_get_default();
264 qWarning(
"QGeoSatelliteInfoSourceGypsy unable to create Gypsy control.");
268 path = m_engine->eng_gypsy_control_create(m_control, deviceName.toLatin1().constData(), &error);
270 qWarning (
"QGeoSatelliteInfoSourceGypsy error creating client.");
272 qWarning (
"error message: %s", error->message);
273 g_error_free (error);
277 m_device = m_engine->eng_gypsy_device_new (path);
278 m_satellite = m_engine->eng_gypsy_satellite_new (path);
279 m_engine->eng_g_free(path);
280 if (!m_device || !m_satellite) {
281 qWarning (
"QGeoSatelliteInfoSourceGypsy error creating satellite device.");
282 qWarning (
"Please check that the GPS device is specified correctly.");
283 qWarning(
"Use '%s' plugin parameter to specify device name directly",
deviceNameParameter);
284 qWarning(
"or use '%s' plugin parameter to specify a GConf key to extract the device name.",
286 qWarning (
"If the GConf key is used, the gconftool-2 tool can be used to set device name "
287 "for the selected key, e.g. on terminal:");
290 g_object_unref(m_device);
292 g_object_unref(m_satellite);
295 m_engine->eng_gypsy_device_start (m_device, &error);
297 qWarning (
"QGeoSatelliteInfoSourceGypsy error starting device: %s ",
300 g_object_unref(m_device);
301 g_object_unref(m_satellite);
319 if (m_updatesOngoing)
322 m_error = QGeoSatelliteInfoSource::NoError;
325 if (!m_requestTimer.isActive()) {
326 m_engine->eng_g_signal_connect (m_satellite,
"satellites-changed",
327 G_CALLBACK (satellites_changed),
this);
329 m_updatesOngoing =
true;
334 if (!m_updatesOngoing)
336 m_updatesOngoing =
false;
340 if (!m_requestTimer.isActive())
341 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
346 if (m_requestOngoing)
349 m_error = QGeoSatelliteInfoSource::NoError;
352 setError(QGeoSatelliteInfoSource::UpdateTimeoutError);
355 m_requestOngoing =
true;
358 GypsyDeviceFixStatus fixStatus = m_engine->eng_gypsy_device_get_fix_status(m_device, &error);
359 if (!error && (fixStatus != GYPSY_DEVICE_FIX_STATUS_INVALID &&
360 fixStatus != GYPSY_DEVICE_FIX_STATUS_NONE)) {
361#ifdef Q_LOCATION_GYPSY_DEBUG
362 qDebug() <<
"QGeoSatelliteInfoSourceGypsy fix available, requesting current satellite data";
364 GPtrArray *satelliteData = m_engine->eng_gypsy_satellite_get_satellites(m_satellite, &error);
367 satellitesChanged(m_satellite, satelliteData);
368 m_engine->eng_gypsy_satellite_free_satellite_array(satelliteData);
374 if (!m_updatesOngoing) {
375 m_engine->eng_g_signal_connect (m_satellite,
"satellites-changed",
376 G_CALLBACK (satellites_changed),
this);
378 m_requestTimer.start();
380#ifdef Q_LOCATION_GYPSY_DEBUG
381 qDebug() <<
"QGeoSatelliteInfoSourceGypsy error asking fix status or satellite data: " << error->message;
389#ifdef Q_LOCATION_GYPSY_DEBUG
390 qDebug(
"QGeoSatelliteInfoSourceGypsy request update timeout occurred.");
395 if (!m_updatesOngoing) {
396 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
398 m_requestOngoing =
false;
399 setError(QGeoSatelliteInfoSource::UpdateTimeoutError);
405 if (m_error != QGeoSatelliteInfoSource::NoError)
406 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