2015-07-10 06:01:56 -07:00
|
|
|
/**
|
|
|
|
* @file tunerstudio_io.cpp
|
|
|
|
*
|
|
|
|
* @date Mar 8, 2015
|
2020-01-13 18:57:43 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
|
|
|
|
2021-08-03 19:05:01 -07:00
|
|
|
#include "pch.h"
|
2022-09-07 12:56:45 -07:00
|
|
|
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "tunerstudio_io.h"
|
2020-06-21 12:50:21 -07:00
|
|
|
|
2019-04-12 19:10:57 -07:00
|
|
|
#if EFI_SIMULATOR
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "rusEfiFunctionalTest.h"
|
2020-06-21 18:47:51 -07:00
|
|
|
#endif // EFI_SIMULATOR
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2021-05-17 02:44:02 -07:00
|
|
|
#if EFI_PROD_CODE || EFI_SIMULATOR
|
2021-02-19 23:11:39 -08:00
|
|
|
size_t TsChannelBase::read(uint8_t* buffer, size_t size) {
|
2021-02-19 04:40:59 -08:00
|
|
|
return readTimeout(buffer, size, SR5_READ_TIMEOUT);
|
2017-05-30 11:08:12 -07:00
|
|
|
}
|
2021-03-28 06:06:36 -07:00
|
|
|
#endif
|
2017-05-30 11:08:12 -07:00
|
|
|
|
2022-04-15 06:47:12 -07:00
|
|
|
#define isBigPacket(size) ((size) > BLOCKING_FACTOR + 7)
|
|
|
|
|
2022-04-14 19:41:46 -07:00
|
|
|
void TsChannelBase::copyAndWriteSmallCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size) {
|
2020-11-15 07:28:23 -08:00
|
|
|
// don't transmit too large a buffer
|
2023-09-05 18:28:39 -07:00
|
|
|
criticalAssertVoid(!isBigPacket(size), "copyAndWriteSmallCrcPacket tried to transmit too large a packet")
|
2020-11-15 07:28:23 -08:00
|
|
|
|
|
|
|
// If transmitting data, copy it in to place in the scratch buffer
|
|
|
|
// We want to prevent the data changing itself (higher priority threads could write
|
|
|
|
// tsOutputChannels) during the CRC computation. Instead compute the CRC on our
|
|
|
|
// local buffer that nobody else will write.
|
|
|
|
if (size) {
|
2022-07-30 09:07:36 -07:00
|
|
|
memcpy(scratchBuffer + SCRATCH_BUFFER_PREFIX_SIZE, buf, size);
|
2020-11-15 07:28:23 -08:00
|
|
|
}
|
|
|
|
|
2022-04-14 19:41:46 -07:00
|
|
|
crcAndWriteBuffer(responseCode, size);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TsChannelBase::crcAndWriteBuffer(uint8_t responseCode, size_t size) {
|
2023-09-05 18:28:39 -07:00
|
|
|
criticalAssertVoid(!isBigPacket(size), "crcAndWriteBuffer tried to transmit too large a packet")
|
2022-04-15 06:01:04 -07:00
|
|
|
|
2020-11-15 07:28:23 -08:00
|
|
|
// Index 0/1 = packet size (big endian)
|
|
|
|
*(uint16_t*)scratchBuffer = SWAP_UINT16(size + 1);
|
|
|
|
// Index 2 = response code
|
|
|
|
scratchBuffer[2] = responseCode;
|
|
|
|
|
|
|
|
// CRC is computed on the responseCode and payload but not length
|
|
|
|
uint32_t crc = crc32(&scratchBuffer[2], size + 1); // command part of CRC
|
|
|
|
|
|
|
|
// Place the CRC at the end
|
2022-07-30 09:07:36 -07:00
|
|
|
*reinterpret_cast<uint32_t*>(&scratchBuffer[size + SCRATCH_BUFFER_PREFIX_SIZE]) = SWAP_UINT32(crc);
|
2020-11-15 07:28:23 -08:00
|
|
|
|
|
|
|
// Write to the underlying stream
|
2021-10-18 16:59:08 -07:00
|
|
|
write(reinterpret_cast<uint8_t*>(scratchBuffer), size + 7, true);
|
2021-12-06 19:19:07 -08:00
|
|
|
flush();
|
2020-11-15 07:28:23 -08:00
|
|
|
}
|
|
|
|
|
2022-11-24 18:41:20 -08:00
|
|
|
uint32_t TsChannelBase::writePacketHeader(const uint8_t responseCode, const size_t size) {
|
2020-11-15 07:28:23 -08:00
|
|
|
uint8_t headerBuffer[3];
|
|
|
|
*(uint16_t*)headerBuffer = SWAP_UINT16(size + 1);
|
|
|
|
*(uint8_t*)(headerBuffer + 2) = responseCode;
|
2022-11-24 18:41:20 -08:00
|
|
|
// Write header
|
|
|
|
write(headerBuffer, sizeof(headerBuffer), /*isEndOfPacket*/false);
|
|
|
|
|
|
|
|
// Command part of CRC
|
|
|
|
return crc32((void*)(headerBuffer + 2), 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
void TsChannelBase::writeCrcPacketLarge(const uint8_t responseCode, const uint8_t* buf, const size_t size) {
|
|
|
|
uint8_t crcBuffer[4];
|
2020-11-15 07:28:23 -08:00
|
|
|
|
|
|
|
// Command part of CRC
|
2022-11-24 18:41:20 -08:00
|
|
|
uint32_t crc = writePacketHeader(responseCode, size);
|
2020-11-15 07:28:23 -08:00
|
|
|
// Data part of CRC
|
|
|
|
crc = crc32inc((void*)buf, crc, size);
|
|
|
|
*(uint32_t*)crcBuffer = SWAP_UINT32(crc);
|
|
|
|
|
|
|
|
|
|
|
|
// If data, write that
|
|
|
|
if (size) {
|
2022-10-15 22:21:44 -07:00
|
|
|
write(buf, size, /*isEndOfPacket*/false);
|
2020-11-15 07:28:23 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
// Lastly the CRC footer
|
2022-10-15 22:21:44 -07:00
|
|
|
write(crcBuffer, sizeof(crcBuffer), /*isEndOfPacket*/true);
|
2021-12-06 19:19:07 -08:00
|
|
|
flush();
|
2020-11-15 07:28:23 -08:00
|
|
|
}
|
2020-11-15 04:14:50 -08:00
|
|
|
|
2023-11-01 07:32:53 -07:00
|
|
|
TsChannelBase::TsChannelBase(const char *p_name) {
|
|
|
|
this->name = p_name;
|
2021-09-18 12:33:14 -07:00
|
|
|
}
|
|
|
|
|
2022-04-13 23:01:34 -07:00
|
|
|
void TsChannelBase::assertPacketSize(size_t size, bool allowLongPackets) {
|
|
|
|
if (isBigPacket(size) && !allowLongPackets) {
|
2023-08-20 19:23:44 -07:00
|
|
|
criticalError("[USE PROPER CONSOLE VERSION ] disallowed long packet of size %d", size);
|
2022-04-13 23:01:34 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-11-15 04:14:50 -08:00
|
|
|
/**
|
|
|
|
* Adds size to the beginning of a packet and a crc32 at the end. Then send the packet.
|
|
|
|
*/
|
2022-02-11 13:03:20 -08:00
|
|
|
void TsChannelBase::writeCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size, bool allowLongPackets) {
|
2020-11-15 07:28:23 -08:00
|
|
|
// don't transmit a null buffer...
|
|
|
|
if (!buf) {
|
|
|
|
size = 0;
|
|
|
|
}
|
2020-11-15 04:14:50 -08:00
|
|
|
|
2022-04-13 23:01:34 -07:00
|
|
|
assertPacketSize(size, allowLongPackets);
|
2022-02-11 13:03:20 -08:00
|
|
|
|
2022-04-13 23:01:34 -07:00
|
|
|
if (isBigPacket(size)) {
|
2022-02-10 20:17:42 -08:00
|
|
|
// for larger packets we do not use a buffer for CRC calculation meaning data is now allowed to modify while pending
|
2021-02-19 17:48:21 -08:00
|
|
|
writeCrcPacketLarge(responseCode, buf, size);
|
2022-02-11 13:03:20 -08:00
|
|
|
} else {
|
|
|
|
// for small packets we use a buffer for CRC calculation
|
2022-04-14 19:41:46 -07:00
|
|
|
copyAndWriteSmallCrcPacket(responseCode, buf, size);
|
2020-11-15 07:02:40 -08:00
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2022-02-11 13:03:20 -08:00
|
|
|
void TsChannelBase::sendResponse(ts_response_format_e mode, const uint8_t * buffer, int size, bool allowLongPackets /* = false */) {
|
2015-07-10 06:01:56 -07:00
|
|
|
if (mode == TS_CRC) {
|
2022-02-11 13:03:20 -08:00
|
|
|
writeCrcPacket(TS_RESPONSE_OK, buffer, size, allowLongPackets);
|
2015-07-10 06:01:56 -07:00
|
|
|
} else {
|
2020-09-11 02:50:48 -07:00
|
|
|
if (size > 0) {
|
2021-10-18 16:59:08 -07:00
|
|
|
write(buffer, size, true);
|
2021-02-19 17:48:21 -08:00
|
|
|
flush();
|
2020-09-11 02:50:48 -07:00
|
|
|
}
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
}
|