Robin Mueller
b03e53b6e9
All checks were successful
EIVE/eive-obsw/pipeline/pr-main This commit looks good
73 lines
2.7 KiB
C++
73 lines
2.7 KiB
C++
#include "MpsocCommunication.h"
|
|
|
|
#include "fsfw/globalfunctions/CRC.h"
|
|
#include "fsfw/returnvalues/returnvalue.h"
|
|
#include "fsfw/tmtcpacket/ccsds/SpacePacketReader.h"
|
|
#include "fsfw/tmtcpacket/ccsds/header.h"
|
|
#include "linux/payload/plocMpsocHelpers.h"
|
|
#include "unistd.h"
|
|
|
|
MpsocCommunication::MpsocCommunication(object_id_t objectId, SerialConfig cfg)
|
|
: SystemObject(objectId), readRingBuf(4096, true), helper(cfg) {}
|
|
|
|
ReturnValue_t MpsocCommunication::initialize() { return helper.initialize(); }
|
|
|
|
ReturnValue_t MpsocCommunication::send(const uint8_t* data, size_t dataLen) {
|
|
return helper.send(data, dataLen);
|
|
}
|
|
|
|
ReturnValue_t MpsocCommunication::parseAndRetrieveNextPacket() {
|
|
// We do not have a data link layer, so this whole thing is a mess in any case..
|
|
// But basically, we try to parse space packets from the internal ring buffer and trasnfer
|
|
// them to the higher level device handler. The CRC check is performed here as well, with
|
|
// few other ways to detect if we even have a valid packet.
|
|
size_t availableReadData = readRingBuf.getAvailableReadData();
|
|
// Minimum valid size for a space packet header.
|
|
if (availableReadData < ccsds::HEADER_LEN + 1) {
|
|
return returnvalue::OK;
|
|
}
|
|
readRingBuf.readData(readBuf, availableReadData);
|
|
spReader.setReadOnlyData(readBuf, availableReadData);
|
|
auto res = spReader.checkSize();
|
|
if (res != returnvalue::OK) {
|
|
return res;
|
|
}
|
|
// The packet might be garbage, with no way to recover without a data link layer.
|
|
if (spReader.getFullPacketLen() > 4096) {
|
|
readRingBuf.clear();
|
|
// TODO: Maybe we should also clear the serial input buffer in Linux?
|
|
return FAULTY_PACKET_SIZE;
|
|
}
|
|
if (availableReadData < spReader.getFullPacketLen()) {
|
|
// Might be split packet where the rest still has to be read.
|
|
return returnvalue::OK;
|
|
}
|
|
if (CRC::crc16ccitt(readBuf, spReader.getFullPacketLen()) != 0) {
|
|
// Possibly invalid packet. We can not even trust the detected packet length.
|
|
// Just clear the whole read buffer as well.
|
|
readRingBuf.clear();
|
|
triggerEvent(mpsoc::CRC_FAILURE);
|
|
return CRC_CHECK_FAILED;
|
|
}
|
|
readRingBuf.deleteData(spReader.getFullPacketLen());
|
|
return PACKET_RECEIVED;
|
|
}
|
|
|
|
ReturnValue_t MpsocCommunication::readSerialInterface() {
|
|
int bytesRead = read(helper.rawFd(), readBuf, sizeof(readBuf));
|
|
if (bytesRead < 0) {
|
|
return returnvalue::FAILED;
|
|
}
|
|
if (bytesRead > 0) {
|
|
if (MPSOC_LOW_LEVEL_RX_WIRETAPPING) {
|
|
sif::debug << "Read " << bytesRead << " bytes on the MPSoC interface" << std::endl;
|
|
}
|
|
return readRingBuf.writeData(readBuf, bytesRead);
|
|
}
|
|
return returnvalue::OK;
|
|
}
|
|
|
|
const SpacePacketReader& MpsocCommunication::getSpReader() const { return spReader; }
|
|
|
|
SerialCommunicationHelper& MpsocCommunication::getComHelper() { return helper; }
|