2022-04-06 08:36:34 +02:00
|
|
|
#include "PlocSupvHelper.h"
|
|
|
|
|
|
|
|
#include <filesystem>
|
|
|
|
#include <fstream>
|
|
|
|
|
|
|
|
#include "OBSWConfig.h"
|
|
|
|
#ifdef XIPHOS_Q7S
|
|
|
|
#include "bsp_q7s/memory/FilesystemHelper.h"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "mission/utility/Timestamp.h"
|
|
|
|
|
|
|
|
PlocSupvHelper::PlocSupvHelper(object_id_t objectId) : SystemObject(objectId) {}
|
|
|
|
|
|
|
|
PlocSupvHelper::~PlocSupvHelper() {}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::initialize() {
|
|
|
|
#ifdef XIPHOS_Q7S
|
|
|
|
sdcMan = SdCardManager::instance();
|
|
|
|
if (sdcMan == nullptr) {
|
|
|
|
sif::warning << "PlocSupvHelper::initialize: Invalid SD Card Manager" << std::endl;
|
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::performOperation(uint8_t operationCode) {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
semaphore.acquire();
|
|
|
|
while (true) {
|
|
|
|
switch (internalState) {
|
|
|
|
case InternalState::IDLE: {
|
|
|
|
semaphore.acquire();
|
|
|
|
break;
|
|
|
|
}
|
2022-04-07 11:00:07 +02:00
|
|
|
case InternalState::UPDATE: {
|
2022-04-06 08:36:34 +02:00
|
|
|
result = performUpdate();
|
|
|
|
if (result == RETURN_OK) {
|
2022-04-07 11:00:07 +02:00
|
|
|
triggerEvent(SUPV_UPDATE_SUCCESSFUL);
|
2022-04-06 08:36:34 +02:00
|
|
|
} else {
|
2022-04-07 11:00:07 +02:00
|
|
|
triggerEvent(SUPV_UPDATE_FAILED);
|
2022-04-06 08:36:34 +02:00
|
|
|
}
|
|
|
|
internalState = InternalState::IDLE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
default:
|
|
|
|
sif::debug << "PlocSupvHelper::performOperation: Invalid state" << std::endl;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::setComIF(DeviceCommunicationIF* communicationInterface_) {
|
|
|
|
uartComIF = dynamic_cast<UartComIF*>(communicationInterface_);
|
|
|
|
if (uartComIF == nullptr) {
|
|
|
|
sif::warning << "PlocSupvHelper::initialize: Invalid uart com if" << std::endl;
|
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlocSupvHelper::setComCookie(CookieIF* comCookie_) { comCookie = comCookie_; }
|
|
|
|
|
2022-04-07 11:00:07 +02:00
|
|
|
ReturnValue_t PlocSupvHelper::startUpdate(std::string file, uint8_t memoryId,
|
|
|
|
uint32_t startAddress) {
|
2022-04-06 08:36:34 +02:00
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
#ifdef XIPHOS_Q7S
|
2022-04-07 11:00:07 +02:00
|
|
|
result = FilesystemHelper::checkPath(file);
|
2022-04-06 08:36:34 +02:00
|
|
|
if (result != RETURN_OK) {
|
2022-04-07 11:00:07 +02:00
|
|
|
sif::warning << "PlocSupvHelper::startUpdate: File " << file << " does not exists" << std::endl;
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
#endif
|
2022-04-07 11:00:07 +02:00
|
|
|
update.file = file;
|
|
|
|
update.memoryId = memoryId;
|
|
|
|
update.startAddress = startAddress;
|
|
|
|
internalState = InternalState::UPDATE;
|
2022-04-06 08:36:34 +02:00
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlocSupvHelper::stopProcess() { terminate = true; }
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::performUpdate() {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
result = eraseMemory();
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
uint8_t tempData[supv::UpdatePacket::MAX_UPDATE_DATA];
|
|
|
|
std::ifstream file(update.file, std::ifstream::binary);
|
|
|
|
// Set position of next character to end of file input stream
|
|
|
|
file.seekg(0, file.end);
|
|
|
|
// tellg returns position of character in input stream
|
|
|
|
size_t remainingSize = file.tellg();
|
|
|
|
size_t dataLength = 0;
|
|
|
|
size_t bytesRead = 0;
|
|
|
|
while (remainingSize > 0) {
|
|
|
|
update.startAddress = bytesRead;
|
|
|
|
if (terminate) {
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
if (remainingSize > supv::UpdatePacket::MAX_UPDATE_DATA) {
|
|
|
|
dataLength = supv::UpdatePacket::MAX_UPDATE_DATA;
|
|
|
|
} else {
|
|
|
|
dataLength = remainingSize;
|
|
|
|
}
|
|
|
|
if (file.is_open()) {
|
|
|
|
file.seekg(bytesRead, file.beg);
|
|
|
|
file.read(reinterpret_cast<char*>(tempData), dataLength);
|
|
|
|
bytesRead += dataLength;
|
|
|
|
remainingSize -= dataLength;
|
|
|
|
} else {
|
|
|
|
return FILE_CLOSED_ACCIDENTALLY;
|
|
|
|
}
|
|
|
|
supv::UpdatePacket tc(update.memoryId, update.startAddress, tempData);
|
|
|
|
result = handlePacketTransmission(tc);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::eraseMemory() {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
supv::EraseMemory eraseMemory(memoryId, startAddress, length);
|
|
|
|
result = handlePacketTransmission(eraseMemory);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::flashfclose() {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
(*sequenceCount)++;
|
|
|
|
supv::FlashFclose flashFclose(*sequenceCount);
|
|
|
|
result = flashFclose.createPacket(flashWrite.mpsocFile);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = handlePacketTransmission(flashFclose);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::handlePacketTransmission(SpacePacket& tc) {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
result = sendCommand(tc);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = handleAck();
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
result = handleExe();
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::sendCommand(supv::TcBase& tc) {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
result = uartComIF->sendMessage(comCookie, tc.getWholeData(), tc.getFullSize());
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
sif::warning << "PlocSupvHelper::sendCommand: Failed to send command" << std::endl;
|
|
|
|
triggerEvent(SENDING_COMMAND_FAILED, result, static_cast<uint32_t>(internalState));
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::handleAck() {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
supv::TmPacket tmPacket;
|
|
|
|
result = handleTmReception(&tmPacket, supv::SIZE_ACK_REPORT);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
uint16_t apid = tmPacket.getAPID();
|
|
|
|
if (apid != supv::APID_ACK_SUCCESS) {
|
|
|
|
handleAckApidFailure(apid);
|
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlocSupvHelper::handleAckApidFailure(uint16_t apid) {
|
|
|
|
if (apid == supv::APID_ACK_FAILURE) {
|
|
|
|
triggerEvent(ACK_FAILURE_REPORT, static_cast<uint32_t>(internalState));
|
|
|
|
sif::warning << "PlocSupvHelper::handleAckApidFailure: Received acknowledgement failure "
|
|
|
|
<< "report" << std::endl;
|
|
|
|
} else {
|
|
|
|
triggerEvent(ACK_INVALID_APID, apid, static_cast<uint32_t>(internalState));
|
|
|
|
sif::warning << "PlocSupvHelper::handleAckApidFailure: Expected acknowledgement report "
|
|
|
|
<< "but received space packet with apid " << std::hex << apid << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::handleExe() {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
supv::TmPacket tmPacket;
|
|
|
|
result = handleTmReception(&tmPacket, supv::SIZE_EXE_REPORT);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
uint16_t apid = tmPacket.getAPID();
|
|
|
|
if (apid != supv::apid::EXE_SUCCESS) {
|
|
|
|
handleExeApidFailure(apid);
|
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
return RETURN_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
void PlocSupvHelper::handleExeApidFailure(uint16_t apid) {
|
|
|
|
if (apid == supv::apid::EXE_FAILURE) {
|
2022-04-07 11:00:07 +02:00
|
|
|
triggerEvent(SUPV_EXE_FAILURE_REPORT, static_cast<uint32_t>(internalState));
|
2022-04-06 08:36:34 +02:00
|
|
|
sif::warning << "PlocSupvHelper::handleExeApidFailure: Received execution failure "
|
|
|
|
<< "report" << std::endl;
|
|
|
|
} else {
|
2022-04-07 11:00:07 +02:00
|
|
|
triggerEvent(SUPV_EXE_INVALID_APID, apid, static_cast<uint32_t>(internalState));
|
2022-04-06 08:36:34 +02:00
|
|
|
sif::warning << "PlocSupvHelper::handleExeApidFailure: Expected execution report "
|
|
|
|
<< "but received space packet with apid " << std::hex << apid << std::endl;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::handleTmReception(supv::TmPacket* tmPacket, size_t remainingBytes) {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
size_t readBytes = 0;
|
|
|
|
size_t currentBytes = 0;
|
|
|
|
for (int retries = 0; retries < RETRIES; retries++) {
|
|
|
|
result = receive(tmPacket->getWholeData() + readBytes, ¤tBytes, remainingBytes);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
readBytes += currentBytes;
|
|
|
|
remainingBytes = remainingBytes - currentBytes;
|
|
|
|
if (remainingBytes == 0) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (remainingBytes != 0) {
|
|
|
|
sif::warning << "PlocSupvHelper::handleTmReception: Failed to receive reply" << std::endl;
|
|
|
|
triggerEvent(MISSING_EXE, remainingBytes, static_cast<uint32_t>(internalState));
|
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
result = tmPacket->checkCrc();
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
sif::warning << "PlocSupvHelper::handleTmReception: CRC check failed" << std::endl;
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
(*sequenceCount)++;
|
|
|
|
uint16_t recvSeqCnt = tmPacket->getPacketSequenceCount();
|
|
|
|
if (recvSeqCnt != *sequenceCount) {
|
|
|
|
triggerEvent(MPSOC_HELPER_SEQ_CNT_MISMATCH, *sequenceCount, recvSeqCnt);
|
|
|
|
*sequenceCount = recvSeqCnt;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
ReturnValue_t PlocSupvHelper::receive(uint8_t* data, size_t* readBytes, size_t requestBytes) {
|
|
|
|
ReturnValue_t result = RETURN_OK;
|
|
|
|
uint8_t* buffer = nullptr;
|
|
|
|
result = uartComIF->requestReceiveMessage(comCookie, requestBytes);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
sif::warning << "PlocSupvHelper::receive: Failed to request reply" << std::endl;
|
|
|
|
triggerEvent(MPSOC_HELPER_REQUESTING_REPLY_FAILED, result,
|
|
|
|
static_cast<uint32_t>(static_cast<uint32_t>(internalState)));
|
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
result = uartComIF->readReceivedMessage(comCookie, &buffer, readBytes);
|
|
|
|
if (result != RETURN_OK) {
|
|
|
|
sif::warning << "PlocSupvHelper::receive: Failed to read received message" << std::endl;
|
|
|
|
triggerEvent(MPSOC_HELPER_READING_REPLY_FAILED, result, static_cast<uint32_t>(internalState));
|
|
|
|
return RETURN_FAILED;
|
|
|
|
}
|
|
|
|
if (*readBytes > 0) {
|
|
|
|
std::memcpy(data, buffer, *readBytes);
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|