From 042e5b69849b28df367b0540156512adc2f4ed32 Mon Sep 17 00:00:00 2001 From: Marek Niepieklo Date: Wed, 17 Feb 2021 17:09:58 +0100 Subject: [PATCH] [EGD-4625] Fix update timeout timer Moved timer handling to Service Desktop Use message comm. to update timer state --- .../service-desktop/ServiceDesktop.cpp | 30 ++++++++++- .../service-desktop/WorkerDesktop.cpp | 52 ++++++++++++++++--- .../service-desktop/DesktopMessages.hpp | 18 +++++++ .../service-desktop/ServiceDesktop.hpp | 1 + .../service-desktop/WorkerDesktop.hpp | 20 +++++-- source/MessageType.hpp | 1 + 6 files changed, 111 insertions(+), 11 deletions(-) diff --git a/module-services/service-desktop/ServiceDesktop.cpp b/module-services/service-desktop/ServiceDesktop.cpp index bb3c2558c0d48661a718ccf02d5b33f7942869aa..904982cd16d9c51356290060e3075e68780cd5d7 100644 --- a/module-services/service-desktop/ServiceDesktop.cpp +++ b/module-services/service-desktop/ServiceDesktop.cpp @@ -29,7 +29,6 @@ ServiceDesktop::ServiceDesktop() : sys::Service(service::name::service_desktop, updateOS = std::make_unique(this); settings = std::make_unique(this); - } ServiceDesktop::~ServiceDesktop() @@ -51,6 +50,10 @@ sys::ReturnCodes ServiceDesktop::InitHandler() else { desktopWorker->run(); } + + transferTimer = std::make_unique("WorkerDesktop file upload", this, sdesktop::file_transfer_timeout); + transferTimer->connect([&](sys::Timer &) { desktopWorker->cancelTransferOnTimeout(); }); + connect(sdesktop::developerMode::DeveloperModeRequest(), [&](sys::Message *msg) { auto request = static_cast(msg); if (request->event != nullptr) { @@ -114,6 +117,31 @@ sys::ReturnCodes ServiceDesktop::InitHandler() return std::make_shared(); }); + connect(sdesktop::transfer::TransferTimerState(), [&](sys::Message *msg) { + sdesktop::transfer::TransferTimerState *timerStateMsg = + dynamic_cast(msg); + + if (timerStateMsg != nullptr && timerStateMsg->messageType == MessageType::TransferTimer) { + switch (timerStateMsg->req) { + case sdesktop::transfer::TransferTimerState::Start: + transferTimer->start(); + break; + case sdesktop::transfer::TransferTimerState::Reload: + transferTimer->reload(); + break; + case sdesktop::transfer::TransferTimerState::Stop: + transferTimer->stop(); + break; + case sdesktop::transfer::TransferTimerState::None: + [[fallthrough]]; + default: + LOG_DEBUG("ServiceDesktop::SetTransferTimerState unhandled req:%u", timerStateMsg->req); + break; + } + } + return std::make_shared(); + }); + settings->registerValueChange(updateos::settings::history, [this](const std::string &value) { updateOS->setInitialHistory(value); }); diff --git a/module-services/service-desktop/WorkerDesktop.cpp b/module-services/service-desktop/WorkerDesktop.cpp index 5d7147badff9a9e89542153ed57bdbe400f837a1..162100e1cb705be79013bce73b175be4fa515231 100644 --- a/module-services/service-desktop/WorkerDesktop.cpp +++ b/module-services/service-desktop/WorkerDesktop.cpp @@ -3,6 +3,7 @@ #include "service-desktop/ServiceDesktop.hpp" #include "service-desktop/WorkerDesktop.hpp" +#include "service-desktop/DesktopMessages.hpp" #include "parser/MessageHandler.hpp" #include "parser/ParserFSM.hpp" #include "endpoints/Context.hpp" @@ -20,9 +21,6 @@ inline constexpr auto uploadFailedMessage = "file upload terminated before all d WorkerDesktop::WorkerDesktop(sys::Service *ownerServicePtr) : sys::Worker(ownerServicePtr), ownerService(ownerServicePtr), parser(ownerServicePtr), fileDes(nullptr) { - transferTimer = - std::make_unique("WorkerDesktop file upload", ownerServicePtr, sdesktop::file_transfer_timeout); - transferTimer->connect([=](sys::Timer &) { timerHandler(); }); } bool WorkerDesktop::init(std::list queues) @@ -77,6 +75,22 @@ bool WorkerDesktop::handleMessage(uint32_t queueID) bsp::usbCDCSend(sendMsg); delete sendMsg; } + else if (qname == SERVICE_QUEUE_NAME) { + auto &serviceQueue = getServiceQueue(); + sys::WorkerCommand cmd; + + if (serviceQueue.Dequeue(&cmd, 0)) { + switch (static_cast(cmd.command)) { + case Command::CancelTransfer: + transferTimeoutHandler(); + break; + } + } + else { + LOG_ERROR("handleMessage xQueueReceive failed for %s.", SERVICE_QUEUE_NAME.c_str()); + return false; + } + } else { LOG_INFO("handeMessage got message on an unhandled queue"); } @@ -95,7 +109,7 @@ sys::ReturnCodes WorkerDesktop::startDownload(const std::filesystem::path &desti if (fileSize <= 0) return sys::ReturnCodes::Failure; - transferTimer->start(); + startTransferTimer(); writeFileSizeExpected = fileSize; rawModeEnabled = true; @@ -104,6 +118,26 @@ sys::ReturnCodes WorkerDesktop::startDownload(const std::filesystem::path &desti return sys::ReturnCodes::Success; } +void WorkerDesktop::startTransferTimer() +{ + auto msg = std::make_shared( + sdesktop::transfer::TransferTimerState::Request::Start); + ownerService->bus.sendUnicast(std::move(msg), service::name::service_desktop); +} + +void WorkerDesktop::stopTransferTimer() +{ + auto msg = + std::make_shared(sdesktop::transfer::TransferTimerState::Request::Stop); + ownerService->bus.sendUnicast(std::move(msg), service::name::service_desktop); +} +void WorkerDesktop::reloadTransferTimer() +{ + auto msg = std::make_shared( + sdesktop::transfer::TransferTimerState::Request::Reload); + ownerService->bus.sendUnicast(std::move(msg), service::name::service_desktop); +} + void WorkerDesktop::stopTransfer(const TransferFailAction action) { LOG_DEBUG("stopTransfer %s", @@ -124,7 +158,7 @@ void WorkerDesktop::stopTransfer(const TransferFailAction action) fclose(fileDes); // stop the timeout timer - transferTimer->stop(); + stopTransferTimer(); // reset all counters writeFileSizeExpected = 0; @@ -142,7 +176,7 @@ void WorkerDesktop::stopTransfer(const TransferFailAction action) void WorkerDesktop::rawDataReceived(void *dataPtr, uint32_t dataLen) { if (getRawMode()) { - transferTimer->reload(); + reloadTransferTimer(); if (dataPtr == nullptr || dataLen == 0) { LOG_ERROR("transferDataReceived invalid data"); @@ -170,10 +204,14 @@ void WorkerDesktop::rawDataReceived(void *dataPtr, uint32_t dataLen) } } -void WorkerDesktop::timerHandler() +void WorkerDesktop::cancelTransferOnTimeout() { LOG_DEBUG("timeout timer: run"); + sendCommand({.command = static_cast(Command::CancelTransfer), .data = nullptr}); +} +void WorkerDesktop::transferTimeoutHandler() +{ if (getRawMode()) { LOG_DEBUG("timeout timer: stopping transfer"); uploadFileFailedResponse(); diff --git a/module-services/service-desktop/service-desktop/DesktopMessages.hpp b/module-services/service-desktop/service-desktop/DesktopMessages.hpp index 2f63f93e805991073de59eb185a3ffd927451ac4..465a4fe08c9b20bb9e27056137065488ce1e6e09 100644 --- a/module-services/service-desktop/service-desktop/DesktopMessages.hpp +++ b/module-services/service-desktop/service-desktop/DesktopMessages.hpp @@ -143,4 +143,22 @@ namespace sdesktop }; } // namespace bluetooth + + namespace transfer + { + class TransferTimerState : public sys::DataMessage + { + public: + enum Request + { + None, + Start, + Reload, + Stop + }; + enum Request req = Request::None; + TransferTimerState(enum Request req = None) : sys::DataMessage(MessageType::TransferTimer), req(req){}; + ~TransferTimerState() override = default; + }; + } // namespace transfer } // namespace sdesktop diff --git a/module-services/service-desktop/service-desktop/ServiceDesktop.hpp b/module-services/service-desktop/service-desktop/ServiceDesktop.hpp index f830fce4d5a709db721bf673a6f73197e3abf827..c4ef36ec61c37b5fb0050546da2603cb83559384 100644 --- a/module-services/service-desktop/service-desktop/ServiceDesktop.hpp +++ b/module-services/service-desktop/service-desktop/ServiceDesktop.hpp @@ -46,6 +46,7 @@ class ServiceDesktop : public sys::Service private: std::unique_ptr settings; + std::unique_ptr transferTimer; }; namespace sys diff --git a/module-services/service-desktop/service-desktop/WorkerDesktop.hpp b/module-services/service-desktop/service-desktop/WorkerDesktop.hpp index baaeaad781f0b8e790266a0ce615996d9672a454..fc92d709c09fb868a3d82fff70c00e0cf8afa5cb 100644 --- a/module-services/service-desktop/service-desktop/WorkerDesktop.hpp +++ b/module-services/service-desktop/service-desktop/WorkerDesktop.hpp @@ -6,6 +6,7 @@ #include #include #include +#include #include "Service/Message.hpp" #include "Service/Service.hpp" #include "Service/Worker.hpp" @@ -21,6 +22,10 @@ class WorkerDesktop : public sys::Worker, public bsp::USBDeviceListener doNothing, removeDesitnationFile }; + enum class Command + { + CancelTransfer, + }; WorkerDesktop(sys::Service *ownerServicePtr); virtual bool init(std::list queues) override; @@ -34,21 +39,30 @@ class WorkerDesktop : public sys::Worker, public bsp::USBDeviceListener { return receiveQueue; } + sys::ReturnCodes startDownload(const std::filesystem::path &destinationPath, const uint32_t fileSize); void stopTransfer(const TransferFailAction action); - void timerHandler(void); + void cancelTransferOnTimeout(); void rawDataReceived(void *dataPtr, uint32_t dataLen) override; bool getRawMode() const noexcept override; private: void uploadFileFailedResponse(); + + void transferTimeoutHandler(); + + void startTransferTimer(); + void stopTransferTimer(); + void reloadTransferTimer(); + + bool stateChangeWait(); + xQueueHandle receiveQueue; FILE *fileDes = nullptr; uint32_t writeFileSizeExpected = 0; uint32_t writeFileDataWritten = 0; std::filesystem::path filePath; - volatile bool rawModeEnabled = false; - std::unique_ptr transferTimer; + std::atomic rawModeEnabled = false; }; diff --git a/source/MessageType.hpp b/source/MessageType.hpp index 43e0046311126dd9bcd473c444673be2fe71ea60..d9be7c42a22e79a1590e40a500086e4e8220ac77 100644 --- a/source/MessageType.hpp +++ b/source/MessageType.hpp @@ -211,6 +211,7 @@ enum class MessageType Restore, Factory, DeveloperModeRequest, + TransferTimer, // FOTA messages HttpRequest,