#include #include "obexconnection.h" #include "storagemanager.h" static QString generate_send_name(const QString &store, ulong checksum) { return QString("%1_%2.jsn").arg(store).arg(checksum); } StorageManager::StorageManager(ObexConnection *obex, ToqManager *toq) : QObject(toq), _obex(obex), _toq(toq) { _toq->setEndpointListener(ToqConnection::StorageServiceEndpoint, this); } void StorageManager::handleMessage(const ToqConnection::Message &msg) { Q_ASSERT(msg.destination == ToqConnection::StorageServiceEndpoint); switch (msg.type) { case 0: handleGetStoreStatusMessage(msg); break; case 1: handleGetStoreMessage(msg); break; default: qWarning() << "Unknown message type" << msg.type; break; } } void StorageManager::handleGetStoreStatusMessage(const ToqConnection::Message &msg) { QString storeName = msg.toJson().object()["store"].toString(); QJsonObject reply; if (storeName.contains('*')) { QJsonArray results; for (auto it = _stores.begin(); it != _stores.end(); ++it) { QJsonObject result; result.insert("store", it.key()); result.insert("sequence", qint64(it.value().checksum)); results.append(result); } reply.insert("result", int(0)); reply.insert("description", QString("Found all Stores")); reply.insert("stores", results); } else if (_stores.contains(storeName)) { const Store &store = _stores[storeName]; QJsonArray results; QJsonObject result; result.insert("store", storeName); result.insert("sequence", qint64(store.checksum)); results.append(result); reply.insert("result", int(0)); reply.insert("description", QString("Found the store %1").arg(storeName)); reply.insert("stores", results); } else { qWarning() << "Store" << storeName << "not found!"; reply.insert("result", int(-1)); reply.insert("description", QString("Store %1 not found").arg(storeName)); reply.insert("stores", QJsonArray()); } _toq->sendReply(msg, 0x4000, reply); } void StorageManager::handleGetStoreMessage(const ToqConnection::Message &msg) { QString storeName = msg.toJson().object()["store"].toString(); QJsonObject reply; if (_stores.contains(storeName)) { const Store &store = _stores[storeName]; reply.insert("result", int(0)); reply.insert("description", QLatin1String("Update store request received")); reply.insert("store", storeName); reply.insert("sequence", qint64(store.checksum)); reply.insert("transfer_mode", QLatin1String("OPP")); QJsonObject opp; QString filename = generate_send_name(storeName, store.checksum); opp.insert("filename", filename); opp.insert("checksum", qint64(store.checksum)); reply.insert("OPP", opp); _toq->sendReply(msg, 0x4001, reply); ObexTransfer *transfer = _obex->put(filename, store.contents); transfer->setParent(this); connect(transfer, &ObexTransfer::finished, this, &StorageManager::handleObexFinished); connect(transfer, &ObexTransfer::error, this, &StorageManager::handleObexError); } else { reply.insert("result", int(-1)); reply.insert("description", QString("Store %1 not found").arg(storeName)); _toq->sendReply(msg, 0x4001, reply); } } void StorageManager::updateStore(const QString &storeName, const QJsonObject &json) { Store& store = _stores[storeName]; QJsonDocument doc(json); QByteArray data = doc.toJson(QJsonDocument::Compact); quint32 checksum = ToqConnection::checksum(data); if (store.checksum != checksum) { store.contents = data; store.checksum = checksum; // Send updated store message if (_toq->isConnected()) { QJsonObject msg; msg.insert("store", storeName); msg.insert("sequence", qint64(checksum)); _toq->sendMessage(ToqConnection::StorageServiceEndpoint, ToqConnection::StorageServiceEndpoint + 1, 0x8000, msg); } } } void StorageManager::handleObexFinished() { ObexTransfer *transfer = static_cast(sender()); disconnect(transfer, 0, this, 0); transfer->deleteLater(); } void StorageManager::handleObexError(int resp) { ObexTransfer *transfer = static_cast(sender()); qWarning() << "Failure while updating store:" << resp; disconnect(transfer, 0, this, 0); transfer->deleteLater(); }