Added RouteWaypointList- and RouteWaypointListView classes.
[situare] / src / routing / routingservice.cpp
index e451d44..ed0842c 100644 (file)
@@ -3,6 +3,7 @@
    Copyright (C) 2010  Ixonos Plc. Authors:
 
       Henri Lampela - henri.lampela@ixonos.com
+      Sami Rämö - sami.ramo@ixonos.com
 
    Situare is free software; you can redistribute it and/or
    modify it under the terms of the GNU General Public License
    USA.
 */
 
-#include <QFile>
+#include "parser.h"
+
+#include <QCryptographicHash>
 #include <QDebug>
-#include <QtGlobal>
-#include <QStringList>
 #include <QNetworkReply>
-#include <QPointF>
+#include <QStringList>
+#include <QtGlobal>
 
-#include "common.h"
+#if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+#include <QDBusInterface>
+#include <QDBusMessage>
+#endif
+
+#include "coordinates/geocoordinate.h"
+#include "error.h"
+#include "location.h"
 #include "network/networkaccessmanager.h"
-#include "parser.h"
 #include "route.h"
 #include "routesegment.h"
 
 #include "routingservice.h"
 
+// defines for IMEI retrieval via dbus
+#define SIM_DBUS_SERVICE  "com.nokia.phone.SIM"
+#define SIM_DBUS_PATH     "/com/nokia/phone/SIM/security"
+#define SIM_DBUS_IFACE    "Phone.Sim.Security"
+#define SIM_IMEI_REQ      "get_imei"
+
 const int NO_ERROR = 0;
-/// @todo REGISTER API KEY, THE FOLLOWING IS FROM CLOUDMADE EXAMPLE URL'S
-const QString CLOUDMADE_API_KEY = "BC9A493B41014CAABB98F0471D759707";
-/// @todo implement tokens & authentication
+
+// cloudmade
+const QString CLOUDMADE_AUTH_PART = "http://auth.cloudmade.com/token/";
+const QString CLOUDMADE_API_KEY = "0cea0072adbf42ce823f4c78b974f12d";
 
 RoutingService::RoutingService(QObject *parent)
         : QObject(parent)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    m_networkManager = NetworkAccessManager::instance();
+    m_pendingRequest.clear();
+    m_token.clear();
+
+    m_networkManager = new NetworkAccessManager(this);
     connect(m_networkManager, SIGNAL(finished(QNetworkReply*)),
             this, SLOT(requestFinished(QNetworkReply*)), Qt::QueuedConnection);
-}
-
-RoutingService::~RoutingService()
-{
-    qDebug() << __PRETTY_FUNCTION__;
-}
-
-void RoutingService::fetchRoute(QPointF from, QPointF to)
-{
-    qDebug() << __PRETTY_FUNCTION__;
-
-    QString url = "http://routes.cloudmade.com/";
-    url.append(CLOUDMADE_API_KEY);
-    url.append("/api/0.3/");
-    url.append(QString::number(from.x()) + "," + QString::number(from.y()) + ",");
-    url.append(QString::number(to.x()) + "," + QString::number(to.y()));
-    url.append("/car/fastest.js?lang=en&units=km");
-
-    qWarning() << __PRETTY_FUNCTION__ << url;
 
-    sendRequest(QUrl(url));
 }
 
 void RoutingService::parseRouteData(const QByteArray &jsonReply)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    qWarning() << __PRETTY_FUNCTION__ << jsonReply;
-
     QJson::Parser parser;
     bool ok;
     QVariantMap result = parser.parse (jsonReply, &ok).toMap();
@@ -95,7 +91,8 @@ void RoutingService::parseRouteData(const QByteArray &jsonReply)
 
             foreach(QVariant routeGeometry, result["route_geometry"].toList()) {
                 QStringList list = routeGeometry.toStringList();
-                route.appendGeometryPoint(QPointF(list.at(1).toDouble(), list.at(0).toDouble()));
+                route.appendGeometryPoint(GeoCoordinate(list.at(0).toDouble(),
+                                                        list.at(1).toDouble()));
             }
 
             foreach(QVariant routeInstructions, result["route_instructions"].toList()) {
@@ -108,7 +105,7 @@ void RoutingService::parseRouteData(const QByteArray &jsonReply)
                 segment.setLengthCaption(list.at(4));
                 segment.setEarthDirection(list.at(5));
                 segment.setAzimuth(list.at(6).toDouble());
-                if (list.count() == 8) {
+                if (list.count() == 9) {
                     segment.setTurnType(list.at(7));
                     segment.setTurnAngle(list.at(8).toDouble());
                 }
@@ -120,19 +117,80 @@ void RoutingService::parseRouteData(const QByteArray &jsonReply)
     }
 }
 
