2020-08-02 19:31:11 -07:00
|
|
|
/**
|
|
|
|
* @file mmc_card_access.cpp
|
|
|
|
*
|
2020-08-07 13:27:21 -07:00
|
|
|
*
|
|
|
|
* 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.
|
|
|
|
*
|
2020-08-02 19:31:11 -07:00
|
|
|
*/
|
|
|
|
|
2020-08-07 12:53:11 -07:00
|
|
|
#include "engine.h"
|
2020-08-02 19:31:11 -07:00
|
|
|
|
2020-08-06 20:34:47 -07:00
|
|
|
#if EFI_SIMULATOR
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <dirent.h>
|
2020-08-06 21:59:00 -07:00
|
|
|
#include <sys/types.h>
|
|
|
|
#include <sys/stat.h>
|
|
|
|
#include <fcntl.h>
|
2020-08-06 20:34:47 -07:00
|
|
|
#endif
|
|
|
|
|
2020-08-07 12:53:11 -07:00
|
|
|
#if EFI_FILE_LOGGING
|
|
|
|
#include "ff.h"
|
2020-08-07 14:20:16 -07:00
|
|
|
#define ROOT_DIR "/"
|
2020-08-07 12:53:11 -07:00
|
|
|
#endif // EFI_FILE_LOGGING
|
|
|
|
|
2020-08-06 20:34:47 -07:00
|
|
|
#define DIR_RESPONSE_SIZE 512
|
2020-08-07 12:53:11 -07:00
|
|
|
#define DIR_ENTRY_SIZE 32
|
2020-08-06 20:34:47 -07:00
|
|
|
|
|
|
|
#define DIR_RESPONSE_BUFFER_SIZE (DIR_RESPONSE_SIZE + 2)
|
|
|
|
|
|
|
|
#define DOT '.'
|
|
|
|
|
2020-08-06 19:05:26 -07:00
|
|
|
#if EFI_FILE_LOGGING || EFI_SIMULATOR || EFI_UNIT_TEST
|
|
|
|
|
|
|
|
#include "mmc_card.h"
|
|
|
|
#include "efilib.h"
|
2020-08-07 12:53:11 -07:00
|
|
|
#include "hardware.h"
|
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
EXTERN_ENGINE
|
|
|
|
;
|
2020-08-06 19:05:26 -07:00
|
|
|
|
|
|
|
/**
|
|
|
|
* for funny reasons file name has to be at least 4 symbols before the dot
|
|
|
|
*/
|
|
|
|
bool isLogFile(const char *fileName) {
|
2020-08-06 20:34:47 -07:00
|
|
|
int dotIndex = indexOf(fileName, DOT);
|
2020-08-06 19:05:26 -07:00
|
|
|
if (dotIndex == -1) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (dotIndex < 4) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return 0 == strncmp(fileName + dotIndex, DOT_MLG, 4);
|
|
|
|
}
|
2020-08-07 13:27:21 -07:00
|
|
|
#endif // EFI_FILE_LOGGING || EFI_SIMULATOR || EFI_UNIT_TEST
|
2020-08-06 19:05:26 -07:00
|
|
|
|
2021-02-14 12:03:07 -08:00
|
|
|
// Enable when logging is enabled, but not USB mass storage
|
|
|
|
#if (EFI_FILE_LOGGING && !HAL_USE_USB_MSD) || EFI_SIMULATOR
|
2020-08-02 19:31:11 -07:00
|
|
|
#include "mmc_card.h"
|
|
|
|
|
2020-08-07 12:01:25 -07:00
|
|
|
#if EFI_SIMULATOR
|
|
|
|
static FILE *uploading;
|
|
|
|
#endif // EFI_SIMULATOR
|
|
|
|
|
2020-08-07 13:27:21 -07:00
|
|
|
#if EFI_FILE_LOGGING
|
|
|
|
static FIL uploading NO_CACHE;
|
|
|
|
#endif // EFI_FILE_LOGGING
|
|
|
|
|
2020-08-02 19:31:11 -07:00
|
|
|
extern LoggingWithStorage sharedLogger;
|
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
#define TRANSFER_SIZE 2048
|
2020-08-02 19:31:11 -07:00
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
static uint8_t buffer[TRANSFER_SIZE + 2];
|
2020-08-02 19:31:11 -07:00
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
static void setFileEntry(uint8_t *buffer, int index, const char *fileName,
|
|
|
|
int fileSize) {
|
2020-08-05 22:15:41 -07:00
|
|
|
int offset = 32 * index;
|
2020-08-06 20:34:47 -07:00
|
|
|
|
|
|
|
int dotIndex = indexOf(fileName, DOT);
|
|
|
|
// assert dotIndex != -1
|
|
|
|
memcpy(buffer + offset, fileName, dotIndex);
|
2020-08-07 14:20:16 -07:00
|
|
|
for (int i = dotIndex; i < 8; i++) {
|
2020-08-06 20:34:47 -07:00
|
|
|
buffer[offset + i] = 0;
|
|
|
|
}
|
|
|
|
memcpy(buffer + offset + 8, &fileName[dotIndex + 1], 3);
|
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
buffer[offset + 11] = 1;
|
|
|
|
|
2020-08-06 21:59:00 -07:00
|
|
|
for (int i = 0; i < 4; i++) {
|
|
|
|
buffer[offset + 18 + i] = fileName[dotIndex + i - 4];
|
|
|
|
}
|
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
*(uint32_t*) (&buffer[offset + 28]) = fileSize;
|
2020-08-05 22:15:41 -07:00
|
|
|
}
|
|
|
|
|
2021-02-19 23:11:39 -08:00
|
|
|
void handleTsR(TsChannelBase* tsChannel, char *input) {
|
2020-08-06 21:59:00 -07:00
|
|
|
#if EFI_SIMULATOR
|
|
|
|
printf("TS_SD r %d\n", input[1]);
|
|
|
|
#endif // EFI_SIMULATOR
|
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
const uint16_t *data16 = reinterpret_cast<uint16_t*>(input);
|
2020-08-02 20:09:38 -07:00
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_RTC) {
|
2020-08-02 19:31:11 -07:00
|
|
|
scheduleMsg(&sharedLogger, "TS_SD: RTC read command");
|
|
|
|
memset(buffer, 0, 9);
|
2021-02-19 17:48:21 -08:00
|
|
|
tsChannel->sendResponse(TS_CRC, buffer, 9);
|
2020-08-02 19:31:11 -07:00
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
} else if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_FETCH_INFO) {
|
2020-08-06 21:59:00 -07:00
|
|
|
uint16_t length = SWAP_UINT16(data16[2]);
|
2020-08-07 14:20:16 -07:00
|
|
|
scheduleMsg(&sharedLogger, "TS_SD: fetch buffer command, length=%d",
|
|
|
|
length);
|
2020-08-02 20:09:38 -07:00
|
|
|
|
|
|
|
if (length == 16) {
|
2020-08-05 22:15:41 -07:00
|
|
|
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
|
2020-08-02 20:09:38 -07:00
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
buffer[4] = 0;
|
|
|
|
buffer[5] = 0x20; // 0x20 00 00 of 512 is 1G virtual card
|
2020-08-07 14:20:16 -07:00
|
|
|
buffer[6] = 0;
|
|
|
|
buffer[7] = 0;
|
2020-08-05 22:15:41 -07:00
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
buffer[8] = 0;
|
|
|
|
buffer[9] = 1; // number of files
|
2020-08-05 22:15:41 -07:00
|
|
|
|
2021-02-19 17:48:21 -08:00
|
|
|
tsChannel->sendResponse(TS_CRC, buffer, 16);
|
2020-08-07 14:20:16 -07:00
|
|
|
} else if (length == DIR_RESPONSE_BUFFER_SIZE) {
|
|
|
|
// SD read directory command
|
|
|
|
memset(buffer, 0, DIR_RESPONSE_BUFFER_SIZE);
|
2020-08-02 20:09:38 -07:00
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
#if EFI_SIMULATOR
|
2020-08-07 14:20:16 -07:00
|
|
|
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);
|
2020-08-06 20:34:47 -07:00
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
#endif // EFI_SIMULATOR
|
2020-08-07 12:53:11 -07:00
|
|
|
|
|
|
|
#if EFI_FILE_LOGGING
|
2020-08-07 14:20:16 -07:00
|
|
|
DIR dir;
|
|
|
|
FRESULT res = f_opendir(&dir, ROOT_DIR);
|
|
|
|
if (res != FR_OK) {
|
|
|
|
scheduleMsg(&sharedLogger, "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)) {
|
2020-08-07 12:53:11 -07:00
|
|
|
// struct stat statBuffer;
|
|
|
|
// int status;
|
|
|
|
//
|
|
|
|
// int fileSize = 0;
|
|
|
|
// status = stat(fileName, &statBuffer);
|
|
|
|
// if (status == 0) {
|
|
|
|
// fileSize = statBuffer.st_size;
|
|
|
|
// }
|
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
FILINFO fileInfo;
|
|
|
|
// todo: handle return value?
|
|
|
|
f_stat(fileName, &fileInfo);
|
2020-08-07 12:53:11 -07:00
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
setFileEntry(buffer, index, fileName,
|
|
|
|
(int) fileInfo.fsize);
|
|
|
|
index++;
|
|
|
|
}
|
2020-08-07 12:53:11 -07:00
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
}
|
|
|
|
}
|
2020-08-07 12:53:11 -07:00
|
|
|
|
|
|
|
#endif // EFI_FILE_LOGGING
|
|
|
|
|
2021-02-19 17:48:21 -08:00
|
|
|
tsChannel->sendResponse(TS_CRC, buffer,
|
2020-08-07 14:20:16 -07:00
|
|
|
DIR_RESPONSE_BUFFER_SIZE);
|
2020-08-05 22:15:41 -07:00
|
|
|
}
|
|
|
|
} else if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_FETCH_DATA) {
|
2020-08-07 12:01:25 -07:00
|
|
|
uint16_t blockNumber = SWAP_UINT16(data16[1]);
|
2020-08-07 14:20:16 -07:00
|
|
|
scheduleMsg(&sharedLogger, "TS_SD: fetch data command blockNumber=%d",
|
|
|
|
blockNumber);
|
2020-08-05 22:15:41 -07:00
|
|
|
|
2020-08-07 13:37:36 -07:00
|
|
|
// int offset = blockNumber * TRANSFER_SIZE;
|
2020-08-02 20:09:38 -07:00
|
|
|
|
2020-08-07 12:01:25 -07:00
|
|
|
buffer[0] = input[2];
|
|
|
|
buffer[1] = input[3];
|
|
|
|
|
2020-08-07 13:27:21 -07:00
|
|
|
int got;
|
2020-08-07 12:53:11 -07:00
|
|
|
#if EFI_SIMULATOR
|
2020-08-07 13:27:21 -07:00
|
|
|
got = fread(&buffer[2], 1, TRANSFER_SIZE, uploading);
|
2020-08-07 12:53:11 -07:00
|
|
|
#endif // EFI_SIMULATOR
|
|
|
|
|
|
|
|
#if EFI_FILE_LOGGING
|
2020-08-07 13:27:21 -07:00
|
|
|
got = 0;
|
2020-08-07 14:20:16 -07:00
|
|
|
f_read(&uploading, (void*) &buffer[2], TRANSFER_SIZE, (UINT*) &got);
|
2020-08-07 12:53:11 -07:00
|
|
|
#endif // EFI_FILE_LOGGING
|
2020-08-07 12:01:25 -07:00
|
|
|
|
2021-02-19 17:48:21 -08:00
|
|
|
tsChannel->sendResponse(TS_CRC, buffer, 2 + got);
|
2020-08-02 20:09:38 -07:00
|
|
|
} else {
|
|
|
|
scheduleMsg(&sharedLogger, "TS_SD: unexpected r");
|
|
|
|
}
|
2020-08-02 19:31:11 -07:00
|
|
|
}
|
|
|
|
|
2021-02-19 23:11:39 -08:00
|
|
|
void handleTsW(TsChannelBase* tsChannel, char *input) {
|
2020-08-07 14:20:16 -07:00
|
|
|
const uint16_t *data16 = reinterpret_cast<uint16_t*>(input);
|
2020-08-02 20:09:38 -07:00
|
|
|
|
2020-08-06 21:59:00 -07:00
|
|
|
#if EFI_SIMULATOR
|
|
|
|
printf("TS_SD w %d\n", input[1]);
|
|
|
|
#endif // EFI_SIMULATOR
|
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
if (input[0] == 0 && input[1] == TS_SD_PROTOCOL_FETCH_INFO) {
|
2020-08-02 20:09:38 -07:00
|
|
|
int code = data16[2];
|
|
|
|
scheduleMsg(&sharedLogger, "TS_SD: w, code=%d", code);
|
|
|
|
|
2020-08-05 22:15:41 -07:00
|
|
|
if (input[5] == TS_SD_PROTOCOL_DO) {
|
2020-08-06 21:59:00 -07:00
|
|
|
scheduleMsg(&sharedLogger, "TS_SD_PROTOCOL_DO");
|
2020-08-05 22:15:41 -07:00
|
|
|
sendOkResponse(tsChannel, TS_CRC);
|
|
|
|
} else if (input[5] == TS_SD_PROTOCOL_READ_DIR) {
|
2020-08-06 21:59:00 -07:00
|
|
|
scheduleMsg(&sharedLogger, "TS_SD_PROTOCOL_READ_DIR");
|
2020-08-05 22:15:41 -07:00
|
|
|
sendOkResponse(tsChannel, TS_CRC);
|
|
|
|
} else if (input[5] == TS_SD_PROTOCOL_REMOVE_FILE) {
|
2020-08-06 21:59:00 -07:00
|
|
|
#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
|
2020-08-07 14:20:16 -07:00
|
|
|
|
|
|
|
#if EFI_FILE_LOGGING
|
|
|
|
DIR dir;
|
|
|
|
FRESULT res = f_opendir(&dir, ROOT_DIR);
|
|
|
|
if (res != FR_OK) {
|
|
|
|
scheduleMsg(&sharedLogger, "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)) {
|
|
|
|
scheduleMsg(&sharedLogger, "Removing %s", fileName);
|
|
|
|
f_unlink(fileName);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif // EFI_FILE_LOGGING
|
|
|
|
|
2020-08-06 21:59:00 -07:00
|
|
|
sendOkResponse(tsChannel, TS_CRC);
|
2020-08-05 22:15:41 -07:00
|
|
|
|
|
|
|
} else if (input[5] == TS_SD_PROTOCOL_FETCH_COMPRESSED) {
|
2020-08-06 21:59:00 -07:00
|
|
|
#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);
|
2020-08-07 12:01:25 -07:00
|
|
|
uploading = fopen(fileName, "rb");
|
|
|
|
if (uploading == NULL) {
|
|
|
|
printf("Error opening %s\n", fileName);
|
|
|
|
exit(1);
|
|
|
|
}
|
2020-08-06 21:59:00 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
closedir(dr);
|
|
|
|
#endif // EFI_SIMULATOR
|
2020-08-07 13:27:21 -07:00
|
|
|
|
|
|
|
#if EFI_FILE_LOGGING
|
2020-08-07 14:20:16 -07:00
|
|
|
DIR dir;
|
|
|
|
FRESULT res = f_opendir(&dir, ROOT_DIR);
|
|
|
|
|
|
|
|
if (res != FR_OK) {
|
|
|
|
scheduleMsg(&sharedLogger, "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)) {
|
2021-01-11 05:49:20 -08:00
|
|
|
/* FRESULT err = */
|
|
|
|
f_open(&uploading, fileName, FA_READ);// This file has the index for next log file name
|
2020-08-07 14:20:16 -07:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-08-07 13:27:21 -07:00
|
|
|
|
|
|
|
#endif // EFI_FILE_LOGGING
|
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
sendOkResponse(tsChannel, TS_CRC);
|
|
|
|
}
|
2020-08-07 13:27:21 -07:00
|
|
|
|
2020-08-07 14:20:16 -07:00
|
|
|
} else {
|
2020-08-02 20:09:38 -07:00
|
|
|
scheduleMsg(&sharedLogger, "TS_SD: unexpected w");
|
2020-08-07 14:20:16 -07:00
|
|
|
}
|
2020-08-02 19:31:11 -07:00
|
|
|
}
|
|
|
|
|
2021-02-14 12:03:07 -08:00
|
|
|
#endif // (EFI_FILE_LOGGING && !HAL_USE_USB_MSD)
|