diff options
author | Javier <dev.git@javispedro.com> | 2015-03-28 21:06:07 +0100 |
---|---|---|
committer | Javier <dev.git@javispedro.com> | 2015-03-28 21:06:07 +0100 |
commit | 1cd1d83ee243db6f3ee929de1346c8e385b2148f (patch) | |
tree | 6943fe89c2d64e262ee0114378f8700ff8ae2c08 /saltoqd/fmsmanager.cpp | |
parent | 08d36eb82a9cc7ef9cc3efe40f26e1a732c8c602 (diff) | |
download | saltoq-1cd1d83ee243db6f3ee929de1346c8e385b2148f.tar.gz saltoq-1cd1d83ee243db6f3ee929de1346c8e385b2148f.zip |
implement fms file transfer (via bt obex push)
Diffstat (limited to 'saltoqd/fmsmanager.cpp')
-rw-r--r-- | saltoqd/fmsmanager.cpp | 157 |
1 files changed, 157 insertions, 0 deletions
diff --git a/saltoqd/fmsmanager.cpp b/saltoqd/fmsmanager.cpp new file mode 100644 index 0000000..26e147b --- /dev/null +++ b/saltoqd/fmsmanager.cpp @@ -0,0 +1,157 @@ +#include "obexconnection.h" +#include "fmsmanager.h" + +static QString generate_send_name(const QString &path, int transactionId, int checksum) +{ + Q_UNUSED(checksum); + int slash = path.lastIndexOf('/'); + int dot = path.lastIndexOf('.'); + + int start = slash >= 0 ? slash + 1 : 0; + int len = dot > start ? (path.length() - 1) - (dot + 1) : -1; + + QString base = path.mid(start, len); + QString ext; + + if (len != -1) { + ext = path.mid(dot + 1); + } + + return QString("%1_%2.%3").arg(base).arg(transactionId).arg(ext); +} + +FmsManager::FmsManager(ObexConnection *obex, ToqManager *toq) : + QObject(toq), _obex(obex), _toq(toq), + _curTransfer(0) +{ + connect(_toq, &ToqManager::disconnected, + this, &FmsManager::handleToqDisconnected); + connect(_obex, &ObexConnection::connected, + this, &FmsManager::handleObexConnected); + connect(_obex, &ObexConnection::disconnected, + this, &FmsManager::handleObexDisconnected); + + _toq->setEndpointListener(ToqConnection::FMSEndpoint, this); +} + +void FmsManager::handleMessage(const ToqConnection::Message &msg) +{ + Q_ASSERT(msg.destination == ToqConnection::FMSEndpoint); + switch (msg.type) { + case 0x4001: // Reply to file transfer + handleTransferResult(msg.payload.object()); + break; + default: + qWarning() << "Unknown message type" << msg.type; + break; + } +} + +void FmsManager::updateFile(const QString &path, const QByteArray &contents) +{ + File& file = _files[path]; + quint32 checksum = ToqConnection::checksum(contents); + file.mtime = QDateTime::currentDateTimeUtc(); + if (checksum != file.checksum) { + file.contents = contents; + file.checksum = checksum; + _pending.insert(path); + handleQueue(); + } +} + +void FmsManager::deleteFile(const QString &path) +{ + if (_files.contains(path)) { + _files.remove(path); + _pending.insert(path); + handleQueue(); + } +} + +void FmsManager::handleTransferResult(const QJsonObject &msg) +{ + if (msg["transaction_id"].toInt() != _curTransferTransactionId) { + qWarning() << "Received a result for an invalid transaction id"; + return; + } + + int result = msg["result"].toInt(); + if (result != 0) { + qWarning() << "FMS transfer file failed with result" << result; + } + + cleanCurTransfer(); + handleQueue(); +} + +void FmsManager::handleQueue() +{ + if (_pending.isEmpty()) return; + if (_curTransfer) return; + if (!_obex->isConnected()) return; + + QString path = *_pending.begin(); + _pending.remove(path); + + if (_files.contains(path)) { + File &file = _files[path]; + int transactionId = _toq->newTransactionId(); + QString name = generate_send_name(path, transactionId, file.checksum); + + QJsonObject obj; + obj.insert("sent_file_name", name); + obj.insert("file_path", path); + obj.insert("transaction_id", transactionId); + obj.insert("checksum", qint64(file.checksum)); + + _toq->sendMessage(ToqConnection::FMSEndpoint, ToqConnection::FMSEndpoint + 1, + transactionId, 1, obj); + + _curTransfer = _obex->put(name, file.contents); + _curTransferTransactionId = transactionId; + _curTransferPath = path; + + connect(_curTransfer, &ObexTransfer::error, + this, &FmsManager::handleObexError); + } else { + // TODO Remove files! + } +} + +void FmsManager::handleToqDisconnected() +{ + _pending.clear(); + if (_curTransfer) { + _curTransfer->cancel(); + cleanCurTransfer(); + } +} + +void FmsManager::handleObexConnected() +{ + handleQueue(); +} + +void FmsManager::handleObexDisconnected() +{ + // Assume it's temporary and that we will eventually reconnect +} + +void FmsManager::handleObexError(int response) +{ + Q_ASSERT(_curTransfer == sender()); + Q_UNUSED(response); + qWarning() << "OBEX error while uploading" << _curTransferPath; + cleanCurTransfer(); +} + +void FmsManager::cleanCurTransfer() +{ + if (_curTransfer) { + _curTransfer->deleteLater(); + _curTransfer = 0; + _curTransferTransactionId = 0; + _curTransferPath.clear(); + } +} |