2 Situare - A location system for Facebook
3 Copyright (C) 2010 Ixonos Plc. Authors:
5 Henri Lampela - henri.lampela@ixonos.com
6 Sami Rämö - sami.ramo@ixonos.com
8 Situare is free software; you can redistribute it and/or
9 modify it under the terms of the GNU General Public License
10 version 2 as published by the Free Software Foundation.
12 Situare is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Situare; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
25 #include <QCryptographicHash>
28 #include <QNetworkReply>
29 #include <QStringList>
32 #if defined(Q_WS_MAEMO_5) & defined(ARMEL)
33 #include <QDBusInterface>
34 #include <QDBusMessage>
37 #include "coordinates/geocoordinate.h"
40 #include "network/networkaccessmanager.h"
42 #include "routesegment.h"
44 #include "routingservice.h"
46 // defines for IMEI retrieval via dbus
47 #define SIM_DBUS_SERVICE "com.nokia.phone.SIM"
48 #define SIM_DBUS_PATH "/com/nokia/phone/SIM/security"
49 #define SIM_DBUS_IFACE "Phone.Sim.Security"
50 #define SIM_IMEI_REQ "get_imei"
52 const int NO_ERROR = 0;
55 const QString CLOUDMADE_AUTH_PART = "http://auth.cloudmade.com/token/";
56 const QString CLOUDMADE_API_KEY = "0cea0072adbf42ce823f4c78b974f12d";
58 RoutingService::RoutingService(QObject *parent)
61 qDebug() << __PRETTY_FUNCTION__;
63 m_pendingRequest.clear();
66 m_networkManager = new NetworkAccessManager(this);
67 connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
68 this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
72 void RoutingService::parseRouteData(const QByteArray &jsonReply)
74 qDebug() << __PRETTY_FUNCTION__;
78 QVariantMap result = parser.parse (jsonReply, &ok).toMap();
80 emit error(ErrorContext::SITUARE, SituareError::ERROR_ROUTING_FAILED);
82 } else if(result.value("status").toInt() == NO_ERROR) {
83 QVariant routeSummary = result.value("route_summary");
84 QMap<QString, QVariant> routeSummaryMap = routeSummary.toMap();
87 route.setEndPointName(routeSummaryMap["end_point"].toString());
88 route.setStartPointName(routeSummaryMap["start_point"].toString());
89 route.setTotalDistance(routeSummaryMap["total_distance"].toInt());
90 route.setTotalTime(routeSummaryMap["total_time"].toInt());
92 foreach(QVariant routeGeometry, result["route_geometry"].toList()) {
93 QStringList list = routeGeometry.toStringList();
94 route.appendGeometryPoint(GeoCoordinate(list.at(0).toDouble(), list.at(1).toDouble()));
97 foreach(QVariant routeInstructions, result["route_instructions"].toList()) {
98 QStringList list = routeInstructions.toStringList();
100 segment.setInstruction(list.at(0));
101 segment.setLength(list.at(1).toDouble());
102 segment.setPositionIndex(list.at(2).toInt());
103 segment.setTime(list.at(3).toInt());
104 segment.setLengthCaption(list.at(4));
105 segment.setEarthDirection(list.at(5));
106 segment.setAzimuth(list.at(6).toDouble());
107 if (list.count() == 9) {
108 segment.setTurnType(list.at(7));
109 segment.setTurnAngle(list.at(8).toDouble());
111 route.appendSegment(segment);
114 emit routeParsed(route);
116 emit error(ErrorContext::SITUARE, SituareError::ERROR_ROUTING_FAILED);
117 qCritical() << __PRETTY_FUNCTION__ << "routing failed, json status_message:"
118 << result.value("status_message").toString();
122 void RoutingService::requestAuthorizationToken()
124 qDebug() << __PRETTY_FUNCTION__;
126 // create token request of format: http://auth.cloudmade.com/token/APIKEY?userid=UserID
127 // where APIKEY is our application specific key and userID is md5 hashed value of IMEI code
128 QString url = CLOUDMADE_AUTH_PART;
129 url.append(CLOUDMADE_API_KEY);
130 QString uidPart = "?userid=";
133 #if defined(Q_WS_MAEMO_5) & defined(ARMEL)
134 // get the device IMEI code
135 QDBusInterface interface(SIM_DBUS_SERVICE, SIM_DBUS_PATH, SIM_DBUS_IFACE,
136 QDBusConnection::systemBus());
138 QDBusMessage reply = interface.call(SIM_IMEI_REQ);
139 if (reply.type() == QDBusMessage::ErrorMessage)
140 qDebug() << reply.errorMessage();
142 QList<QVariant> args = reply.arguments();
143 qDebug() << QString("Phone's IMEI: %1").arg(args.at(0).toString());
144 rawData = args.at(0).toByteArray();
147 // for desktop we need to use login name
148 rawData.append(system("whoami"));
151 QCryptographicHash crypto(QCryptographicHash::Md5);
152 crypto.addData(rawData);
153 uidPart.append(crypto.result().toHex());
159 void RoutingService::requestFinished(QNetworkReply *reply)
161 qDebug() << __PRETTY_FUNCTION__;
163 QByteArray replyArray = reply->readAll();
165 if (reply->error()) {
166 emit error(ErrorContext::NETWORK, reply->error());
167 } else if(reply->url().toString().contains(CLOUDMADE_AUTH_PART)) {
168 m_token = replyArray;
169 m_pendingRequest.append(m_token);
170 sendRequest(m_pendingRequest);
171 m_pendingRequest.clear();
173 parseRouteData(replyArray);
176 reply->deleteLater();
179 void RoutingService::requestRoute(const GeoCoordinate &from, const GeoCoordinate &to)
181 qDebug() << __PRETTY_FUNCTION__;
183 QString url = "http://routes.cloudmade.com/";
184 url.append(CLOUDMADE_API_KEY);
185 url.append("/api/0.3/");
186 url.append(QString::number(from.latitude()) + "," + QString::number(from.longitude()) + ",");
187 url.append(QString::number(to.latitude()) + "," + QString::number(to.longitude()));
188 url.append("/car/fastest.js?lang=en");
190 if (QLocale::system().measurementSystem() == QLocale::ImperialSystem)
191 url.append("&units=miles");
193 url.append("&units=km");
195 url.append("&token=");
196 if(m_token.isEmpty()) {
197 m_pendingRequest.append(url);
198 requestAuthorizationToken();
201 sendRequest(QUrl(url));
205 void RoutingService::sendRequest(const QUrl &url)
207 qDebug() << __PRETTY_FUNCTION__;
209 QNetworkRequest request;
212 request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
215 m_networkManager->post(request, ba, false);