1 /****************************************************************************
3 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
4 ** All rights reserved.
5 ** Contact: Nokia Corporation (qt-info@nokia.com)
7 ** This file is part of the Qt Mobility Components.
9 ** $QT_BEGIN_LICENSE:LGPL$
10 ** GNU Lesser General Public License Usage
11 ** This file may be used under the terms of the GNU Lesser General Public
12 ** License version 2.1 as published by the Free Software Foundation and
13 ** appearing in the file LICENSE.LGPL included in the packaging of this
14 ** file. Please review the following information to ensure the GNU Lesser
15 ** General Public License version 2.1 requirements will be met:
16 ** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
18 ** In addition, as a special exception, Nokia gives you certain additional
19 ** rights. These rights are described in the Nokia Qt LGPL Exception
20 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
22 ** GNU General Public License Usage
23 ** Alternatively, this file may be used under the terms of the GNU General
24 ** Public License version 3.0 as published by the Free Software Foundation
25 ** and appearing in the file LICENSE.GPL included in the packaging of this
26 ** file. Please review the following information to ensure the GNU General
27 ** Public License version 3.0 requirements will be met:
28 ** http://www.gnu.org/copyleft/gpl.html.
31 ** Alternatively, this file may be used in accordance with the terms and
32 ** conditions contained in a signed written agreement between you and Nokia.
40 ****************************************************************************/
42 #include "liblocationwrapper_p.h"
50 Q_GLOBAL_STATIC(LiblocationWrapper, LocationEngine)
52 LiblocationWrapper *LiblocationWrapper::instance()
54 return LocationEngine();
57 LiblocationWrapper::LiblocationWrapper()
59 locationControl(NULL),
63 origUpdateInterval(0),
65 validLastUpdate(false),
66 validLastSatUpdate(false),
67 locationState(LiblocationWrapper::Undefined) {
68 qDebug() << "* LiblocationWrapper Fremantle Backport";
71 LiblocationWrapper::~LiblocationWrapper()
74 g_object_unref(locationDevice);
76 g_object_unref(locationControl);
79 bool LiblocationWrapper::inited()
82 if (!(locationState & LiblocationWrapper::Inited)) {
85 locationControl = location_gpsd_control_get_default();
87 if (locationControl) {
88 g_object_set(G_OBJECT(locationControl),
89 "preferred-method", LOCATION_METHOD_USER_SELECTED,
90 "preferred-interval", LOCATION_INTERVAL_1S,
93 (LocationGPSDevice*)g_object_new(LOCATION_TYPE_GPS_DEVICE,
98 g_signal_connect(G_OBJECT(locationControl), "error-verbose",
99 G_CALLBACK(&locationError),
100 static_cast<void*>(this));
102 g_signal_connect(G_OBJECT(locationDevice), "changed",
103 G_CALLBACK(&locationChanged),
104 static_cast<void*>(this));
105 locationState = LiblocationWrapper::Inited;
116 void LiblocationWrapper::locationError(LocationGPSDevice *device,
117 gint errorCode, gpointer data)
120 QString locationError;
123 case LOCATION_ERROR_USER_REJECTED_DIALOG:
124 locationError = "User didn't enable requested methods";
126 case LOCATION_ERROR_USER_REJECTED_SETTINGS:
127 locationError = "User changed settings, which disabled location.";
129 case LOCATION_ERROR_BT_GPS_NOT_AVAILABLE:
130 locationError = "Problems with BT GPS";
132 case LOCATION_ERROR_METHOD_NOT_ALLOWED_IN_OFFLINE_MODE:
133 locationError = "Requested method is not allowed in offline mode";
135 case LOCATION_ERROR_SYSTEM:
136 locationError = "System error.";
139 locationError = "Unknown error.";
142 qDebug() << "Location error:" << locationError;
144 LiblocationWrapper *object;
145 object = (LiblocationWrapper *)data;
146 emit object->error();
149 void LiblocationWrapper::locationChanged(LocationGPSDevice *device,
152 QGeoPositionInfo posInfo;
153 QGeoCoordinate coordinate;
154 QGeoSatelliteInfo satInfo;
155 int satellitesInUseCount = 0;
156 LiblocationWrapper *object;
158 if (!data || !device) {
162 object = (LiblocationWrapper *)data;
166 if (device->fix->fields & LOCATION_GPS_DEVICE_TIME_SET) {
167 posInfo.setTimestamp(QDateTime::fromTime_t(device->fix->time));
170 if (device->fix->fields & LOCATION_GPS_DEVICE_LATLONG_SET) {
171 coordinate.setLatitude(device->fix->latitude);
172 coordinate.setLongitude(device->fix->longitude);
173 posInfo.setAttribute(QGeoPositionInfo::HorizontalAccuracy,
174 device->fix->eph / 100.0);
175 posInfo.setAttribute(QGeoPositionInfo::VerticalAccuracy,
179 if (device->fix->fields & LOCATION_GPS_DEVICE_ALTITUDE_SET) {
180 coordinate.setAltitude(device->fix->altitude);
183 if (device->fix->fields & LOCATION_GPS_DEVICE_SPEED_SET) {
184 posInfo.setAttribute(QGeoPositionInfo::GroundSpeed,
185 device->fix->speed / 3.6);
188 if (device->fix->fields & LOCATION_GPS_DEVICE_CLIMB_SET) {
189 posInfo.setAttribute(QGeoPositionInfo::VerticalSpeed,
193 if (device->fix->fields & LOCATION_GPS_DEVICE_TRACK_SET) {
194 posInfo.setAttribute(QGeoPositionInfo::Direction,
199 if (device->satellites_in_view) {
200 QList<QGeoSatelliteInfo> satsInView;
201 QList<QGeoSatelliteInfo> satsInUse;
203 for (i = 0;i < device->satellites->len;i++) {
204 LocationGPSDeviceSatellite *satData =
205 (LocationGPSDeviceSatellite *)g_ptr_array_index(device->satellites,
207 satInfo.setSignalStrength(satData->signal_strength);
208 satInfo.setPrnNumber(satData->prn);
209 satInfo.setAttribute(QGeoSatelliteInfo::Elevation,
211 satInfo.setAttribute(QGeoSatelliteInfo::Azimuth,
214 satsInView.append(satInfo);
215 if (satData->in_use) {
216 satellitesInUseCount++;
217 satsInUse.append(satInfo);
221 if (!satsInView.isEmpty())
222 object->satellitesInViewUpdated(satsInView);
224 if (!satsInUse.isEmpty())
225 object->satellitesInUseUpdated(satsInUse);
229 posInfo.setCoordinate(coordinate);
231 emit object->positionUpdated(posInfo);
234 QGeoPositionInfo LiblocationWrapper::lastKnownPosition(bool fromSatellitePositioningMethodsOnly) const
236 QGeoPositionInfo posInfo;
237 QGeoCoordinate coordinate;
246 GConfItem lastKnownPositionTime("/system/nokia/location/lastknown/time");
247 GConfItem lastKnownPositionLatitude("/system/nokia/location/lastknown/latitude");
248 GConfItem lastKnownPositionLongitude("/system/nokia/location/lastknown/longitude");
249 GConfItem lastKnownPositionAltitude("/system/nokia/location/lastknown/altitude");
250 GConfItem lastKnownPositionSpeed("/system/nokia/location/lastknown/speed");
251 GConfItem lastKnownPositionTrack("/system/nokia/location/lastknown/track");
252 GConfItem lastKnownPositionClimb("/system/nokia/location/lastknown/climb");
254 if (validLastSatUpdate)
255 return lastSatUpdate;
257 if (!fromSatellitePositioningMethodsOnly)
261 time = lastKnownPositionTime.value().toDouble();
262 latitude = lastKnownPositionLatitude.value().toDouble();
263 longitude = lastKnownPositionLongitude.value().toDouble();
264 altitude = lastKnownPositionAltitude.value().toDouble();
265 speed = lastKnownPositionSpeed.value().toDouble();
266 track = lastKnownPositionTrack.value().toDouble();
267 climb = lastKnownPositionClimb.value().toDouble();
269 if (longitude && latitude) {
270 coordinate.setLongitude(longitude);
271 coordinate.setLatitude(latitude);
273 coordinate.setAltitude(altitude);
275 posInfo.setCoordinate(coordinate);
279 posInfo.setAttribute(QGeoPositionInfo::GroundSpeed, speed);
283 posInfo.setAttribute(QGeoPositionInfo::Direction, track);
287 posInfo.setAttribute(QGeoPositionInfo::VerticalSpeed, climb);
290 // Only positions with time (3D) are provided.
292 posInfo.setTimestamp(QDateTime::fromTime_t(time));
296 return QGeoPositionInfo();
299 void LiblocationWrapper::satellitesInViewUpdated(const QList<QGeoSatelliteInfo> &satellites)
301 satsInView = satellites;
304 void LiblocationWrapper::satellitesInUseUpdated(const QList<QGeoSatelliteInfo> &satellites)
306 satsInUse = satellites;
309 QList<QGeoSatelliteInfo> LiblocationWrapper::satellitesInView()
314 QList<QGeoSatelliteInfo> LiblocationWrapper::satellitesInUse()
319 void LiblocationWrapper::start() {
322 if ((locationState & LiblocationWrapper::Inited) &&
323 !(locationState & LiblocationWrapper::Started)) {
324 if (!errorHandlerId) {
326 g_signal_connect(G_OBJECT(locationControl), "error-verbose",
327 G_CALLBACK(&locationError),
328 static_cast<void*>(this));
333 g_signal_connect(G_OBJECT(locationDevice), "changed",
334 G_CALLBACK(&locationChanged),
335 static_cast<void*>(this));
338 location_gpsd_control_start(locationControl);
340 locationState |= LiblocationWrapper::Started;
341 locationState &= ~LiblocationWrapper::Stopped;
345 void LiblocationWrapper::stop() {
348 if (startcounter > 0)
351 if ((locationState & (LiblocationWrapper::Started |
352 LiblocationWrapper::Inited)) &&
353 !(locationState & LiblocationWrapper::Stopped)) {
355 g_signal_handler_disconnect(G_OBJECT(locationControl),
358 g_signal_handler_disconnect(G_OBJECT(locationDevice),
363 location_gpsd_control_stop(locationControl);
365 locationState &= ~LiblocationWrapper::Started;
366 locationState |= LiblocationWrapper::Stopped;
370 bool LiblocationWrapper::isActive() {
371 if (locationState & LiblocationWrapper::Started)
377 #include "moc_liblocationwrapper_p.cpp"