M module-services/service-desktop/ServiceDesktop.cpp => module-services/service-desktop/ServiceDesktop.cpp +29 -1
@@ 29,7 29,6 @@ ServiceDesktop::ServiceDesktop() : sys::Service(service::name::service_desktop,
updateOS = std::make_unique<UpdateMuditaOS>(this);
settings = std::make_unique<settings::Settings>(this);
-
}
ServiceDesktop::~ServiceDesktop()
@@ 51,6 50,10 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
else {
desktopWorker->run();
}
+
+ transferTimer = std::make_unique<sys::Timer>("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<sdesktop::developerMode::DeveloperModeRequest *>(msg);
if (request->event != nullptr) {
@@ 114,6 117,31 @@ sys::ReturnCodes ServiceDesktop::InitHandler()
return std::make_shared<sys::ResponseMessage>();
});
+ connect(sdesktop::transfer::TransferTimerState(), [&](sys::Message *msg) {
+ sdesktop::transfer::TransferTimerState *timerStateMsg =
+ dynamic_cast<sdesktop::transfer::TransferTimerState *>(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<sys::ResponseMessage>();
+ });
+
settings->registerValueChange(updateos::settings::history,
[this](const std::string &value) { updateOS->setInitialHistory(value); });
M module-services/service-desktop/WorkerDesktop.cpp => module-services/service-desktop/WorkerDesktop.cpp +45 -7
@@ 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<sys::Timer>("WorkerDesktop file upload", ownerServicePtr, sdesktop::file_transfer_timeout);
- transferTimer->connect([=](sys::Timer &) { timerHandler(); });
}
bool WorkerDesktop::init(std::list<sys::WorkerQueueInfo> 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<Command>(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>(
+ 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>(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>(
+ 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<uint32_t>(Command::CancelTransfer), .data = nullptr});
+}
+void WorkerDesktop::transferTimeoutHandler()
+{
if (getRawMode()) {
LOG_DEBUG("timeout timer: stopping transfer");
uploadFileFailedResponse();
M module-services/service-desktop/service-desktop/DesktopMessages.hpp => module-services/service-desktop/service-desktop/DesktopMessages.hpp +18 -0
@@ 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
M module-services/service-desktop/service-desktop/ServiceDesktop.hpp => module-services/service-desktop/service-desktop/ServiceDesktop.hpp +1 -0
@@ 46,6 46,7 @@ class ServiceDesktop : public sys::Service
private:
std::unique_ptr<settings::Settings> settings;
+ std::unique_ptr<sys::Timer> transferTimer;
};
namespace sys
M module-services/service-desktop/service-desktop/WorkerDesktop.hpp => module-services/service-desktop/service-desktop/WorkerDesktop.hpp +17 -3
@@ 6,6 6,7 @@
#include <string.h>
#include <stdio.h>
#include <filesystem>
+#include <atomic>
#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<sys::WorkerQueueInfo> 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<sys::Timer> transferTimer;
+ std::atomic<bool> rawModeEnabled = false;
};
M source/MessageType.hpp => source/MessageType.hpp +1 -0
@@ 211,6 211,7 @@ enum class MessageType
Restore,
Factory,
DeveloperModeRequest,
+ TransferTimer,
// FOTA messages
HttpRequest,