[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish.spec
|
|
[-]
[+]
|
Changed |
_service
^
|
@@ -2,7 +2,7 @@
<service name="tar_git">
<param name="url">https://github.com/piggz/harbour-amazfish.git</param>
<param name="branch">master</param>
- <param name="revision">2.0.8</param>
+ <param name="revision">2.1.0</param>
<param name="debian">N</param>
<param name="dumb">N</param>
</service>
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/daemon.pro
^
|
@@ -14,7 +14,7 @@
LIBS += -Lqble/qble -L$$OUT_PWD/../lib -lamazfish -lz
PKGCONFIG += dbus-1
-QT += positioning KDb3 network dbus
+QT += positioning KDb3 network dbus KArchive
CONFIG += c++14
equals(FLAVOR, "silica") {
@@ -46,7 +46,7 @@
calendar
}
-INCLUDEPATH += /usr/include/mkcal-qt5 /usr/include/KF5/KCalendarCore
+INCLUDEPATH += /usr/include/mkcal-qt5 /usr/include/KF5/KCalendarCore /usr/include/KF5/KArchive
INCLUDEPATH += $$PWD/src/services/ \
$$PWD/src/operations/ \
@@ -111,11 +111,14 @@
src/devices/gtsdevice.cpp \
src/devices/gtsfirmwareinfo.cpp \
src/devices/pinetimejfdevice.cpp \
+ src/operations/adafruitblefsoperation.cpp \
+ src/operations/adafruitblefsworker.cpp \
src/operations/dfuoperation.cpp \
src/operations/dfuworker.cpp \
src/operations/updatefirmwareoperationnew.cpp \
src/operations/huamiupdatefirmwareoperation2020.cpp \
src/qaesencryption.cpp \
+ src/services/adafruitblefsservice.cpp \
src/services/currenttimeservice.cpp \
src/services/dfuservice.cpp \
src/services/infinitimemotionservice.cpp \
@@ -178,11 +181,14 @@
src/devices/gtsdevice.h \
src/devices/gtsfirmwareinfo.h \
src/devices/pinetimejfdevice.h \
+ src/operations/adafruitblefsoperation.h \
+ src/operations/adafruitblefsworker.h \
src/operations/dfuoperation.h \
src/operations/dfuworker.h \
src/operations/updatefirmwareoperationnew.h \
src/operations/huamiupdatefirmwareoperation2020.h \
src/qaesencryption.h \
+ src/services/adafruitblefsservice.h \
src/services/currenttimeservice.h \
src/services/dfuservice.h \
src/services/infinitimemotionservice.h \
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/devices/gts2device.cpp
^
|
@@ -38,6 +38,13 @@
return new Gts2FirmwareInfo(bytes);
}
+void Gts2Device::incomingCall(const QString &caller)
+{
+ //GTS2 handles call notificaion as a BT headset type device
+ //using a seperate BT connection
+ return;
+}
+
void Gts2Device::initialise()
{
qDebug() << Q_FUNC_INFO;
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/devices/gts2device.h
^
|
@@ -15,7 +15,8 @@
explicit Gts2Device(const QString &pairedName, QObject *parent = nullptr);
QString deviceType() const override;
QStringList supportedDisplayItems() const override;
- virtual AbstractFirmwareInfo *firmwareInfo(const QByteArray &bytes) override;
+ AbstractFirmwareInfo *firmwareInfo(const QByteArray &bytes) override;
+ void incomingCall(const QString &caller) override;
protected:
void initialise() override;
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/devices/infinitimefirmwareinfo.cpp
^
|
@@ -1,5 +1,9 @@
#include "infinitimefirmwareinfo.h"
+#include <KArchive>
+#include <kzip.h>
+#include <KCompressionDevice>
+
InfinitimeFirmwareInfo::InfinitimeFirmwareInfo(const QByteArray &bytes)
{
m_bytes = bytes;
@@ -22,8 +26,25 @@
qDebug() << "Determining firmware type";
m_type = Invalid;
- if (m_bytes.startsWith(UCHARARR_TO_BYTEARRAY(FW_HEADER))) {
- m_type = Firmware;
+ if (m_bytes.startsWith(UCHARARR_TO_BYTEARRAY(ZIP_HEADER))) {
+ QDataStream in(&m_bytes, QIODevice::ReadOnly);
+ KCompressionDevice dev(in.device(), false, KCompressionDevice::CompressionType::None);
+ KZip zip(&dev);
+
+ if(zip.open(QIODevice::ReadOnly))
+ {
+ auto* root = zip.directory();
+ if(root->entry("manifest.json") != nullptr)
+ {
+ qDebug() << "DFU file detected";
+ m_type = Firmware;
+ }
+ else if(root->entry("resources.json") != nullptr)
+ {
+ qDebug() << "Resource file detected";
+ m_type = Res_Compressed;
+ }
+ }
}
}
@@ -33,6 +54,9 @@
case Firmware:
m_version = "FW ()";
break;
+ case Res_Compressed:
+ m_version = "Ressource ()";
+ break;
default:
m_version = "unknown";
}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/devices/infinitimefirmwareinfo.h
^
|
@@ -13,8 +13,8 @@
void determineFirmwareType();
void determineFirmwareVersion();
- const uint8_t FW_HEADER[4]{ // DFU Zip file
- 0x3D, 0xB8, 0xF3, 0x96
+ const uint8_t ZIP_HEADER[4]{ // Zip file
+ 0x50, 0x4b, 0x03, 0x04
};
};
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/devices/pinetimejfdevice.cpp
^
|
@@ -10,9 +10,39 @@
#include "hrmservice.h"
#include "infinitimemotionservice.h"
#include "infinitimeweatherservice.h"
-
+#include "adafruitblefsservice.h"
#include <QtXml/QtXml>
+namespace {
+ size_t GetMtuForCharacteristic(QString path, const char* characteristicUUID)
+ {
+ size_t transferMtu = 20;
+ QDBusInterface adapterIntro("org.bluez", path, "org.freedesktop.DBus.Introspectable", QDBusConnection::systemBus(), 0);
+ QDBusReply<QString> adapterXml = adapterIntro.call("Introspect");
+ QDomDocument adapterDoc;
+ adapterDoc.setContent(adapterXml.value());
+ QDomNodeList adapterNodes = adapterDoc.elementsByTagName("node");
+
+ for (int x = 0; x < adapterNodes.count(); x++)
+ {
+ QDomElement node = adapterNodes.at(x).toElement();
+ QString nodeName = node.attribute("name");
+ if (nodeName.startsWith("char")) {
+ QString nodePath = path + "/" + nodeName;
+ QDBusInterface characteristicInterface("org.bluez", nodePath, "org.bluez.GattCharacteristic1", QDBusConnection::systemBus(), 0);
+ QString currentCharacteristicUUID = characteristicInterface.property("UUID").toString();
+ if(currentCharacteristicUUID == characteristicUUID){
+ QDBusInterface mtuInterface("org.bluez", nodePath, "org.bluez.GattCharacteristic1", QDBusConnection::systemBus(), 0);
+ QString mtu = mtuInterface.property("MTU").toString();
+ transferMtu = mtu.toInt();
+ }
+
+ }
+ }
+ return transferMtu;
+ }
+}
+
PinetimeJFDevice::PinetimeJFDevice(const QString &pairedName, QObject *parent) : AbstractDevice(pairedName, parent)
{
qDebug() << "PinetimeJFDevice:: " << pairedName;
@@ -122,6 +152,9 @@
addService(InfiniTimeMotionService::UUID_SERVICE_MOTION, new InfiniTimeMotionService(path, this));
} else if (uuid == InfiniTimeWeatherService::UUID_SERVICE_WEATHER && !service(InfiniTimeWeatherService::UUID_SERVICE_WEATHER)) {
addService(InfiniTimeWeatherService::UUID_SERVICE_WEATHER, new InfiniTimeWeatherService(path, this));
+ } else if (uuid == AdafruitBleFsService::UUID_SERVICE_FS && !service(AdafruitBleFsService::UUID_SERVICE_FS)) {
+ size_t transferMtu = GetMtuForCharacteristic(path, AdafruitBleFsService::UUID_CHARACTERISTIC_FS_TRANSFER);
+ addService(AdafruitBleFsService::UUID_SERVICE_FS, new AdafruitBleFsService(path, this, transferMtu));
} else if ( !service(uuid)) {
addService(uuid, new QBLEService(uuid, path, this));
}
@@ -176,6 +209,11 @@
//motion->enableNotification(InfiniTimeMotionService::UUID_CHARACTERISTIC_MOTION_MOTION);
connect(motion, &InfiniTimeMotionService::informationChanged, this, &AbstractDevice::informationChanged, Qt::UniqueConnection);
}
+
+ AdafruitBleFsService *bleFs = qobject_cast<AdafruitBleFsService*>(service(AdafruitBleFsService::UUID_SERVICE_FS));
+ if (bleFs) {
+ connect(bleFs, &AdafruitBleFsService::downloadProgress, this, &PinetimeJFDevice::downloadProgress, Qt::UniqueConnection);
+ }
}
void PinetimeJFDevice::onPropertiesChanged(QString interface, QVariantMap map, QStringList list)
@@ -247,18 +285,39 @@
void PinetimeJFDevice::prepareFirmwareDownload(const AbstractFirmwareInfo *info)
{
- DfuService *fw = qobject_cast<DfuService*>(service(DfuService::UUID_SERVICE_DFU));
- if (fw){
- fw->prepareFirmwareDownload(info, new DfuOperation(info, fw));
+ firmwareType = info->type();
+ if(info->type() == AbstractFirmwareInfo::Type::Firmware) {
+ DfuService *fw = qobject_cast<DfuService*>(service(DfuService::UUID_SERVICE_DFU));
+ if (fw){
+ fw->prepareFirmwareDownload(info);
+ }
+ } else if (info->type() == AbstractFirmwareInfo::Type::Res_Compressed) {
+ AdafruitBleFsService* s = qobject_cast<AdafruitBleFsService*>(service(AdafruitBleFsService::UUID_SERVICE_FS));
+ if(s) {
+ s->prepareDownload(new AdafruitBleFsOperation(s, info));
+ }
}
}
void PinetimeJFDevice::startDownload()
{
qDebug() << Q_FUNC_INFO;
- DfuService *fw = qobject_cast<DfuService*>(service(DfuService::UUID_SERVICE_DFU));
- if (fw){
- fw->startDownload();
+
+ if(firmwareType == AbstractFirmwareInfo::Type::Firmware)
+ {
+ DfuService *fw = qobject_cast<DfuService*>(service(DfuService::UUID_SERVICE_DFU));
+ if (fw)
+ {
+ fw->startDownload();
+ }
+ }
+ else if(firmwareType == AbstractFirmwareInfo::Type::Res_Compressed)
+ {
+ AdafruitBleFsService* s = qobject_cast<AdafruitBleFsService*>(service(AdafruitBleFsService::UUID_SERVICE_FS));
+ if(s)
+ {
+ s->updateFiles();
+ }
}
}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/devices/pinetimejfdevice.h
^
|
@@ -42,6 +42,7 @@
void parseServices();
void initialise();
Q_SLOT void serviceEvent(const QString &characteristic, uint8_t event);
+ AbstractFirmwareInfo::Type firmwareType;
};
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/adafruitblefsoperation.cpp
^
|
@@ -0,0 +1,244 @@
+#include "adafruitblefsoperation.h"
+#include "adafruitblefsservice.h"
+#include "adafruitblefsworker.h"
+#include <QMetaType>
+
+AdafruitBleFsOperation::AdafruitBleFsOperation(QBLEService *service, const AbstractFirmwareInfo *info) : AbstractOperation(service), info{info}
+{
+
+}
+
+AdafruitBleFsOperation::~AdafruitBleFsOperation()
+{
+
+}
+
+void AdafruitBleFsOperation::start()
+{
+
+}
+
+bool AdafruitBleFsOperation::handleMetaData(const QByteArray &value)
+{
+ return true;
+}
+
+void AdafruitBleFsOperation::handleData(const QByteArray &data)
+{
+ const uint8_t cmdId = data[0];
+
+ switch(cmdId) {
+ case RESPONSE_LIST_DIR:
+ handleListDirectory(data);
+ break;
+ case RESPONSE_DELETE_FILE:
+ handleDeleteFile(data);
+ break;
+ case RESPONSE_WRITE_FILE:
+ handleWriteFile(data);
+ break;
+ case RESPONSE_CREATE_DIR:
+ handleCreateDirectory(data);
+ break;
+ default:
+ break;
+ }
+}
+
+void AdafruitBleFsOperation::handleListDirectory(const QByteArray &value)
+{
+ uint8_t status = value[1];
+ uint16_t pathSize = value[2] + (value[3] << 8);
+ uint32_t entryNr = value[4] + (value[5] << 8) + (value[6] << 16) + (value[7] << 24);
+ uint32_t entryTotal = value[8] + (value[9] << 8) + (value[10] << 16) + (value[11] << 24);
+ uint32_t flags = value[12] + (value[13] << 8) + (value[14] << 16) + (value[15] << 24);
+ bool isDirectory = (flags & 0x01) == 1;
+ uint64_t timestamp = value[16] + (value[17] << 8) + (value[18] << 16) + (value[19] << 24)
+ + + ((uint64_t)value[20] << 32) + + ((uint64_t)value[21] << 40) + + ((uint64_t)value[22] << 48) + + ((uint64_t)value[23] << 56);
+ uint32_t fileSize = value[24] + (value[25] << 8) + (value[26] << 16) + (value[27] << 24);
+ std::string filename;
+ for(int i = 0; i < pathSize; i++) {
+ filename += (char)value[28+i];
+ }
+ filename[pathSize] = 0;
+
+ if(entryNr == 0)
+ {
+ listDirectoryEntries.clear();
+ }
+
+ if(status == static_cast<uint8_t>(Status::Success))
+ {
+ File f {filename, timestamp, isDirectory};
+ listDirectoryEntries.push_back(f);
+ }
+
+ if(entryNr == entryTotal)
+ {
+ listDirectoryPromise.set_value(listDirectoryEntries);
+ }
+}
+
+void AdafruitBleFsOperation::handleDeleteFile(const QByteArray &value)
+{
+ deleteFilePromise.set_value();
+}
+
+void AdafruitBleFsOperation::handleWriteFile(const QByteArray &value)
+{
+ uint8_t status = value[1];
+ uint32_t offset = (uint32_t)value[4] + ((uint32_t)value[5] << 8) + ((uint32_t)value[6] << 16) + ((uint32_t)value[7] << 24);
+ uint64_t timestamp = value[8] + (value[9] << 8) + (value[10] << 16) + (value[11] << 24) + ((uint64_t)value[12] << 32) + ((uint64_t)value[13] << 40) + ((uint64_t)value[14] << 48) + ((uint64_t)value[15] << 56);
+ uint32_t freeSpace = value[16] + (value[17] << 8) + (value[18] << 16) + (value[19] << 24);
+
+ writeFilePromise.set_value(status == static_cast<uint8_t>(Status::Success));
+}
+
+std::future<std::vector<AdafruitBleFsOperation::File>> AdafruitBleFsOperation::listDirectory(const std::string& path)
+{
+ this->listDirectoryPromise = std::promise<std::vector<File>>();
+
+ QByteArray cmd;
+ cmd += REQUEST_LIST_DIR;
+ cmd += PADDING_BYTE;
+ cmd += (uint8_t)(path.size() & 0xff);
+ cmd += (uint8_t)((path.size() >> 8) & 0xff);
+ for(int i = 0; i < path.size(); i++) {
+ cmd += path[i];
+ }
+ m_service->writeValue(AdafruitBleFsService::UUID_CHARACTERISTIC_FS_TRANSFER, cmd);
+
+ return listDirectoryPromise.get_future();
+}
+
+std::future<void> AdafruitBleFsOperation::eraseFile(const std::string& filename)
+{
+ deleteFilePromise = std::promise<void>();
+
+ QByteArray cmd;
+ cmd += REQUEST_DELETE_FILE;
+ cmd += PADDING_BYTE;
+ cmd += (uint8_t)(filename.size() & 0xff);
+ cmd += (uint8_t)((filename.size() >> 8) & 0xff);
+ for(int i = 0; i < filename.size(); i++) {
+ cmd += filename[i];
+ }
+ m_service->writeValue(AdafruitBleFsService::UUID_CHARACTERISTIC_FS_TRANSFER, cmd);
+
+ return deleteFilePromise.get_future();
+}
+
+
+std::future<bool> AdafruitBleFsOperation::writeFileStart(const std::string& filePath, size_t fileSize, size_t offset)
+{
+ writeFilePromise = std::promise<bool>();
+
+ QByteArray cmd;
+ cmd += REQUEST_WRITE_FILE_START;
+ cmd += PADDING_BYTE;
+ cmd += (uint8_t)(filePath.size() & 0xff);
+ cmd += (uint8_t)((filePath.size() >> 8) & 0xff);
+ cmd += offset & 0xff;
+ cmd += (offset >> 8) & 0xff;
+ cmd += (offset >> 16) & 0xff;
+ cmd += (offset >> 24) & 0xff;
+ cmd += (uint8_t)0; // timestamp
+ cmd += (uint8_t)0;
+ cmd += (uint8_t)0;
+ cmd += (uint8_t)0;
+ cmd += (uint8_t)0;
+ cmd += (uint8_t)0;
+ cmd += (uint8_t)0;
+ cmd += (uint8_t)0;
+ cmd += fileSize & 0xff;
+ cmd += (fileSize >> 8) & 0xff;
+ cmd += (fileSize >> 16) & 0xff;
+ cmd += (fileSize >> 24) & 0xff;
+ for(int i = 0; i < filePath.size(); i++)
+ {
+ cmd += filePath[i];
+ }
+ m_service->writeValue(AdafruitBleFsService::UUID_CHARACTERISTIC_FS_TRANSFER, cmd);
+
+ return writeFilePromise.get_future();
+}
+
+std::future<bool> AdafruitBleFsOperation::writeFileData(const std::vector<uint8_t> data, size_t offset)
+{
+ writeFilePromise = std::promise<bool>();
+
+ QByteArray cmd;
+ cmd += REQUEST_WRITE_FILE_DATA;
+ cmd += (uint8_t)0x01;
+ cmd += PADDING_BYTE;
+ cmd += PADDING_BYTE;
+ cmd += offset & 0xff;
+ cmd += (offset >> 8) & 0xff;
+ cmd += (offset >> 16) & 0xff;
+ cmd += (offset >> 24) & 0xff;
+ cmd += data.size() & 0xff;
+ cmd += (data.size() >> 8) & 0xff;
+ cmd += (data.size() >> 16) & 0xff;
+ cmd += (data.size() >> 24) & 0xff;
+ for(int i = 0; i < data.size(); i++)
+ {
+ cmd += data[i];
+ }
+
+ m_service->writeValue(AdafruitBleFsService::UUID_CHARACTERISTIC_FS_TRANSFER, cmd);
+
+ return writeFilePromise.get_future();
+}
+
+void AdafruitBleFsOperation::updateFiles(const int mtu)
+{
+ if(m_worker == nullptr)
+ {
+ m_worker = new BleFsWorker(info);
+ m_worker->moveToThread(&m_workerThread);
+ QObject::connect(&m_workerThread, &QThread::finished, m_worker, &QObject::deleteLater);
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/adafruitblefsoperation.h
^
|
@@ -0,0 +1,75 @@
+#ifndef ADAFRUITBLEFSOPERATION_H
+#define ADAFRUITBLEFSOPERATION_H
+
+#include "abstractoperation.h"
+#include "abstractfirmwareinfo.h"
+#include <future>
+
+class AdafruitBleFsService;
+class BleFsWorker;
+
+class AdafruitBleFsOperation : public QObject, public AbstractOperation
+{
+ Q_OBJECT
+public:
+ AdafruitBleFsOperation(QBLEService *service, const AbstractFirmwareInfo *info);
+ ~AdafruitBleFsOperation();
+ bool handleMetaData(const QByteArray &meta) override;
+ void handleData(const QByteArray &data) override;
+ void start() override;
+
+ struct File {
+ std::string name;
+ uint64_t timestamp;
+ bool isDirectory;
+ };
+
+
+ std::future<std::vector<File>> listDirectory(const std::string& path);
+ std::future<void> eraseFile(const std::string& file);
+ std::future<bool> writeFileStart(const std::string& filePath, size_t fileSize, size_t offset);
+ std::future<bool> writeFileData(const std::vector<uint8_t> data, size_t offset);
+ std::future<bool> createDirectory(const std::string& path);
+
+ void updateFiles(const int mtu);
+ void downloadProgress(int percent);
+
+private:
+ static const uint8_t PADDING_BYTE = 0x00;
+ static const uint8_t REQUEST_WRITE_FILE_START = 0x20;
+ static const uint8_t RESPONSE_WRITE_FILE = 0x21;
+ static const uint8_t REQUEST_WRITE_FILE_DATA = 0x22;
+ static const uint8_t REQUEST_DELETE_FILE = 0x30;
+ static const uint8_t RESPONSE_DELETE_FILE = 0x31;
+ static const uint8_t REQUEST_LIST_DIR = 0x50;
+ static const uint8_t RESPONSE_LIST_DIR = 0x51;
+ static const uint8_t REQUEST_CREATE_DIR = 0x40;
+ static const uint8_t RESPONSE_CREATE_DIR = 0x41;
+
+ enum class Status : uint8_t {
+ Success = 0x01,
+ Error = 0x02,
+ ReadOnly = 0x05
+ };
+
+ void handleListDirectory(const QByteArray &data);
+ void handleDeleteFile(const QByteArray &data);
+ void handleWriteFile(const QByteArray &data);
+ void handleCreateDirectory(const QByteArray &data);
+
+ const AbstractFirmwareInfo *info;
+
+ std::vector<File> listDirectoryEntries;
+
+ std::promise<std::vector<File>> listDirectoryPromise;
+ std::promise<void> deleteFilePromise;
+ std::promise<bool> writeFilePromise;
+ std::promise<bool> createDirectoryPromise;
+
+ QThread m_workerThread;
+ BleFsWorker* m_worker = nullptr;
+
+ Q_SIGNAL void startUpdateFiles(AdafruitBleFsOperation* service, const int mtu);
+};
+
+#endif // ADAFRUITBLEFSOPERATION_H
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/adafruitblefsworker.cpp
^
|
@@ -0,0 +1,211 @@
+#include "adafruitblefsworker.h"
+#include "adafruitblefsservice.h"
+#include "adafruitblefsoperation.h"
+#include <KArchive>
+#include <kzip.h>
+#include <KCompressionDevice>
+
+namespace
+{
+ KZip openArchive(QByteArray& bytes)
+ {
+ QDataStream in(&bytes, QIODevice::ReadOnly);
+ KCompressionDevice dev(in.device(), false, KCompressionDevice::CompressionType::None);
+ KZip zip(&dev);
+ return std::move(zip);
+ }
+
+ const KArchiveDirectory* getArchiveRootDirectory(KZip& zip)
+ {
+ if(!zip.open(QIODevice::ReadOnly))
+ {
+ return nullptr;
+ }
+
+ auto* root = zip.directory();
+ auto list = root->entries();
+ return root;
+ }
+
+ size_t getTotalSize(const QJsonArray& resourceList, const KArchiveDirectory* root)
+ {
+ size_t totalSize = 0;
+ for(const QJsonValue& resource : resourceList) {
+ auto sourceFile = resource.toObject().value("filename").toString();// resource["filename"].toString();
+ auto* resourceEntry = dynamic_cast<const KZipFileEntry*>(root->entry(sourceFile));
+ totalSize += resourceEntry->size();
+ }
+ return totalSize;
+ }
+
+ bool fileExists(std::vector<AdafruitBleFsOperation::File> list, QString name)
+ {
+ auto it = std::find_if(list.begin(), list.end(), [name](const AdafruitBleFsOperation::File& f)
+ {
+ return f.name == name.toStdString();
+ });
+
+ return it != list.end();
+ }
+}
+
+BleFsWorker::BleFsWorker(const AbstractFirmwareInfo *info, QObject *parent) : QObject(parent), info{info}
+{
+
+}
+
+
+BleFsWorker::~BleFsWorker()
+{
+
+}
+
+
+
+void BleFsWorker::updateFiles(AdafruitBleFsOperation* service, int transferMtu)
+{
+ // Open ZIP file
+ auto archiveBytes = info->bytes();
+
+ QDataStream in(&archiveBytes, QIODevice::ReadOnly);
+ KCompressionDevice dev(in.device(), false, KCompressionDevice::CompressionType::None);
+ KZip zip(&dev);
+
+ auto* archiveRoot = getArchiveRootDirectory(zip);
+ if(archiveRoot == nullptr)
+ {
+ return;
+ }
+
+ auto archiveEntries = archiveRoot->entries();
+ if(!archiveEntries.contains("resources.json"))
+ return;
+
+ // Get manifest file data from the archive
+ auto* manifestEntry = dynamic_cast<const KZipFileEntry*>(archiveRoot->entry("resources.json"));
+ if(manifestEntry == nullptr)
+ return;
+
+ auto manifestData = manifestEntry->data();
+
+ // Open manifest file and parse JSON
+ QJsonDocument manifestDocument = QJsonDocument::fromJson(manifestData);
+ if(manifestDocument.isNull() || !manifestDocument.isObject())
+ return;
+
+ QJsonObject manifestObject = manifestDocument.object();
+ if(manifestObject["resources"].isUndefined() || !manifestObject["resources"].isArray())
+ return;
+
+ auto resourceList = manifestObject["resources"].toArray();
+
+ if(manifestObject["obsolete_files"].isUndefined() || !manifestObject["obsolete_files"].isArray())
+ return;
+
+ auto obsoleteFileList = manifestObject["obsolete_files"].toArray();
+
+ // Remove obsolete files
+ for(const QJsonValue& file : obsoleteFileList)
+ {
+ if(file.toObject().value("path").isUndefined() || !file.toObject().value("path").isString())
+ continue;
+
+ auto path = file.toObject().value("path");
+ eraseRemoteFile(service, path.toString());
+ }
+
+ // Get total size to be uploaded
+ auto totalSize = getTotalSize(resourceList, archiveRoot);
+
+ // Upload the resources
+ int progressSize = 0;
+ for(const QJsonValue& resource : resourceList)
+ {
+ if(resource.toObject().value("filename").isUndefined() || !resource.toObject().value("filename").isString())
+ continue;
+
+ if(resource.toObject().value("path").isUndefined() || !resource.toObject().value("path").isString())
+ continue;
+
+ auto sourceFile = resource.toObject().value("filename").toString();
+ auto destinationFile = resource.toObject().value("path").toString();
+
+ // Remove the destination file if it already exists on the target
+ QStringList folderList = destinationFile.split('/');
+ QString file = folderList.last();
+ folderList.removeLast();
+ QString folder = folderList.join('/');
+ auto fileList = getRemoteFileList(service, folder);
+
+ if(fileExists(fileList, file))
+ {
+ eraseRemoteFile(service, destinationFile);
+ }
+
+ if(!createParentFolder(service, folderList))
+ continue;
+
+ auto* resourceEntry = dynamic_cast<const KZipFileEntry*>(archiveRoot->entry(sourceFile));
+ if(resourceEntry == nullptr)
+ continue;
+ auto resourceData = resourceEntry->data();
+
+ auto writeFileFuture = service->writeFileStart(destinationFile.toStdString(), resourceData.size(), 0);
+ writeFileFuture.wait();
+ bool success = writeFileFuture.get();
+ if(!success) continue;
+
+ const size_t chunkSize = transferMtu-20;
+ size_t written = 0;
+ while(written < resourceData.size())
+ {
+ std::vector<uint8_t> chunk;
+ size_t remaining = resourceData.size() - written;
+ size_t toWrite = std::min(remaining, chunkSize);
+ for(int i = 0; i < toWrite; i++)
+ {
+ chunk.push_back(resourceData.at(written + i));
+ }
+
+ auto writeFileDataFuture = service->writeFileData(chunk, written);
+ writeFileDataFuture.wait();
+ success = writeFileDataFuture.get();
+ if(!success) break;
+
+ written += toWrite;
+ progressSize += toWrite;
+ service->downloadProgress((100.0f / totalSize) * progressSize);
+ }
+ }
+}
+
+std::vector<AdafruitBleFsOperation::File> BleFsWorker::getRemoteFileList(AdafruitBleFsOperation* service, QString path)
+{
+ auto listDirectoryFuture = service->listDirectory(path.toStdString());
+ listDirectoryFuture.wait();
+ return listDirectoryFuture.get();
+
+}
+
+void BleFsWorker::eraseRemoteFile(AdafruitBleFsOperation* service, QString file)
+{
+ auto eraseFileFuture = service->eraseFile(file.toStdString());
+ eraseFileFuture.wait();
+}
+
+bool BleFsWorker::createParentFolder(AdafruitBleFsOperation* service, QStringList folderList)
+{
+ if(folderList.size() <= 1)
+ return true;
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/adafruitblefsworker.h
^
|
@@ -0,0 +1,32 @@
+#ifndef ADAFRUITBLEFSWORKER_H
+#define ADAFRUITBLEFSWORKER_H
+
+#include <QObject>
+#include "abstractfirmwareinfo.h"
+#include "adafruitblefsoperation.h"
+
+class AdafruitBleFsService;
+
+class BleFsWorker : public QObject
+{
+ Q_OBJECT
+public:
+ explicit BleFsWorker(const AbstractFirmwareInfo *info, QObject *parent = nullptr);
+ ~BleFsWorker();
+
+private:
+ std::vector<AdafruitBleFsOperation::File> getRemoteFileList(AdafruitBleFsOperation* service, QString path);
+ void eraseRemoteFile(AdafruitBleFsOperation* service, QString file);
+ bool createParentFolder(AdafruitBleFsOperation* service, QStringList folderList);
+
+ bool m_interupted = false;
+ const AbstractFirmwareInfo *info;
+
+public slots:
+ void updateFiles(AdafruitBleFsOperation* service, int mtu);
+
+signals:
+ void done();
+};
+
+#endif // ADAFRUITBLEFSWORKER_H
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/dfuoperation.cpp
^
|
@@ -2,9 +2,57 @@
#include "dfuservice.h"
#include "typeconversion.h"
#include <QApplication>
+#include <KArchive>
+#include <kzip.h>
+#include <KCompressionDevice>
-DfuOperation::DfuOperation(const AbstractFirmwareInfo *info, QBLEService *service) : AbstractOperation(service), m_info(info), m_fwBytes(info->bytes())
+namespace {
+QString getFirmwareFileName(QByteArray& manifestData) {
+ QJsonDocument manifestDocument = QJsonDocument::fromJson(manifestData);
+
+ if(manifestDocument.isNull() || !manifestDocument.isObject()) return {};
+ QJsonObject manifestJson = manifestDocument.object();
+
+ if(manifestJson["manifest"].isUndefined() || !manifestJson["manifest"].isObject()) return {};
+ QJsonObject manifestObject = manifestJson["manifest"].toObject();
+
+ if(manifestObject["application"].isUndefined() || !manifestObject["application"].isObject()) return {};
+ QJsonObject applicationObject = manifestObject["application"].toObject();
+
+ if(applicationObject["bin_file"].isUndefined() || !applicationObject["bin_file"].isString()) return {};
+
+ QString binFile = applicationObject["bin_file"].toString();
+ return binFile;
+}
+
+uint16_t getFirmwareCrc(QByteArray& manifestData, bool& valid) {
+ valid = false;
+ QJsonDocument manifestDocument = QJsonDocument::fromJson(manifestData);
+
+ if(manifestDocument.isNull() || !manifestDocument.isObject()) return 0;
+ QJsonObject manifestJson = manifestDocument.object();
+
+ if(manifestJson["manifest"].isUndefined() || !manifestJson["manifest"].isObject()) return 0;
+ auto manifestObject = manifestJson["manifest"].toObject();
+
+ if(manifestObject["application"].isUndefined() || !manifestObject["application"].isObject()) return 0;
+ auto applicationObject = manifestObject["application"].toObject();
+
+ if(applicationObject["init_packet_data"].isUndefined() || !applicationObject["init_packet_data"].isObject()) return 0;
+ auto initPacketDataObject = applicationObject["init_packet_data"].toObject();
+
+
+ if(applicationObject["firmware_crc16"].isUndefined()) return 0;
+
+ uint16_t crc = initPacketDataObject["firmware_crc16"].toInt(0);
+ valid = true;
+ return crc;
+}
+}
+
+DfuOperation::DfuOperation(const AbstractFirmwareInfo *info, QBLEService *service) : AbstractOperation(service), m_info(info)
{
+
}
DfuOperation::~DfuOperation()
@@ -18,10 +66,60 @@
}
}
+bool DfuOperation::probeArchive()
+{
+ QByteArray zippedFwBytes = m_info->bytes();
+ QDataStream in(&zippedFwBytes, QIODevice::ReadOnly);
+ KCompressionDevice dev(in.device(), false, KCompressionDevice::CompressionType::None);
+ KZip zip(&dev);
+
+ if(!zip.open(QIODevice::ReadOnly))
+ {
+ qDebug() << "Cannot open the firmware archive";
+ return false;
+ }
+
+ const auto* root = zip.directory();
+ const auto* manifestEntry = dynamic_cast<const KZipFileEntry*>(root->entry("manifest.json"));
+ if(manifestEntry == nullptr)
+ {
+ qDebug() << "Invalid firmware archive, cannot find manifest.json";
+ }
+
+ auto manifestData = manifestEntry->data();
+ QString firmwareFileName = getFirmwareFileName(manifestData);
+ if(firmwareFileName.isEmpty())
+ {
+ qDebug() << "Invalid firmware archive, cannot read manifest.json";
+ return false;
+ }
+
+ const auto* firmwareEntry = dynamic_cast<const KZipFileEntry*>(root->entry(firmwareFileName));
+ if(firmwareEntry == nullptr)
+ {
+ qDebug() << "Invalid firmware archive, cannot open firmware file";
+ return false;
+ }
+ m_uncompressedFwBytes = firmwareEntry->data();
+
+ bool isCrcValid = false;
+ m_crc16 = getFirmwareCrc(manifestData, isCrcValid);
+ if(!isCrcValid)
+ {
+ qDebug() << "Invalid firmware archive, cannot read CRC";
+ return false;
+ }
+ qDebug() << "Firmware file name : " << firmwareFileName << " (CRC : " << m_crc16 <<")";
+
+ return true;
+}
+
void DfuOperation::start()
{
qDebug() << Q_FUNC_INFO;
- if (m_info->type() == AbstractFirmwareInfo::Firmware) {
+ bool probeOk = probeArchive();
+
+ if (m_info->type() == AbstractFirmwareInfo::Firmware && probeOk && m_uncompressedFwBytes.size() > 0) {
DfuService *serv = dynamic_cast<DfuService*>(m_service);
m_service->enableNotification(serv->UUID_CHARACTERISTIC_DFU_CONTROL);
@@ -33,14 +131,14 @@
QByteArray lengths;
lengths += TypeConversion::fromInt32(0);
lengths += TypeConversion::fromInt32(0);
- lengths += TypeConversion::fromInt32(m_fwBytes.length());
+ lengths += TypeConversion::fromInt32(m_uncompressedFwBytes.length());
m_service->writeValue(DfuService::UUID_CHARACTERISTIC_DFU_PACKET, lengths);
//Send packet request command to control point
m_service->writeValue(DfuService::UUID_CHARACTERISTIC_DFU_CONTROL, UCHAR_TO_BYTEARRAY(DfuService::COMMAND_PACKET_RECEIPT_NOTIFICATION_REQUEST) + QByteArray(1, m_notificationPackets));
} else {
- m_service->message(QObject::tr("File does not seem to be supported"));
+ emit transferError("File does not seem to be supported");
}
}
@@ -103,7 +201,7 @@
m_outstandingPacketNotifications--;
//Use the data from the notification to inform the UI on progress
- int progressPercent = (int) ((((float) bytesReceived) / m_fwBytes.length()) * 100);
+ int progressPercent = (int) ((((float) bytesReceived) / m_uncompressedFwBytes.length()) * 100);
DfuService *serv = qobject_cast<DfuService*>(m_service);
serv->downloadProgress(progressPercent);
serv->setWaitForWatch(false);
@@ -135,7 +233,7 @@
info += TypeConversion::fromInt16(0);
info += TypeConversion::fromInt32(0);
info += TypeConversion::fromInt16(0);
- info += TypeConversion::fromInt16(m_info->getCrc16());
+ info += TypeConversion::fromInt16(m_crc16);
m_service->writeValue(DfuService::UUID_CHARACTERISTIC_DFU_PACKET, info);
return true;
}
@@ -149,7 +247,7 @@
//connect(m_worker, &DfuWorker::done, this, &Controller::handleResults);
m_workerThread.start();
DfuService *serv = qobject_cast<DfuService*>(m_service);
- emit sendFirmware(serv, m_fwBytes, m_notificationPackets);
+ emit sendFirmware(serv, m_uncompressedFwBytes, m_notificationPackets);
}
void DfuOperation::packetNotification()
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/dfuoperation.h
^
|
@@ -2,9 +2,10 @@
#define DFUOPERATION_H
#include "abstractoperation.h"
-#include "bipfirmwareinfo.h"
#include "dfuworker.h"
+class DfuService;
+class AbstractFirmwareInfo;
class DfuOperation : public QObject, public AbstractOperation
{
Q_OBJECT
@@ -15,10 +16,10 @@
void handleData(const QByteArray &data) override;
void start() override;
+ Q_SIGNAL void transferError(const QString error);
protected:
-
const AbstractFirmwareInfo *m_info = nullptr;
- QByteArray m_fwBytes;
+ QByteArray m_uncompressedFwBytes;
virtual bool sendFwInfo();
virtual void sendFirmwareData();
@@ -29,9 +30,12 @@
bool m_transferError = false;
QThread m_workerThread;
DfuWorker *m_worker = nullptr;
+ uint16_t m_crc16;
Q_SIGNAL void sendFirmware(DfuService* service, const QByteArray &data, int notificationPackets);
+
Q_SLOT void packetNotification();
+ bool probeArchive();
};
#endif // DFUOPERATION_H
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/dfuworker.cpp
^
|
@@ -1,4 +1,8 @@
#include "dfuworker.h"
+#include "qdebug.h"
+
+#include <QThread>
+#include "dfuservice.h"
DfuWorker::DfuWorker(QObject *parent) : QObject(parent)
{
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/operations/dfuworker.h
^
|
@@ -2,8 +2,8 @@
#define DFUWORKER_H
#include <QObject>
-#include "dfuservice.h"
+class DfuService;
class DfuWorker : public QObject
{
Q_OBJECT
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/services/adafruitblefsservice.cpp
^
|
@@ -0,0 +1,36 @@
+#include "adafruitblefsservice.h"
+
+const char* AdafruitBleFsService::UUID_SERVICE_FS = "0000febb-0000-1000-8000-00805f9b34fb";
+const char* AdafruitBleFsService::UUID_CHARACTERISTIC_FS_VERSION = "adaf0100-4669-6c65-5472-616e73666572";
+const char* AdafruitBleFsService::UUID_CHARACTERISTIC_FS_TRANSFER = "adaf0200-4669-6c65-5472-616e73666572";
+
+AdafruitBleFsService::AdafruitBleFsService(const QString &path, QObject *parent, size_t mtu) : QBLEService(UUID_SERVICE_FS, path, parent), mtu(mtu)
+{
+ qDebug() << Q_FUNC_INFO;
+
+ connect(this, &QBLEService::characteristicChanged, this, &AdafruitBleFsService::characteristicChanged);
+ enableNotification(UUID_CHARACTERISTIC_FS_TRANSFER);
+}
+
+void AdafruitBleFsService::prepareDownload(AdafruitBleFsOperation* operation)
+{
+ this->operation = operation;
+}
+
+
+void AdafruitBleFsService::updateFiles()
+{
+ operation->updateFiles(mtu);
+}
+
+
+void AdafruitBleFsService::characteristicChanged(const QString &characteristic, const QByteArray &value)
+{
+ qDebug() << Q_FUNC_INFO << characteristic << value;
+
+ if (characteristic == AdafruitBleFsService::UUID_CHARACTERISTIC_FS_VERSION) {
+ qDebug() << "Version : " << (value[0] + (value[1] << 8));
+ } else {
+ operation->handleData(value);
+ }
+}
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/services/adafruitblefsservice.h
^
|
@@ -0,0 +1,35 @@
+#ifndef ADAFRUITBLEFSSERVICE_H
+#define ADAFRUITBLEFSSERVICE_H
+
+#include "qble/qbleservice.h"
+#include "adafruitblefsoperation.h"
+
+/*
+{0000febb-0000-1000-8000-00805f9b34fb} FS Service
+--adaf0100-4669-6c65-5472-616e73666572 // Version
+--adaf0200-4669-6c65-5472-616e73666572 // transfer
+*/
+
+class AdafruitBleFsService : public QBLEService
+{
+ Q_OBJECT
+
+public:
+ AdafruitBleFsService(const QString &path, QObject *parent, size_t mtu);
+ static const char *UUID_SERVICE_FS;
+ static const char *UUID_CHARACTERISTIC_FS_VERSION;
+ static const char *UUID_CHARACTERISTIC_FS_TRANSFER;
+
+ void prepareDownload(AdafruitBleFsOperation* operation);
+ void updateFiles();
+
+ Q_SIGNAL void downloadProgress(int percent);
+
+private:
+ Q_SLOT void characteristicChanged(const QString &characteristic, const QByteArray &value);
+
+ AdafruitBleFsOperation* operation = nullptr;
+ const size_t mtu;
+};
+
+#endif // ADAFRUITBLEFSSERVICE_H
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/services/dfuservice.cpp
^
|
@@ -31,25 +31,19 @@
qDebug() << "...got metadata";
if (m_operationRunning == 1 && m_updateFirmware) {
if (m_updateFirmware->handleMetaData(value)) {
- delete m_updateFirmware;
- m_updateFirmware = nullptr;
+ m_updateFirmware.release();
m_operationRunning = 0;
}
}
}
}
-void DfuService::prepareFirmwareDownload(const AbstractFirmwareInfo *info, DfuOperation* operation)
+void DfuService::prepareFirmwareDownload(const AbstractFirmwareInfo *info)
{
- if (!m_updateFirmware) {
- m_updateFirmware = operation;
+ if (m_operationRunning == 1) {
+ emit message(tr("An operation is currently running, please try later"));
} else {
- if (m_operationRunning == 1) {
- emit message(tr("An operation is currently running, please try later"));
- } else {
- delete m_updateFirmware;
- m_updateFirmware = new DfuOperation(info, this);
- }
+ m_updateFirmware.reset(new DfuOperation(info, this));
}
}
@@ -58,6 +52,7 @@
qDebug() << Q_FUNC_INFO;
if (m_updateFirmware && m_operationRunning == 0) {
m_operationRunning = 1;
+ connect(m_updateFirmware.get(), &DfuOperation::transferError, this, &DfuService::onTransferError);
m_updateFirmware->start();
} else {
emit message(tr("No file selected"));
@@ -73,8 +68,7 @@
void DfuService::abortOperations()
{
if (m_updateFirmware) {
- delete m_updateFirmware;
- m_updateFirmware = nullptr;
+ m_updateFirmware.release();
}
m_operationRunning = 0;
emit operationRunningChanged();
@@ -89,3 +83,9 @@
{
return m_waitForWatch.load();
}
+
+void DfuService::onTransferError(const QString error) {
+ m_operationRunning = 0;
+ qDebug() << "Transfer error : " << error;
+ emit message(error);
+}
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/services/dfuservice.h
^
|
@@ -1,9 +1,10 @@
#ifndef DFUSERVICE_H
#define DFUSERVICE_H
+#include <memory>
#include "qble/qbleservice.h"
#include "abstractfirmwareinfo.h"
-
+#include "dfuoperation.h"
/*
{00001530-1212-EFDE-1523-785FEABCD123} DFU Service
--00001531-1212-EFDE-1523-785FEABCD123 //Control Point
@@ -47,7 +48,7 @@
static constexpr uint8_t ERROR_CRC_ERROR = 0x05;
static constexpr uint8_t ERROR_OPERATION_FAILED = 0x06;
- void prepareFirmwareDownload(const AbstractFirmwareInfo *info, DfuOperation* operation);
+ void prepareFirmwareDownload(const AbstractFirmwareInfo *info);
void startDownload();
Q_SIGNAL void downloadProgress(int percent);
@@ -59,9 +60,10 @@
private:
Q_SLOT void characteristicChanged(const QString &characteristic, const QByteArray &value);
+ Q_SLOT void onTransferError(const QString error);
int m_operationRunning = 0;
- DfuOperation *m_updateFirmware = nullptr;
+ std::unique_ptr<DfuOperation> m_updateFirmware = nullptr;
std::atomic<bool> m_waitForWatch;
};
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/services/infinitimeresourceservice.cpp
^
|
@@ -0,0 +1,21 @@
+#include "infinitimeresourceservice.h"
+
+InfiniTimeResourceService::InfiniTimeResourceService(AdafruitBleFsService* fsService) : fsService{fsService}
+{
+
+}
+
+void InfiniTimeResourceService::listDirectory() {
+ qDebug() << "TEST4";
+ auto p = fsService->listDirectory();
+
+ p.wait();
+ auto l = p.get();
+ qDebug() << "Received " << l.size() << "files";
+ for(auto& f : l) {
+ qDebug() << "\n\t" << (f.isDirectory ? "Directory" : "File") << " : " << f.name
+ << "\n\t Timestamp : " << f.timestamp;
+
+
+ }
+}
|
[-]
[+]
|
Added |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/daemon/src/services/infinitimeresourceservice.h
^
|
@@ -0,0 +1,17 @@
+#ifndef INFINITIMERESOURCESERVICE_H
+#define INFINITIMERESOURCESERVICE_H
+
+#include "adafruitblefsservice.h"
+#include "qble/qbleservice.h"
+
+class InfiniTimeResourceService : public QBLEService {
+public:
+ InfiniTimeResourceService(AdafruitBleFsService* fsService);
+
+ void listDirectory();
+
+private:
+ AdafruitBleFsService* fsService = nullptr;
+};
+
+#endif // INFINITIMERESOURCESERVICE_H
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/qml/pages/FirstPage.qml
^
|
@@ -79,7 +79,7 @@
LabelPL {
id: lblProgress
x: 10
- anchors.left: txtMessage.right
+ anchors.left: lblLastMessage.right
anchors.leftMargin: 5
horizontalAlignment: Text.AlignLeft
color: styler.themeSecondaryHighlightColor
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/qml/pages/PairPage.qml
^
|
@@ -1,5 +1,5 @@
import QtQuick 2.0
-import QtBluetooth 5.2
+import org.kde.bluezqt 1.0 as BluezQt
import QtQml.Models 2.2
import uk.co.piggz.amazfish 1.0
import "../components"
@@ -11,12 +11,45 @@
title: qsTr("Pair Device")
placeholderText: _placeholderText || qsTr("No devices found")
- placeholderEnabled: discoveryModel.rowCount() > 0
+ placeholderEnabled: devicesModel.rowCount() > 0
property string deviceType
property string _placeholderText
property string _deviceName
property string _deviceAddress
+ property QtObject adapter: _bluetoothManager ? _bluetoothManager.usableAdapter : null
+ property QtObject _bluetoothManager : BluezQt.Manager
+
+ function startDiscovery() {
+ if (!adapter || adapter.discovering) {
+ return
+ }
+ adapter.startDiscovery()
+ }
+
+ function stopDiscovery() {
+ if (adapter && adapter.discovering) {
+ adapter.stopDiscovery()
+ }
+ }
+
+ Timer {
+ id: delayedATimer
+ repeat: false
+ running: true
+ interval: 100
+ onTriggered: {
+ console.log("Delayed Manager operational:", _bluetoothManager.operational, _bluetoothManager.usableAdapter);
+ if (typeof(devicesModel.filters) == 'number') {
+ devicesModel.filters = BluezQt.DevicesModelPrivate.AllDevices;
+ }
+ }
+ }
+
+ Component.onCompleted: {
+ console.log("Manager operational:", _bluetoothManager.operational, _bluetoothManager.usableAdapter);
+
+ }
Connections {
target: DaemonInterfaceInstance
@@ -31,15 +64,13 @@
}
}
- BluetoothDiscoveryModel {
- id: discoveryModel
- running: true
- discoveryMode: BluetoothDiscoveryModel.DeviceDiscovery
+ BluezQt.DevicesModel {
+ id: devicesModel
}
DelegateModel {
id: delegateModel
- model: discoveryModel
+ model: devicesModel
groups: DelegateModelGroup {
id: visibleItems
@@ -57,19 +88,20 @@
for (var i = 0; i < itemsCount; ++i) {
var item = items.get(i)
- item.inVisible = item.model.deviceName.indexOf(deviceType) !== -1
+ item.inVisible = item.model.FriendlyName.indexOf(deviceType) !== -1
}
}
delegate: ListItemPL {
id: listItem
contentHeight: styler.themeItemSizeLarge
+// visible: model.FriendlyName.indexOf(deviceType) >= 0
onClicked: {
AmazfishConfig.pairedAddress = "";
AmazfishConfig.pairedName = "";
- discoveryModel.running = false;
- _deviceName = model.deviceName;
- _deviceAddress = AmazfishConfig.localAdapter+"/dev_" + model.remoteAddress.replace(/:/g, '_');
+ stopDiscovery();
+ _deviceName = model.FriendlyName;
+ _deviceAddress = AmazfishConfig.localAdapter+"/dev_" + model.Address.replace(/:/g, '_');
DaemonInterfaceInstance.pair(_deviceName, _deviceAddress)
}
@@ -87,7 +119,7 @@
id: nameLabel
//truncationMode: TruncationMode.Fade
width: parent.width
- text: model.deviceName
+ text: model.FriendlyName
color: listItem.pressed ? styler.themeHighlightColor : styler.themePrimaryColor
}
@@ -99,7 +131,7 @@
}
//truncationMode: TruncationMode.Fade
width: parent.width
- text: model.remoteAddress
+ text: model.Address
//font.pixelSize: Theme.fontSizeSmall
color: listItem.pressed ? styler.themeSecondaryHighlightColor : styler.themeSecondaryColor
}
@@ -118,18 +150,23 @@
PageMenuItemPL {
enabled: !DaemonInterfaceInstance.pairing
- text: discoveryModel.running
+ text: adapter.discovering
? qsTr("Stop scanning")
: qsTr("Scan for devices")
onClicked: {
_placeholderText = ""
- discoveryModel.running = !discoveryModel.running
+ if (adapter.discovering) {
+ stopDiscovery();
+ } else {
+ startDiscovery();
+ console.log(devicesModel.rowCount());
+ }
}
}
PageMenuItemPL {
visible: text
- text: discoveryModel.running
+ text: adapter.discovering
? qsTr("Scanning for devices…")
: DaemonInterfaceInstance.pairing
? qsTr("Pairing…")
@@ -139,7 +176,7 @@
BusyIndicatorPL {
id: busyIndicator
- running: (discoveryModel.running && !page.count) || DaemonInterfaceInstance.connectionState == "pairing"
+ running: (adapter.discovering && !page.count) || DaemonInterfaceInstance.connectionState == "pairing"
}
}
|
[-]
[+]
|
Deleted |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/translations/harbour-amazfish-ui-de.ts
^
|
@@ -1,1192 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="de_DE">
-<context>
- <name>AddCityPage</name>
- <message>
- <source>Set Location</source>
- <translation>Ort festlegen</translation>
- </message>
-</context>
-<context>
- <name>Alarm</name>
- <message>
- <source>Enabled</source>
- <translation>Aktiviert</translation>
- </message>
- <message>
- <source>Mon</source>
- <translation>Mo</translation>
- </message>
- <message>
- <source>Tue</source>
- <translation>Di</translation>
- </message>
- <message>
- <source>Wed</source>
- <translation>Mi</translation>
- </message>
- <message>
- <source>Thu</source>
- <translation>Do</translation>
- </message>
- <message>
- <source>Fri</source>
- <translation>Fr</translation>
- </message>
- <message>
- <source>Sat</source>
- <translation>Sa</translation>
- </message>
- <message>
- <source>Sun</source>
- <translation>So</translation>
- </message>
-</context>
-<context>
- <name>AnalysisPage</name>
- <message>
- <source>Analysis</source>
- <translation>Auswertung</translation>
- </message>
- <message>
- <source>Heartrate</source>
- <translation>Pulsrate</translation>
- </message>
- <message>
- <source>Steps</source>
- <translation>Schritte</translation>
- </message>
- <message>
- <source>Intensity</source>
- <translation>Intensität</translation>
- </message>
-</context>
-<context>
- <name>AuthKeyDialog</name>
- <message>
- <source>Enter auth key</source>
- <translation>Auth-Key Eingeben</translation>
- </message>
-</context>
-<context>
- <name>BipFirmwarePage</name>
- <message>
- <source>Send file</source>
- <translation>Datei senden</translation>
- </message>
- <message>
- <source>Download File</source>
- <translation>Datei herunterladen</translation>
- </message>
- <message>
- <source>Select a file to download.</source>
- <translation>Wähle eine Datei zum herunterladen aus.</translation>
- </message>
- <message>
- <source>None</source>
- <translation>Keins</translation>
- </message>
- <message>
- <source>Choose File</source>
- <translation>Datei wählen</translation>
- </message>
- <message>
- <source>File type/version: </source>
- <translation>Dateityp/Version: </translation>
- </message>
- <message>
- <source>File not supported on this device</source>
- <translation>Datei für dieses Gerät nicht unterstützt</translation>
- </message>
-</context>
-<context>
- <name>DaemonInterface</name>
- <message>
- <source>Unexpected error</source>
- <translation>Unerwarteter Fehler</translation>
- </message>
-</context>
-<context>
- <name>DebugInfo</name>
- <message>
- <source>Refresh</source>
- <translation>Aktualisieren</translation>
- </message>
- <message>
- <source>Address: </source>
- <translation>Adresse:</translation>
- </message>
- <message>
- <source>Serial No: </source>
- <translation>Serien Nr:</translation>
- </message>
- <message>
- <source>Hardware Rev: </source>
- <translation>Hardware Rev:</translation>
- </message>
- <message>
- <source>Software Rev: </source>
- <translation>Software Rev:</translation>
- </message>
- <message>
- <source>Connection State: </source>
- <translation>Verbindungsstatus:</translation>
- </message>
- <message>
- <source>GPS Ver: </source>
- <translation>GPS Ver:</translation>
- </message>
- <message>
- <source>Test Notification</source>
- <translation>Test Benachrichtigung</translation>
- </message>
- <message>
- <source>Test Email</source>
- <translation>Test E-Mail</translation>
- </message>
- <message>
- <source>Test Call</source>
- <translation>Testanruf</translation>
- </message>
- <message>
- <source>Fetch debug log</source>
- <translation>Debugprotokoll abrufen</translation>
- </message>
- <message>
- <source>Test Popup</source>
- <translation>Test Popup</translation>
- </message>
- <message>
- <source>Send Weather</source>
- <translation>Sende Wetterdaten</translation>
- </message>
- <message>
- <source>A:</source>
- <translation>A:</translation>
- </message>
- <message>
- <source>S:</source>
- <translation>S:</translation>
- </message>
- <message>
- <source>Update Calendar</source>
- <translation>Kalender updaten</translation>
- </message>
- <message>
- <source>Model: </source>
- <translation>Modell: </translation>
- </message>
- <message>
- <source>Firmware Rev: </source>
- <translation>Firmware: </translation>
- </message>
- <message>
- <source>Manufacturer: </source>
- <translation>Hersteller: </translation>
- </message>
- <message>
- <source>Music Control</source>
- <translation>Musik kontrollieren</translation>
- </message>
- <message>
- <source>Debugging</source>
- <translation>Debugging</translation>
- </message>
- <message>
- <source>Information</source>
- <translation>Information</translation>
- </message>
|
[-]
[+]
|
Deleted |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/translations/harbour-amazfish-ui-es.ts
^
|
@@ -1,1192 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="es">
-<context>
- <name>AddCityPage</name>
- <message>
- <source>Set Location</source>
- <translation>Establecer ubicación</translation>
- </message>
-</context>
-<context>
- <name>Alarm</name>
- <message>
- <source>Enabled</source>
- <translation>Habilitado</translation>
- </message>
- <message>
- <source>Mon</source>
- <translation>Lun</translation>
- </message>
- <message>
- <source>Tue</source>
- <translation>Mar</translation>
- </message>
- <message>
- <source>Wed</source>
- <translation>Mié</translation>
- </message>
- <message>
- <source>Thu</source>
- <translation>Jue</translation>
- </message>
- <message>
- <source>Fri</source>
- <translation>Vie</translation>
- </message>
- <message>
- <source>Sat</source>
- <translation>Sáb</translation>
- </message>
- <message>
- <source>Sun</source>
- <translation>Dom</translation>
- </message>
-</context>
-<context>
- <name>AnalysisPage</name>
- <message>
- <source>Analysis</source>
- <translation>Análisis</translation>
- </message>
- <message>
- <source>Heartrate</source>
- <translation>Frecuencia cardiaca</translation>
- </message>
- <message>
- <source>Steps</source>
- <translation>Pasos</translation>
- </message>
- <message>
- <source>Intensity</source>
- <translation>Intensidad</translation>
- </message>
-</context>
-<context>
- <name>AuthKeyDialog</name>
- <message>
- <source>Enter auth key</source>
- <translation>Introduce clave</translation>
- </message>
-</context>
-<context>
- <name>BipFirmwarePage</name>
- <message>
- <source>Send file</source>
- <translation>Enviar</translation>
- </message>
- <message>
- <source>Download File</source>
- <translation>Enviar archivo</translation>
- </message>
- <message>
- <source>Select a file to download.</source>
- <translation>Selecciona archivo para enviar.</translation>
- </message>
- <message>
- <source>None</source>
- <translation>Ninguno</translation>
- </message>
- <message>
- <source>Choose File</source>
- <translation>Elige archivo</translation>
- </message>
- <message>
- <source>File type/version: </source>
- <translation>Tipo de archivo/ver.: </translation>
- </message>
- <message>
- <source>File not supported on this device</source>
- <translation>Archivo no soportado en este dispositivo</translation>
- </message>
-</context>
-<context>
- <name>DaemonInterface</name>
- <message>
- <source>Unexpected error</source>
- <translation>Error inesperado</translation>
- </message>
-</context>
-<context>
- <name>DebugInfo</name>
- <message>
- <source>Refresh</source>
- <translation>Actualizar</translation>
- </message>
- <message>
- <source>Address: </source>
- <translation>Dirección: </translation>
- </message>
- <message>
- <source>Serial No: </source>
- <translation>Nº Serie: </translation>
- </message>
- <message>
- <source>Hardware Rev: </source>
- <translation>Rev. hardware: </translation>
- </message>
- <message>
- <source>Software Rev: </source>
- <translation>Rev. software: </translation>
- </message>
- <message>
- <source>Connection State: </source>
- <translation>Estado de conexión: </translation>
- </message>
- <message>
- <source>GPS Ver: </source>
- <translation>Ver. GPS: </translation>
- </message>
- <message>
- <source>Test Notification</source>
- <translation>Test de notificación</translation>
- </message>
- <message>
- <source>Test Email</source>
- <translation>Test de email</translation>
- </message>
- <message>
- <source>Test Call</source>
- <translation>Test de llamada</translation>
- </message>
- <message>
- <source>Fetch debug log</source>
- <translation>Registro de depuración</translation>
- </message>
- <message>
- <source>Test Popup</source>
- <translation>Test de ventana emergente</translation>
- </message>
- <message>
- <source>Send Weather</source>
- <translation>Enviar Tiempo</translation>
- </message>
- <message>
- <source>A:</source>
- <translation>A:</translation>
- </message>
- <message>
- <source>S:</source>
- <translation>S:</translation>
- </message>
- <message>
- <source>Update Calendar</source>
- <translation>Actualizar calendario</translation>
- </message>
- <message>
- <source>Model: </source>
- <translation>Modelo: </translation>
- </message>
- <message>
- <source>Firmware Rev: </source>
- <translation>Rev. firmware: </translation>
- </message>
- <message>
- <source>Manufacturer: </source>
- <translation>Fabricante: </translation>
- </message>
- <message>
- <source>Music Control</source>
- <translation>Control de música</translation>
- </message>
- <message>
- <source>Debugging</source>
- <translation>Depuración</translation>
- </message>
- <message>
- <source>Information</source>
- <translation>Información</translation>
- </message>
|
[-]
[+]
|
Deleted |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/translations/harbour-amazfish-ui-nl.ts
^
|
@@ -1,1192 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="nl_NL">
-<context>
- <name>AddCityPage</name>
- <message>
- <source>Set Location</source>
- <translation>Locatie instellen</translation>
- </message>
-</context>
-<context>
- <name>Alarm</name>
- <message>
- <source>Enabled</source>
- <translation>Ingeschakeld</translation>
- </message>
- <message>
- <source>Mon</source>
- <translation>Ma</translation>
- </message>
- <message>
- <source>Tue</source>
- <translation>Di</translation>
- </message>
- <message>
- <source>Wed</source>
- <translation>Wo</translation>
- </message>
- <message>
- <source>Thu</source>
- <translation>Do</translation>
- </message>
- <message>
- <source>Fri</source>
- <translation>Vr</translation>
- </message>
- <message>
- <source>Sat</source>
- <translation>Za</translation>
- </message>
- <message>
- <source>Sun</source>
- <translation>Zo</translation>
- </message>
-</context>
-<context>
- <name>AnalysisPage</name>
- <message>
- <source>Analysis</source>
- <translation>Analyse</translation>
- </message>
- <message>
- <source>Heartrate</source>
- <translation>Hartslag</translation>
- </message>
- <message>
- <source>Steps</source>
- <translation>Stappen</translation>
- </message>
- <message>
- <source>Intensity</source>
- <translation>Intensiteit</translation>
- </message>
-</context>
-<context>
- <name>AuthKeyDialog</name>
- <message>
- <source>Enter auth key</source>
- <translation>Auth-sleutel invoeren</translation>
- </message>
-</context>
-<context>
- <name>BipFirmwarePage</name>
- <message>
- <source>Send file</source>
- <translation>Verstuur bestand</translation>
- </message>
- <message>
- <source>Download File</source>
- <translation>Download bestand</translation>
- </message>
- <message>
- <source>Select a file to download.</source>
- <translation>Selecteer een bestand om te downloaden.</translation>
- </message>
- <message>
- <source>None</source>
- <translation>Geen</translation>
- </message>
- <message>
- <source>Choose File</source>
- <translation>Kies bestand</translation>
- </message>
- <message>
- <source>File type/version: </source>
- <translation>Bestandstype/-versie: </translation>
- </message>
- <message>
- <source>File not supported on this device</source>
- <translation>Bestand niet ondersteund op dit apparaat</translation>
- </message>
-</context>
-<context>
- <name>DaemonInterface</name>
- <message>
- <source>Unexpected error</source>
- <translation>Onverwachte fout</translation>
- </message>
-</context>
-<context>
- <name>DebugInfo</name>
- <message>
- <source>Refresh</source>
- <translation>Verversen</translation>
- </message>
- <message>
- <source>Address: </source>
- <translation>Adres: </translation>
- </message>
- <message>
- <source>Serial No: </source>
- <translation>Serienummer: </translation>
- </message>
- <message>
- <source>Hardware Rev: </source>
- <translation>Hardware-revisie: </translation>
- </message>
- <message>
- <source>Software Rev: </source>
- <translation>Software-revisie: </translation>
- </message>
- <message>
- <source>Connection State: </source>
- <translation>Verbindingsstatus: </translation>
- </message>
- <message>
- <source>GPS Ver: </source>
- <translation>GPS-versie: </translation>
- </message>
- <message>
- <source>Test Notification</source>
- <translation>Testmelding</translation>
- </message>
- <message>
- <source>Test Email</source>
- <translation>Test e-mail</translation>
- </message>
- <message>
- <source>Test Call</source>
- <translation>Test oproep</translation>
- </message>
- <message>
- <source>Fetch debug log</source>
- <translation>Foutenlogboek ophalen</translation>
- </message>
- <message>
- <source>Test Popup</source>
- <translation>Test melding</translation>
- </message>
- <message>
- <source>Debugging</source>
- <translation>Foutopsporing</translation>
- </message>
- <message>
- <source>Information</source>
- <translation>Informatie</translation>
- </message>
- <message>
- <source>Model: </source>
- <translation>Model: </translation>
- </message>
- <message>
- <source>Firmware Rev: </source>
- <translation>Firmware-revisie: </translation>
- </message>
- <message>
- <source>Manufacturer: </source>
- <translation>Fabrikant: </translation>
- </message>
- <message>
- <source>A:</source>
- <translation>A:</translation>
- </message>
- <message>
- <source>S:</source>
- <translation>S:</translation>
- </message>
- <message>
- <source>Function Tests</source>
- <translation>Functionele testen</translation>
- </message>
- <message>
- <source>Send Weather</source>
- <translation>Verstuur weer</translation>
- </message>
- <message>
- <source>Update Calendar</source>
- <translation>Agenda bijwerken</translation>
- </message>
|
[-]
[+]
|
Deleted |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/translations/harbour-amazfish-ui-ru.ts
^
|
@@ -1,1192 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1">
-<context>
- <name>AddCityPage</name>
- <message>
- <source>Set Location</source>
- <translation type="unfinished">Задать местоположение</translation>
- </message>
-</context>
-<context>
- <name>Alarm</name>
- <message>
- <source>Enabled</source>
- <translation>Включено</translation>
- </message>
- <message>
- <source>Mon</source>
- <translation>Пн</translation>
- </message>
- <message>
- <source>Tue</source>
- <translation>Вт</translation>
- </message>
- <message>
- <source>Wed</source>
- <translation>Ср</translation>
- </message>
- <message>
- <source>Thu</source>
- <translation>Чт</translation>
- </message>
- <message>
- <source>Fri</source>
- <translation>Пт</translation>
- </message>
- <message>
- <source>Sat</source>
- <translation>Сб</translation>
- </message>
- <message>
- <source>Sun</source>
- <translation>Вс</translation>
- </message>
-</context>
-<context>
- <name>AnalysisPage</name>
- <message>
- <source>Analysis</source>
- <translation>Анализ</translation>
- </message>
- <message>
- <source>Heartrate</source>
- <translation>ЧСС</translation>
- </message>
- <message>
- <source>Steps</source>
- <translation>Шаги</translation>
- </message>
- <message>
- <source>Intensity</source>
- <translation>Нагрузка</translation>
- </message>
-</context>
-<context>
- <name>AuthKeyDialog</name>
- <message>
- <source>Enter auth key</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>BipFirmwarePage</name>
- <message>
- <source>Send file</source>
- <translation>Отправить файл</translation>
- </message>
- <message>
- <source>Download File</source>
- <translation>Загрузка файлов</translation>
- </message>
- <message>
- <source>Select a file to download.</source>
- <translation>Выберите файл для загрузки</translation>
- </message>
- <message>
- <source>None</source>
- <translation>Пусто</translation>
- </message>
- <message>
- <source>Choose File</source>
- <translation>Файл</translation>
- </message>
- <message>
- <source>File type/version: </source>
- <translation>Тип/версия файла: </translation>
- </message>
- <message>
- <source>File not supported on this device</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>DaemonInterface</name>
- <message>
- <source>Unexpected error</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>DebugInfo</name>
- <message>
- <source>Refresh</source>
- <translation>Обновить</translation>
- </message>
- <message>
- <source>Address: </source>
- <translation>Адрес: </translation>
- </message>
- <message>
- <source>Serial No: </source>
- <translation>Серийный №: </translation>
- </message>
- <message>
- <source>Hardware Rev: </source>
- <translation>Версия аппаратуры: </translation>
- </message>
- <message>
- <source>Software Rev: </source>
- <translation>Версия ПО: </translation>
- </message>
- <message>
- <source>Connection State: </source>
- <translation>Подключение: </translation>
- </message>
- <message>
- <source>GPS Ver: </source>
- <translation>Версия GPS: </translation>
- </message>
- <message>
- <source>Test Notification</source>
- <translation>Проверить уведомления</translation>
- </message>
- <message>
- <source>Test Email</source>
- <translation>Проверить отправку почты</translation>
- </message>
- <message>
- <source>Test Call</source>
- <translation>Проверить вызовы</translation>
- </message>
- <message>
- <source>Fetch debug log</source>
- <translation>Получить журнал отладки</translation>
- </message>
- <message>
- <source>Test Popup</source>
- <translation>Проверить всплывающие уведомления</translation>
- </message>
- <message>
- <source>Send Weather</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>A:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>S:</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Update Calendar</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Model: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Firmware Rev: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Manufacturer: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Music Control</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Debugging</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <source>Information</source>
- <translation type="unfinished"></translation>
- </message>
|
[-]
[+]
|
Deleted |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/translations/harbour-amazfish-ui-sv.ts
^
|
@@ -1,1192 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1" language="sv">
-<context>
- <name>AddCityPage</name>
- <message>
- <source>Set Location</source>
- <translation>Ange plats</translation>
- </message>
-</context>
-<context>
- <name>Alarm</name>
- <message>
- <source>Enabled</source>
- <translation>Aktiverad</translation>
- </message>
- <message>
- <source>Mon</source>
- <translation>Mån</translation>
- </message>
- <message>
- <source>Tue</source>
- <translation>Tis</translation>
- </message>
- <message>
- <source>Wed</source>
- <translation>Ons</translation>
- </message>
- <message>
- <source>Thu</source>
- <translation>Tor</translation>
- </message>
- <message>
- <source>Fri</source>
- <translation>Fre</translation>
- </message>
- <message>
- <source>Sat</source>
- <translation>Lör</translation>
- </message>
- <message>
- <source>Sun</source>
- <translation>Sön</translation>
- </message>
-</context>
-<context>
- <name>AnalysisPage</name>
- <message>
- <source>Analysis</source>
- <translation>Analys</translation>
- </message>
- <message>
- <source>Heartrate</source>
- <translation>Hjärtfrekvens</translation>
- </message>
- <message>
- <source>Steps</source>
- <translation>Steg</translation>
- </message>
- <message>
- <source>Intensity</source>
- <translation>Intensitet</translation>
- </message>
-</context>
-<context>
- <name>AuthKeyDialog</name>
- <message>
- <source>Enter auth key</source>
- <translation>Ange autentiseringsnyckel</translation>
- </message>
-</context>
-<context>
- <name>BipFirmwarePage</name>
- <message>
- <source>Send file</source>
- <translation>Skicka fil</translation>
- </message>
- <message>
- <source>Download File</source>
- <translation>Ladda ner fil</translation>
- </message>
- <message>
- <source>Select a file to download.</source>
- <translation>Välj en fil att ladda ner.</translation>
- </message>
- <message>
- <source>None</source>
- <translation>Ingen</translation>
- </message>
- <message>
- <source>Choose File</source>
- <translation>Välj fil</translation>
- </message>
- <message>
- <source>File type/version: </source>
- <translation>Filtyp/version: </translation>
- </message>
- <message>
- <source>File not supported on this device</source>
- <translation>Filformatet stöds inte på denna enhet</translation>
- </message>
-</context>
-<context>
- <name>DaemonInterface</name>
- <message>
- <source>Unexpected error</source>
- <translation>Oväntat fel</translation>
- </message>
-</context>
-<context>
- <name>DebugInfo</name>
- <message>
- <source>Refresh</source>
- <translation>Uppdatera</translation>
- </message>
- <message>
- <source>Address: </source>
- <translation>Adress: </translation>
- </message>
- <message>
- <source>Serial No: </source>
- <translation>Serienummer: </translation>
- </message>
- <message>
- <source>Hardware Rev: </source>
- <translation>Hårdvarurevision: </translation>
- </message>
- <message>
- <source>Software Rev: </source>
- <translation>Mjukvarurevision: </translation>
- </message>
- <message>
- <source>Connection State: </source>
- <translation>Anslutningsstatus: </translation>
- </message>
- <message>
- <source>GPS Ver: </source>
- <translation>GPS-version: </translation>
- </message>
- <message>
- <source>Test Notification</source>
- <translation>Testa avisering</translation>
- </message>
- <message>
- <source>Test Email</source>
- <translation>Testa e-post</translation>
- </message>
- <message>
- <source>Test Call</source>
- <translation>Testa samtal</translation>
- </message>
- <message>
- <source>Fetch debug log</source>
- <translation>Hämta felsökningslogg</translation>
- </message>
- <message>
- <source>Test Popup</source>
- <translation>Testa popup</translation>
- </message>
- <message>
- <source>Send Weather</source>
- <translation>Skicka väder</translation>
- </message>
- <message>
- <source>A:</source>
- <translation>A:</translation>
- </message>
- <message>
- <source>S:</source>
- <translation>S:</translation>
- </message>
- <message>
- <source>Update Calendar</source>
- <translation>Uppdatera kalender</translation>
- </message>
- <message>
- <source>Model: </source>
- <translation>Modell: </translation>
- </message>
- <message>
- <source>Firmware Rev: </source>
- <translation>Mjukvara: </translation>
- </message>
- <message>
- <source>Manufacturer: </source>
- <translation>Tillverkare: </translation>
- </message>
- <message>
- <source>Music Control</source>
- <translation>Musikkontroll</translation>
- </message>
- <message>
- <source>Debugging</source>
- <translation>Felsökning</translation>
- </message>
- <message>
- <source>Information</source>
- <translation>Information</translation>
- </message>
|
[-]
[+]
|
Deleted |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/translations/harbour-amazfish-ui.ts
^
|
@@ -1,1496 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<!DOCTYPE TS>
-<TS version="2.1">
-<context>
- <name>AddCityPage</name>
- <message>
- <location filename="../qml/pages/AddCityPage.qml" line="8"/>
- <source>Set Location</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>Alarm</name>
- <message>
- <location filename="../qml/components/Alarm.qml" line="34"/>
- <source>Enabled</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/components/Alarm.qml" line="92"/>
- <source>Mon</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/components/Alarm.qml" line="98"/>
- <source>Tue</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/components/Alarm.qml" line="104"/>
- <source>Wed</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/components/Alarm.qml" line="110"/>
- <source>Thu</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/components/Alarm.qml" line="116"/>
- <source>Fri</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/components/Alarm.qml" line="122"/>
- <source>Sat</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/components/Alarm.qml" line="128"/>
- <source>Sun</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>AnalysisPage</name>
- <message>
- <location filename="../qml/pages/AnalysisPage.qml" line="8"/>
- <source>Analysis</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/AnalysisPage.qml" line="40"/>
- <source>Heartrate</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/AnalysisPage.qml" line="57"/>
- <source>Steps</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/AnalysisPage.qml" line="74"/>
- <source>Intensity</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>AuthKeyDialog</name>
- <message>
- <location filename="../qml/pages/AuthKeyDialog.qml" line="18"/>
- <source>Enter auth key</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>BipFirmwarePage</name>
- <message>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="9"/>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="27"/>
- <source>None</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="7"/>
- <source>Download File</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="22"/>
- <source>Select a file to download.</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="26"/>
- <source>Choose File</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="44"/>
- <source>File type/version: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="49"/>
- <source>Send file</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/BipFirmwarePage.qml" line="53"/>
- <source>File not supported on this device</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>DaemonInterface</name>
- <message>
- <location filename="../src/daemoninterface.cpp" line="65"/>
- <source>Unexpected error</source>
- <translation type="unfinished"></translation>
- </message>
-</context>
-<context>
- <name>DebugInfo</name>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="15"/>
- <source>Refresh</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="8"/>
- <source>Debugging</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="31"/>
- <source>Information</source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="35"/>
- <source>Address: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="40"/>
- <location filename="../qml/pages/DebugInfo.qml" line="216"/>
- <source>Serial No: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="45"/>
- <location filename="../qml/pages/DebugInfo.qml" line="219"/>
- <source>Hardware Rev: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="50"/>
- <location filename="../qml/pages/DebugInfo.qml" line="222"/>
- <source>Software Rev: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="55"/>
- <location filename="../qml/pages/DebugInfo.qml" line="228"/>
- <source>Model: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="60"/>
- <location filename="../qml/pages/DebugInfo.qml" line="234"/>
- <source>Firmware Rev: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="65"/>
- <location filename="../qml/pages/DebugInfo.qml" line="231"/>
- <source>Manufacturer: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="69"/>
- <source>Connection State: </source>
- <translation type="unfinished"></translation>
- </message>
- <message>
- <location filename="../qml/pages/DebugInfo.qml" line="74"/>
- <location filename="../qml/pages/DebugInfo.qml" line="225"/>
- <source>GPS Ver: </source>
|
[-]
[+]
|
Changed |
_service:tar_git:harbour-amazfish-2.1.0.tar.bz2/ui/ui.pro
^
|
@@ -14,7 +14,7 @@
CONFIG-=qtquickcompiler
-QT += positioning KDb3 bluetooth quick
+QT += positioning KDb3 quick
LIBS += -Lqble/qble -L$$OUT_PWD/../lib -lamazfish
PKGCONFIG += mlite5
|