+void RoutingService::requestAuthorizationToken()
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    // create token request of format: http://auth.cloudmade.com/token/APIKEY?userid=UserID
+    // where APIKEY is our application specific key and userID is md5 hashed value of IMEI code
+    QString url = CLOUDMADE_AUTH_PART;
+    url.append(CLOUDMADE_API_KEY);
+    QString uidPart = "?userid=";
+    QByteArray rawData;
+
+#if defined(Q_WS_MAEMO_5) & defined(ARMEL)
+    // get the device IMEI code
+    QDBusInterface interface(SIM_DBUS_SERVICE, SIM_DBUS_PATH, SIM_DBUS_IFACE,
+                             QDBusConnection::systemBus());
+
+    QDBusMessage reply = interface.call(SIM_IMEI_REQ);
+    if (reply.type() == QDBusMessage::ErrorMessage)
+        qDebug() << reply.errorMessage();
+    else {
+        QList<QVariant> args = reply.arguments();
+        qDebug() << QString("Phone's IMEI: %1").arg(args.at(0).toString());
+        rawData = args.at(0).toByteArray();
+    }
+#else
+    // for desktop we need to use login name
+    rawData.append(system("whoami"));
+#endif
+
+    QCryptographicHash crypto(QCryptographicHash::Md5);
+    crypto.addData(rawData);
+    uidPart.append(crypto.result().toHex());
+
+    url.append(uidPart);
+    sendRequest(url);
+}
+
 void RoutingService::requestFinished(QNetworkReply *reply)
 {
     qDebug() << __PRETTY_FUNCTION__;
 
-    if (m_currentRequests.contains(reply)) {
+    QByteArray replyArray = reply->readAll();
 
-        if (reply->error())
-            emit error(ErrorContext::NETWORK, reply->error());
-        else
-            parseRouteData(reply->readAll());
+    if (reply->error()) {
+        emit error(ErrorContext::NETWORK, reply->error());
+    } else if(reply->url().toString().contains(CLOUDMADE_AUTH_PART)) {
+        m_token = replyArray;
+        m_pendingRequest.append(m_token);
+        sendRequest(m_pendingRequest);
+        m_pendingRequest.clear();
+    } else {
+        parseRouteData(replyArray);
+    }
 
-        m_currentRequests.removeAll(reply);
-        reply->deleteLater();
+    reply->deleteLater();
+}
+
+void RoutingService::requestRoute(const GeoCoordinate &from, const GeoCoordinate &to)
+{
+    qDebug() << __PRETTY_FUNCTION__;
+
+    QString url = "http://routes.cloudmade.com/";
+    url.append(CLOUDMADE_API_KEY);
+    url.append("/api/0.3/");
+    url.append(QString::number(from.latitude()) + "," + QString::number(from.longitude()) + ",");
+    url.append(QString::number(to.latitude()) + "," + QString::number(to.longitude()));
+    url.append("/car/fastest.js?lang=en&units=km&token=");
+
+    if(m_token.isEmpty()) {
+        m_pendingRequest.append(url);
+        requestAuthorizationToken();
+    } else {
+        url.append(m_token);
+        sendRequest(QUrl(url));
     }
 }
 
@@ -145,7 +203,6 @@ void RoutingService::sendRequest(const QUrl &url)
     request.setUrl(url);
     request.setAttribute(QNetworkRequest::CacheSaveControlAttribute, false);
 
-    QNetworkReply *reply = m_networkManager->get(request, true);
-
-    m_currentRequests.append(reply);
+    QByteArray ba;
+    m_networkManager->post(request, ba, false);
 }