- /cap_bssids.txt append on save; handshakeLoadPersistedBssids after SD mount - Boot order: SD then load file then first WiFi scan (reds match SD) - Pre-save walk of in-memory PCAP counting EAPOL-Key frames - SD_AppendLine / SD_ForEachLine; drop g_sd_ready clear on write fail - README + MUST_DO updates Made-with: Cursor
118 lines
2.8 KiB
C++
118 lines
2.8 KiB
C++
#include "SD_Card.h"
|
|
#include "Display_ST7789.h"
|
|
#include "HandshakeCapture.h"
|
|
#include "SPI_Bus_Lock.h"
|
|
|
|
uint16_t SDCard_Size = 0;
|
|
static bool g_sd_ready = false;
|
|
static bool s_sd_vfs_was_open = false;
|
|
|
|
static void beginSDOperation() {
|
|
SPIBus_SetDisplayPaused(true);
|
|
SPIBus_Lock();
|
|
}
|
|
|
|
static void endSDOperation() {
|
|
SPIBus_Unlock();
|
|
SPIBus_SetDisplayPaused(false);
|
|
}
|
|
|
|
bool SD_IsReady() {
|
|
return g_sd_ready;
|
|
}
|
|
|
|
bool SD_Init() {
|
|
beginSDOperation();
|
|
g_sd_ready = false;
|
|
pinMode(SD_CS, OUTPUT);
|
|
digitalWrite(SD_CS, HIGH);
|
|
// Shared SPI with ST7789: ensure display CS idle so SD sees a clean bus.
|
|
digitalWrite(EXAMPLE_PIN_NUM_LCD_CS, HIGH);
|
|
|
|
if (s_sd_vfs_was_open) {
|
|
SD.end();
|
|
s_sd_vfs_was_open = false;
|
|
HANDSHAKE_LOGLN("[SD] previous mount closed before re-begin");
|
|
}
|
|
|
|
HANDSHAKE_LOGF("[SD] begin(cs=%d)...\n", SD_CS);
|
|
if (!SD.begin(SD_CS, SPI)) {
|
|
HANDSHAKE_LOGLN("[SD] FAIL: SD.begin() returned false");
|
|
endSDOperation();
|
|
return false;
|
|
}
|
|
uint8_t ct = (uint8_t)SD.cardType();
|
|
HANDSHAKE_LOGF("[SD] cardType=%u (0=NONE)\n", (unsigned)ct);
|
|
if (SD.cardType() == CARD_NONE) {
|
|
HANDSHAKE_LOGLN("[SD] FAIL: CARD_NONE after begin");
|
|
SD.end();
|
|
s_sd_vfs_was_open = false;
|
|
endSDOperation();
|
|
return false;
|
|
}
|
|
g_sd_ready = true;
|
|
s_sd_vfs_was_open = true;
|
|
SDCard_Size = SD.totalBytes() / (1024 * 1024);
|
|
HANDSHAKE_LOGF("[SD] OK size=%u MiB ready=%d\n", (unsigned)SDCard_Size, (int)g_sd_ready);
|
|
endSDOperation();
|
|
return true;
|
|
}
|
|
|
|
bool SD_WriteFileAtomic(const char* path, const uint8_t* data, size_t len) {
|
|
if (path == nullptr || data == nullptr || len == 0) return false;
|
|
|
|
beginSDOperation();
|
|
|
|
bool ok = false;
|
|
File file = SD.open(path, FILE_WRITE);
|
|
if (file) {
|
|
ok = (file.write(data, len) == len);
|
|
file.close();
|
|
}
|
|
endSDOperation();
|
|
|
|
if (len >= 1024) yield();
|
|
return ok;
|
|
}
|
|
|
|
bool SD_AppendLine(const char* path, const char* line) {
|
|
if (path == nullptr || line == nullptr) return false;
|
|
beginSDOperation();
|
|
bool ok = false;
|
|
File f = SD.open(path, FILE_APPEND);
|
|
if (f) {
|
|
size_t n = strlen(line);
|
|
ok = (f.write((const uint8_t*)line, n) == n);
|
|
f.close();
|
|
}
|
|
endSDOperation();
|
|
return ok;
|
|
}
|
|
|
|
bool SD_ForEachLine(const char* path, SD_LineCallback cb, void* user) {
|
|
if (path == nullptr || cb == nullptr) return false;
|
|
beginSDOperation();
|
|
if (!SD.exists(path)) {
|
|
endSDOperation();
|
|
return true;
|
|
}
|
|
File f = SD.open(path, FILE_READ);
|
|
if (!f) {
|
|
endSDOperation();
|
|
return false;
|
|
}
|
|
char buf[80];
|
|
while (f.available()) {
|
|
int n = f.readBytesUntil('\n', buf, (int)sizeof(buf) - 1);
|
|
if (n < 0) n = 0;
|
|
buf[n] = '\0';
|
|
while (n > 0 && (buf[n - 1] == '\r' || buf[n - 1] == ' ')) {
|
|
buf[--n] = '\0';
|
|
}
|
|
if (n > 0) cb(buf, user);
|
|
}
|
|
f.close();
|
|
endSDOperation();
|
|
return true;
|
|
}
|