rusefi-1/firmware/console/binary/tunerstudio_io.cpp

109 lines
2.9 KiB
C++
Raw Normal View History

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
*/
#include "pch.h"
#include "os_access.h"
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
#if EFI_PROD_CODE || EFI_SIMULATOR
size_t TsChannelBase::read(uint8_t* buffer, size_t size) {
return readTimeout(buffer, size, SR5_READ_TIMEOUT);
2017-05-30 11:08:12 -07:00
}
#endif
2017-05-30 11:08:12 -07:00
void TsChannelBase::writeCrcPacketSmall(uint8_t responseCode, const uint8_t* buf, size_t size) {
auto scratchBuffer = this->scratchBuffer;
// don't transmit too large a buffer
efiAssertVoid(OBD_PCM_Processor_Fault, size <= BLOCKING_FACTOR + 7, "writeCrcPacketSmall tried to transmit too large a packet")
// 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) {
memcpy(scratchBuffer + 3, buf, size);
}
// 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
*reinterpret_cast<uint32_t*>(&scratchBuffer[size + 3]) = SWAP_UINT32(crc);
// Write to the underlying stream
write(reinterpret_cast<uint8_t*>(scratchBuffer), size + 7, true);
flush();
}
void TsChannelBase::writeCrcPacketLarge(uint8_t responseCode, const uint8_t* buf, size_t size) {
uint8_t headerBuffer[3];
uint8_t crcBuffer[4];
*(uint16_t*)headerBuffer = SWAP_UINT16(size + 1);
*(uint8_t*)(headerBuffer + 2) = responseCode;
// Command part of CRC
uint32_t crc = crc32((void*)(headerBuffer + 2), 1);
// Data part of CRC
crc = crc32inc((void*)buf, crc, size);
*(uint32_t*)crcBuffer = SWAP_UINT32(crc);
// Write header
write(headerBuffer, sizeof(headerBuffer), false);
// If data, write that
if (size) {
write(buf, size, false);
}
// Lastly the CRC footer
write(crcBuffer, sizeof(crcBuffer), true);
flush();
}
TsChannelBase::TsChannelBase(const char *name) {
this->name = name;
}
/**
* Adds size to the beginning of a packet and a crc32 at the end. Then send the packet.
*/
void TsChannelBase::writeCrcPacket(uint8_t responseCode, const uint8_t* buf, size_t size) {
// don't transmit a null buffer...
if (!buf) {
size = 0;
}
if (size <= BLOCKING_FACTOR + 7) {
// small packets use small packet optimization
writeCrcPacketSmall(responseCode, buf, size);
} else {
writeCrcPacketLarge(responseCode, buf, size);
}
2015-07-10 06:01:56 -07:00
}
void TsChannelBase::sendResponse(ts_response_format_e mode, const uint8_t * buffer, int size) {
2015-07-10 06:01:56 -07:00
if (mode == TS_CRC) {
writeCrcPacket(TS_RESPONSE_OK, buffer, size);
2015-07-10 06:01:56 -07:00
} else {
2020-09-11 02:50:48 -07:00
if (size > 0) {
write(buffer, size, true);
flush();
2020-09-11 02:50:48 -07:00
}
2015-07-10 06:01:56 -07:00
}
}