summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJavier <dev.git@javispedro.com>2015-12-13 03:18:09 +0100
committerJavier <dev.git@javispedro.com>2015-12-13 03:18:09 +0100
commit3340aa0ef68eb735c36185959c8dbd11178575bf (patch)
treecf424e206eb60b7ca9f99bf135ed8dae54d25259
parentf45294559f976258831821ada062c73965201150 (diff)
downloadsapd-3340aa0ef68eb735c36185959c8dbd11178575bf.tar.gz
sapd-3340aa0ef68eb735c36185959c8dbd11178575bf.zip
Bump min Qt requirement to 5.2, bump libwatchfish version
-rw-r--r--hfpag.h5
-rw-r--r--hostmanagerconn.cc110
-rw-r--r--hostmanagerconn.h7
m---------libwatchfish0
-rw-r--r--main.cc2
-rw-r--r--notificationconn.h1
-rw-r--r--qtjson/json.cc549
-rw-r--r--qtjson/json.h112
-rw-r--r--rpm/sapd.yaml4
-rw-r--r--sapbtlistener.cc98
-rw-r--r--sapbtlistener.h17
-rw-r--r--sapbtpeer.cc4
-rw-r--r--sapbtpeer.h9
-rw-r--r--sapd.pro37
-rw-r--r--sappeer.cc67
-rw-r--r--saprotocol.h9
-rw-r--r--webproxyagent.cc57
-rw-r--r--webproxyagent.h27
-rw-r--r--webproxyconn.cc25
-rw-r--r--webproxyconn.h26
20 files changed, 251 insertions, 915 deletions
diff --git a/hfpag.h b/hfpag.h
index e005c8a..40acbdb 100644
--- a/hfpag.h
+++ b/hfpag.h
@@ -1,9 +1,8 @@
#ifndef HFPAG_H
#define HFPAG_H
-#include <QtConnectivity/QBluetoothSocket>
-
-QTM_USE_NAMESPACE
+#include <QtCore/QObject>
+#include <QtBluetooth/QBluetoothSocket>
class HfpAg : public QObject
{
diff --git a/hostmanagerconn.cc b/hostmanagerconn.cc
index de1c61a..e4f5edc 100644
--- a/hostmanagerconn.cc
+++ b/hostmanagerconn.cc
@@ -1,8 +1,13 @@
-#include <QtCore/QDateTime>
#include <QtCore/QDebug>
+#include <QtCore/QDateTime>
+#include <QtCore/QTimeZone>
#include <QtCore/QXmlStreamWriter>
+#include <QtCore/QJsonDocument>
-#include "qtjson/json.h"
+#if SAILFISH
+#include <libwatchfish/walltimemonitor.h>
+static watchfish::WallTimeMonitor *monitor = 0;
+#endif
#include "sappeer.h"
#include "hostmanagerconn.h"
@@ -16,31 +21,38 @@ HostManagerConn::HostManagerConn(SAPConnection *conn, QObject *parent)
connect(_socket, SIGNAL(messageReceived()), SLOT(handleMessageReceived()));
}
-void HostManagerConn::sendMessage(const QString &json)
-{
- qDebug() << "Send JSON:" << json;
- _socket->send(QByteArray(3,0) + json.toUtf8());
-}
-
-void HostManagerConn::sendMessage(const QVariantMap &msg)
+void HostManagerConn::sendMessage(const QJsonObject &msg)
{
- sendMessage(QtJson::serializeStr(msg));
+ QJsonDocument doc(msg);
+ QByteArray data = doc.toJson(QJsonDocument::Compact);
+ qDebug() << "Send JSON:" << data;
+ _socket->send(QByteArray(3,0) + doc.toJson(QJsonDocument::Compact));
}
-void HostManagerConn::handleMessage(const QVariantMap &msg)
+void HostManagerConn::handleMessage(const QJsonObject &msg)
{
- QString msgId = msg["msgId"].toString();
+ const QString msgId = msg["msgId"].toString();
qDebug() << "Got JSON msg" << msgId;
if (msgId == "mgr_watch_info_res") {
- sendMessage("{\"timestamp\":\"1407542281196=B:L>:<=LAMO\",\"type\":\"connect\",\"msgId\":\"mgr_wearable_status_req\"}");
+ QJsonObject reply;
+ reply["timestamp"] = QLatin1String("1407542281196=B:L>:<=LAMO");
+ reply["type"] = QLatin1String("connect");
+ reply["msgId"] = QLatin1String("mgr_wearable_status_req");
+ sendMessage(reply);
} else if (msgId == "mgr_host_status_req") {
- sendMessage(QString("{\"type\":\"connect\",\"data\":%1,\"msgId\":\"mgr_host_status_res\",\"preinstalled\":\"true\"}")
- .arg(QtJson::sanitizeString(generateHostXml())));
-
+ QJsonObject reply;
+ reply["type"] = QLatin1String("connect");
+ reply["msgId"] = QLatin1String("mgr_host_status_res");
+ reply["preinstalled"] = QLatin1String("true");
+ reply["data"] = generateHostXml();
+ sendMessage(reply);
} else if (msgId == "mgr_status_exchange_done") {
performTimeSync();
- sendMessage(QString("{\"btMac\":\"%1\",\"msgId\":\"mgr_setupwizard_eula_finished_req\",\"isOld\":1}")
- .arg(_conn->peer()->localName()));
+ QJsonObject reply;
+ reply["btMac"] = _conn->peer()->localName();
+ reply["msgId"] = QLatin1String("mgr_setupwizard_eula_finished_req");
+ reply["isOld"] = 1;
+ sendMessage(reply);
}
}
@@ -51,22 +63,27 @@ void HostManagerConn::performTimeSync()
// "isfrominitial":true,"msgId":"mgr_sync_init_setting_req","usingCamera":"false","safety_cam":"0",
// "datetime":"2014 08 29 22 23 48","incomingCall":"false"}
- QVariantMap msg;
- msg["msgId"] = "mgr_sync_init_setting_req";
+ QJsonObject msg;
+ msg["msgId"] = QLatin1String("mgr_sync_init_setting_req");
- msg["safety_declared"] = "0";
- msg["safety_voice"] = "0";
- msg["safetyVersion"] = "0";
- msg["safety"] = "false";
- msg["tablet"] = "true";
- msg["incomingCall"] = "false";
- msg["usingCamera"] = "false";
- msg["safety_cam"] = "0";
+ msg["safety_declared"] = QLatin1String("0");
+ msg["safety_voice"] = QLatin1String("0");
+ msg["safetyVersion"] = QLatin1String("0");
+ msg["safety"] = QLatin1String("false");
+ msg["tablet"] = QLatin1String("true");
+ msg["incomingCall"] = QLatin1String("false");
+ msg["usingCamera"] = QLatin1String("false");
+ msg["safety_cam"] = QLatin1String("0");
msg["locale"] = QLocale::system().name(); // ie es_ES
- msg["data1224"] = "24"; // TODO
+ msg["data1224"] = QLatin1String("24"); // TODO
msg["dateformat"] = QLocale::system().dateFormat(QLocale::ShortFormat);
- msg["timezone"] = "Europe/Madrid";
+
+#if SAILFISH
+ msg["timezone"] = monitor->timezone();
+#else
+ msg["timezone"] = QString::fromLatin1(QTimeZone::systemTimeZoneId());
+#endif
QDateTime dt = QDateTime::currentDateTime();
msg["datetimeepoch"] = QString::number(dt.currentMSecsSinceEpoch());
@@ -124,10 +141,18 @@ QString HostManagerConn::generateHostXml()
void HostManagerConn::handleConnected()
{
qDebug() << "Manager socket now connected!";
- QString msg = QString("{\"btMac\":\"%1\",\"msgId\":\"mgr_watch_info_req\",\"hmVer\":\"2.0.14041404\"}").arg(_conn->peer()->localName());
- qDebug() << msg;
- QByteArray data = QByteArray(3,0) + msg.toUtf8();
- _socket->send(data);
+
+#if SAILFISH
+ if (!monitor) {
+ monitor = new watchfish::WallTimeMonitor;
+ }
+#endif
+
+ QJsonObject obj;
+ obj["btMac"] = _conn->peer()->localName();
+ obj["msgId"] = QLatin1String("mgr_watch_info_req");
+ obj["hmVer"] = QLatin1String("2.0.14041404");
+ sendMessage(obj);
}
void HostManagerConn::handleMessageReceived()
@@ -139,17 +164,16 @@ void HostManagerConn::handleMessageReceived()
return;
}
- data.remove(0, 3); // First two bytes contain something related to ???
+ data.remove(0, 3); // What are those first three bytes??? They seem to be always NUL.
+
+ qDebug() << "Got JSON:" << QString::fromUtf8(data);
- QString str = QString::fromUtf8(data);
- bool success = false;
- QVariant json = QtJson::parse(str, success);
+ QJsonParseError error;
+ QJsonDocument json = QJsonDocument::fromJson(data, &error);
- if (success) {
- qDebug() << "Got JSON:" << str;
- handleMessage(json.toMap());
+ if (json.isObject()) {
+ handleMessage(json.object());
} else {
- qWarning() << "Cannot parse JSON msg:" << str;
- return;
+ qWarning() << "Cannot parse JSON msg:" << error.errorString();
}
}
diff --git a/hostmanagerconn.h b/hostmanagerconn.h
index ab143a0..1361d21 100644
--- a/hostmanagerconn.h
+++ b/hostmanagerconn.h
@@ -2,6 +2,7 @@
#define HOSTMANAGERPEER_H
#include <QtCore/QVariant>
+#include <QtCore/QJsonObject>
#include "sapconnection.h"
#include "sapsocket.h"
@@ -13,9 +14,9 @@ public:
HostManagerConn(SAPConnection *conn, QObject *parent = 0);
private:
- void sendMessage(const QString &json);
- void sendMessage(const QVariantMap &msg);
- void handleMessage(const QVariantMap &msg);
+ void sendMessage(const QJsonObject &obj);
+
+ void handleMessage(const QJsonObject &obj);
void performTimeSync();
diff --git a/libwatchfish b/libwatchfish
-Subproject 7ee859f6a5e6a334a172015fce744baeff53905
+Subproject 3b6a0066ef584a076b1a05dc5524cbfa2e2a0bb
diff --git a/main.cc b/main.cc
index feb0acb..71d2b9f 100644
--- a/main.cc
+++ b/main.cc
@@ -7,6 +7,7 @@
#include "capabilityagent.h"
#include "hostmanageragent.h"
+#include "webproxyagent.h"
#include "notificationagent.h"
using std::cerr;
@@ -44,6 +45,7 @@ int main(int argc, char *argv[])
CapabilityAgent::registerServices(manager);
HostManagerAgent::registerServices(manager);
+ WebProxyAgent::registerServices(manager);
NotificationAgent::registerServices(manager);
QScopedPointer<SAPBTListener> sap_listener(new SAPBTListener);
diff --git a/notificationconn.h b/notificationconn.h
index 69f2244..092804a 100644
--- a/notificationconn.h
+++ b/notificationconn.h
@@ -3,6 +3,7 @@
#include <QtCore/QObject>
#include <QtCore/QDateTime>
+#include <QtCore/QHash>
#include "sapconnection.h"
#include "sapsocket.h"
diff --git a/qtjson/json.cc b/qtjson/json.cc
deleted file mode 100644
index 759cf0e..0000000
--- a/qtjson/json.cc
+++ /dev/null
@@ -1,549 +0,0 @@
-/**
- * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa.
- * Copyright (C) 2011 Eeli Reilin
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * \file json.cpp
- */
-
-#include <QDateTime>
-#include "json.h"
-
-namespace QtJson {
- static QString dateFormat, dateTimeFormat;
-
- static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep);
- static QVariant parseValue(const QString &json, int &index, bool &success);
- static QVariant parseObject(const QString &json, int &index, bool &success);
- static QVariant parseArray(const QString &json, int &index, bool &success);
- static QVariant parseString(const QString &json, int &index, bool &success);
- static QVariant parseNumber(const QString &json, int &index);
- static int lastIndexOfNumber(const QString &json, int index);
- static void eatWhitespace(const QString &json, int &index);
- static int lookAhead(const QString &json, int index);
- static int nextToken(const QString &json, int &index);
-
- template<typename T>
- QByteArray serializeMap(const T &map, bool &success) {
- QByteArray str = "{ ";
- QList<QByteArray> pairs;
- for (typename T::const_iterator it = map.begin(), itend = map.end(); it != itend; ++it) {
- QByteArray serializedValue = serialize(it.value());
- if (serializedValue.isNull()) {
- success = false;
- break;
- }
- pairs << sanitizeString(it.key()).toUtf8() + " : " + serializedValue;
- }
-
- str += join(pairs, ", ");
- str += " }";
- return str;
- }
-
-
- /**
- * parse
- */
- QVariant parse(const QString &json) {
- bool success = true;
- return parse(json, success);
- }
-
- /**
- * parse
- */
- QVariant parse(const QString &json, bool &success) {
- success = true;
-
- // Return an empty QVariant if the JSON data is either null or empty
- if (!json.isNull() || !json.isEmpty()) {
- QString data = json;
- // We'll start from index 0
- int index = 0;
-
- // Parse the first value
- QVariant value = parseValue(data, index, success);
-
- // Return the parsed value
- return value;
- } else {
- // Return the empty QVariant
- return QVariant();
- }
- }
-
- QByteArray serialize(const QVariant &data) {
- bool success = true;
- return serialize(data, success);
- }
-
- QByteArray serialize(const QVariant &data, bool &success) {
- QByteArray str;
- success = true;
-
- if (!data.isValid()) { // invalid or null?
- str = "null";
- } else if ((data.type() == QVariant::List) ||
- (data.type() == QVariant::StringList)) { // variant is a list?
- QList<QByteArray> values;
- const QVariantList list = data.toList();
- Q_FOREACH(const QVariant& v, list) {
- QByteArray serializedValue = serialize(v);
- if (serializedValue.isNull()) {
- success = false;
- break;
- }
- values << serializedValue;
- }
-
- str = "[ " + join( values, ", " ) + " ]";
- } else if (data.type() == QVariant::Hash) { // variant is a hash?
- str = serializeMap<>(data.toHash(), success);
- } else if (data.type() == QVariant::Map) { // variant is a map?
- str = serializeMap<>(data.toMap(), success);
- } else if ((data.type() == QVariant::String) ||
- (data.type() == QVariant::ByteArray)) {// a string or a byte array?
- str = sanitizeString(data.toString()).toUtf8();
- } else if (data.type() == QVariant::Double) { // double?
- double value = data.toDouble();
- if ((value - value) == 0.0) {
- str = QByteArray::number(value, 'g');
- if (!str.contains(".") && ! str.contains("e")) {
- str += ".0";
- }
- } else {
- success = false;
- }
- } else if (data.type() == QVariant::Bool) { // boolean value?
- str = data.toBool() ? "true" : "false";
- } else if (data.type() == QVariant::ULongLong) { // large unsigned number?
- str = QByteArray::number(data.value<qulonglong>());
- } else if (data.canConvert<qlonglong>()) { // any signed number?
- str = QByteArray::number(data.value<qlonglong>());
- } else if (data.canConvert<long>()) { //TODO: this code is never executed because all smaller types can be converted to qlonglong
- str = QString::number(data.value<long>()).toUtf8();
- } else if (data.type() == QVariant::DateTime) { // datetime value?
- str = sanitizeString(dateTimeFormat.isEmpty()
- ? data.toDateTime().toString()
- : data.toDateTime().toString(dateTimeFormat)).toUtf8();
- } else if (data.type() == QVariant::Date) { // date value?
- str = sanitizeString(dateTimeFormat.isEmpty()
- ? data.toDate().toString()
- : data.toDate().toString(dateFormat)).toUtf8();
- } else if (data.canConvert<QString>()) { // can value be converted to string?
- // this will catch QUrl, ... (all other types which can be converted to string)
- str = sanitizeString(data.toString()).toUtf8();
- } else {
- success = false;
- }
-
- if (success) {
- return str;
- } else {
- return QByteArray();
- }
- }
-
- QString serializeStr(const QVariant &data) {
- return QString::fromUtf8(serialize(data));
- }
-
- QString serializeStr(const QVariant &data, bool &success) {
- return QString::fromUtf8(serialize(data, success));
- }
-
-
- /**
- * \enum JsonToken
- */
- enum JsonToken {
- JsonTokenNone = 0,
- JsonTokenCurlyOpen = 1,
- JsonTokenCurlyClose = 2,
- JsonTokenSquaredOpen = 3,
- JsonTokenSquaredClose = 4,
- JsonTokenColon = 5,
- JsonTokenComma = 6,
- JsonTokenString = 7,
- JsonTokenNumber = 8,
- JsonTokenTrue = 9,
- JsonTokenFalse = 10,
- JsonTokenNull = 11
- };
-
- QString sanitizeString(QString str) {
- str.replace(QLatin1String("\\"), QLatin1String("\\\\"));
- str.replace(QLatin1String("\""), QLatin1String("\\\""));
- str.replace(QLatin1String("\b"), QLatin1String("\\b"));
- str.replace(QLatin1String("\f"), QLatin1String("\\f"));
- str.replace(QLatin1String("\n"), QLatin1String("\\n"));
- str.replace(QLatin1String("\r"), QLatin1String("\\r"));
- str.replace(QLatin1String("\t"), QLatin1String("\\t"));
- return QString(QLatin1String("\"%1\"")).arg(str);
- }
-
- static QByteArray join(const QList<QByteArray> &list, const QByteArray &sep) {
- QByteArray res;
- Q_FOREACH(const QByteArray &i, list) {
- if (!res.isEmpty()) {
- res += sep;
- }
- res += i;
- }
- return res;
- }
-
- /**
- * parseValue
- */
- static QVariant parseValue(const QString &json, int &index, bool &success) {
- // Determine what kind of data we should parse by
- // checking out the upcoming token
- switch(lookAhead(json, index)) {
- case JsonTokenString:
- return parseString(json, index, success);
- case JsonTokenNumber:
- return parseNumber(json, index);
- case JsonTokenCurlyOpen:
- return parseObject(json, index, success);
- case JsonTokenSquaredOpen:
- return parseArray(json, index, success);
- case JsonTokenTrue:
- nextToken(json, index);
- return QVariant(true);
- case JsonTokenFalse:
- nextToken(json, index);
- return QVariant(false);
- case JsonTokenNull:
- nextToken(json, index);
- return QVariant();
- case JsonTokenNone:
- break;
- }
-
- // If there were no tokens, flag the failure and return an empty QVariant
- success = false;
- return QVariant();
- }
-
- /**
- * parseObject
- */
- static QVariant parseObject(const QString &json, int &index, bool &success) {
- QVariantMap map;
- int token;
-
- // Get rid of the whitespace and increment index
- nextToken(json, index);
-
- // Loop through all of the key/value pairs of the object
- bool done = false;
- while (!done) {
- // Get the upcoming token
- token = lookAhead(json, index);
-
- if (token == JsonTokenNone) {
- success = false;
- return QVariantMap();
- } else if (token == JsonTokenComma) {
- nextToken(json, index);
- } else if (token == JsonTokenCurlyClose) {
- nextToken(json, index);
- return map;
- } else {
- // Parse the key/value pair's name
- QString name = parseString(json, index, success).toString();
-
- if (!success) {
- return QVariantMap();
- }
-
- // Get the next token
- token = nextToken(json, index);
-
- // If the next token is not a colon, flag the failure
- // return an empty QVariant
- if (token != JsonTokenColon) {
- success = false;
- return QVariant(QVariantMap());
- }
-
- // Parse the key/value pair's value
- QVariant value = parseValue(json, index, success);
-
- if (!success) {
- return QVariantMap();
- }
-
- // Assign the value to the key in the map
- map[name] = value;
- }
- }
-
- // Return the map successfully
- return QVariant(map);
- }
-
- /**
- * parseArray
- */
- static QVariant parseArray(const QString &json, int &index, bool &success) {
- QVariantList list;
-
- nextToken(json, index);
-
- bool done = false;
- while(!done) {
- int token = lookAhead(json, index);
-
- if (token == JsonTokenNone) {
- success = false;
- return QVariantList();
- } else if (token == JsonTokenComma) {
- nextToken(json, index);
- } else if (token == JsonTokenSquaredClose) {
- nextToken(json, index);
- break;
- } else {
- QVariant value = parseValue(json, index, success);
- if (!success) {
- return QVariantList();
- }
- list.push_back(value);
- }
- }
-
- return QVariant(list);
- }
-
- /**
- * parseString
- */
- static QVariant parseString(const QString &json, int &index, bool &success) {
- QString s;
- QChar c;
-
- eatWhitespace(json, index);
-
- c = json[index++];
-
- bool complete = false;
- while(!complete) {
- if (index == json.size()) {
- break;
- }
-
- c = json[index++];
-
- if (c == '\"') {
- complete = true;
- break;
- } else if (c == '\\') {
- if (index == json.size()) {
- break;
- }
-
- c = json[index++];
-
- if (c == '\"') {
- s.append('\"');
- } else if (c == '\\') {
- s.append('\\');
- } else if (c == '/') {
- s.append('/');
- } else if (c == 'b') {
- s.append('\b');
- } else if (c == 'f') {
- s.append('\f');
- } else if (c == 'n') {
- s.append('\n');
- } else if (c == 'r') {
- s.append('\r');
- } else if (c == 't') {
- s.append('\t');
- } else if (c == 'u') {
- int remainingLength = json.size() - index;
- if (remainingLength >= 4) {
- QString unicodeStr = json.mid(index, 4);
-
- int symbol = unicodeStr.toInt(0, 16);
-
- s.append(QChar(symbol));
-
- index += 4;
- } else {
- break;
- }
- }
- } else {
- s.append(c);
- }
- }
-
- if (!complete) {
- success = false;
- return QVariant();
- }
-
- return QVariant(s);
- }
-
- /**
- * parseNumber
- */
- static QVariant parseNumber(const QString &json, int &index) {
- eatWhitespace(json, index);
-
- int lastIndex = lastIndexOfNumber(json, index);
- int charLength = (lastIndex - index) + 1;
- QString numberStr;
-
- numberStr = json.mid(index, charLength);
-
- index = lastIndex + 1;
- bool ok;
-
- if (numberStr.contains('.')) {
- return QVariant(numberStr.toDouble(NULL));
- } else if (numberStr.startsWith('-')) {
- int i = numberStr.toInt(&ok);
- if (!ok) {
- qlonglong ll = numberStr.toLongLong(&ok);
- return ok ? ll : QVariant(numberStr);
- }
- return i;
- } else {
- uint u = numberStr.toUInt(&ok);
- if (!ok) {
- qulonglong ull = numberStr.toULongLong(&ok);
- return ok ? ull : QVariant(numberStr);
- }
- return u;
- }
- }
-
- /**
- * lastIndexOfNumber
- */
- static int lastIndexOfNumber(const QString &json, int index) {
- int lastIndex;
-
- for(lastIndex = index; lastIndex < json.size(); lastIndex++) {
- if (QString("0123456789+-.eE").indexOf(json[lastIndex]) == -1) {
- break;
- }
- }
-
- return lastIndex -1;
- }
-
- /**
- * eatWhitespace
- */
- static void eatWhitespace(const QString &json, int &index) {
- for(; index < json.size(); index++) {
- if (QString(" \t\n\r").indexOf(json[index]) == -1) {
- break;
- }
- }
- }
-
- /**
- * lookAhead
- */
- static int lookAhead(const QString &json, int index) {
- int saveIndex = index;
- return nextToken(json, saveIndex);
- }
-
- /**
- * nextToken
- */
- static int nextToken(const QString &json, int &index) {
- eatWhitespace(json, index);
-
- if (index == json.size()) {
- return JsonTokenNone;
- }
-
- QChar c = json[index];
- index++;
- switch(c.toLatin1()) {
- case '{': return JsonTokenCurlyOpen;
- case '}': return JsonTokenCurlyClose;
- case '[': return JsonTokenSquaredOpen;
- case ']': return JsonTokenSquaredClose;
- case ',': return JsonTokenComma;
- case '"': return JsonTokenString;
- case '0': case '1': case '2': case '3': case '4':
- case '5': case '6': case '7': case '8': case '9':
- case '-': return JsonTokenNumber;
- case ':': return JsonTokenColon;
- }
- index--; // ^ WTF?
-
- int remainingLength = json.size() - index;
-
- // True
- if (remainingLength >= 4) {
- if (json[index] == 't' && json[index + 1] == 'r' &&
- json[index + 2] == 'u' && json[index + 3] == 'e') {
- index += 4;
- return JsonTokenTrue;
- }
- }
-
- // False
- if (remainingLength >= 5) {
- if (json[index] == 'f' && json[index + 1] == 'a' &&
- json[index + 2] == 'l' && json[index + 3] == 's' &&
- json[index + 4] == 'e') {
- index += 5;
- return JsonTokenFalse;
- }
- }
-
- // Null
- if (remainingLength >= 4) {
- if (json[index] == 'n' && json[index + 1] == 'u' &&
- json[index + 2] == 'l' && json[index + 3] == 'l') {
- index += 4;
- return JsonTokenNull;
- }
- }
-
- return JsonTokenNone;
- }
-
- void setDateTimeFormat(const QString &format) {
- dateTimeFormat = format;
- }
-
- void setDateFormat(const QString &format) {
- dateFormat = format;
- }
-
- QString getDateTimeFormat() {
- return dateTimeFormat;
- }
-
- QString getDateFormat() {
- return dateFormat;
- }
-
-} //end namespace
diff --git a/qtjson/json.h b/qtjson/json.h
deleted file mode 100644
index 5482b6a..0000000
--- a/qtjson/json.h
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * QtJson - A simple class for parsing JSON data into a QVariant hierarchies and vice-versa.
- * Copyright (C) 2011 Eeli Reilin
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation, either version 3 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program. If not, see <http://www.gnu.org/licenses/>.
- */
-
-/**
- * \file json.h
- */
-
-#ifndef JSON_H
-#define JSON_H
-
-#include <QVariant>
-#include <QString>
-
-
-/**
- * \namespace QtJson
- * \brief A JSON data parser
- *
- * Json parses a JSON data into a QVariant hierarchy.
- */
-namespace QtJson {
- typedef QVariantMap JsonObject;
- typedef QVariantList JsonArray;
-
- /**
- * Parse a JSON string
- *
- * \param json The JSON data
- */
- QVariant parse(const QString &json);
-
- /**
- * Parse a JSON string
- *
- * \param json The JSON data
- * \param success The success of the parsing
- */
- QVariant parse(const QString &json, bool &success);
-
- /**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- *
- * \return QByteArray Textual JSON representation in UTF-8
- */
- QByteArray serialize(const QVariant &data);
-
- /**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- * \param success The success of the serialization
- *
- * \return QByteArray Textual JSON representation in UTF-8
- */
- QByteArray serialize(const QVariant &data, bool &success);
-
- /**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- *
- * \return QString Textual JSON representation
- */
- QString serializeStr(const QVariant &data);
-
- /**
- * This method generates a textual JSON representation
- *
- * \param data The JSON data generated by the parser.
- * \param success The success of the serialization
- *
- * \return QString Textual JSON representation
- */
- QString serializeStr(const QVariant &data, bool &success);
-
- /**
- * This method sets date(time) format to be used for QDateTime::toString
- * If QString is empty, Qt::TextDate is used.
- *
- * \param format The JSON data generated by the parser.
- */
- void setDateTimeFormat(const QString& format);
- void setDateFormat(const QString& format);
-
- /**
- * This method gets date(time) format to be used for QDateTime::toString
- * If QString is empty, Qt::TextDate is used.
- */
- QString getDateTimeFormat();
- QString getDateFormat();
-
- QString sanitizeString(QString str);
-}
-
-#endif //JSON_H
diff --git a/rpm/sapd.yaml b/rpm/sapd.yaml
index 212f735..59681f6 100644
--- a/rpm/sapd.yaml
+++ b/rpm/sapd.yaml
@@ -1,6 +1,6 @@
Name: sapd
Summary: Accesory protocol daemon
-Version: 0.1.0
+Version: 0.1.1
Release: 1
Group: Communications/Bluetooth
URL: https://gitorious.org/javispedro-jolla-misc/sapd/
@@ -18,6 +18,8 @@ PkgConfigBR:
- Qt5DBus
- Qt5Bluetooth
- openssl
+ - dbus-1
+ - timed-qt5
PkgBR:
# Workaround current sailfish qt5connectivity packaging bug
diff --git a/sapbtlistener.cc b/sapbtlistener.cc
index 76ecb94..40c7ac6 100644
--- a/sapbtlistener.cc
+++ b/sapbtlistener.cc
@@ -1,10 +1,5 @@
#include <QtCore/QDebug>
-#ifdef MANUAL_SDP
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#endif
-
#include "saprotocol.h"
#include "sapbtlistener.h"
#include "sapbtpeer.h"
@@ -13,67 +8,6 @@
#include "hfpag.h"
#endif
-namespace
-{
-
-#ifdef MANUAL_SDP
-// Basically, QBluetoothServiceInfo is not yet compatible with Bluez5,
-// so we hack around it by doing our own SDP connection.
-void add_sdp_record(sdp_session_t *session, const QBluetoothUuid &btuuid, quint16 port)
-{
- sdp_list_t *svclass_id, *apseq, *root;
- uuid_t root_uuid, svclass_uuid, l2cap_uuid, rfcomm_uuid;
- sdp_list_t *aproto, *proto[2];
- sdp_data_t *chan;
-
- sdp_record_t *record = sdp_record_alloc();
-
- sdp_set_info_attr(record, "SAP", "gearbttest", "Samsung Accessory Protocol");
-
- sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
- root = sdp_list_append(0, &root_uuid);
- sdp_set_browse_groups(record, root);
-
- QByteArray uuid = btuuid.toRfc4122();
- sdp_uuid128_create(&svclass_uuid, uuid.constData());
- svclass_id = sdp_list_append(0, &svclass_uuid);
- sdp_set_service_classes(record, svclass_id);
-
- sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
- proto[0] = sdp_list_append(0, &l2cap_uuid);
- apseq = sdp_list_append(0, proto[0]);
-
- sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
- proto[1] = sdp_list_append(0, &rfcomm_uuid);
- chan = sdp_data_alloc(SDP_UINT8, &port);
- proto[1] = sdp_list_append(proto[1], chan);
- apseq = sdp_list_append(apseq, proto[1]);
-
- aproto = sdp_list_append(0, apseq);
- sdp_set_access_protos(record, aproto);
-
- if (sdp_record_register(session, record, 0) < 0) {
- qWarning() << "sdp_record_register failed";
- }
-}
-
-void add_sdp_records(quint16 port)
-{
- bdaddr_t addr_any = {{0, 0, 0, 0, 0, 0}};
- bdaddr_t addr_local = {{0, 0, 0, 0xFF, 0xFF, 0xFF}};
-
- sdp_session_t *sess = sdp_connect(&addr_any, &addr_local, 0);
- if (!sess) {
- qWarning() << "sdp_connect failed";
- return;
- }
-
- add_sdp_record(sess, SAProtocol::dataServiceUuid, port);
-}
-#endif
-
-}
-
SAPBTListener::SAPBTListener(QObject *parent) :
QObject(parent), _server(0)
{
@@ -87,14 +21,11 @@ SAPBTListener::~SAPBTListener()
void SAPBTListener::start()
{
if (_server) {
+ qWarning() << "Already started";
return;
}
-#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
_server = new QBluetoothServer(QBluetoothServiceInfo::RfcommProtocol, this);
-#else
- _server = new QRfcommServer(this);
-#endif
connect(_server, SIGNAL(newConnection()), this, SLOT(acceptConnection()));
if (!_server->listen(QBluetoothAddress(), 0)) {
qWarning() << "Failed to start Bluetooth listener socket";
@@ -104,12 +35,6 @@ void SAPBTListener::start()
quint8 serverPort = _server->serverPort();
-#if MANUAL_SDP
- // Basically, QBluetoothServiceInfo is not yet compatible with Bluez5,
- // so we hack around it by doing our own SDP connection.
- add_sdp_records(serverPort);
-#else
-
/*
Service Name: SAP
Service RecHandle: 0x1000b
@@ -160,7 +85,6 @@ void SAPBTListener::start()
if (!_service.registerService()) {
qWarning() << "Failed to register the SAP service";
}
-#endif
}
void SAPBTListener::stop()
@@ -179,19 +103,20 @@ void SAPBTListener::stop()
void SAPBTListener::nudge(const QBluetoothAddress &address)
{
-#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
QBluetoothSocket *socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this);
-#else
- QBluetoothSocket *socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket, this);
-#endif
- connect(socket, SIGNAL(connected()), socket, SLOT(deleteLater()));
+ connect(socket, SIGNAL(connected()), this, SLOT(handleNudgeConnected()));
connect(socket, SIGNAL(error(QBluetoothSocket::SocketError)),
this, SLOT(handleNudgeError(QBluetoothSocket::SocketError)));
qDebug() << "Nudging" << address.toString();
- socket->connectToService(address, 2); //SAPProtocol::nudgeServiceUuid);
+#if SAILFISH
+ // For some reason, using UUIDs here fails on SailfishOS
+ socket->connectToService(address, 1);
+#else
+ socket->connectToService(address, SAProtocol::nudgeServiceUuid);
+#endif
#if DESKTOP
// At the same time set up and HFP connection to the watch.
@@ -214,6 +139,13 @@ void SAPBTListener::acceptConnection()
new SAPBTPeer(SAProtocol::ClientRole, socket, this);
}
+void SAPBTListener::handleNudgeConnected()
+{
+ QBluetoothSocket *socket = static_cast<QBluetoothSocket*>(sender());
+ qDebug() << "Nudge connected:" << socket->peerAddress().toString();
+ new SAPBTPeer(SAProtocol::ClientRole, socket, this);
+}
+
void SAPBTListener::handleNudgeError(QBluetoothSocket::SocketError error)
{
QBluetoothSocket *socket = static_cast<QBluetoothSocket*>(sender());
diff --git a/sapbtlistener.h b/sapbtlistener.h
index 3fe821d..398eb1a 100644
--- a/sapbtlistener.h
+++ b/sapbtlistener.h
@@ -2,19 +2,8 @@
#define SAPBTLISTENER_H
#include <QtCore/QObject>
-
-#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
#include <QtBluetooth/QBluetoothServer>
#include <QtBluetooth/QBluetoothServiceInfo>
-#elif QT_VERSION >= QT_VERSION_CHECK(5,0,0)
-#include <QtBluetooth/QRfcommServer>
-#include <QtBluetooth/QBluetoothServiceInfo>
-QT_USE_NAMESPACE_BLUETOOTH
-#else
-#include <QtConnectivity/QRfcommServer>
-#include <QtConnectivity/QBluetoothServiceInfo>
-QTM_USE_NAMESPACE
-#endif
class SAPBTListener : public QObject
{
@@ -35,15 +24,11 @@ private:
private slots:
void acceptConnection();
+ void handleNudgeConnected();
void handleNudgeError(QBluetoothSocket::SocketError error);
-
private:
-#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
QBluetoothServer *_server;
-#else
- QRfcommServer *_server;
-#endif
QBluetoothServiceInfo _service;
};
diff --git a/sapbtpeer.cc b/sapbtpeer.cc
index 9fc56af..e026a4c 100644
--- a/sapbtpeer.cc
+++ b/sapbtpeer.cc
@@ -1,11 +1,11 @@
-#include <QtEndian>
+#include <QtCore/QtEndian>
#include "saprotocol.h"
#include "wmspeer.h"
#include "crc16.h"
#include "sapsocket.h"
#include "sapbtpeer.h"
-#define PROTO_DEBUG 0
+#define PROTO_DEBUG 1
SAPBTPeer::SAPBTPeer(SAProtocol::Role role, QBluetoothSocket *socket, QObject *parent) :
SAPPeer(role, socket->localAddress().toString(), socket->peerAddress().toString(), parent),
diff --git a/sapbtpeer.h b/sapbtpeer.h
index da77f22..66f8cbb 100644
--- a/sapbtpeer.h
+++ b/sapbtpeer.h
@@ -2,16 +2,7 @@
#define SAPBTPEER_H
#include <QtCore/QObject>
-
-#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
-#include <QtBluetooth/QBluetoothSocket>
-#elif QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtBluetooth/QBluetoothSocket>
-QT_USE_NAMESPACE_BLUETOOTH
-#else
-#include <QtConnectivity/QBluetoothSocket>
-QTM_USE_NAMESPACE
-#endif
#include "sappeer.h"
diff --git a/sapd.pro b/sapd.pro
index 051c2c7..d29aca3 100644
--- a/sapd.pro
+++ b/sapd.pro
@@ -1,33 +1,24 @@
TARGET = sapd
TEMPLATE = app
-QT += core gui dbus
-CONFIG += console
+QT += core gui dbus bluetooth
+CONFIG += console c++11
CONFIG += link_pkgconfig
PKGCONFIG += openssl
exists(/usr/lib/libsailfishapp.so) {
- # Building for Jolla Sailfish, Qt5, Bluez4
- QT += bluetooth
+ # Building for Jolla Sailfish, Qt5, Bluez4(?)
DEFINES += SAILFISH
- PKGCONFIG += dbus-1
- CONFIG += c++11
- SOURCES += libwatchfish/notificationmonitor.cpp libwatchfish/notification.cpp
- HEADERS += libwatchfish/notificationmonitor.h libwatchfish/notification.h
-} else:greaterThan(QT_MAJOR_VERSION, 4) {
+ PKGCONFIG += dbus-1 timed-qt5
+ SOURCES += libwatchfish/notificationmonitor.cpp libwatchfish/notification.cpp \
+ libwatchfish/walltimemonitor.cpp
+ HEADERS += libwatchfish/notificationmonitor.h libwatchfish/notificationmonitor_p.h libwatchfish/notification.h \
+ libwatchfish/walltimemonitor.h libwatchfish/walltimemonitor_p.h
+} else {
# Building for desktop, Qt5, Bluez5
- QT += bluetooth
DEFINES += DESKTOP
SOURCES += hfpag.cc
HEADERS += hfpag.h
-} else {
- # Building for desktop, Qt4, Bluez5
- CONFIG += mobility
- MOBILITY += connectivity
- DEFINES += DESKTOP MANUAL_SDP
- SOURCES += hfpag.cc
- HEADERS += hfpag.h
- PKGCONFIG += bluez
}
target.path = /usr/bin
@@ -56,7 +47,6 @@ SOURCES += main.cc \
sapsocket.cc \
sappeer.cc \
capabilityagent.cc \
- qtjson/json.cc \
sapmanager.cc \
sapserviceinfo.cc \
sapchannelinfo.cc \
@@ -66,7 +56,9 @@ SOURCES += main.cc \
hostmanageragent.cc \
hostmanagerconn.cc \
notificationagent.cc \
- notificationconn.cc
+ notificationconn.cc \
+ webproxyagent.cc \
+ webproxyconn.cc
HEADERS += \
sapbtlistener.h \
@@ -80,7 +72,6 @@ HEADERS += \
sapagent.h \
sappeer.h \
capabilityagent.h \
- qtjson/json.h \
sapmanager.h \
sapserviceinfo.h \
sapchannelinfo.h \
@@ -91,7 +82,9 @@ HEADERS += \
hostmanagerconn.h \
notificationagent.h \
notificationconn.h \
- endianhelpers.h
+ endianhelpers.h \
+ webproxyagent.h \
+ webproxyconn.h
OTHER_FILES += \
rpm/sapd.yaml \
diff --git a/sappeer.cc b/sappeer.cc
index af843e4..60e7660 100644
--- a/sappeer.cc
+++ b/sappeer.cc
@@ -132,7 +132,7 @@ void SAPPeer::acceptServiceConnection(SAPConnectionRequest *connReq, int statusC
resp.sessions.push_back(socket->sessionId());
}
- qDebug() << "acceptServiceConection" << statusCode;
+ qDebug() << "Accepting service conection with status" << statusCode;
writeToSession(SAProtocol::defaultSessionId,
SAProtocol::packServiceConnectionResponseFrame(resp));
@@ -227,7 +227,7 @@ void SAPPeer::handleDefaultSessionMessage(const QByteArray &message)
foreach (const SAProtocol::ServiceConnectionRequestSession &s, req.sessions) {
if (_sessions.contains(s.sessionId)) {
- qWarning() << "Requested session is already in use";
+ qWarning() << "Requested session" << s.sessionId << "is already active";
ok = false;
}
}
@@ -256,73 +256,14 @@ void SAPPeer::handleDefaultSessionMessage(const QByteArray &message)
// TODO set socket QoS parameters
conn->setSocket(s.channelId, socket);
+ qDebug() << " opening channel" << s.sessionId << s.channelId << "payload=" << s.payloadType;
+
_sessions.insert(s.sessionId, socket);
}
SAPConnectionRequest *connReq = new SAPConnectionRequest(conn, req.initiatorId, req.acceptorId);
agent->requestConnection(connReq);
-#if 0
- resp.messageType = SAProtocol::ServiceConnectionResponse;
- resp.acceptorId = req.acceptorId;
- resp.initiatorId = req.initiatorId;
- resp.profile = req.profile;
- resp.statusCode = 0;
-
- QList<SAPSocket*> created_sockets;
-
- SAPAgent *agent = _profiles.value(req.profile, 0);
- if (agent) {
- foreach (const SAProtocol::ServiceConnectionRequestSession &s, req.sessions) {
- if (_openSessions.contains(s.sessionId)) {
- // Session ID already used.
- resp.statusCode = 1;
- break;
- }
-
- SAPSocket *socket = new SAPSocket(this, s.sessionId, this);
-
- qDebug() << "Requesting connection to" << req.profile << s.channelId;
-
- if (!agent->acceptConnection(req.profile, s.channelId, socket)) {
- resp.statusCode = 2;
- break;
- }
-
- // Save for later. We can't emit the connected signal right now
- // because data might be written to the socket even before
- // we send the response.
- created_sockets.append(socket);
-
- resp.sessions.append(s.sessionId);
- }
-
- if (resp.statusCode != 0) {
- resp.sessions.clear(); // TODO Is this correct? Who knows!
- }
- }
-
- qDebug() << "Service connection request statusCode=" << resp.statusCode;
-
- writeToSession(SAProtocol::defaultSessionId,
- SAProtocol::packServiceConnectionResponseFrame(resp));
-
- if (resp.statusCode == 0) {
- foreach (SAPSocket *socket, created_sockets) {
- const int session = socket->sessionId();
- _openSessions.insert(session);
- qDebug() << "Session" << session << "now live";
-
- emit socket->connected();
- }
- } else {
- foreach (SAPSocket *socket, created_sockets) {
- emit socket->disconnected();
- socket->deleteLater();
- }
- }
-#endif
-
break;
}
case SAProtocol::ServiceConnectionResponse: {
diff --git a/saprotocol.h b/saprotocol.h
index 3f38e05..a9f5ac0 100644
--- a/saprotocol.h
+++ b/saprotocol.h
@@ -2,16 +2,7 @@
#define SAPROTOCOL_H
#include <QtCore/QObject>
-
-#if QT_VERSION >= QT_VERSION_CHECK(5,2,0)
-#include <QtBluetooth/QBluetoothUuid>
-#elif QT_VERSION >= QT_VERSION_CHECK(5,0,0)
#include <QtBluetooth/QBluetoothUuid>
-QT_USE_NAMESPACE_BLUETOOTH
-#else
-#include <QtConnectivity/QBluetoothUuid>
-QTM_USE_NAMESPACE
-#endif
class SAProtocol
{
diff --git a/webproxyagent.cc b/webproxyagent.cc
new file mode 100644
index 0000000..186912f
--- /dev/null
+++ b/webproxyagent.cc
@@ -0,0 +1,57 @@
+#include "sapsocket.h"
+#include "sapconnectionrequest.h"
+#include "sapserviceinfo.h"
+#include "sapchannelinfo.h"
+#include "webproxyconn.h"
+#include "webproxyagent.h"
+
+static WebProxyAgent *agent = 0;
+static const QLatin1String webproxy_profile("/system/webproxy");
+
+WebProxyAgent::WebProxyAgent(QObject *parent)
+ : QObject(parent), _peer(0), _socket(0)
+{
+}
+
+WebProxyAgent* WebProxyAgent::instance()
+{
+ if (!agent) {
+ agent = new WebProxyAgent;
+ }
+ return agent;
+}
+
+void WebProxyAgent::peerFound(SAPPeer *peer)
+{
+ qDebug() << "WebProxy peer found" << peer->peerName();
+}
+
+void WebProxyAgent::requestConnection(SAPConnectionRequest *request)
+{
+ qDebug() << "WebProxy request connection from" << request->peer()->peerName();
+ SAPConnection *conn = request->connection();
+ new WebProxyConn(conn, this);
+
+ request->accept();
+}
+
+void WebProxyAgent::registerServices(SAPManager *manager)
+{
+ SAPServiceInfo service;
+ SAPChannelInfo channel;
+
+ service.setProfile(webproxy_profile);
+ service.setFriendlyName("WebProxy");
+ service.setRole(SAPServiceInfo::RoleProvider);
+ service.setVersion(2, 0);
+ service.setConnectionTimeout(0);
+
+ channel.setChannelId(502);
+ channel.setPayloadType(SAPChannelInfo::PayloadBinary);
+ channel.setQoSType(SAPChannelInfo::QoSRestricted);
+ channel.setQoSDataRate(SAPChannelInfo::QoSDataRateLow);
+ channel.setQoSPriority(SAPChannelInfo::QoSPriorityHigh);
+ service.addChannel(channel);
+
+ manager->registerServiceAgent(service, instance());
+}
diff --git a/webproxyagent.h b/webproxyagent.h
new file mode 100644
index 0000000..e3e7329
--- /dev/null
+++ b/webproxyagent.h
@@ -0,0 +1,27 @@
+#ifndef WEBPROXYAGENT_H
+#define WEBPROXYAGENT_H
+
+#include <QtCore/QObject>
+#include "sappeer.h"
+#include "sapmanager.h"
+#include "sapagent.h"
+
+class WebProxyAgent : public QObject, public SAPAgent
+{
+ Q_OBJECT
+
+ explicit WebProxyAgent(QObject *parent = 0);
+
+public:
+ static WebProxyAgent * instance();
+ static void registerServices(SAPManager *manager);
+
+ void peerFound(SAPPeer *peer);
+ void requestConnection(SAPConnectionRequest *request);
+
+private:
+ SAPPeer *_peer;
+ SAPSocket *_socket;
+};
+
+#endif // WEBPROXYAGENT_H
diff --git a/webproxyconn.cc b/webproxyconn.cc
new file mode 100644
index 0000000..a679803
--- /dev/null
+++ b/webproxyconn.cc
@@ -0,0 +1,25 @@
+#include <QtCore/QDebug>
+
+#include "sappeer.h"
+#include "webproxyconn.h"
+
+WebProxyConn::WebProxyConn(SAPConnection *conn, QObject *parent)
+ : QObject(parent), _conn(conn), _socket(conn->sockets().first())
+{
+ connect(_conn, SIGNAL(disconnected()), SLOT(deleteLater()));
+ Q_ASSERT(_socket);
+ connect(_socket, SIGNAL(connected()), SLOT(handleConnected()));
+ connect(_socket, SIGNAL(messageReceived()), SLOT(handleMessageReceived()));
+}
+
+void WebProxyConn::handleConnected()
+{
+ qDebug() << "WebProxy socket now connected!";
+}
+
+void WebProxyConn::handleMessageReceived()
+{
+ QByteArray data = _socket->receive();
+
+ qDebug() << data << data.toHex();
+}
diff --git a/webproxyconn.h b/webproxyconn.h
new file mode 100644
index 0000000..3a05ad3
--- /dev/null
+++ b/webproxyconn.h
@@ -0,0 +1,26 @@
+#ifndef WEBPROXYCONN_H
+#define WEBPROXYCONN_H
+
+#include <QtCore/QObject>
+#include "sapconnection.h"
+#include "sapsocket.h"
+
+class WebProxyConn : public QObject
+{
+ Q_OBJECT
+
+public:
+ WebProxyConn(SAPConnection *conn, QObject *parent = 0);
+
+private:
+
+private slots:
+ void handleConnected();
+ void handleMessageReceived();
+
+private:
+ SAPConnection *_conn;
+ SAPSocket *_socket;
+};
+
+#endif // WEBPROXYCONN_H