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 else if (prn >= 65 && prn <= 96)
146 return QGeoSatelliteInfo::GLONASS;
147 else if (prn >= 193 && prn <= 200)
148 return QGeoSatelliteInfo::QZSS;
149 else if ((prn >= 201 && prn <= 235) || (prn >= 401 && prn <= 437))
150 return QGeoSatelliteInfo::BEIDOU;
151 else if (prn >= 301 && prn <= 336)
152 return QGeoSatelliteInfo::GALILEO;
153 return QGeoSatelliteInfo::Undefined;
157 GPtrArray *satellites)
159 if (!satellite || !satellites)
165 QList<QGeoSatelliteInfo> lastSatellitesInView;
166 QList<QGeoSatelliteInfo> lastSatellitesInUse;
169 for (i = 0; i < satellites->len; i++) {
170 GypsySatelliteDetails *details = (GypsySatelliteDetails *)satellites->pdata[i];
171 QGeoSatelliteInfo info;
172 info.setSatelliteIdentifier(details->satellite_id);
173 info.setSatelliteSystem(idToSystem(details->satellite_id));
174 info.setAttribute(QGeoSatelliteInfo::Elevation, details->elevation);
175 info.setAttribute(QGeoSatelliteInfo::Azimuth, details->azimuth);
176 info.setSignalStrength(details->snr);
178 lastSatellitesInUse.append(info);
179 lastSatellitesInView.append(info);
181 bool sendUpdates(
false);
183 if (m_requestOngoing) {
185 m_requestTimer.stop();
186 m_requestOngoing =
false;
188 if (!m_updatesOngoing) {
189 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
193 if (m_updatesOngoing)
197 emit satellitesInUseUpdated(lastSatellitesInUse);
198 emit satellitesInViewUpdated(lastSatellitesInView);
215 if (gconfKey.isEmpty())
221 GConfClient *client = m_engine->eng_gconf_client_get_default();
225 gchar *device_name = m_engine->eng_gconf_client_get_string(client,
226 gconfKey.toLatin1().constData(),
228 g_object_unref(client);
230 const QString deviceName = QString::fromLatin1(device_name);
231 m_engine->eng_g_free(device_name);
238 GError *error = NULL;
241#if !GLIB_CHECK_VERSION(2
, 36
, 0
)
246 const QString deviceName = extractDeviceNameFromParameters(parameters);
248 if (deviceName.isEmpty() ||
249 (deviceName.trimmed().at(0) ==
'/' && !QFile::exists(deviceName.trimmed()))) {
250 qWarning (
"QGeoSatelliteInfoSourceGypsy Empty/nonexistent GPS device name detected.");
251 qWarning(
"Use '%s' plugin parameter to specify device name directly",
deviceNameParameter);
252 qWarning(
"or use '%s' plugin parameter to specify a GConf key to extract the device name.",
254 qWarning (
"If the GConf key is used, the gconftool-2 tool can be used to set device name "
255 "for the selected key, e.g. on terminal:");
259 m_control = m_engine->eng_gypsy_control_get_default();
261 qWarning(
"QGeoSatelliteInfoSourceGypsy unable to create Gypsy control.");
265 path = m_engine->eng_gypsy_control_create(m_control, deviceName.toLatin1().constData(), &error);
267 qWarning (
"QGeoSatelliteInfoSourceGypsy error creating client.");
269 qWarning (
"error message: %s", error->message);
270 g_error_free (error);
274 m_device = m_engine->eng_gypsy_device_new (path);
275 m_satellite = m_engine->eng_gypsy_satellite_new (path);
276 m_engine->eng_g_free(path);
277 if (!m_device || !m_satellite) {
278 qWarning (
"QGeoSatelliteInfoSourceGypsy error creating satellite device.");
279 qWarning (
"Please check that the GPS device is specified correctly.");
280 qWarning(
"Use '%s' plugin parameter to specify device name directly",
deviceNameParameter);
281 qWarning(
"or use '%s' plugin parameter to specify a GConf key to extract the device name.",
283 qWarning (
"If the GConf key is used, the gconftool-2 tool can be used to set device name "
284 "for the selected key, e.g. on terminal:");
287 g_object_unref(m_device);
289 g_object_unref(m_satellite);
292 m_engine->eng_gypsy_device_start (m_device, &error);
294 qWarning (
"QGeoSatelliteInfoSourceGypsy error starting device: %s ",
297 g_object_unref(m_device);
298 g_object_unref(m_satellite);
316 if (m_updatesOngoing)
319 m_error = QGeoSatelliteInfoSource::NoError;
322 if (!m_requestTimer.isActive()) {
323 m_engine->eng_g_signal_connect (m_satellite,
"satellites-changed",
324 G_CALLBACK (satellites_changed),
this);
326 m_updatesOngoing =
true;
331 if (!m_updatesOngoing)
333 m_updatesOngoing =
false;
337 if (!m_requestTimer.isActive())
338 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
343 if (m_requestOngoing)
346 m_error = QGeoSatelliteInfoSource::NoError;
349 setError(QGeoSatelliteInfoSource::UpdateTimeoutError);
352 m_requestOngoing =
true;
355 GypsyDeviceFixStatus fixStatus = m_engine->eng_gypsy_device_get_fix_status(m_device, &error);
356 if (!error && (fixStatus != GYPSY_DEVICE_FIX_STATUS_INVALID &&
357 fixStatus != GYPSY_DEVICE_FIX_STATUS_NONE)) {
358#ifdef Q_LOCATION_GYPSY_DEBUG
359 qDebug() <<
"QGeoSatelliteInfoSourceGypsy fix available, requesting current satellite data";
361 GPtrArray *satelliteData = m_engine->eng_gypsy_satellite_get_satellites(m_satellite, &error);
364 satellitesChanged(m_satellite, satelliteData);
365 m_engine->eng_gypsy_satellite_free_satellite_array(satelliteData);
371 if (!m_updatesOngoing) {
372 m_engine->eng_g_signal_connect (m_satellite,
"satellites-changed",
373 G_CALLBACK (satellites_changed),
this);
375 m_requestTimer.start();
377#ifdef Q_LOCATION_GYPSY_DEBUG
378 qDebug() <<
"QGeoSatelliteInfoSourceGypsy error asking fix status or satellite data: " << error->message;
386#ifdef Q_LOCATION_GYPSY_DEBUG
387 qDebug(
"QGeoSatelliteInfoSourceGypsy request update timeout occurred.");
392 if (!m_updatesOngoing) {
393 m_engine->eng_g_signal_handlers_disconnect_by_func(G_OBJECT(m_satellite), (
void *)satellites_changed,
this);
395 m_requestOngoing =
false;
396 setError(QGeoSatelliteInfoSource::UpdateTimeoutError);
402 if (m_error != QGeoSatelliteInfoSource::NoError)
403 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