remove TS file read (#3004)
* remove * more defines * test * lots of java * s
This commit is contained in:
parent
1ddf2e2226
commit
0f0b84a6db
|
@ -431,8 +431,6 @@ static bool isKnownCommand(char command) {
|
|||
|| command == TS_GET_FIRMWARE_VERSION
|
||||
|| command == TS_PERF_TRACE_BEGIN
|
||||
|| command == TS_PERF_TRACE_GET_BUFFER
|
||||
|| command == TS_SD_R_COMMAND
|
||||
|| command == TS_SD_W_COMMAND
|
||||
|| command == TS_GET_CONFIG_ERROR;
|
||||
}
|
||||
|
||||
|
@ -713,15 +711,6 @@ int TunerStudioBase::handleCrcCommand(TsChannelBase* tsChannel, char *data, int
|
|||
case TS_GET_FIRMWARE_VERSION:
|
||||
handleGetVersion(tsChannel);
|
||||
break;
|
||||
#if (EFI_FILE_LOGGING && !HAL_USE_USB_MSD) || EFI_SIMULATOR
|
||||
// This is only enabled on ECUs without USB mass storage
|
||||
case TS_SD_R_COMMAND:
|
||||
handleTsR(tsChannel, data);
|
||||
break;
|
||||
case TS_SD_W_COMMAND:
|
||||
handleTsW(tsChannel, data);
|
||||
break;
|
||||
#endif // (EFI_FILE_LOGGING && !HAL_USE_USB_MSD)
|
||||
#if EFI_TEXT_LOGGING
|
||||
case TS_GET_TEXT:
|
||||
handleGetText(tsChannel);
|
||||
|
|
|
@ -23,7 +23,6 @@ HW_LAYER_EMS_CPP = \
|
|||
$(PROJECT_DIR)/hw_layer/hardware.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/smart_gpio.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/mmc_card.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/mmc_card_access.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/adc/adc_inputs.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/adc/adc_subscription.cpp \
|
||||
$(PROJECT_DIR)/hw_layer/adc/ads1015.cpp \
|
||||
|
|
|
@ -14,16 +14,10 @@
|
|||
|
||||
#define DOT_MLG ".mlg"
|
||||
|
||||
bool isLogFile(const char *fileName);
|
||||
void initEarlyMmcCard();
|
||||
void initMmcCard();
|
||||
bool isSdCardAlive(void);
|
||||
|
||||
void readLogFileContent(char *buffer, short fileId, short offset, short length);
|
||||
|
||||
void handleTsR(TsChannelBase* tsChannel, char *input);
|
||||
void handleTsW(TsChannelBase* tsChannel, char *input);
|
||||
|
||||
extern "C"
|
||||
#endif
|
||||
void onUsbConnectedNotifyMmcI(void);
|
||||
|
|
|
@ -1,366 +0,0 @@
|
|||
/**
|
||||
* @file mmc_card_access.cpp
|
||||
*
|
||||
*
|
||||
* Here we have code related to file transfer from rusEFI ECU to desktop
|
||||
* We are mostly compatible with TS MS3 transder protocol as described at Megasquirt_Serial_Protocol-2014-10-28.pdf
|
||||
* rusEFI simulator reads local files.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "engine.h"
|
||||
|
||||
#if EFI_SIMULATOR
|
||||
#include <stdio.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#if EFI_FILE_LOGGING
|
||||
#include "ff.h"
|
||||
#define ROOT_DIR "/"
|
||||
#endif // EFI_FILE_LOGGING
|
||||
|
||||
#define DIR_RESPONSE_SIZE 512
|
||||
#define DIR_ENTRY_SIZE 32
|
||||
|
||||
#define DIR_RESPONSE_BUFFER_SIZE (DIR_RESPONSE_SIZE + 2)
|
||||
|
||||
#define DOT '.'
|
||||
|
||||
#if EFI_FILE_LOGGING || EFI_SIMULATOR || EFI_UNIT_TEST
|
||||
|
||||
#include "mmc_card.h"
|
||||
#include "efilib.h"
|
||||
#include "hardware.h"
|
||||
|
||||
/**
|
||||
* for funny reasons file name has to be at least 4 symbols before the dot
|
||||
*/
|
||||
bool isLogFile(const char *fileName) {
|
||||
int dotIndex = indexOf(fileName, DOT);
|
||||
if (dotIndex == -1) {
|
||||
return false;
|
||||
}
|
||||
if (dotIndex < 4) {
|
||||
return false;
|
||||
}
|
||||
return 0 == strncmp(fileName + dotIndex, DOT_MLG, 4);
|
||||
}
|
||||
#endif // EFI_FILE_LOGGING || EFI_SIMULATOR || EFI_UNIT_TEST
|
||||
|
||||
// Enable when logging is enabled, but not USB mass storage
|
||||
#if (EFI_FILE_LOGGING && !HAL_USE_USB_MSD) || EFI_SIMULATOR
|
||||
#include "mmc_card.h"
|
||||
|
||||
#if EFI_SIMULATOR
|
||||
static FILE *uploading;
|
||||
#endif // EFI_SIMULATOR
|
||||
|
||||
#if EFI_FILE_LOGGING
|
||||
static FIL uploading NO_CACHE;
|
||||
#endif // EFI_FILE_LOGGING
|
||||
|
||||
#define TRANSFER_SIZE 2048
|
||||
|
||||
static uint8_t buffer[TRANSFER_SIZE + 2];
|
||||
|
||||
static void setFileEntry(uint8_t *buffer, int index, const char *fileName,
|
||||
int fileSize) {
|
||||
int offset = 32 * index;
|
||||
|
||||
int dotIndex = indexOf(fileName, DOT);
|
||||
// assert dotIndex != -1
|
||||
memcpy(buffer + offset, fileName, dotIndex);
|
||||
for (int i = dotIndex; i < 8; i++) {
|
||||
buffer[offset + i] = 0;
|
||||
}
|
||||
memcpy(buffer + offset + 8, &fileName[dotIndex + 1], 3);
|
||||
|
||||
buffer[offset + 11] = 1;
|
||||
|
||||
for (int i = 0; i < 4; i++) {
|
||||
buffer[offset + 18 + i] = fileName[dotIndex + i - 4];
|
||||
}
|
||||
|
||||
*(uint32_t*) (&buffer[offset + 28]) = fileSize;
|
||||
}
|
||||
|
||||
void handleTsR(TsChannelBase* tsChannel, char *input) {
|
||||
#if EFI_SIMULATOR
|
||||
printf("TS_SD r %d\n", input[1]);
|
||||
#endif // EFI_SIMULATOR
|
||||
|
||||
const uint16_t *data16 = reinterpret_cast<uint16_t*>(input);
|
||||
|
||||
if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_RTC) {
|
||||
efiPrintf("TS_SD: RTC read command");
|
||||
memset(buffer, 0, 9);
|
||||
tsChannel->sendResponse(TS_CRC, buffer, 9);
|
||||
|
||||
} else if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_FETCH_INFO) {
|
||||
uint16_t length = SWAP_UINT16(data16[2]);
|
||||
efiPrintf("TS_SD: fetch buffer command, length=%d",
|
||||
length);
|
||||
|
||||
if (length == 16) {
|
||||
buffer[0] = 1 + 4; // Card present + Ready
|
||||
buffer[1] = 0; // Y - error code
|
||||
|
||||
buffer[2] = 2; // higher byte of '512' sector size
|
||||
buffer[3] = 0; // lower byte
|
||||
|
||||
buffer[4] = 0;
|
||||
buffer[5] = 0x20; // 0x20 00 00 of 512 is 1G virtual card
|
||||
buffer[6] = 0;
|
||||
buffer[7] = 0;
|
||||
|
||||
buffer[8] = 0;
|
||||
buffer[9] = 1; // number of files
|
||||
|
||||
tsChannel->sendResponse(TS_CRC, buffer, 16);
|
||||
} else if (length == DIR_RESPONSE_BUFFER_SIZE) {
|
||||
// SD read directory command
|
||||
memset(buffer, 0, DIR_RESPONSE_BUFFER_SIZE);
|
||||
|
||||
#if EFI_SIMULATOR
|
||||
DIR *dr = opendir(".");
|
||||
if (dr == NULL) {
|
||||
// opendir returns NULL if couldn't open directory
|
||||
printf("Could not open current directory" );
|
||||
return;
|
||||
}
|
||||
|
||||
int index = 0;
|
||||
struct dirent *de; // Pointer for directory entry
|
||||
while ((de = readdir(dr)) != NULL) {
|
||||
const char * fileName = de->d_name;
|
||||
printf("%s\n", fileName);
|
||||
if (index >= DIR_RESPONSE_SIZE / DIR_ENTRY_SIZE) {
|
||||
break;
|
||||
}
|
||||
if (isLogFile(fileName)) {
|
||||
struct stat statBuffer;
|
||||
int status;
|
||||
|
||||
int fileSize = 0;
|
||||
status = stat(fileName, &statBuffer);
|
||||
if (status == 0) {
|
||||
fileSize = statBuffer.st_size;
|
||||
}
|
||||
setFileEntry(buffer, index, fileName, fileSize);
|
||||
index++;
|
||||
}
|
||||
}
|
||||
closedir(dr);
|
||||
|
||||
#endif // EFI_SIMULATOR
|
||||
|
||||
#if EFI_FILE_LOGGING
|
||||
DIR dir;
|
||||
FRESULT res = f_opendir(&dir, ROOT_DIR);
|
||||
if (res != FR_OK) {
|
||||
efiPrintf("Error opening directory");
|
||||
} else {
|
||||
int index = 0;
|
||||
while (true) {
|
||||
if (index >= DIR_RESPONSE_SIZE / DIR_ENTRY_SIZE) {
|
||||
break;
|
||||
}
|
||||
FILINFO fno;
|
||||
res = f_readdir(&dir, &fno);
|
||||
char *fileName = fno.fname;
|
||||
if (res != FR_OK || fileName[0] == 0) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (isLogFile(fileName)) {
|
||||
// struct stat statBuffer;
|
||||
// int status;
|
||||
//
|
||||
// int fileSize = 0;
|
||||
// status = stat(fileName, &statBuffer);
|
||||
// if (status == 0) {
|
||||
// fileSize = statBuffer.st_size;
|
||||
// }
|
||||
|
||||
FILINFO fileInfo;
|
||||
// todo: handle return value?
|
||||
f_stat(fileName, &fileInfo);
|
||||
|
||||
setFileEntry(buffer, index, fileName,
|
||||
(int) fileInfo.fsize);
|
||||
index++;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EFI_FILE_LOGGING
|
||||
|
||||
tsChannel->sendResponse(TS_CRC, buffer,
|
||||
DIR_RESPONSE_BUFFER_SIZE);
|
||||
}
|
||||
} else if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_FETCH_DATA) {
|
||||
uint16_t blockNumber = SWAP_UINT16(data16[1]);
|
||||
efiPrintf("TS_SD: fetch data command blockNumber=%d",
|
||||
blockNumber);
|
||||
|
||||
// int offset = blockNumber * TRANSFER_SIZE;
|
||||
|
||||
buffer[0] = input[2];
|
||||
buffer[1] = input[3];
|
||||
|
||||
int got;
|
||||
#if EFI_SIMULATOR
|
||||
got = fread(&buffer[2], 1, TRANSFER_SIZE, uploading);
|
||||
#endif // EFI_SIMULATOR
|
||||
|
||||
#if EFI_FILE_LOGGING
|
||||
got = 0;
|
||||
f_read(&uploading, (void*) &buffer[2], TRANSFER_SIZE, (UINT*) &got);
|
||||
#endif // EFI_FILE_LOGGING
|
||||
|
||||
tsChannel->sendResponse(TS_CRC, buffer, 2 + got);
|
||||
} else {
|
||||
efiPrintf("TS_SD: unexpected r");
|
||||
}
|
||||
}
|
||||
|
||||
void handleTsW(TsChannelBase* tsChannel, char *input) {
|
||||
const uint16_t *data16 = reinterpret_cast<uint16_t*>(input);
|
||||
|
||||
#if EFI_SIMULATOR
|
||||
printf("TS_SD w %d\n", input[1]);
|
||||
#endif // EFI_SIMULATOR
|
||||
|
||||
if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_FETCH_INFO) {
|
||||
int code = data16[2];
|
||||
efiPrintf("TS_SD: w, code=%d", code);
|
||||
|
||||
if (input[5] == TS_SD_PROTOCOL_DO) {
|
||||
efiPrintf("TS_SD_PROTOCOL_DO");
|
||||
sendOkResponse(tsChannel, TS_CRC);
|
||||
} else if (input[5] == TS_SD_PROTOCOL_READ_DIR) {
|
||||
efiPrintf("TS_SD_PROTOCOL_READ_DIR");
|
||||
sendOkResponse(tsChannel, TS_CRC);
|
||||
} else if (input[5] == TS_SD_PROTOCOL_REMOVE_FILE) {
|
||||
#if EFI_SIMULATOR
|
||||
DIR *dr = opendir(".");
|
||||
if (dr == NULL) {
|
||||
// opendir returns NULL if couldn't open directory
|
||||
printf("Could not open current directory" );
|
||||
return;
|
||||
}
|
||||
struct dirent *de; // Pointer for directory entry
|
||||
while ((de = readdir(dr)) != NULL) {
|
||||
const char * fileName = de->d_name;
|
||||
printf("%s\n", fileName);
|
||||
if (isLogFile(fileName)) {
|
||||
int dotIndex = indexOf(fileName, DOT);
|
||||
if (0 == strncmp(input + 6, &fileName[dotIndex - 4], 4)) {
|
||||
printf("Removing %s\n", fileName);
|
||||
remove(fileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dr);
|
||||
#endif // EFI_SIMULATOR
|
||||
|
||||
#if EFI_FILE_LOGGING
|
||||
DIR dir;
|
||||
FRESULT res = f_opendir(&dir, ROOT_DIR);
|
||||
if (res != FR_OK) {
|
||||
efiPrintf("Error opening directory");
|
||||
} else {
|
||||
while (true) {
|
||||
FILINFO fno;
|
||||
res = f_readdir(&dir, &fno);
|
||||
char *fileName = fno.fname;
|
||||
if (res != FR_OK || fileName[0] == 0) {
|
||||
break;
|
||||
}
|
||||
if (isLogFile(fileName)) {
|
||||
int dotIndex = indexOf(fileName, DOT);
|
||||
if (0 == strncmp(input + 6, &fileName[dotIndex - 4], 4)) {
|
||||
efiPrintf("Removing %s", fileName);
|
||||
f_unlink(fileName);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif // EFI_FILE_LOGGING
|
||||
|
||||
sendOkResponse(tsChannel, TS_CRC);
|
||||
|
||||
} else if (input[5] == TS_SD_PROTOCOL_FETCH_COMPRESSED) {
|
||||
#if EFI_SIMULATOR
|
||||
DIR *dr = opendir(".");
|
||||
|
||||
if (dr == NULL) {
|
||||
// opendir returns NULL if couldn't open directory
|
||||
printf("Could not open current directory" );
|
||||
return;
|
||||
}
|
||||
|
||||
struct dirent *de; // Pointer for directory entry
|
||||
while ((de = readdir(dr)) != NULL) {
|
||||
const char * fileName = de->d_name;
|
||||
printf("%s\n", fileName);
|
||||
if (isLogFile(fileName)) {
|
||||
int dotIndex = indexOf(fileName, DOT);
|
||||
if (0 == strncmp(input + 6, &fileName[dotIndex - 4], 4)) {
|
||||
printf("Will be uploading %s\n", fileName);
|
||||
uploading = fopen(fileName, "rb");
|
||||
if (uploading == NULL) {
|
||||
printf("Error opening %s\n", fileName);
|
||||
exit(1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
closedir(dr);
|
||||
#endif // EFI_SIMULATOR
|
||||
|
||||
#if EFI_FILE_LOGGING
|
||||
DIR dir;
|
||||
FRESULT res = f_opendir(&dir, ROOT_DIR);
|
||||
|
||||
if (res != FR_OK) {
|
||||
efiPrintf("Error opening directory");
|
||||
} else {
|
||||
memset(&uploading, 0, sizeof(FIL)); // clear the memory
|
||||
while (true) {
|
||||
FILINFO fno;
|
||||
res = f_readdir(&dir, &fno);
|
||||
char *fileName = fno.fname;
|
||||
if (res != FR_OK || fileName[0] == 0) {
|
||||
break;
|
||||
}
|
||||
if (isLogFile(fileName)) {
|
||||
int dotIndex = indexOf(fileName, DOT);
|
||||
if (0 == strncmp(input + 6, &fileName[dotIndex - 4], 4)) {
|
||||
/* FRESULT err = */
|
||||
f_open(&uploading, fileName, FA_READ);// This file has the index for next log file name
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif // EFI_FILE_LOGGING
|
||||
|
||||
sendOkResponse(tsChannel, TS_CRC);
|
||||
}
|
||||
|
||||
} else {
|
||||
efiPrintf("TS_SD: unexpected w");
|
||||
}
|
||||
}
|
||||
|
||||
#endif // (EFI_FILE_LOGGING && !HAL_USE_USB_MSD)
|
|
@ -1991,17 +1991,6 @@ end_struct
|
|||
! 0x74
|
||||
#define TS_TEST_COMMAND 't'
|
||||
|
||||
#define TS_SD_R_COMMAND 'r'
|
||||
#define TS_SD_W_COMMAND 'w'
|
||||
|
||||
#define TS_SD_PROTOCOL_RTC 7
|
||||
#define TS_SD_PROTOCOL_FETCH_INFO 0x11
|
||||
#define TS_SD_PROTOCOL_FETCH_DATA 0x14
|
||||
#define TS_SD_PROTOCOL_DO 1
|
||||
#define TS_SD_PROTOCOL_READ_DIR 2
|
||||
#define TS_SD_PROTOCOL_REMOVE_FILE 6
|
||||
#define TS_SD_PROTOCOL_FETCH_COMPRESSED 8
|
||||
|
||||
! High speed logger commands
|
||||
#define TS_SET_LOGGER_SWITCH 'l'
|
||||
#define TS_GET_LOGGER_GET_BUFFER 'L'
|
||||
|
|
|
@ -88,10 +88,6 @@ public class BinaryProtocol {
|
|||
|
||||
public static String findCommand(byte command) {
|
||||
switch (command) {
|
||||
case Fields.TS_SD_R_COMMAND:
|
||||
return "SD_R_COMMAND";
|
||||
case Fields.TS_SD_W_COMMAND:
|
||||
return "SD_W_COMMAND";
|
||||
case Fields.TS_PAGE_COMMAND:
|
||||
return "PAGE";
|
||||
case Fields.TS_COMMAND_F:
|
||||
|
|
|
@ -189,10 +189,6 @@ public class BinaryProtocolServer {
|
|||
System.err.println("NOT IMPLEMENTED TS_GET_COMPOSITE_BUFFER_DONE_DIFFERENTLY relay");
|
||||
// todo: relay command
|
||||
stream.sendPacket(TS_OK.getBytes());
|
||||
} else if (command == TS_SD_R_COMMAND) {
|
||||
handleSD_R_command(stream, packet, payload);
|
||||
} else if (command == TS_SD_W_COMMAND) {
|
||||
handleSD_W_command(stream, packet, payload);
|
||||
} else if (command == Fields.TS_OUTPUT_COMMAND) {
|
||||
DataInputStream dis = new DataInputStream(new ByteArrayInputStream(payload, 1, payload.length - 1));
|
||||
int offset = swap16(dis.readShort());
|
||||
|
@ -220,137 +216,6 @@ public class BinaryProtocolServer {
|
|||
}
|
||||
}
|
||||
|
||||
private void handleSD_W_command(TcpIoStream stream, Packet packet, byte[] payload) throws IOException {
|
||||
log.info("TS_SD: 'w' " + IoStream.printHexBinary(packet.packet));
|
||||
if (payload[1] == 0 && payload[2] == TS_SD_PROTOCOL_FETCH_INFO) {
|
||||
|
||||
if (payload[6] == TS_SD_PROTOCOL_DO) {
|
||||
log.info("TS_SD: do command, command=" + payload[payload.length - 1]);
|
||||
sendOkResponse(stream);
|
||||
} else if (payload[6] == TS_SD_PROTOCOL_READ_DIR) {
|
||||
log.info("TS_SD: read directory command " + payload[payload.length - 1]);
|
||||
sendOkResponse(stream);
|
||||
} else if (payload[6] == TS_SD_PROTOCOL_REMOVE_FILE) {
|
||||
String pattern = new String(payload, 7, 4);
|
||||
log.info("TS_SD: remove file command " + Arrays.toString(packet.packet) + " " + pattern);
|
||||
|
||||
sendOkResponse(stream);
|
||||
} else if (payload[6] == TS_SD_PROTOCOL_FETCH_COMPRESSED) {
|
||||
log.info("TS_SD: read compressed file command " + Arrays.toString(packet.packet));
|
||||
ByteBuffer bb = ByteBuffer.wrap(payload, 7, 8);
|
||||
bb.order(ByteOrder.BIG_ENDIAN);
|
||||
int sectorNumber = bb.getInt();
|
||||
int sectorCount = bb.getInt();
|
||||
log.info("TS_SD: sectorNumber=" + sectorNumber + ", sectorCount=" + sectorCount);
|
||||
sendOkResponse(stream);
|
||||
} else {
|
||||
log.info("TS_SD: Got unexpected w fetch " + IoStream.printHexBinary(packet.packet));
|
||||
}
|
||||
} else {
|
||||
log.info("TS_SD: Got unexpected w " + IoStream.printHexBinary(packet.packet));
|
||||
}
|
||||
}
|
||||
|
||||
private void handleSD_R_command(TcpIoStream stream, Packet packet, byte[] payload) throws IOException {
|
||||
log.info("TS_SD: 'r' " + IoStream.printHexBinary(packet.packet));
|
||||
if (payload[1] == 0 && payload[2] == TS_SD_PROTOCOL_RTC) {
|
||||
log.info("TS_SD: RTC read command");
|
||||
byte[] response = new byte[9];
|
||||
stream.sendPacket(response);
|
||||
} else if (payload[1] == 0 && payload[2] == TS_SD_PROTOCOL_FETCH_INFO) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(payload, 5, 2);
|
||||
bb.order(ByteOrder.BIG_ENDIAN);
|
||||
int bufferLength = bb.getShort();
|
||||
log.info("TS_SD: fetch buffer command, length=" + bufferLength);
|
||||
|
||||
byte[] response = new byte[1 + bufferLength];
|
||||
|
||||
response[0] = TS_RESPONSE_OK;
|
||||
|
||||
if (bufferLength == 16) {
|
||||
response[1] = 1 + 4; // Card present + Ready
|
||||
response[2] = 0; // Y - error code
|
||||
|
||||
response[3] = 2; // higher byte of '512' sector size
|
||||
response[4] = 0; // lower byte
|
||||
|
||||
response[5] = 0;
|
||||
response[6] = 0x20; // 0x20 00 00 of 512 is 1G virtual card
|
||||
response[7] = 0;
|
||||
response[8] = 0;
|
||||
|
||||
response[9] = 0;
|
||||
response[10] = 1; // number of files
|
||||
} else if (bufferLength == 0x202){
|
||||
// SD read directory command
|
||||
//
|
||||
|
||||
setFileEntry(response, 0, "hello123mlq", (int) new File(TEST_FILE).length());
|
||||
setFileEntry(response, 1, "he mlq", 1024);
|
||||
setFileEntry(response, 2, "_333o123mlq", 1000000);
|
||||
|
||||
} else {
|
||||
log.info("TS_SD: Got unexpected r fetch " + IoStream.printHexBinary(packet.packet));
|
||||
return;
|
||||
}
|
||||
log.info("TS_SD: sending " + IoStream.printHexBinary(response));
|
||||
stream.sendPacket(response);
|
||||
} else if (payload[1] == 0 && payload[2] == TS_SD_PROTOCOL_FETCH_DATA) {
|
||||
ByteBuffer bb = ByteBuffer.wrap(payload, 3, 4);
|
||||
bb.order(ByteOrder.BIG_ENDIAN);
|
||||
int blockNumber = bb.getShort();
|
||||
int suffix = bb.getShort();
|
||||
log.info("TS_SD: fetch data command blockNumber=" + blockNumber + ", requesting=" + suffix);
|
||||
|
||||
|
||||
|
||||
File f = new File(BinaryProtocolServer.TEST_FILE);
|
||||
FileInputStream fis = new FileInputStream(f);
|
||||
int size = (int) f.length();
|
||||
|
||||
|
||||
int offset = blockNumber * FAST_TRANSFER_PACKET_SIZE;
|
||||
int len = Math.max(0, Math.min(size - offset, FAST_TRANSFER_PACKET_SIZE));
|
||||
|
||||
byte[] response = new byte[1 + 2 + len];
|
||||
response[0] = TS_RESPONSE_OK;
|
||||
response[1] = payload[3];
|
||||
response[2] = payload[4];
|
||||
|
||||
if (len > 0) {
|
||||
fis.skip(offset);
|
||||
log.info("TS_SD reading " + offset + " " + len + " of " + size);
|
||||
fis.read(response, 3, len);
|
||||
}
|
||||
|
||||
stream.sendPacket(response);
|
||||
} else {
|
||||
log.info("TS_SD: Got unexpected r " + IoStream.printHexBinary(packet.packet));
|
||||
}
|
||||
}
|
||||
|
||||
private static void setFileEntry(byte[] response, int index, String fileName, int fileSize) {
|
||||
int offset = 1 + 32 * index;
|
||||
System.arraycopy(fileName.getBytes(), 0, response, offset, 11);
|
||||
response[offset + 11] = 1; // file
|
||||
// 12-15 = undefined
|
||||
|
||||
response[offset + 14] = 0x11;
|
||||
response[offset + 15] = 0x13; // time
|
||||
|
||||
response[offset + 16] = 0x24;
|
||||
response[offset + 17] = 0x25; // 0x2425 = FAT16 date format September 4, 1998
|
||||
|
||||
for (int i = 18; i < 22; i++)
|
||||
response[offset + i] = (byte) (i + 10 * index); // sector number
|
||||
|
||||
for (int i = 24; i < 28; i++) {
|
||||
response[offset + i] = (byte) (i + index);
|
||||
}
|
||||
|
||||
IoHelper.putInt(response, offset + 28, IoHelper.swap32(fileSize));
|
||||
}
|
||||
|
||||
private static void sendOkResponse(TcpIoStream stream) throws IOException {
|
||||
byte[] response = new byte[1];
|
||||
response[0] = TS_RESPONSE_OK;
|
||||
|
|
|
@ -1,51 +0,0 @@
|
|||
package com.rusefi.ts_plugin;
|
||||
|
||||
import com.efiAnalytics.plugin.ecu.ControllerAccess;
|
||||
import com.rusefi.binaryprotocol.BinaryProtocol;
|
||||
import com.rusefi.io.ConnectionStateListener;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.io.LinkManager;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.Objects;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class LocalSdCardReader {
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
|
||||
private final SdCardReaderPanel sdCardReaderPanel;
|
||||
|
||||
public LocalSdCardReader(Supplier<ControllerAccess> controllerAccessSupplier) {
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
|
||||
ConnectPanel connectPanel = new ConnectPanel(new ConnectionStateListener() {
|
||||
public void onConnectionEstablished() {
|
||||
sdCardReaderPanel.onConnectionEstablished();
|
||||
}
|
||||
|
||||
public void onConnectionFailed() {
|
||||
}
|
||||
});
|
||||
topPanel.add(connectPanel.getContent(), BorderLayout.NORTH);
|
||||
sdCardReaderPanel = new SdCardReaderPanel(controllerAccessSupplier, new Supplier<IoStream>() {
|
||||
@Override
|
||||
public IoStream get() {
|
||||
LinkManager controllerConnector = connectPanel.getControllerConnector();
|
||||
Objects.requireNonNull(controllerConnector, "controllerConnector");
|
||||
BinaryProtocol binaryProtocol = controllerConnector.getConnector().getBinaryProtocol();
|
||||
Objects.requireNonNull(binaryProtocol, "binaryProtocol");
|
||||
return binaryProtocol.getStream();
|
||||
}
|
||||
}, content.getParent());
|
||||
|
||||
content.add(topPanel, BorderLayout.NORTH);
|
||||
content.add(sdCardReaderPanel.getContent(), BorderLayout.CENTER);
|
||||
|
||||
content.add(new JLabel("<html>This tab allows direct access to SD card<br/>Please be sure to disconnect Tuner Studio from ECU while downloading files using this tab"), BorderLayout.SOUTH);
|
||||
}
|
||||
|
||||
public Component getContent() {
|
||||
return new JScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
}
|
||||
}
|
|
@ -20,8 +20,6 @@ import java.util.function.Supplier;
|
|||
* @see PluginBodySandbox
|
||||
*/
|
||||
public class PluginEntry implements TsPluginBody {
|
||||
private static final String LOCAL_SD_CARD = "Local SD Card";
|
||||
private static final String REMOTE_SD_CARD = "Remote SD Card";
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
|
||||
static final ImageIcon LOGO = AutoupdateUtil.loadIcon("/rusefi_online_color_300.png");
|
||||
|
@ -48,31 +46,12 @@ public class PluginEntry implements TsPluginBody {
|
|||
TuneUploadTab tuneUploadTab = new TuneUploadTab(controllerAccessSupplier);
|
||||
LogUploadSelector logUploadTab = new LogUploadSelector(controllerAccessSupplier);
|
||||
BroadcastTab broadcastTab = new BroadcastTab();
|
||||
Component localSdCard = new LocalSdCardReader(controllerAccessSupplier).getContent();
|
||||
Component remoteSdCard = new RemoteSdCardReader(controllerAccessSupplier).getContent();
|
||||
RemoteTab remoteTab = new RemoteTab(new RemoteTab.Listener() {
|
||||
@Override
|
||||
public void onConnected() {
|
||||
tabbedPane.remove(localSdCard);
|
||||
tabbedPane.addTab(REMOTE_SD_CARD, remoteSdCard);
|
||||
}
|
||||
});
|
||||
|
||||
RemoteTabController.INSTANCE.listeners.add(new RemoteTabController.Listener() {
|
||||
@Override
|
||||
public void onChange(RemoteTabController.State state) {
|
||||
if (state == RemoteTabController.State.NOT_CONNECTED) {
|
||||
tabbedPane.remove(remoteSdCard);
|
||||
tabbedPane.addTab(LOCAL_SD_CARD, localSdCard);
|
||||
}
|
||||
}
|
||||
});
|
||||
RemoteTab remoteTab = new RemoteTab();
|
||||
|
||||
tabbedPane.addTab("Tune Upload", tuneUploadTab.getContent());
|
||||
tabbedPane.addTab("Log Upload", logUploadTab.getContent());
|
||||
tabbedPane.addTab("Broadcast", broadcastTab.getContent());
|
||||
tabbedPane.addTab("Remote ECU", remoteTab.getContent());
|
||||
tabbedPane.addTab(LOCAL_SD_CARD, localSdCard);
|
||||
this.content.add(tabbedPane);
|
||||
|
||||
InstanceAuthContext.startup();
|
||||
|
|
|
@ -1,36 +0,0 @@
|
|||
package com.rusefi.ts_plugin;
|
||||
|
||||
import com.efiAnalytics.plugin.ecu.ControllerAccess;
|
||||
import com.rusefi.io.IoStream;
|
||||
import com.rusefi.proxy.client.LocalApplicationProxy;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
public class RemoteSdCardReader {
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
|
||||
private final SdCardReaderPanel sdCardReaderPanel;
|
||||
|
||||
public RemoteSdCardReader(Supplier<ControllerAccess> controllerAccessSupplier) {
|
||||
|
||||
sdCardReaderPanel = new SdCardReaderPanel(controllerAccessSupplier, new Supplier<IoStream>() {
|
||||
@Override
|
||||
public IoStream get() {
|
||||
LocalApplicationProxy localApplicationProxy = RemoteTabController.INSTANCE.getLocalApplicationProxy();
|
||||
if (localApplicationProxy == null)
|
||||
throw new NullPointerException("Not connected");
|
||||
return localApplicationProxy.getAuthenticatorToProxyStream();
|
||||
}
|
||||
}, content.getParent());
|
||||
|
||||
content.add(sdCardReaderPanel.getContent(), BorderLayout.CENTER);
|
||||
}
|
||||
|
||||
public Component getContent() {
|
||||
return new JScrollPane(content, JScrollPane.VERTICAL_SCROLLBAR_ALWAYS, JScrollPane.HORIZONTAL_SCROLLBAR_AS_NEEDED);
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -60,8 +60,6 @@ public class RemoteTab {
|
|||
return new Dimension(100, size.height);
|
||||
}
|
||||
};
|
||||
private final Listener listener;
|
||||
|
||||
|
||||
private StreamStatusControl streamStatusControl = null;
|
||||
|
||||
|
@ -69,8 +67,7 @@ public class RemoteTab {
|
|||
|
||||
private final Executor listDownloadExecutor = Executors.newSingleThreadExecutor(new NamedThreadFactory("online list downloader", true));
|
||||
|
||||
public RemoteTab(Listener listener) {
|
||||
this.listener = listener;
|
||||
public RemoteTab() {
|
||||
JButton refresh = new JButton("Refresh Remote Controllers List");
|
||||
refresh.addActionListener(e -> requestControllersList());
|
||||
|
||||
|
@ -294,7 +291,6 @@ public class RemoteTab {
|
|||
streamStatusControl = new StreamStatusControl(authenticatorToProxyStream);
|
||||
}
|
||||
|
||||
listener.onConnected();
|
||||
setStatus("Connected to " + userDetails.getUserName(),
|
||||
new JLabel("You can now connect your TunerStudio to IP address localhost and port " + getLocalPort()),
|
||||
new URLLabel(SignatureHelper.getUrl(controllerInfo.getSignature()).first),
|
||||
|
|
|
@ -1,287 +0,0 @@
|
|||
package com.rusefi.ts_plugin;
|
||||
|
||||
import com.devexperts.logging.Logging;
|
||||
import com.efiAnalytics.plugin.ecu.ControllerAccess;
|
||||
import com.rusefi.autoupdate.AutoupdateUtil;
|
||||
import com.rusefi.config.generated.Fields;
|
||||
import com.rusefi.io.IoStream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.putgemin.VerticalFlowLayout;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.nio.ByteOrder;
|
||||
import java.text.CharacterIterator;
|
||||
import java.text.StringCharacterIterator;
|
||||
import java.util.function.Supplier;
|
||||
|
||||
import static com.devexperts.logging.Logging.getLogging;
|
||||
import static com.rusefi.config.generated.Fields.TS_SD_PROTOCOL_FETCH_INFO;
|
||||
import static com.rusefi.shared.FileUtil.close;
|
||||
|
||||
public class SdCardReaderPanel {
|
||||
private final static int TRANSFER_HEADER_SIZE = 3;
|
||||
private static final Logging log = getLogging(SdCardReaderPanel.class);
|
||||
|
||||
private final JPanel fileList = new JPanel(new VerticalFlowLayout());
|
||||
private final JLabel status = new JLabel();
|
||||
private final Supplier<ControllerAccess> controllerAccessSupplier;
|
||||
private final Supplier<IoStream> ioStreamSupplier;
|
||||
private final Container parent;
|
||||
|
||||
private final JPanel content = new JPanel(new BorderLayout());
|
||||
|
||||
public SdCardReaderPanel(Supplier<ControllerAccess> controllerAccessSupplier,
|
||||
Supplier<IoStream> ioStreamSupplier, Container parent) {
|
||||
this.controllerAccessSupplier = controllerAccessSupplier;
|
||||
this.ioStreamSupplier = ioStreamSupplier;
|
||||
this.parent = parent;
|
||||
JButton refresh = new JButton("Refresh");
|
||||
refresh.addActionListener(e -> ConnectPanel.IO_THREAD.execute(this::requestFileList));
|
||||
|
||||
JButton open = new JButton("Open Destination Folder");
|
||||
JPanel lowPanel = new JPanel(new FlowLayout());
|
||||
lowPanel.add(refresh);
|
||||
lowPanel.add(open);
|
||||
|
||||
JPanel topPanel = new JPanel(new BorderLayout());
|
||||
topPanel.add(status, BorderLayout.CENTER);
|
||||
topPanel.add(lowPanel, BorderLayout.SOUTH);
|
||||
|
||||
content.add(topPanel, BorderLayout.NORTH);
|
||||
content.add(fileList, BorderLayout.CENTER);
|
||||
|
||||
open.addActionListener(new AbstractAction() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
try {
|
||||
String folder = getDestinationFolder();
|
||||
Runtime.getRuntime().exec("explorer.exe /select," + folder + File.separator);
|
||||
} catch (IOException ex) {
|
||||
log.error("Error", ex);
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
public JPanel getContent() {
|
||||
return content;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private byte[] getDirContent() throws IOException {
|
||||
byte[] packet;
|
||||
byte[] response;
|
||||
IoStream stream = ioStreamSupplier.get();
|
||||
|
||||
packet = new byte[3];
|
||||
packet[0] = Fields.TS_SD_R_COMMAND;
|
||||
packet[2] = Fields.TS_SD_PROTOCOL_RTC;
|
||||
response = stream.sendAndGetPacket(packet, "RTC status", false);
|
||||
log.info("RTC response " + IoStream.printHexBinary(response));
|
||||
if (response == null)
|
||||
throw new IOException("RTC No packet");
|
||||
|
||||
packet = new byte[17];
|
||||
packet[0] = Fields.TS_SD_W_COMMAND;
|
||||
packet[2] = TS_SD_PROTOCOL_FETCH_INFO;
|
||||
packet[6] = Fields.TS_SD_PROTOCOL_READ_DIR;
|
||||
response = stream.sendAndGetPacket(packet, "read dir command", false);
|
||||
if (response == null)
|
||||
throw new IOException("Read Dir No packet");
|
||||
log.info("read dir command " + IoStream.printHexBinary(response));
|
||||
|
||||
packet = new byte[8];
|
||||
packet[0] = Fields.TS_SD_R_COMMAND;
|
||||
packet[1] = 0;
|
||||
packet[2] = TS_SD_PROTOCOL_FETCH_INFO;
|
||||
packet[5] = 0x02;
|
||||
packet[6] = 0x02;
|
||||
response = stream.sendAndGetPacket(packet, "read command", true);
|
||||
if (response == null)
|
||||
throw new IOException("No packet");
|
||||
log.info("read command " + IoStream.printHexBinary(response));
|
||||
return response;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public String getDestinationFolder() {
|
||||
return LogUploadSelector.getLogsFolderDir(controllerAccessSupplier.get().getEcuConfigurationNames()[0]);
|
||||
}
|
||||
|
||||
private void downloadFile(String fileName) {
|
||||
String lastFour = ConnectPanel.getLastFour(fileName);
|
||||
|
||||
byte[] packet = new byte[17];
|
||||
packet[0] = Fields.TS_SD_W_COMMAND;
|
||||
packet[2] = TS_SD_PROTOCOL_FETCH_INFO;
|
||||
packet[6] = Fields.TS_SD_PROTOCOL_FETCH_COMPRESSED;
|
||||
applyLastFour(lastFour, packet);
|
||||
|
||||
IoStream stream = ioStreamSupplier.get();
|
||||
|
||||
FileOutputStream fos = null;
|
||||
try {
|
||||
byte[] response = stream.sendAndGetPacket(packet, "Download file", false);
|
||||
log.info("Download file " + IoStream.printHexBinary(response));
|
||||
setStatus("Downloading " + fileName);
|
||||
|
||||
fos = new FileOutputStream(getDestinationFolder() + File.separator + fileName, false);
|
||||
int chunk = 0;
|
||||
int totalSize = 0;
|
||||
long start = System.currentTimeMillis();
|
||||
while (true) {
|
||||
packet = new byte[17];
|
||||
packet[0] = Fields.TS_SD_R_COMMAND;
|
||||
packet[2] = Fields.TS_SD_PROTOCOL_FETCH_DATA;
|
||||
packet[3] = (byte) chunk;
|
||||
packet[4] = (byte) (chunk >> 8);
|
||||
|
||||
// we are competing with gauge poking thread for instance
|
||||
response = stream.sendAndGetPacket(packet, "Get file", true);
|
||||
|
||||
if (response == null) {
|
||||
log.info("No content response");
|
||||
break;
|
||||
}
|
||||
|
||||
int dataBytes = response.length - TRANSFER_HEADER_SIZE;
|
||||
totalSize += dataBytes;
|
||||
|
||||
if (chunk % 10 == 0)
|
||||
log.info("Got content package size " + response.length + "/total=" + totalSize);
|
||||
|
||||
fos.write(response, TRANSFER_HEADER_SIZE, dataBytes);
|
||||
|
||||
if (dataBytes != 2048) {
|
||||
log.info(response.length + " must be the last packet");
|
||||
long duration = System.currentTimeMillis() - start;
|
||||
setStatus(fileName + " downloaded " + humanReadableByteCountBin(totalSize) + " in " + duration + " ms");
|
||||
break;
|
||||
}
|
||||
if (chunk % 10 == 0)
|
||||
setStatus(humanReadableByteCountBin(totalSize) + " so far");
|
||||
chunk++;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
} finally {
|
||||
close(fos);
|
||||
}
|
||||
}
|
||||
|
||||
private void applyLastFour(String lastFour, byte[] packet) {
|
||||
for (int i = 0; i < 4; i++)
|
||||
packet[7 + i] = (byte) lastFour.charAt(i);
|
||||
}
|
||||
|
||||
private static String humanReadableByteCountBin(long bytes) {
|
||||
long absB = bytes == Long.MIN_VALUE ? Long.MAX_VALUE : Math.abs(bytes);
|
||||
if (absB < 1024) {
|
||||
return bytes + " B";
|
||||
}
|
||||
long value = absB;
|
||||
CharacterIterator ci = new StringCharacterIterator("KMGTPE");
|
||||
for (int i = 40; i >= 0 && absB > 0xfffccccccccccccL >> i; i -= 10) {
|
||||
value >>= 10;
|
||||
ci.next();
|
||||
}
|
||||
value *= Long.signum(bytes);
|
||||
return String.format("%.1f %ciB", value / 1024.0, ci.current());
|
||||
}
|
||||
|
||||
private void deleteFile(String fileName) {
|
||||
String lastFour = ConnectPanel.getLastFour(fileName);
|
||||
|
||||
byte[] packet = new byte[17];
|
||||
packet[0] = Fields.TS_SD_W_COMMAND;
|
||||
packet[2] = TS_SD_PROTOCOL_FETCH_INFO;
|
||||
packet[6] = Fields.TS_SD_PROTOCOL_REMOVE_FILE;
|
||||
applyLastFour(lastFour, packet);
|
||||
|
||||
IoStream stream = ioStreamSupplier.get();
|
||||
|
||||
try {
|
||||
stream.sendPacket(packet);
|
||||
byte[] response = stream.getDataBuffer().getPacket("delete file");
|
||||
log.info("Delete file " + IoStream.printHexBinary(response));
|
||||
} catch (IOException e) {
|
||||
throw new IllegalStateException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private void requestFileList() {
|
||||
int fileCount = 0;
|
||||
status.setText("Reading file list...");
|
||||
try {
|
||||
byte[] response = getDirContent();
|
||||
|
||||
fileList.removeAll();
|
||||
|
||||
for (int fileIndex = 0; fileIndex < 512 / 32; fileIndex++) {
|
||||
int offset = 32 * fileIndex;
|
||||
String fileNamePart = new String(response, 1 + offset, 8).trim();
|
||||
if (fileNamePart.trim().isEmpty())
|
||||
break;
|
||||
fileCount++;
|
||||
String fileExt = new String(response, 1 + offset + 8, 3).trim();
|
||||
String fileName = fileNamePart + "." + fileExt;
|
||||
|
||||
ByteBuffer bb = ByteBuffer.wrap(response, 1 + offset + 28, 4);
|
||||
bb.order(ByteOrder.LITTLE_ENDIAN);
|
||||
int fileSize = bb.getInt();
|
||||
|
||||
JPanel filePanel = new JPanel(new FlowLayout());
|
||||
|
||||
filePanel.add(new JLabel(fileName + " " + humanReadableByteCountBin(fileSize)));
|
||||
|
||||
JButton download = new JButton("Download");
|
||||
download.addActionListener(e -> ConnectPanel.IO_THREAD.execute(() -> downloadFile(fileName)));
|
||||
|
||||
filePanel.add(download);
|
||||
JButton delete = new JButton("Delete");
|
||||
delete.addActionListener(e1 -> {
|
||||
int result = JOptionPane.showConfirmDialog(null, "Are you sure you want to remove " + fileName,
|
||||
"rusEfi", JOptionPane.YES_NO_OPTION);
|
||||
if (result == JOptionPane.YES_OPTION) {
|
||||
|
||||
ConnectPanel.IO_THREAD.execute(() -> {
|
||||
deleteFile(fileName);
|
||||
setStatus("Deleted " + fileName);
|
||||
requestFileList();
|
||||
});
|
||||
}
|
||||
});
|
||||
filePanel.add(delete);
|
||||
|
||||
fileList.add(filePanel);
|
||||
fileList.revalidate();
|
||||
AutoupdateUtil.trueLayout(fileList);
|
||||
|
||||
log.info("Filename " + fileName + " size " + fileSize);
|
||||
|
||||
AutoupdateUtil.trueLayout(parent);
|
||||
}
|
||||
|
||||
} catch (IOException ioException) {
|
||||
ioException.printStackTrace();
|
||||
}
|
||||
|
||||
if (fileCount == 0) {
|
||||
status.setText("No files found.");
|
||||
}
|
||||
}
|
||||
|
||||
public void setStatus(String message) {
|
||||
SwingUtilities.invokeLater(() -> status.setText(message));
|
||||
}
|
||||
|
||||
public void onConnectionEstablished() {
|
||||
ConnectPanel.IO_THREAD.execute(this::requestFileList);
|
||||
}
|
||||
}
|
|
@ -28,13 +28,6 @@
|
|||
|
||||
#include "gtest/gtest.h"
|
||||
|
||||
TEST(util, isLogFileName) {
|
||||
ASSERT_FALSE(isLogFile("aaaa"));
|
||||
ASSERT_FALSE(isLogFile("aaa.mlq"));
|
||||
ASSERT_TRUE (isLogFile("aaaa.mlg"));
|
||||
ASSERT_FALSE(isLogFile("aaaa.aaa"));
|
||||
}
|
||||
|
||||
TEST(util, negativeZero) {
|
||||
ASSERT_TRUE(IS_NEGATIVE_ZERO(-0.0));
|
||||
|
||||
|
|
Loading…
Reference in New Issue