diff options
| author | Jouni Roivas <jroivas@iki.fi> | 2014-01-13 21:59:34 +0200 |
|---|---|---|
| committer | Jouni Roivas <jroivas@iki.fi> | 2014-01-13 21:59:34 +0200 |
| commit | 7e4e1e0192da304ae4efecdf8724a7c3f2c2d5ee (patch) | |
| tree | bfb0eec985e83b76ed1c9b1a8949a9f36e226f6f | |
| parent | 6e0fd5a7c7a4749fb342bfd8b3671485bcba3159 (diff) | |
Initial import
| -rw-r--r-- | qml/cover/CoverPage.qml | 47 | ||||
| -rw-r--r-- | qml/pages/WatchPage.qml | 222 | ||||
| -rw-r--r-- | qml/waterwatch.qml | 42 | ||||
| -rw-r--r-- | rpm/waterwatch.yaml | 31 | ||||
| -rw-r--r-- | src/watchconnector.cpp | 283 | ||||
| -rw-r--r-- | src/watchconnector.h | 125 | ||||
| -rw-r--r-- | src/waterwatch.cpp | 44 | ||||
| -rw-r--r-- | waterwatch.desktop | 7 | ||||
| -rw-r--r-- | waterwatch.png | bin | 0 -> 2965 bytes | |||
| -rw-r--r-- | waterwatch.pro | 20 |
10 files changed, 821 insertions, 0 deletions
diff --git a/qml/cover/CoverPage.qml b/qml/cover/CoverPage.qml new file mode 100644 index 0000000..b717b49 --- /dev/null +++ b/qml/cover/CoverPage.qml @@ -0,0 +1,47 @@ +/* + Copyright (C) 2013 Jouni Roivas + Copyright (C) 2013 Jolla Ltd. + Contact: Thomas Perl <thomas.perl@jollamobile.com> + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import QtQuick 2.0 +import Sailfish.Silica 1.0 + +CoverBackground { + Label { + id: label + anchors.centerIn: parent + text: "WaterWatch" + } + Label { + anchors.top: label.bottom + anchors.horizontalCenter: parent.horizontalCenter + text: watchConnector.name + font.pointSize: Theme.fontSizeSmall + } +} diff --git a/qml/pages/WatchPage.qml b/qml/pages/WatchPage.qml new file mode 100644 index 0000000..743e130 --- /dev/null +++ b/qml/pages/WatchPage.qml @@ -0,0 +1,222 @@ +/* + Copyright (C) 2013 Jouni Roivas + Copyright (C) 2013 Jolla Ltd. + Contact: Thomas Perl <thomas.perl@jollamobile.com> + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import QtQuick 2.0 +import QtQml 2.1 +import Sailfish.Silica 1.0 +import QtBluetooth 5.0 +import Sailfish.Bluetooth 1.0 +import Bluetooth 0.0 +import org.nemomobile.voicecall 1.0 +import org.nemomobile.notifications 1.0 +import watch 0.1 + +Page { + id: page + WatchConnector { + id: watchConnector + + onHangup: { + // Watch instantiated hangup, follow the orders + manager.hangupAll(); + } + } + property var callerDetails: new Object + + VoiceCallManager { + id:manager + + function hangupAll() { + for (var index = 0; index < voiceCalls.count; index++) { + voiceCalls.instance(index).hangup(); + } + } + + onError: { + console.log("Error: "+message) + watchConnector.endPhoneCall(); + } + + function updateState() { + //This needs cleaning up... + var statusPriority = [ + VoiceCall.STATUS_ALERTING, + VoiceCall.STATUS_DIALING, + VoiceCall.STATUS_DISCONNECTED, + VoiceCall.STATUS_ACTIVE, + VoiceCall.STATUS_HELD, + VoiceCall.STATUS_NULL + ] + + var newPrimaryCall = null + for (var p = 0; p < statusPriority.length; p++) { + for (var i = 0; i < voiceCalls.count; i++) { + if (voiceCalls.instance(i).status === statusPriority[p]) { + newPrimaryCall = voiceCalls.instance(i) + break + } + } + if (newPrimaryCall) { + break + } + } + var person = ""; + if (newPrimaryCall && callerDetails[newPrimaryCall.handlerId]) { + person = callerDetails[newPrimaryCall.handlerId].person + } + + for (var ic = 0; ic < voiceCalls.count; ic++) { + var call = voiceCalls.instance(ic) + console.log("call: " + call.lineId + " state: " + call.statusText + " " + call.status + " " + call.handlerId + "\n") + if (call.status === VoiceCall.STATUS_ALERTING || call.status === VoiceCall.STATUS_DIALING) { + console.log("Tell outgoing: " + call.lineId); + //FIXME: Not working? + watchConnector.ring(call.lineId, person, 0); + } else if (call.status === VoiceCall.STATUS_INCOMING || call.status === VoiceCall.STATUS_WAITING) { + console.log("Tell incoming: " + call.lineId); + watchConnector.ring(call.lineId, person); + } else if (call.status === VoiceCall.STATUS_DISCONNECTED || call.status === VoiceCall.STATUS_NULL) { + console.log("Endphone"); + watchConnector.endPhoneCall(); + } else if (call.status === VoiceCall.ACTIVE) { + console.log("Startphone"); + watchConnector.startPhoneCall(); + } + } + } + } + Timer { + id: updateStateTimer + interval: 50 + onTriggered: manager.updateState() + } + + Instantiator { + id: callMonitor + model: manager.voiceCalls + + delegate: QtObject { + property string callStatus: instance.status + property string remoteUid + property string person: "" + onCallStatusChanged: { + console.log("Status changed: " + callStatus); + if (callStatus === VoiceCall.STATUS_DISCONNECTED || callStatus === VoiceCall.STATUS_NULL) { + watchConnector.endPhoneCall(); + manager.updateState(); + } else { + updateStateTimer.start(); + } + } + Component.onCompleted: { + remoteUid = instance.lineId + person = remoteUid !== "" ? people.personByPhoneNumber(remoteUid) : "" + manager.updateState() + } + } + onObjectAdded: { + callerDetails[object.handlerId] = object + } + onObjectRemoved: { + delete callerDetails[object.handlerId] + manager.updateState() + } + } + + + SilicaFlickable { + anchors.fill: parent + + contentHeight: column.height + + Column { + id: column + + width: page.width + spacing: Theme.paddingLarge + PageHeader { + title: "WaterWatch" + } + Label { + visible: !watchConnector.isConnected + text: "Waiting for watch...\nIf it can't be found plase\ncheck it's available and\npaired in Bluetooth settings." + width: column.width + } + Repeater { + model: KnownDevicesModel { id: knownDevicesModel } + delegate: ListItem { + id: pairedItem + visible: (model.paired && watchConnector.isConnected) + Label { + text: model.alias.length ? model.alias : model.address + } + onVisibleChanged: { + if (pairedItem.visible) { + watchConnector.deviceConnect(model.alias, model.address); + } + } + } + } + Button { + text: "Ping" + onClicked: { + watchConnector.ping(66) + } + } + Button { + text: "Send SMS" + onClicked: { + watchConnector.sendSMSNotification("Dummy", "Hello world!") + } + } + Button { + text: "Ring" + onClicked: { + watchConnector.ring("+1234567890", "Test user") + } + } + Button { + text: "Start call" + onClicked: { + watchConnector.startPhoneCall() + } + } + Button { + text: "End call" + onClicked: { + watchConnector.endPhoneCall() + } + } + } + } +} + + diff --git a/qml/waterwatch.qml b/qml/waterwatch.qml new file mode 100644 index 0000000..b41c7f5 --- /dev/null +++ b/qml/waterwatch.qml @@ -0,0 +1,42 @@ +/* + Copyright (C) 2013 Jouni Roivas + Copyright (C) 2013 Jolla Ltd. + Contact: Thomas Perl <thomas.perl@jollamobile.com> + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +import QtQuick 2.0 +import Sailfish.Silica 1.0 +import "pages" + +ApplicationWindow +{ + initialPage: Component { WatchPage { } } + cover: Qt.resolvedUrl("cover/CoverPage.qml") +} + + diff --git a/rpm/waterwatch.yaml b/rpm/waterwatch.yaml new file mode 100644 index 0000000..e2f0359 --- /dev/null +++ b/rpm/waterwatch.yaml @@ -0,0 +1,31 @@ +Name: waterwatch +Summary: Support for Pebble watch in SailfishOS +Version: 0.1 +Release: 1 +Group: Qt/Qt +URL: http://example.org/ +License: BSD +Sources: +- '%{name}-%{version}.tar.bz2' +Description: | + Include support for Pebble watch to receive event from SailfishOS device. Communicates via Bluetooth, supporting the Pebble protocol. +Configure: none +Builder: qtc5 +PkgConfigBR: +- Qt5Bluetooth +- Qt5Quick +- Qt5Qml +- Qt5Core +- sailfishapp >= 0.0.10 +Requires: +- sailfishsilica-qt5 >= 0.10.9 +Files: +- '%{_bindir}' +- '%{_datadir}/%{name}/qml' +- '%{_datadir}/applications/%{name}.desktop' +- '%{_datadir}/icons/hicolor/86x86/apps/%{name}.png' +- /usr/bin +- /usr/share/waterwatch +- /usr/share/applications +- /usr/share/icons/hicolor/86x86/apps +PkgBR: [] diff --git a/src/watchconnector.cpp b/src/watchconnector.cpp new file mode 100644 index 0000000..55e4b80 --- /dev/null +++ b/src/watchconnector.cpp @@ -0,0 +1,283 @@ +#include "watchconnector.h" +#include <QDateTime> + +WatchConnector::WatchConnector(QObject *parent) : + QObject(parent) +{ + socket = nullptr; +} + +WatchConnector::~WatchConnector() +{ +} + +void WatchConnector::deviceDiscovered(const QBluetoothDeviceInfo &device) +{ + //FIXME: Configurable + if (device.name().startsWith("Pebble")) { + qDebug() << "Found Pebble:" << device.name() << '(' << device.address().toString() << ')'; + handleWatch(device); + } else { + qDebug() << "Found other device:" << device.name() << '(' << device.address().toString() << ')'; + } +} + +void WatchConnector::deviceConnect(const QString name, const QString address) +{ + if (name.startsWith("Pebble")) { + QBluetoothDeviceInfo device(QBluetoothAddress(address), name, 0); + deviceDiscovered(device); + } +} + +void WatchConnector::handleWatch(const QBluetoothDeviceInfo &device) +{ + qDebug() << "handleWatch" << device.name(); + if (socket != nullptr) { + socket->close(); + socket->deleteLater(); + socket = nullptr; + } + + socket = new QBluetoothSocket(QBluetoothSocket::RfcommSocket); + qDebug() << "Creating socket"; + + // FIXME: Assuming port 1 (with Pebble) + socket->connectToService(device.address(), 1); + + connect(socket, SIGNAL(readyRead()), this, SLOT(readSocket())); + connect(socket, SIGNAL(connected()), this, SLOT(connected())); + connect(socket, SIGNAL(disconnected()), this, SLOT(disconnected())); +} + +QString WatchConnector::decodeEndpoint(unsigned int val) +{ + //FIXME: Create a map of these values + switch(val) { + case watchTIME: + return "TIME"; + case watchVERSION: + return "VERSION"; + case watchPHONE_VERSION: + return "PHONE_VERSION"; + case watchSYSTEM_MESSAGE: + return "SYSTEM_MESSAGE"; + case watchMUSIC_CONTROL: + return "MUSIC_CONTROL"; + case watchPHONE_CONTROL: + return "PHONE_CONTROL"; + case watchAPPLICATION_MESSAGE: + return "APP_MSG"; + case watchLAUNCHER: + return "LAUNCHER"; + case watchLOGS: + return "LOGS"; + case watchPING: + return "PING"; + case watchLOG_DUMP: + return "DUMP"; + case watchRESET: + return "RESET"; + case watchAPP: + return "APP"; + case watchAPP_LOGS: + return "APP_LOGS"; + case watchNOTIFICATION: + return "NOTIFICATION"; + case watchRESOURCE: + return "RESOURCE"; + case watchAPP_MANAGER: + return "APP_MANAG"; + case watchSCREENSHOT: + return "SCREENSHOT"; + case watchPUTBYTES: + return "PUTBYTES"; + default: + return "Unknown: "+ QString::number(val); + } +} + +void WatchConnector::decodeMsg(QByteArray data) +{ + unsigned int datalen = 0; + int index = 0; + datalen = (data.at(index) << 8) + data.at(index+1); + index += 2; + + unsigned int endpoint = 0; + endpoint = (data.at(index) << 8) + data.at(index+1); + index += 2; + + qDebug() << "Length:" << datalen << " Endpoint:" << decodeEndpoint(endpoint); + qDebug() << "Data:" << data.mid(index).toHex(); + if (endpoint == watchPHONE_CONTROL) { + if (data.length() >= 5) { + if (data.at(4) == callHANGUP) { + emit hangup(); + } + } + } +} + +void WatchConnector::readSocket() +{ + qDebug() << "read"; + + QBluetoothSocket *socket = qobject_cast<QBluetoothSocket *>(sender()); + if (!socket) return; + + while (socket->bytesAvailable()) { + QByteArray line = socket->readAll(); + emit messageReceived(socket->peerName(), QString::fromUtf8(line.constData(), line.length())); + decodeMsg(line); + } +} + +void WatchConnector::connected() +{ + qDebug() << "Connected!"; + is_connected = true; + emit nameChanged(); + emit connectedChanged(); +} + +void WatchConnector::disconnected() +{ + qDebug() << "Disconnected!"; + is_connected = false; + + QBluetoothSocket *socket = qobject_cast<QBluetoothSocket *>(sender()); + if (!socket) return; + + socket->deleteLater(); + socket = nullptr; + emit connectedChanged(); +} + +void WatchConnector::sendData(const QByteArray &data) +{ + if (socket == nullptr) return; + + socket->write(data); +} + +void WatchConnector::sendMessage(unsigned int endpoint, QByteArray data) +{ + qDebug() << "Sending message"; + QByteArray msg; + + // First send the length + msg.append((data.length() & 0xFF00) >> 8); + msg.append(data.length() & 0xFF); + + // Then the endpoint + msg.append((endpoint & 0xFF00) >> 8); + msg.append(endpoint & 0xFF); + + // Finally the data + msg.append(data); + + sendData(msg); +} + +void WatchConnector::buildData(QByteArray &res, QStringList data) +{ + for (QString d : data) + { + QByteArray tmp = d.left(0xF0).toUtf8(); + res.append(tmp.length() & 0xFF); + res.append(tmp); + } +} + +QByteArray WatchConnector::buildMessageData(unsigned int lead, QStringList data) +{ + QByteArray res; + res.append(lead & 0xFF); + buildData(res, data); + + return res; +} + +void WatchConnector::ping(unsigned int val) +{ + QByteArray res; + res.append((char)0); + + res.append((char)((val >> 24) & 0xff)); + res.append((char)((val >> 16) & 0xff)); + res.append((char)((val >> 8) & 0xff)); + res.append((char)(val & 0xff)); + + sendMessage(watchPING, res); +} + +QString WatchConnector::timeStamp() +{ + return QString::number(QDateTime::currentMSecsSinceEpoch()); +} + +void WatchConnector::sendNotification(unsigned int lead, QString sender, QString data, QString subject) +{ + QStringList tmp; + tmp.append(sender); + tmp.append(data); + tmp.append(timeStamp()); + if (lead == 0) tmp.append(subject); + + QByteArray res = buildMessageData(lead, tmp); + + sendMessage(watchNOTIFICATION, res); +} + +void WatchConnector::sendSMSNotification(QString sender, QString data) +{ + sendNotification(1, sender, data, ""); +} + +void WatchConnector::sendEmailNotification(QString sender, QString data, QString subject) +{ + sendNotification(0, sender, data, subject); +} + +void WatchConnector::phoneControl(char act, unsigned int cookie, QStringList datas) +{ + QByteArray head; + head.append((char)act); + head.append((cookie >> 24)& 0xFF); + head.append((cookie >> 16)& 0xFF); + head.append((cookie >> 8)& 0xFF); + head.append(cookie & 0xFF); + if (datas.length()>0) buildData(head, datas); + + sendMessage(watchPHONE_CONTROL, head); +} + +void WatchConnector::ring(QString number, QString name, bool incoming, unsigned int cookie) +{ + QStringList tmp; + tmp.append(number); + tmp.append(name); + + char act = callINCOMING; + if (!incoming) { + act = callOUTGOING; + } + + phoneControl(act, cookie, tmp); +} + +void WatchConnector::startPhoneCall(unsigned int cookie) +{ + phoneControl(callSTART, cookie, QStringList()); +} + +void WatchConnector::endPhoneCall(unsigned int cookie) +{ + phoneControl(callEND, cookie, QStringList()); +} + +void registerWatchConnector() +{ + qmlRegisterType<WatchConnector>("watch", 0, 1, "WatchConnector"); +} diff --git a/src/watchconnector.h b/src/watchconnector.h new file mode 100644 index 0000000..59ea632 --- /dev/null +++ b/src/watchconnector.h @@ -0,0 +1,125 @@ +/* + Copyright (C) 2013 Jouni Roivas + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#ifndef WATCHCONNECTOR_H +#define WATCHCONNECTOR_H + +#include <QObject> +#include <QtQml> +#include <QStringList> +#include <QBluetoothDeviceInfo> +#include <QBluetoothSocket> +#include <QBluetoothServiceInfo> + +using namespace QtBluetooth; + +class WatchConnector : public QObject +{ + Q_OBJECT + Q_PROPERTY(QString name READ name NOTIFY nameChanged) + Q_PROPERTY(QString isConnected READ isConnected NOTIFY connectedChanged) +public: + enum { + watchTIME = 11, + watchVERSION = 16, + watchPHONE_VERSION = 17, + watchSYSTEM_MESSAGE = 18, + watchMUSIC_CONTROL = 32, + watchPHONE_CONTROL = 33, + watchAPPLICATION_MESSAGE = 48, + watchLAUNCHER = 49, + watchLOGS = 2000, + watchPING = 2001, + watchLOG_DUMP = 2002, + watchRESET = 2003, + watchAPP = 2004, + watchAPP_LOGS = 2006, + watchNOTIFICATION = 3000, + watchRESOURCE = 4000, + watchAPP_MANAGER = 6000, + watchSCREENSHOT = 8000, + watchPUTBYTES = 48879 + }; + enum { + callANSWER = 1, + callHANGUP = 2, + callGET_STATE = 3, + callINCOMING = 4, + callOUTGOING = 5, + callMISSED = 6, + callRING = 7, + callSTART = 8, + callEND = 9 + }; + explicit WatchConnector(QObject *parent = 0); + virtual ~WatchConnector(); + bool isConnected() const { return is_connected; } + QString name() const { if (socket != nullptr) return socket->peerName(); return "";} + + QString timeStamp(); + QString decodeEndpoint(unsigned int val); + +signals: + void messageReceived(QString peer, QString msg); + void nameChanged(); + void connectedChanged(); + void hangup(); + +public slots: + void sendData(const QByteArray &data); + void sendMessage(unsigned int endpoint, QByteArray data); + void ping(unsigned int val); + void sendNotification(unsigned int lead, QString sender, QString data, QString subject); + void sendSMSNotification(QString sender, QString data); + void sendEmailNotification(QString sender, QString data, QString subject); + + void buildData(QByteArray &res, QStringList data); + QByteArray buildMessageData(unsigned int lead, QStringList data); + + void phoneControl(char act, unsigned int cookie, QStringList datas); + void ring(QString number, QString name, bool incoming=true, unsigned int cookie=0); + void startPhoneCall(unsigned int cookie=0); + void endPhoneCall(unsigned int cookie=0); + + void deviceConnect(const QString name, const QString address); + void deviceDiscovered(const QBluetoothDeviceInfo&); + void handleWatch(const QBluetoothDeviceInfo&); + void readSocket(); + void connected(); + void disconnected(); + +private: + void decodeMsg(QByteArray data); + QBluetoothSocket *socket; + bool is_connected; +}; + +void registerWatchConnector(); + +#endif // WATCHCONNECTOR_H diff --git a/src/waterwatch.cpp b/src/waterwatch.cpp new file mode 100644 index 0000000..2f65cc0 --- /dev/null +++ b/src/waterwatch.cpp @@ -0,0 +1,44 @@ +/* + Copyright (C) 2013 Jouni Roivas + Copyright (C) 2013 Jolla Ltd. + Contact: Thomas Perl <thomas.perl@jollamobile.com> + All rights reserved. + + You may use this file under the terms of BSD license as follows: + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of the Jolla Ltd nor the + names of its contributors may be used to endorse or promote products + derived from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR + ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ + +#include <QtQuick> + +#include <sailfishapp.h> +#include "watchconnector.h" + +int main(int argc, char *argv[]) +{ + // Registert WatchController object on QML side + registerWatchConnector(); + + return SailfishApp::main(argc, argv); +} + diff --git a/waterwatch.desktop b/waterwatch.desktop new file mode 100644 index 0000000..4ddba76 --- /dev/null +++ b/waterwatch.desktop @@ -0,0 +1,7 @@ +[Desktop Entry] +Type=Application +X-Nemo-Application-Type=silica-qt5 +Name=waterwatch +Icon=waterwatch +Exec=waterwatch + diff --git a/waterwatch.png b/waterwatch.png Binary files differnew file mode 100644 index 0000000..4c883a0 --- /dev/null +++ b/waterwatch.png diff --git a/waterwatch.pro b/waterwatch.pro new file mode 100644 index 0000000..65a9018 --- /dev/null +++ b/waterwatch.pro @@ -0,0 +1,20 @@ +TARGET = waterwatch + +CONFIG += sailfishapp + +SOURCES += src/waterwatch.cpp \ + src/watchconnector.cpp + +QT += bluetooth +QMAKE_CXXFLAGS += -std=c++0x + +OTHER_FILES += qml/waterwatch.qml \ + qml/cover/CoverPage.qml \ + rpm/waterwatch.spec \ + rpm/waterwatch.yaml \ + waterwatch.desktop \ + qml/pages/WatchPage.qml + +HEADERS += \ + src/watchconnector.h + |
