2022-08-22 10:35:23 +02:00
|
|
|
#include <etl/crc16_ccitt.h>
|
2022-11-04 11:08:47 +01:00
|
|
|
#include <fcntl.h> // Contains file controls like O_RDWR
|
2022-10-25 11:31:06 +02:00
|
|
|
#include <fsfw/filesystem/HasFileSystemIF.h>
|
2022-11-04 11:16:22 +01:00
|
|
|
#include <fsfw/tasks/SemaphoreFactory.h>
|
2022-11-07 10:00:54 +01:00
|
|
|
#include <linux/devices/ploc/PlocSupvUartMan.h>
|
2022-11-04 11:08:47 +01:00
|
|
|
#include <unistd.h>
|
2022-08-22 10:35:23 +02:00
|
|
|
|
2022-08-20 20:26:25 +02:00
|
|
|
#include <cmath>
|
2022-04-06 08:36:34 +02:00
|
|
|
#include <filesystem>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include "OBSWConfig.h"
|
2022-11-04 12:04:47 +01:00
|
|
|
#include "tas/hdlc.h"
|
2022-04-06 08:36:34 +02:00
|
|
|
#ifdef XIPHOS_Q7S
|
2022-09-16 11:53:33 +02:00
|
|
|
#include "bsp_q7s/fs/FilesystemHelper.h"
|
|
|
|
#include "bsp_q7s/fs/SdCardManager.h"
|
2022-04-06 08:36:34 +02:00
|
|
|
#endif
|
|
|
|
|
2022-05-13 10:47:10 +02:00
|
|
|
#include "fsfw/tasks/TaskFactory.h"
|
2022-05-13 18:37:16 +02:00
|
|
|
#include "fsfw/timemanager/Countdown.h"
|
2022-11-04 11:08:47 +01:00
|
|
|
#include "fsfw_hal/linux/uart/helper.h"
|
2022-04-14 07:52:21 +02:00
|
|
|
#include "mission/utility/Filenaming.h"
|
2022-04-16 17:19:32 +02:00
|
|
|
#include "mission/utility/ProgressPrinter.h"
|
|
|
|
#include "mission/utility/Timestamp.h"
|
2022-04-06 08:36:34 +02:00
|
|
|
|
2022-11-04 11:08:47 +01:00
|
|
|
using namespace returnvalue;
|
2022-11-07 11:19:10 +01:00
|
|
|
using namespace supv;
|
2022-11-04 11:08:47 +01:00
|
|
|
|
2022-11-04 11:38:21 +01:00
|
|
|
PlocSupvHelper::PlocSupvHelper(object_id_t objectId)
|
2022-11-04 12:45:20 +01:00
|
|
|
: SystemObject(objectId),
|
|
|
|
recRingBuf(4096, true),
|
|
|
|
ipcRingBuf(1200 * MAX_STORED_DECODED_PACKETS, true) {
|
2022-08-15 17:25:16 +02:00
|
|
|
spParams.maxSize = sizeof(commandBuffer);
|
2022-08-15 18:53:25 +02:00
|
|
|
resetSpParams();
|
2022-11-04 11:16:22 +01:00
|
|
|
semaphore = SemaphoreFactory::instance()->createBinarySemaphore();
|
|
|
|
semaphore->acquire();
|
|
|
|
lock = MutexFactory::instance()->createMutex();
|
2022-08-15 17:25:16 +02:00
|
|
|
}
|
2022-04-06 08:36:34 +02:00
|
|
|
|
2022-11-04 11:34:33 +01:00
|
|
|
PlocSupvHelper::~PlocSupvHelper() = default;
|
2022-04-06 08:36:34 +02:00
|
|
|
|
2022-11-04 11:53:07 +01:00
|
|
|
ReturnValue_t PlocSupvHelper::initializeInterface(CookieIF* cookie) {
|
|
|
|
UartCookie* uartCookie = dynamic_cast<UartCookie*>(cookie);
|
|
|
|
if (uartCookie == nullptr) {
|
|
|
|
return FAILED;
|
|
|
|
}
|
|
|
|
std::string devname = uartCookie->getDeviceFile();
|
|
|
|
/* Get file descriptor */
|
|
|
|
serialPort = open(devname.c_str(), O_RDWR);
|
|
|
|
if (serialPort < 0) {
|
|
|
|
sif::warning << "ScexUartReader::initializeInterface: open call failed with error [" << errno
|
|
|
|
<< ", " << strerror(errno) << std::endl;
|
|
|
|
return FAILED;
|
|
|
|
}
|
|
|
|
// Setting up UART parameters
|
|
|
|
tty.c_cflag &= ~PARENB; // Clear parity bit
|
|
|
|
uart::setParity(tty, uartCookie->getParity());
|
|
|
|
uart::setStopbits(tty, uartCookie->getStopBits());
|
|
|
|
uart::setBitsPerWord(tty, BitsPerWord::BITS_8);
|
|
|
|
tty.c_cflag &= ~CRTSCTS; // Disable RTS/CTS hardware flow control
|
|
|
|
uart::enableRead(tty);
|
|
|
|
uart::ignoreCtrlLines(tty);
|
|
|
|
|
|
|
|
// Use non-canonical mode and clear echo flag
|
|
|
|
tty.c_lflag &= ~(ICANON | ECHO);
|
|
|
|
|
|
|
|
// Non-blocking mode, 0.5 seconds timeout
|
|
|
|
tty.c_cc[VTIME] = 5;
|
|
|
|
tty.c_cc[VMIN] = 0;
|
|
|
|
|
|
|
|
uart::setBaudrate(tty, uartCookie->getBaudrate());
|
|
|
|
if (tcsetattr(serialPort, TCSANOW, &tty) != 0) {
|
|
|
|
sif::warning << "ScexUartReader::initializeInterface: tcsetattr call failed with error ["
|
|
|
|
<< errno << ", " << strerror(errno) << std::endl;
|
|
|
|
}
|
|
|
|
// Flush received and unread data
|
|
|
|
tcflush(serialPort, TCIOFLUSH);
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
|
2022-04-06 08:36:34 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::initialize() {
|
|
|
|
#ifdef XIPHOS_Q7S
|
|
|
|
sdcMan = SdCardManager::instance();
|
|
|
|
if (sdcMan == nullptr) {
|
|
|
|
sif::warning << "PlocSupvHelper::initialize: Invalid SD Card Manager" << std::endl;
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
#endif
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) {
|
2022-11-04 13:40:42 +01:00
|
|
|
bool putTaskToSleep = false;
|
2022-04-06 08:36:34 +02:00
|
|
|
while (true) {
|
2022-11-04 11:34:33 +01:00
|
|
|
semaphore->acquire();
|
|
|
|
while (true) {
|
2022-11-04 13:40:42 +01:00
|
|
|
putTaskToSleep = handleUartReception();
|
|
|
|
if (putTaskToSleep) {
|
2022-11-07 10:00:54 +01:00
|
|
|
performUartShutdown();
|
2022-08-22 12:08:39 +02:00
|
|
|
break;
|
2022-05-23 12:05:42 +02:00
|
|
|
}
|
2022-11-04 11:34:33 +01:00
|
|
|
lock->lockMutex();
|
2022-11-04 12:51:01 +01:00
|
|
|
InternalState currentState = state;
|
2022-11-04 11:34:33 +01:00
|
|
|
lock->unlockMutex();
|
|
|
|
switch (currentState) {
|
2022-11-07 10:00:54 +01:00
|
|
|
case InternalState::SLEEPING:
|
|
|
|
case InternalState::GO_TO_SLEEP: {
|
2022-11-04 13:40:42 +01:00
|
|
|
putTaskToSleep = true;
|
2022-04-13 11:56:37 +02:00
|
|
|
break;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
2022-11-07 10:00:54 +01:00
|
|
|
case InternalState::LONGER_REQUEST: {
|
|
|
|
if (handleRunningLongerRequest() == REQUEST_DONE) {
|
|
|
|
MutexGuard mg(lock);
|
|
|
|
state = InternalState::DEFAULT;
|
|
|
|
}
|
2022-11-04 11:34:33 +01:00
|
|
|
break;
|
|
|
|
}
|
2022-11-07 10:00:54 +01:00
|
|
|
case InternalState::DEFAULT: {
|
2022-11-04 11:34:33 +01:00
|
|
|
break;
|
|
|
|
}
|
2022-11-04 13:40:42 +01:00
|
|
|
}
|
|
|
|
if (putTaskToSleep) {
|
2022-11-07 10:00:54 +01:00
|
|
|
performUartShutdown();
|
2022-11-04 13:40:42 +01:00
|
|
|
break;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-11-04 13:40:42 +01:00
|
|
|
bool PlocSupvHelper::handleUartReception() {
|
|
|
|
ReturnValue_t result = OK;
|
|
|
|
ssize_t bytesRead = read(serialPort, reinterpret_cast<void*>(recBuf.data()),
|
|
|
|
static_cast<unsigned int>(recBuf.size()));
|
|
|
|
if (bytesRead == 0) {
|
|
|
|
{
|
|
|
|
MutexGuard mg(lock);
|
2022-11-07 10:00:54 +01:00
|
|
|
if (state == InternalState::GO_TO_SLEEP) {
|
2022-11-04 13:40:42 +01:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
while (result != NO_PACKET_FOUND) {
|
|
|
|
result = tryHdlcParsing();
|
|
|
|
}
|
|
|
|
} else if (bytesRead < 0) {
|
|
|
|
sif::warning << "PlocSupvHelper::performOperation: read call failed with error [" << errno
|
|
|
|
<< ", " << strerror(errno) << "]" << std::endl;
|
|
|
|
return true;
|
|
|
|
} else if (bytesRead >= static_cast<int>(recBuf.size())) {
|
|
|
|
sif::error << "PlocSupvHelper::performOperation: Receive buffer too small for " << bytesRead
|
|
|
|
<< " bytes" << std::endl;
|
|
|
|
} else if (bytesRead > 0) {
|
|
|
|
if (debugMode) {
|
|
|
|
sif::info << "Received " << bytesRead << " bytes from the PLOC Supervisor:" << std::endl;
|
|
|
|
}
|
|
|
|
recRingBuf.writeData(recBuf.data(), bytesRead);
|
|
|
|
tryHdlcParsing();
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
2022-04-10 18:46:39 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::setComIF(UartComIF* uartComIF_) {
|
|
|
|
if (uartComIF_ == nullptr) {
|
|
|
|
sif::warning << "PlocSupvHelper::initialize: Provided invalid uart com if" << std::endl;
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
2022-04-10 18:46:39 +02:00
|
|
|
uartComIF = uartComIF_;
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void PlocSupvHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; }
|
|
|
|
|
2022-08-20 22:52:48 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::startUpdate(std::string file, uint8_t memoryId,
|
|
|
|
uint32_t startAddress) {
|
2022-08-24 12:02:16 +02:00
|
|
|
supv::UpdateParams params;
|
|
|
|
params.file = file;
|
|
|
|
params.memId = memoryId;
|
|
|
|
params.startAddr = startAddress;
|
|
|
|
params.bytesWritten = 0;
|
|
|
|
params.seqCount = 1;
|
|
|
|
params.deleteMemory = true;
|
|
|
|
return performUpdate(params);
|
2022-08-20 22:52:48 +02:00
|
|
|
}
|
|
|
|
|
2022-08-24 12:02:16 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::performUpdate(const supv::UpdateParams& params) {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
#ifdef XIPHOS_Q7S
|
2022-08-24 12:02:16 +02:00
|
|
|
result = FilesystemHelper::checkPath(params.file);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-24 12:02:16 +02:00
|
|
|
sif::warning << "PlocSupvHelper::startUpdate: File " << params.file << " does not exist"
|
|
|
|
<< std::endl;
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
result = FilesystemHelper::fileExists(params.file);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-24 12:02:16 +02:00
|
|
|
sif::warning << "PlocSupvHelper::startUpdate: The file " << params.file << " does not exist"
|
2022-04-10 18:46:39 +02:00
|
|
|
<< std::endl;
|
2022-04-16 17:19:32 +02:00
|
|
|
return result;
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
|
|
|
#endif
|
|
|
|
#ifdef TE0720_1CFA
|
|
|
|
if (not std::filesystem::exists(file)) {
|
|
|
|
sif::warning << "PlocSupvHelper::startUpdate: The file " << file << " does not exist"
|
|
|
|
<< std::endl;
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
2022-04-06 08:36:34 +02:00
|
|
|
#endif
|
2022-08-24 12:02:16 +02:00
|
|
|
update.file = params.file;
|
2022-08-23 18:26:14 +02:00
|
|
|
update.fullFileSize = getFileSize(update.file);
|
2022-08-24 12:02:16 +02:00
|
|
|
if (params.bytesWritten > update.fullFileSize) {
|
|
|
|
sif::warning << "Invalid start bytes counter " << params.bytesWritten
|
2022-08-23 18:26:14 +02:00
|
|
|
<< ", smaller than full file length" << update.fullFileSize << std::endl;
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-08-23 18:26:14 +02:00
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
update.length = update.fullFileSize - params.bytesWritten;
|
|
|
|
update.memoryId = params.memId;
|
|
|
|
update.startAddress = params.startAddr;
|
2022-08-20 20:26:25 +02:00
|
|
|
update.progressPercent = 0;
|
2022-08-24 12:02:16 +02:00
|
|
|
update.bytesWritten = params.bytesWritten;
|
2022-08-22 13:52:39 +02:00
|
|
|
update.crcShouldBeChecked = true;
|
2022-05-23 12:05:42 +02:00
|
|
|
update.packetNum = 1;
|
2022-08-24 12:02:16 +02:00
|
|
|
update.deleteMemory = params.deleteMemory;
|
|
|
|
update.sequenceCount = params.seqCount;
|
2022-11-04 13:40:42 +01:00
|
|
|
request = Request::UPDATE;
|
2022-04-10 18:46:39 +02:00
|
|
|
uartComIF->flushUartTxAndRxBuf(comCookie);
|
2022-11-04 11:16:22 +01:00
|
|
|
semaphore->release();
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-08-22 13:50:24 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::performMemCheck(std::string file, uint8_t memoryId,
|
|
|
|
uint32_t startAddress) {
|
|
|
|
update.file = file;
|
2022-08-23 18:26:14 +02:00
|
|
|
update.fullFileSize = getFileSize(file);
|
2022-08-22 13:50:24 +02:00
|
|
|
return performMemCheck(memoryId, startAddress, getFileSize(update.file), true);
|
|
|
|
}
|
|
|
|
|
2022-08-22 12:08:39 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::performMemCheck(uint8_t memoryId, uint32_t startAddress,
|
2022-08-22 13:50:24 +02:00
|
|
|
size_t sizeToCheck, bool checkCrc) {
|
2022-08-22 12:08:39 +02:00
|
|
|
update.memoryId = memoryId;
|
|
|
|
update.startAddress = startAddress;
|
|
|
|
update.length = sizeToCheck;
|
2022-08-22 13:50:24 +02:00
|
|
|
update.crcShouldBeChecked = checkCrc;
|
2022-11-04 13:40:42 +01:00
|
|
|
request = Request::CHECK_MEMORY;
|
2022-08-22 12:08:39 +02:00
|
|
|
uartComIF->flushUartTxAndRxBuf(comCookie);
|
2022-11-04 11:16:22 +01:00
|
|
|
semaphore->release();
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-08-22 12:08:39 +02:00
|
|
|
}
|
|
|
|
|
2022-05-23 12:05:42 +02:00
|
|
|
void PlocSupvHelper::initiateUpdateContinuation() {
|
2022-11-04 13:40:42 +01:00
|
|
|
request = Request::CONTINUE_UPDATE;
|
2022-11-04 11:16:22 +01:00
|
|
|
semaphore->release();
|
2022-05-23 12:05:42 +02:00
|
|
|
}
|
|
|
|
|
2022-11-04 11:08:47 +01:00
|
|
|
ReturnValue_t PlocSupvHelper::startEventBufferRequest(std::string path) {
|
2022-04-13 11:56:37 +02:00
|
|
|
#ifdef XIPHOS_Q7S
|
|
|
|
ReturnValue_t result = FilesystemHelper::checkPath(path);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-13 11:56:37 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
if (not std::filesystem::exists(path)) {
|
|
|
|
return PATH_NOT_EXISTS;
|
|
|
|
}
|
|
|
|
eventBufferReq.path = path;
|
2022-11-04 13:40:42 +01:00
|
|
|
request = Request::REQUEST_EVENT_BUFFER;
|
2022-04-13 11:56:37 +02:00
|
|
|
uartComIF->flushUartTxAndRxBuf(comCookie);
|
2022-11-04 11:16:22 +01:00
|
|
|
semaphore->release();
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-04-13 11:56:37 +02:00
|
|
|
}
|
|
|
|
|
2022-04-06 08:36:34 +02:00
|
|
|
void PlocSupvHelper::stopProcess() { terminate = true; }
|
|
|
|
|
2022-08-22 13:50:24 +02:00
|
|
|
void PlocSupvHelper::executeFullCheckMemoryCommand() {
|
|
|
|
ReturnValue_t result;
|
|
|
|
if (update.crcShouldBeChecked) {
|
2022-08-22 22:25:22 +02:00
|
|
|
sif::info << "PLOC SUPV Mem Check: Calculating Image CRC" << std::endl;
|
2022-08-22 13:50:24 +02:00
|
|
|
result = calcImageCrc();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 13:50:24 +02:00
|
|
|
triggerEvent(SUPV_MEM_CHECK_FAIL, result);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2022-08-22 22:25:22 +02:00
|
|
|
sif::info << "PLOC SUPV Mem Check: Selecting Memory" << std::endl;
|
2022-08-22 13:50:24 +02:00
|
|
|
result = selectMemory();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 13:50:24 +02:00
|
|
|
triggerEvent(SUPV_MEM_CHECK_FAIL, result);
|
|
|
|
return;
|
|
|
|
}
|
2022-08-22 22:25:22 +02:00
|
|
|
sif::info << "PLOC SUPV Mem Check: Preparing Update" << std::endl;
|
2022-08-22 13:50:24 +02:00
|
|
|
result = prepareUpdate();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 13:50:24 +02:00
|
|
|
triggerEvent(SUPV_MEM_CHECK_FAIL, result);
|
|
|
|
return;
|
|
|
|
}
|
2022-08-22 22:25:22 +02:00
|
|
|
sif::info << "PLOC SUPV Mem Check: Memory Check" << std::endl;
|
2022-08-22 13:50:24 +02:00
|
|
|
result = handleCheckMemoryCommand();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result == returnvalue::OK) {
|
2022-08-22 13:50:24 +02:00
|
|
|
triggerEvent(SUPV_MEM_CHECK_OK, result);
|
|
|
|
} else {
|
|
|
|
triggerEvent(SUPV_MEM_CHECK_FAIL, result);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-08-24 12:02:16 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::executeUpdate() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-22 22:25:22 +02:00
|
|
|
sif::info << "PLOC SUPV Update MPSoC: Calculating Image CRC" << std::endl;
|
2022-04-19 13:33:37 +02:00
|
|
|
result = calcImageCrc();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-19 13:33:37 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-22 22:25:22 +02:00
|
|
|
sif::info << "PLOC SUPV Update MPSoC: Selecting Memory" << std::endl;
|
2022-05-23 12:05:42 +02:00
|
|
|
result = selectMemory();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-05-23 12:05:42 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-22 22:25:22 +02:00
|
|
|
sif::info << "PLOC SUPV Update MPSoC: Preparing Update" << std::endl;
|
2022-04-10 18:46:39 +02:00
|
|
|
result = prepareUpdate();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-10 18:46:39 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 15:16:46 +02:00
|
|
|
if (update.deleteMemory) {
|
2022-08-24 12:02:16 +02:00
|
|
|
sif::info << "PLOC SUPV Update MPSoC: Erasing Memory" << std::endl;
|
|
|
|
result = eraseMemory();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-24 12:02:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
2022-08-20 20:26:25 +02:00
|
|
|
return updateOperation();
|
2022-05-23 12:05:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::continueUpdate() {
|
|
|
|
ReturnValue_t result = prepareUpdate();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-05-23 12:05:42 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-20 20:26:25 +02:00
|
|
|
return updateOperation();
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::updateOperation() {
|
|
|
|
sif::info << "PlocSupvHelper::performUpdate: Writing Update Packets" << std::endl;
|
|
|
|
auto result = writeUpdatePackets();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-05-23 12:05:42 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-20 20:26:25 +02:00
|
|
|
sif::info << "PlocSupvHelper::performUpdate: Memory Check" << std::endl;
|
|
|
|
return handleCheckMemoryCommand();
|
2022-05-23 12:05:42 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::writeUpdatePackets() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-04-16 17:19:32 +02:00
|
|
|
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
2022-08-23 18:26:14 +02:00
|
|
|
ProgressPrinter progressPrinter("Supervisor update", update.fullFileSize,
|
2022-04-25 11:03:02 +02:00
|
|
|
ProgressPrinter::HALF_PERCENT);
|
2022-04-16 17:19:32 +02:00
|
|
|
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
2022-08-20 20:26:25 +02:00
|
|
|
uint8_t tempData[supv::WriteMemory::CHUNK_MAX + 1]{};
|
2022-04-06 08:36:34 +02:00
|
|
|
std::ifstream file(update.file, std::ifstream::binary);
|
2022-04-10 18:46:39 +02:00
|
|
|
uint16_t dataLength = 0;
|
2022-08-15 17:25:16 +02:00
|
|
|
ccsds::SequenceFlags seqFlags;
|
2022-08-23 18:26:14 +02:00
|
|
|
while (update.bytesWritten < update.fullFileSize) {
|
2022-04-06 08:36:34 +02:00
|
|
|
if (terminate) {
|
2022-05-04 12:49:43 +02:00
|
|
|
terminate = false;
|
2022-05-13 18:37:16 +02:00
|
|
|
triggerEvent(TERMINATED_UPDATE_PROCEDURE);
|
2022-04-10 18:46:39 +02:00
|
|
|
return PROCESS_TERMINATED;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
2022-08-23 18:26:14 +02:00
|
|
|
size_t remainingSize = update.fullFileSize - update.bytesWritten;
|
2022-08-20 22:52:48 +02:00
|
|
|
bool lastSegment = false;
|
|
|
|
if (remainingSize > supv::WriteMemory::CHUNK_MAX) {
|
2022-04-10 18:46:39 +02:00
|
|
|
dataLength = supv::WriteMemory::CHUNK_MAX;
|
2022-04-06 08:36:34 +02:00
|
|
|
} else {
|
2022-08-20 22:52:48 +02:00
|
|
|
lastSegment = true;
|
|
|
|
dataLength = static_cast<uint16_t>(remainingSize);
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
if (file.is_open()) {
|
2022-08-20 20:26:25 +02:00
|
|
|
file.seekg(update.bytesWritten, std::ios::beg);
|
2022-04-06 08:36:34 +02:00
|
|
|
file.read(reinterpret_cast<char*>(tempData), dataLength);
|
2022-04-19 13:33:37 +02:00
|
|
|
if (!file) {
|
|
|
|
sif::warning << "PlocSupvHelper::performUpdate: Read only " << file.gcount() << " of "
|
2022-04-25 11:03:02 +02:00
|
|
|
<< dataLength << " bytes" << std::endl;
|
2022-04-19 13:33:37 +02:00
|
|
|
sif::info << "PlocSupvHelper::performUpdate: Failed when trying to read byte "
|
2022-05-23 12:05:42 +02:00
|
|
|
<< update.bytesWritten << std::endl;
|
2022-04-19 13:33:37 +02:00
|
|
|
}
|
2022-04-06 08:36:34 +02:00
|
|
|
} else {
|
|
|
|
return FILE_CLOSED_ACCIDENTALLY;
|
|
|
|
}
|
2022-05-23 12:05:42 +02:00
|
|
|
if (update.bytesWritten == 0) {
|
2022-08-15 17:25:16 +02:00
|
|
|
seqFlags = ccsds::SequenceFlags::FIRST_SEGMENT;
|
2022-08-20 22:52:48 +02:00
|
|
|
} else if (lastSegment) {
|
2022-08-15 17:25:16 +02:00
|
|
|
seqFlags = ccsds::SequenceFlags::LAST_SEGMENT;
|
2022-04-10 18:46:39 +02:00
|
|
|
} else {
|
2022-08-15 17:25:16 +02:00
|
|
|
seqFlags = ccsds::SequenceFlags::CONTINUATION;
|
|
|
|
}
|
2022-08-15 18:53:25 +02:00
|
|
|
resetSpParams();
|
2022-08-23 18:26:14 +02:00
|
|
|
float progress = static_cast<float>(update.bytesWritten) / update.fullFileSize;
|
2022-08-20 22:52:48 +02:00
|
|
|
uint8_t progPercent = std::floor(progress * 100);
|
|
|
|
if (progPercent > update.progressPercent) {
|
|
|
|
update.progressPercent = progPercent;
|
|
|
|
if (progPercent % 5 == 0) {
|
|
|
|
// Useful to allow restarting the update
|
2022-08-22 12:08:39 +02:00
|
|
|
triggerEvent(SUPV_UPDATE_PROGRESS, buildProgParams1(progPercent, update.sequenceCount),
|
|
|
|
update.bytesWritten);
|
2022-08-20 22:52:48 +02:00
|
|
|
}
|
|
|
|
}
|
2022-08-15 17:25:16 +02:00
|
|
|
supv::WriteMemory packet(spParams);
|
2022-08-20 20:26:25 +02:00
|
|
|
result = packet.buildPacket(seqFlags, update.sequenceCount, update.memoryId,
|
2022-08-15 17:25:16 +02:00
|
|
|
update.startAddress + update.bytesWritten, dataLength, tempData);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 12:08:39 +02:00
|
|
|
triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount),
|
|
|
|
update.bytesWritten);
|
2022-08-15 17:25:16 +02:00
|
|
|
return result;
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
|
|
|
result = handlePacketTransmission(packet);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 12:08:39 +02:00
|
|
|
triggerEvent(WRITE_MEMORY_FAILED, buildProgParams1(progPercent, update.sequenceCount),
|
|
|
|
update.bytesWritten);
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-20 20:26:25 +02:00
|
|
|
update.sequenceCount++;
|
2022-05-23 12:05:42 +02:00
|
|
|
update.packetNum += 1;
|
|
|
|
update.bytesWritten += dataLength;
|
2022-08-20 20:26:25 +02:00
|
|
|
|
2022-04-16 17:19:32 +02:00
|
|
|
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
2022-05-23 12:05:42 +02:00
|
|
|
progressPrinter.print(update.bytesWritten);
|
2022-04-16 17:19:32 +02:00
|
|
|
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
2022-04-17 14:52:43 +02:00
|
|
|
}
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-08-22 12:08:39 +02:00
|
|
|
uint32_t PlocSupvHelper::buildProgParams1(uint8_t percent, uint16_t seqCount) {
|
|
|
|
return (static_cast<uint32_t>(percent) << 24) | static_cast<uint32_t>(seqCount);
|
|
|
|
}
|
|
|
|
|
2022-04-13 11:56:37 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::performEventBufferRequest() {
|
|
|
|
using namespace supv;
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 18:53:25 +02:00
|
|
|
resetSpParams();
|
2022-08-15 17:25:16 +02:00
|
|
|
RequestLoggingData packet(spParams);
|
|
|
|
result = packet.buildPacket(RequestLoggingData::Sa::REQUEST_EVENT_BUFFERS);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 17:25:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-13 11:56:37 +02:00
|
|
|
result = sendCommand(packet);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-13 11:56:37 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = handleAck();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-13 11:56:37 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
result =
|
|
|
|
handleTmReception(ccsds::HEADER_LEN, tmBuf.data(), supv::recv_timeout::UPDATE_STATUS_REPORT);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-13 11:56:37 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
ploc::SpTmReader spReader(tmBuf.data(), tmBuf.size());
|
|
|
|
bool exeAlreadyReceived = false;
|
|
|
|
if (spReader.getApid() == supv::APID_EXE_FAILURE) {
|
|
|
|
exeAlreadyReceived = true;
|
|
|
|
result = handleRemainingExeReport(spReader);
|
|
|
|
} else if (spReader.getApid() == supv::APID_MRAM_DUMP_TM) {
|
|
|
|
result = handleEventBufferReception(spReader);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not exeAlreadyReceived) {
|
|
|
|
result = handleExe();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-24 12:02:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::handleRemainingExeReport(ploc::SpTmReader& reader) {
|
|
|
|
size_t remBytes = reader.getPacketDataLen() + 1;
|
|
|
|
ReturnValue_t result = handleTmReception(remBytes, tmBuf.data() + ccsds::HEADER_LEN);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-24 12:02:16 +02:00
|
|
|
sif::warning << "Reading exe failure report failed" << std::endl;
|
|
|
|
}
|
|
|
|
result = exeReportHandling();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-24 12:02:16 +02:00
|
|
|
sif::warning << "Handling exe report failed" << std::endl;
|
2022-04-13 11:56:37 +02:00
|
|
|
}
|
2022-04-14 07:52:21 +02:00
|
|
|
return result;
|
2022-04-13 11:56:37 +02:00
|
|
|
}
|
|
|
|
|
2022-05-23 12:05:42 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::selectMemory() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 18:53:25 +02:00
|
|
|
resetSpParams();
|
2022-08-15 17:25:16 +02:00
|
|
|
supv::MPSoCBootSelect packet(spParams);
|
|
|
|
result = packet.buildPacket(update.memoryId);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 17:25:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-05-23 12:05:42 +02:00
|
|
|
result = handlePacketTransmission(packet);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-05-23 12:05:42 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-05-23 12:05:42 +02:00
|
|
|
}
|
|
|
|
|
2022-04-10 18:46:39 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::prepareUpdate() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 18:53:25 +02:00
|
|
|
resetSpParams();
|
2022-11-07 11:19:10 +01:00
|
|
|
supv::NoPayloadPacket packet(spParams, supv::APID_BOOT_MAN,
|
|
|
|
static_cast<uint8_t>(BootManServiceIds::PREPARE_UPDATE));
|
2022-08-15 17:25:16 +02:00
|
|
|
result = packet.buildPacket();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-20 12:11:08 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-05-12 14:04:55 +02:00
|
|
|
result = handlePacketTransmission(packet, PREPARE_UPDATE_EXECUTION_REPORT);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
|
2022-04-10 18:46:39 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::eraseMemory() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 18:53:25 +02:00
|
|
|
resetSpParams();
|
2022-08-15 17:25:16 +02:00
|
|
|
supv::EraseMemory eraseMemory(spParams);
|
2022-08-23 18:26:14 +02:00
|
|
|
result = eraseMemory.buildPacket(update.memoryId, update.startAddress + update.bytesWritten,
|
|
|
|
update.length);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 17:25:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-22 12:41:08 +02:00
|
|
|
result = handlePacketTransmission(eraseMemory, supv::recv_timeout::ERASE_MEMORY);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
|
2022-08-15 18:34:26 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::handlePacketTransmission(ploc::SpTcBase& packet,
|
2022-04-19 13:33:37 +02:00
|
|
|
uint32_t timeoutExecutionReport) {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-04-10 18:46:39 +02:00
|
|
|
result = sendCommand(packet);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = handleAck();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-19 13:33:37 +02:00
|
|
|
result = handleExe(timeoutExecutionReport);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
|
2022-08-15 18:34:26 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::sendCommand(ploc::SpTcBase& packet) {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 17:25:16 +02:00
|
|
|
rememberApid = packet.getApid();
|
|
|
|
result = uartComIF->sendMessage(comCookie, packet.getFullPacket(), packet.getFullPacketLen());
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
sif::warning << "PlocSupvHelper::sendCommand: Failed to send command" << std::endl;
|
2022-11-04 12:51:01 +01:00
|
|
|
triggerEvent(SUPV_SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(state));
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::handleAck() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 18:34:26 +02:00
|
|
|
|
|
|
|
result = handleTmReception(supv::SIZE_ACK_REPORT);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-17 14:52:43 +02:00
|
|
|
triggerEvent(ACK_RECEPTION_FAILURE, result, static_cast<uint32_t>(rememberApid));
|
2022-04-10 18:46:39 +02:00
|
|
|
sif::warning << "PlocSupvHelper::handleAck: Error in reception of acknowledgment report"
|
|
|
|
<< std::endl;
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-15 18:34:26 +02:00
|
|
|
supv::AcknowledgmentReport ackReport(tmBuf.data(), tmBuf.size());
|
2022-08-15 18:43:28 +02:00
|
|
|
result = checkReceivedTm(ackReport);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 18:34:26 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-25 11:03:02 +02:00
|
|
|
result = ackReport.checkApid();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-25 11:03:02 +02:00
|
|
|
if (result == SupvReturnValuesIF::RECEIVED_ACK_FAILURE) {
|
|
|
|
triggerEvent(SUPV_ACK_FAILURE_REPORT, static_cast<uint32_t>(ackReport.getRefApid()));
|
|
|
|
} else if (result == SupvReturnValuesIF::INVALID_APID) {
|
|
|
|
triggerEvent(SUPV_ACK_INVALID_APID, static_cast<uint32_t>(rememberApid));
|
|
|
|
}
|
|
|
|
return result;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
|
2022-04-19 13:33:37 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::handleExe(uint32_t timeout) {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 18:34:26 +02:00
|
|
|
|
2022-08-22 12:08:39 +02:00
|
|
|
result = handleTmReception(supv::SIZE_EXE_REPORT, tmBuf.data(), timeout);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-17 14:52:43 +02:00
|
|
|
triggerEvent(EXE_RECEPTION_FAILURE, result, static_cast<uint32_t>(rememberApid));
|
2022-04-10 18:46:39 +02:00
|
|
|
sif::warning << "PlocSupvHelper::handleExe: Error in reception of execution report"
|
|
|
|
<< std::endl;
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-22 12:41:08 +02:00
|
|
|
|
|
|
|
return exeReportHandling();
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::exeReportHandling() {
|
2022-08-15 18:34:26 +02:00
|
|
|
supv::ExecutionReport exeReport(tmBuf.data(), tmBuf.size());
|
2022-08-22 12:41:08 +02:00
|
|
|
|
|
|
|
ReturnValue_t result = checkReceivedTm(exeReport);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 18:34:26 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-25 11:03:02 +02:00
|
|
|
result = exeReport.checkApid();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-25 11:03:02 +02:00
|
|
|
if (result == SupvReturnValuesIF::RECEIVED_EXE_FAILURE) {
|
|
|
|
triggerEvent(SUPV_EXE_FAILURE_REPORT, static_cast<uint32_t>(exeReport.getRefApid()));
|
|
|
|
} else if (result == SupvReturnValuesIF::INVALID_APID) {
|
|
|
|
triggerEvent(SUPV_EXE_INVALID_APID, static_cast<uint32_t>(rememberApid));
|
|
|
|
}
|
|
|
|
return result;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
2022-08-22 13:50:24 +02:00
|
|
|
return result;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
|
2022-08-22 12:08:39 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::handleTmReception(size_t remainingBytes, uint8_t* readBuf,
|
|
|
|
uint32_t timeout) {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
size_t readBytes = 0;
|
|
|
|
size_t currentBytes = 0;
|
2022-04-19 13:33:37 +02:00
|
|
|
Countdown countdown(timeout);
|
2022-08-22 12:08:39 +02:00
|
|
|
if (readBuf == nullptr) {
|
|
|
|
readBuf = tmBuf.data();
|
|
|
|
}
|
2022-04-19 13:33:37 +02:00
|
|
|
while (!countdown.hasTimedOut()) {
|
2022-08-22 12:08:39 +02:00
|
|
|
result = receive(readBuf + readBytes, ¤tBytes, remainingBytes);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
readBytes += currentBytes;
|
|
|
|
remainingBytes = remainingBytes - currentBytes;
|
|
|
|
if (remainingBytes == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (remainingBytes != 0) {
|
2022-05-12 14:04:55 +02:00
|
|
|
sif::warning << "PlocSupvHelper::handleTmReception: Failed to read " << std::dec
|
2022-08-22 12:08:39 +02:00
|
|
|
<< remainingBytes << " remaining bytes" << std::endl;
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-08-15 18:43:28 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::checkReceivedTm(ploc::SpTmReader& reader) {
|
|
|
|
ReturnValue_t result = reader.checkSize();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 18:43:28 +02:00
|
|
|
triggerEvent(SUPV_REPLY_SIZE_MISSMATCH, rememberApid);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = reader.checkCrc();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 18:43:28 +02:00
|
|
|
triggerEvent(SUPV_REPLY_CRC_MISSMATCH, rememberApid);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-04-06 08:36:34 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::receive(uint8_t* data, size_t* readBytes, size_t requestBytes) {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-04-06 08:36:34 +02:00
|
|
|
uint8_t* buffer = nullptr;
|
|
|
|
result = uartComIF->requestReceiveMessage(comCookie, requestBytes);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
sif::warning << "PlocSupvHelper::receive: Failed to request reply" << std::endl;
|
2022-04-10 18:46:39 +02:00
|
|
|
triggerEvent(SUPV_HELPER_REQUESTING_REPLY_FAILED, result,
|
2022-11-04 12:51:01 +01:00
|
|
|
static_cast<uint32_t>(static_cast<uint32_t>(state)));
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-06 08:36:34 +02:00
|
|
|
sif::warning << "PlocSupvHelper::receive: Failed to read received message" << std::endl;
|
2022-11-04 12:51:01 +01:00
|
|
|
triggerEvent(SUPV_HELPER_READING_REPLY_FAILED, result, static_cast<uint32_t>(state));
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
if (*readBytes > 0) {
|
|
|
|
std::memcpy(data, buffer, *readBytes);
|
2022-05-13 18:37:16 +02:00
|
|
|
} else {
|
2022-05-13 10:47:10 +02:00
|
|
|
TaskFactory::delayTask(40);
|
|
|
|
}
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-10 18:46:39 +02:00
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::calcImageCrc() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-23 18:26:14 +02:00
|
|
|
if (update.fullFileSize == 0) {
|
2022-08-24 17:27:47 +02:00
|
|
|
return returnvalue::FAILED;
|
2022-08-22 13:50:24 +02:00
|
|
|
}
|
2022-04-10 18:46:39 +02:00
|
|
|
#ifdef XIPHOS_Q7S
|
|
|
|
result = FilesystemHelper::checkPath(update.file);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-10 18:46:39 +02:00
|
|
|
sif::warning << "PlocSupvHelper::calcImageCrc: File " << update.file << " does not exist"
|
|
|
|
<< std::endl;
|
|
|
|
return result;
|
|
|
|
}
|
2022-08-22 13:50:24 +02:00
|
|
|
#endif
|
|
|
|
|
|
|
|
auto crc16Calcer = etl::crc16_ccitt();
|
2022-04-10 18:46:39 +02:00
|
|
|
std::ifstream file(update.file, std::ifstream::binary);
|
2022-08-23 18:26:14 +02:00
|
|
|
std::array<uint8_t, 1025> crcBuf{};
|
2022-04-19 13:33:37 +02:00
|
|
|
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
2022-08-23 18:26:14 +02:00
|
|
|
ProgressPrinter progress("Supervisor update crc calculation", update.fullFileSize,
|
2022-04-25 11:03:02 +02:00
|
|
|
ProgressPrinter::ONE_PERCENT);
|
2022-04-19 13:33:37 +02:00
|
|
|
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
|
|
|
uint32_t byteCount = 0;
|
2022-08-23 18:26:14 +02:00
|
|
|
size_t bytesToRead = 1024;
|
|
|
|
while (byteCount < update.fullFileSize) {
|
|
|
|
size_t remLen = update.fullFileSize - byteCount;
|
2022-08-22 10:35:23 +02:00
|
|
|
if (remLen < 1024) {
|
|
|
|
bytesToRead = remLen;
|
2022-08-23 18:26:14 +02:00
|
|
|
} else {
|
|
|
|
bytesToRead = 1024;
|
2022-08-22 10:35:23 +02:00
|
|
|
}
|
2022-04-10 18:46:39 +02:00
|
|
|
file.seekg(byteCount, file.beg);
|
2022-08-22 10:35:23 +02:00
|
|
|
file.read(reinterpret_cast<char*>(crcBuf.data()), bytesToRead);
|
|
|
|
crc16Calcer.add(crcBuf.begin(), crcBuf.begin() + bytesToRead);
|
|
|
|
|
2022-04-19 13:33:37 +02:00
|
|
|
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
|
|
|
progress.print(byteCount);
|
|
|
|
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
2022-08-22 10:35:23 +02:00
|
|
|
byteCount += bytesToRead;
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
2022-04-19 13:33:37 +02:00
|
|
|
#if OBSW_DEBUG_PLOC_SUPERVISOR == 1
|
|
|
|
progress.print(byteCount);
|
|
|
|
#endif /* OBSW_DEBUG_PLOC_SUPERVISOR == 1 */
|
2022-08-22 10:35:23 +02:00
|
|
|
update.crc = crc16Calcer.value();
|
2022-04-10 18:46:39 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::handleCheckMemoryCommand() {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-08-15 18:53:25 +02:00
|
|
|
resetSpParams();
|
2022-08-22 12:08:39 +02:00
|
|
|
// Will hold status report for later processing
|
|
|
|
std::array<uint8_t, 32> statusReportBuf{};
|
2022-08-22 13:50:24 +02:00
|
|
|
supv::UpdateStatusReport updateStatusReport(tmBuf.data(), tmBuf.size());
|
2022-04-10 18:46:39 +02:00
|
|
|
// Verification of update write procedure
|
2022-08-15 17:25:16 +02:00
|
|
|
supv::CheckMemory packet(spParams);
|
2022-08-23 18:26:14 +02:00
|
|
|
result = packet.buildPacket(update.memoryId, update.startAddress, update.fullFileSize);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 17:25:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-10 18:46:39 +02:00
|
|
|
result = sendCommand(packet);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-10 18:46:39 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = handleAck();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-10 18:46:39 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-21 01:38:45 +02:00
|
|
|
|
2022-08-24 12:02:16 +02:00
|
|
|
bool exeAlreadyHandled = false;
|
|
|
|
uint32_t timeout = std::max(CRC_EXECUTION_TIMEOUT, supv::recv_timeout::UPDATE_STATUS_REPORT);
|
|
|
|
result = handleTmReception(ccsds::HEADER_LEN, tmBuf.data(), timeout);
|
|
|
|
ploc::SpTmReader spReader(tmBuf.data(), tmBuf.size());
|
2022-08-22 12:41:08 +02:00
|
|
|
if (spReader.getApid() == supv::APID_EXE_FAILURE) {
|
2022-08-24 12:02:16 +02:00
|
|
|
exeAlreadyHandled = true;
|
|
|
|
result = handleRemainingExeReport(spReader);
|
2022-08-22 12:41:08 +02:00
|
|
|
} else if (spReader.getApid() == supv::APID_UPDATE_STATUS_REPORT) {
|
|
|
|
size_t remBytes = spReader.getPacketDataLen() + 1;
|
2022-08-24 12:02:16 +02:00
|
|
|
result = handleTmReception(remBytes, tmBuf.data() + ccsds::HEADER_LEN,
|
|
|
|
supv::recv_timeout::UPDATE_STATUS_REPORT);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 12:41:08 +02:00
|
|
|
sif::warning
|
|
|
|
<< "PlocSupvHelper::handleCheckMemoryCommand: Failed to receive update status report"
|
|
|
|
<< std::endl;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = updateStatusReport.checkCrc();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 13:50:24 +02:00
|
|
|
sif::warning << "PlocSupvHelper::handleCheckMemoryCommand: CRC check failed" << std::endl;
|
2022-08-22 12:41:08 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-22 13:50:24 +02:00
|
|
|
// Copy into other buffer because data will be overwritten when reading execution report
|
|
|
|
std::memcpy(statusReportBuf.data(), tmBuf.data(), updateStatusReport.getNominalSize());
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
2022-08-21 01:38:45 +02:00
|
|
|
|
2022-08-24 12:02:16 +02:00
|
|
|
if (not exeAlreadyHandled) {
|
|
|
|
result = handleExe(CRC_EXECUTION_TIMEOUT);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-24 12:02:16 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
2022-08-22 12:08:39 +02:00
|
|
|
|
2022-08-21 01:38:45 +02:00
|
|
|
// Now process the status report
|
2022-08-22 13:50:24 +02:00
|
|
|
updateStatusReport.setData(statusReportBuf.data(), statusReportBuf.size());
|
2022-08-22 12:08:39 +02:00
|
|
|
result = updateStatusReport.parseDataField();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-10 18:46:39 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-22 13:50:24 +02:00
|
|
|
if (update.crcShouldBeChecked) {
|
|
|
|
result = updateStatusReport.verifycrc(update.crc);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-22 13:50:24 +02:00
|
|
|
sif::warning << "PlocSupvHelper::handleCheckMemoryCommand: CRC failure. Expected CRC 0x"
|
|
|
|
<< std::setfill('0') << std::hex << std::setw(4)
|
|
|
|
<< static_cast<uint16_t>(update.crc) << " but received CRC 0x" << std::setw(4)
|
|
|
|
<< updateStatusReport.getCrc() << std::dec << std::endl;
|
|
|
|
return result;
|
|
|
|
}
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
uint32_t PlocSupvHelper::getFileSize(std::string filename) {
|
|
|
|
std::ifstream file(filename, std::ifstream::binary);
|
|
|
|
file.seekg(0, file.end);
|
2022-04-16 17:19:32 +02:00
|
|
|
uint32_t size = file.tellg();
|
|
|
|
file.close();
|
|
|
|
return size;
|
2022-04-10 18:46:39 +02:00
|
|
|
}
|
2022-04-13 11:56:37 +02:00
|
|
|
|
2022-08-24 12:02:16 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::handleEventBufferReception(ploc::SpTmReader& reader) {
|
2022-08-24 17:27:47 +02:00
|
|
|
ReturnValue_t result = returnvalue::OK;
|
2022-10-25 11:31:06 +02:00
|
|
|
#ifdef XIPHOS_Q7S
|
|
|
|
if (not sdcMan->getActiveSdCard()) {
|
|
|
|
return HasFileSystemIF::FILESYSTEM_INACTIVE;
|
|
|
|
}
|
|
|
|
#endif
|
2022-04-16 17:19:32 +02:00
|
|
|
std::string filename = Filenaming::generateAbsoluteFilename(
|
|
|
|
eventBufferReq.path, eventBufferReq.filename, timestamping);
|
2022-04-13 11:56:37 +02:00
|
|
|
std::ofstream file(filename, std::ios_base::app | std::ios_base::out);
|
|
|
|
uint32_t packetsRead = 0;
|
2022-04-14 07:52:21 +02:00
|
|
|
size_t requestLen = 0;
|
2022-08-24 12:02:16 +02:00
|
|
|
bool firstPacket = true;
|
2022-04-14 07:52:21 +02:00
|
|
|
for (packetsRead = 0; packetsRead < NUM_EVENT_BUFFER_PACKETS; packetsRead++) {
|
2022-04-13 11:56:37 +02:00
|
|
|
if (terminate) {
|
|
|
|
triggerEvent(SUPV_EVENT_BUFFER_REQUEST_TERMINATED, packetsRead - 1);
|
|
|
|
file.close();
|
|
|
|
return PROCESS_TERMINATED;
|
|
|
|
}
|
2022-04-14 07:52:21 +02:00
|
|
|
if (packetsRead == NUM_EVENT_BUFFER_PACKETS - 1) {
|
|
|
|
requestLen = SIZE_EVENT_BUFFER_LAST_PACKET;
|
|
|
|
} else {
|
|
|
|
requestLen = SIZE_EVENT_BUFFER_FULL_PACKET;
|
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
if (firstPacket) {
|
|
|
|
firstPacket = false;
|
|
|
|
requestLen -= 6;
|
|
|
|
}
|
2022-08-15 18:34:26 +02:00
|
|
|
result = handleTmReception(requestLen);
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-04-14 07:52:21 +02:00
|
|
|
sif::debug << "PlocSupvHelper::handleEventBufferReception: Failed while trying to read packet"
|
2022-04-16 17:19:32 +02:00
|
|
|
<< " " << packetsRead + 1 << std::endl;
|
2022-04-14 07:52:21 +02:00
|
|
|
file.close();
|
2022-04-13 11:56:37 +02:00
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
ReturnValue_t result = reader.checkCrc();
|
2022-08-24 17:27:47 +02:00
|
|
|
if (result != returnvalue::OK) {
|
2022-08-15 18:34:26 +02:00
|
|
|
triggerEvent(SUPV_REPLY_CRC_MISSMATCH, rememberApid);
|
|
|
|
return result;
|
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
uint16_t apid = reader.getApid();
|
2022-04-13 11:56:37 +02:00
|
|
|
if (apid != supv::APID_MRAM_DUMP_TM) {
|
|
|
|
sif::warning << "PlocSupvHelper::handleEventBufferReception: Did not expect space packet "
|
2022-04-14 07:52:21 +02:00
|
|
|
<< "with APID 0x" << std::hex << apid << std::endl;
|
|
|
|
file.close();
|
|
|
|
return EVENT_BUFFER_REPLY_INVALID_APID;
|
2022-04-13 11:56:37 +02:00
|
|
|
}
|
2022-08-24 12:02:16 +02:00
|
|
|
file.write(reinterpret_cast<const char*>(reader.getPacketData()),
|
|
|
|
reader.getPayloadDataLength());
|
2022-04-13 11:56:37 +02:00
|
|
|
}
|
2022-04-14 07:52:21 +02:00
|
|
|
return result;
|
2022-04-13 11:56:37 +02:00
|
|
|
}
|
2022-08-15 18:53:25 +02:00
|
|
|
|
|
|
|
void PlocSupvHelper::resetSpParams() { spParams.buf = commandBuffer; }
|
2022-11-04 11:08:47 +01:00
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::sendMessage(CookieIF* cookie, const uint8_t* sendData,
|
|
|
|
size_t sendLen) {
|
2022-11-04 12:51:01 +01:00
|
|
|
if (sendData == nullptr or sendLen == 0) {
|
|
|
|
return FAILED;
|
|
|
|
}
|
|
|
|
lock->lockMutex();
|
2022-11-07 10:00:54 +01:00
|
|
|
if (state == InternalState::SLEEPING or state == InternalState::LONGER_REQUEST) {
|
2022-11-04 12:51:01 +01:00
|
|
|
lock->unlockMutex();
|
|
|
|
return FAILED;
|
|
|
|
}
|
|
|
|
lock->unlockMutex();
|
2022-11-04 13:40:42 +01:00
|
|
|
return encodeAndSendPacket(sendData, sendLen);
|
2022-11-04 11:08:47 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::getSendSuccess(CookieIF* cookie) { return returnvalue::OK; }
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::requestReceiveMessage(CookieIF* cookie, size_t requestLen) {
|
|
|
|
return returnvalue::OK;
|
|
|
|
}
|
|
|
|
|
2022-11-07 10:00:54 +01:00
|
|
|
ReturnValue_t PlocSupvHelper::handleRunningLongerRequest() {
|
2022-11-04 13:40:42 +01:00
|
|
|
ReturnValue_t result = OK;
|
|
|
|
switch (request) {
|
|
|
|
case Request::UPDATE: {
|
|
|
|
result = executeUpdate();
|
|
|
|
if (result == returnvalue::OK) {
|
|
|
|
triggerEvent(SUPV_UPDATE_SUCCESSFUL, result);
|
|
|
|
} else if (result == PROCESS_TERMINATED) {
|
|
|
|
// Event already triggered
|
|
|
|
} else {
|
|
|
|
triggerEvent(SUPV_UPDATE_FAILED, result);
|
|
|
|
}
|
2022-11-07 10:00:54 +01:00
|
|
|
break;
|
2022-11-04 13:40:42 +01:00
|
|
|
}
|
|
|
|
case Request::CHECK_MEMORY: {
|
|
|
|
executeFullCheckMemoryCommand();
|
2022-11-07 10:00:54 +01:00
|
|
|
break;
|
2022-11-04 13:40:42 +01:00
|
|
|
}
|
|
|
|
case Request::CONTINUE_UPDATE: {
|
|
|
|
result = continueUpdate();
|
|
|
|
if (result == returnvalue::OK) {
|
|
|
|
triggerEvent(SUPV_CONTINUE_UPDATE_SUCCESSFUL, result);
|
|
|
|
} else if (result == PROCESS_TERMINATED) {
|
|
|
|
// Event already triggered
|
|
|
|
} else {
|
|
|
|
triggerEvent(SUPV_CONTINUE_UPDATE_FAILED, result);
|
|
|
|
}
|
2022-11-07 10:00:54 +01:00
|
|
|
break;
|
2022-11-04 13:40:42 +01:00
|
|
|
}
|
|
|
|
case Request::REQUEST_EVENT_BUFFER: {
|
|
|
|
result = performEventBufferRequest();
|
|
|
|
if (result == returnvalue::OK) {
|
|
|
|
triggerEvent(SUPV_EVENT_BUFFER_REQUEST_SUCCESSFUL, result);
|
|
|
|
} else if (result == PROCESS_TERMINATED) {
|
|
|
|
// Event already triggered
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
triggerEvent(SUPV_EVENT_BUFFER_REQUEST_FAILED, result);
|
|
|
|
}
|
2022-11-07 10:00:54 +01:00
|
|
|
break;
|
2022-11-04 13:40:42 +01:00
|
|
|
}
|
2022-11-07 10:00:54 +01:00
|
|
|
case Request::DEFAULT: {
|
2022-11-04 13:40:42 +01:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::encodeAndSendPacket(const uint8_t* sendData, size_t sendLen) {
|
|
|
|
size_t encodedLen = 0;
|
|
|
|
hdlc_add_framing(sendData, sendLen, sendBuf.data(), &encodedLen);
|
|
|
|
size_t bytesWritten = write(serialPort, sendBuf.data(), encodedLen);
|
|
|
|
if (bytesWritten != encodedLen) {
|
|
|
|
sif::warning << "ScexUartReader::sendMessage: Sending ping command to solar experiment failed"
|
|
|
|
<< std::endl;
|
|
|
|
return FAILED;
|
|
|
|
}
|
|
|
|
return returnvalue::OK;
|
|
|
|
}
|
|
|
|
|
2022-11-04 11:08:47 +01:00
|
|
|
ReturnValue_t PlocSupvHelper::readReceivedMessage(CookieIF* cookie, uint8_t** buffer,
|
|
|
|
size_t* size) {
|
2022-11-04 12:51:01 +01:00
|
|
|
MutexGuard mg(lock);
|
|
|
|
if (ipcQueue.empty()) {
|
|
|
|
*size = 0;
|
|
|
|
return OK;
|
|
|
|
}
|
|
|
|
ipcQueue.retrieve(size);
|
|
|
|
*buffer = ipcBuffer.data();
|
|
|
|
ReturnValue_t result = ipcRingBuf.readData(ipcBuffer.data(), *size, true);
|
|
|
|
if (result != OK) {
|
2022-11-04 13:40:42 +01:00
|
|
|
sif::warning << "PlocSupvHelper::readReceivedMessage: Reading RingBuffer failed" << std::endl;
|
2022-11-04 12:51:01 +01:00
|
|
|
}
|
|
|
|
return OK;
|
2022-11-04 11:08:47 +01:00
|
|
|
}
|
2022-11-04 11:53:07 +01:00
|
|
|
|
2022-11-04 13:40:42 +01:00
|
|
|
ReturnValue_t PlocSupvHelper::tryHdlcParsing() {
|
|
|
|
size_t bytesRead = 0;
|
|
|
|
ReturnValue_t result = parseRecRingBufForHdlc(bytesRead);
|
|
|
|
if (result == returnvalue::OK) {
|
|
|
|
// Packet found, advance read pointer.
|
|
|
|
ipcRingBuf.writeData(decodedBuf.data(), bytesRead);
|
|
|
|
recRingBuf.deleteData(bytesRead);
|
|
|
|
} else if (result != NO_PACKET_FOUND) {
|
|
|
|
sif::warning << "ScexUartReader::performOperation: Possible packet loss" << std::endl;
|
|
|
|
// Markers found at wrong place
|
|
|
|
// which might be a hint for a possibly lost packet.
|
|
|
|
// Maybe trigger event?
|
|
|
|
recRingBuf.deleteData(bytesRead);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
2022-11-04 12:04:47 +01:00
|
|
|
ReturnValue_t PlocSupvHelper::parseRecRingBufForHdlc(size_t& readSize) {
|
2022-11-04 11:53:07 +01:00
|
|
|
size_t availableData = recRingBuf.getAvailableReadData();
|
|
|
|
if (availableData == 0) {
|
2022-11-04 12:04:47 +01:00
|
|
|
return NO_PACKET_FOUND;
|
2022-11-04 11:53:07 +01:00
|
|
|
}
|
2022-11-04 12:04:47 +01:00
|
|
|
if (availableData > encodedBuf.size()) {
|
|
|
|
return DECODE_BUF_TOO_SMALL;
|
2022-11-04 11:53:07 +01:00
|
|
|
}
|
|
|
|
ReturnValue_t result = recRingBuf.readData(encodedBuf.data(), availableData);
|
2022-11-04 12:04:47 +01:00
|
|
|
if (result != returnvalue::OK) {
|
|
|
|
return result;
|
2022-11-04 11:53:07 +01:00
|
|
|
}
|
|
|
|
bool startMarkerFound = false;
|
|
|
|
size_t startIdx = 0;
|
|
|
|
return returnvalue::OK;
|
2022-11-04 12:04:47 +01:00
|
|
|
for (size_t idx = 0; idx < availableData; idx++) {
|
|
|
|
// handle start marker
|
|
|
|
if (encodedBuf[idx] == HDLC_START_MARKER) {
|
|
|
|
if (not startMarkerFound) {
|
|
|
|
startMarkerFound = true;
|
|
|
|
startIdx = idx;
|
|
|
|
} else {
|
|
|
|
readSize = idx;
|
|
|
|
return POSSIBLE_PACKET_LOSS_CONSECUTIVE_START;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (encodedBuf[idx] == HDLC_END_MARKER) {
|
|
|
|
if (startMarkerFound) {
|
|
|
|
// Probably a packet, so decode it
|
2022-11-04 12:38:30 +01:00
|
|
|
size_t decodedLen = 0;
|
|
|
|
hdlc_remove_framing(encodedBuf.data() + startIdx, idx + 1, decodedBuf.data(), &decodedLen);
|
|
|
|
readSize = decodedLen;
|
|
|
|
return returnvalue::OK;
|
|
|
|
} else {
|
|
|
|
readSize = ++idx;
|
|
|
|
return POSSIBLE_PACKET_LOSS_CONSECUTIVE_END;
|
2022-11-04 12:04:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2022-11-04 12:38:30 +01:00
|
|
|
return NO_PACKET_FOUND;
|
2022-11-04 11:53:07 +01:00
|
|
|
}
|
2022-11-07 10:00:54 +01:00
|
|
|
|
|
|
|
void PlocSupvHelper::performUartShutdown() {
|
|
|
|
tcflush(serialPort, TCIOFLUSH);
|
|
|
|
state = InternalState::GO_TO_SLEEP;
|
|
|
|
}
|