mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 04:50:12 -07:00
mem spi mount/unmount/test/check/tree/info/remove/rename/wwipe - now uses cliparser. remove/rename uses NG
This commit is contained in:
parent
59379247e6
commit
02aabf90d3
2 changed files with 242 additions and 180 deletions
|
@ -2097,29 +2097,39 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
}
|
}
|
||||||
case CMD_SPIFFS_REMOVE: {
|
case CMD_SPIFFS_REMOVE: {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
uint8_t filename[32];
|
|
||||||
uint8_t *pfilename = packet->data.asBytes;
|
struct p {
|
||||||
memcpy(filename, pfilename, SPIFFS_OBJ_NAME_LEN);
|
uint8_t len;
|
||||||
if (DBGLEVEL >= DBG_DEBUG) Dbprintf("Filename received for spiffs REMOVE : %s", filename);
|
uint8_t fn[32];
|
||||||
rdv40_spiffs_remove((char *) filename, RDV40_SPIFFS_SAFETY_SAFE);
|
} PACKED;
|
||||||
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
|
||||||
|
if (DBGLEVEL >= DBG_DEBUG) {
|
||||||
|
Dbprintf("Filename received for spiffs REMOVE : %s", payload->fn);
|
||||||
|
}
|
||||||
|
|
||||||
|
rdv40_spiffs_remove((char *)payload->fn, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
|
reply_ng(CMD_SPIFFS_REMOVE, PM3_SUCCESS, NULL, 0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_SPIFFS_RENAME: {
|
case CMD_SPIFFS_RENAME: {
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
uint8_t src[32];
|
struct p {
|
||||||
uint8_t dest[32];
|
uint8_t slen;
|
||||||
uint8_t *pfilename = packet->data.asBytes;
|
uint8_t src[32];
|
||||||
char *token;
|
uint8_t dlen;
|
||||||
token = strtok((char *)pfilename, ",");
|
uint8_t dest[32];
|
||||||
strncpy((char *)src, token, sizeof(src) - 1);
|
} PACKED;
|
||||||
token = strtok(NULL, ",");
|
|
||||||
strncpy((char *)dest, token, sizeof(dest) - 1);
|
struct p *payload = (struct p *) packet->data.asBytes;
|
||||||
|
|
||||||
if (DBGLEVEL >= DBG_DEBUG) {
|
if (DBGLEVEL >= DBG_DEBUG) {
|
||||||
Dbprintf("Filename received as source for spiffs RENAME : %s", src);
|
Dbprintf("Filename received as source for spiffs RENAME : %s", payload->src);
|
||||||
Dbprintf("Filename received as destination for spiffs RENAME : %s", dest);
|
Dbprintf("Filename received as destination for spiffs RENAME : %s", payload->dest);
|
||||||
}
|
}
|
||||||
rdv40_spiffs_rename((char *) src, (char *)dest, RDV40_SPIFFS_SAFETY_SAFE);
|
rdv40_spiffs_rename((char *)payload->src, (char *)payload->dest, RDV40_SPIFFS_SAFETY_SAFE);
|
||||||
|
reply_ng(CMD_SPIFFS_RENAME, PM3_SUCCESS, NULL, 0);
|
||||||
LED_B_OFF();
|
LED_B_OFF();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,34 +8,15 @@
|
||||||
// Proxmark3 RDV40 Flash memory commands
|
// Proxmark3 RDV40 Flash memory commands
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
#include "cmdflashmemspiffs.h"
|
#include "cmdflashmemspiffs.h"
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include "cmdparser.h" // command_t
|
||||||
#include "cmdparser.h" // command_t
|
|
||||||
#include "pmflash.h"
|
#include "pmflash.h"
|
||||||
#include "fileutils.h" //saveFile
|
#include "fileutils.h" //saveFile
|
||||||
#include "comms.h" //getfromdevice
|
#include "comms.h" //getfromdevice
|
||||||
|
#include "cliparser.h"
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int usage_flashmemspiffs_remove(void) {
|
|
||||||
PrintAndLogEx(NORMAL, "Remove a file from spiffs filesystem\n");
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: mem spiffs remove <filename>");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" mem spiffs remove lasttag.bin"));
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usage_flashmemspiffs_rename(void) {
|
|
||||||
PrintAndLogEx(NORMAL, "Rename/move a file in spiffs filesystem\n");
|
|
||||||
PrintAndLogEx(NORMAL, "Usage: mem spiffs rename <source> <destination>");
|
|
||||||
PrintAndLogEx(NORMAL, "");
|
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" mem spiffs rename lasttag.bin oldtag.bin"));
|
|
||||||
return PM3_SUCCESS;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int usage_flashmemspiffs_copy(void) {
|
static int usage_flashmemspiffs_copy(void) {
|
||||||
PrintAndLogEx(NORMAL, "Copy a file to another (destructively) in spiffs filesystem\n");
|
PrintAndLogEx(NORMAL, "Copy a file to another (destructively) in spiffs filesystem\n");
|
||||||
PrintAndLogEx(NORMAL, "Usage: mem spiffs copy <source> <destination>");
|
PrintAndLogEx(NORMAL, "Usage: mem spiffs copy <source> <destination>");
|
||||||
|
@ -82,121 +63,260 @@ static int usage_flashmemspiffs_wipe(void) {
|
||||||
PrintAndLogEx(NORMAL, _YELLOW_(" mem spiffs wipe"));
|
PrintAndLogEx(NORMAL, _YELLOW_(" mem spiffs wipe"));
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) {
|
||||||
|
|
||||||
|
int ret_val = PM3_SUCCESS;
|
||||||
|
|
||||||
|
// We want to mount before multiple operation so the lazy writes/append will not
|
||||||
|
// trigger a mount + umount each loop iteration (lazy ops device side)
|
||||||
|
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
||||||
|
|
||||||
|
// Send to device
|
||||||
|
uint32_t bytes_sent = 0;
|
||||||
|
uint32_t bytes_remaining = datalen;
|
||||||
|
uint32_t append = 0;
|
||||||
|
|
||||||
|
// fast push mode
|
||||||
|
conn.block_after_ACK = true;
|
||||||
|
|
||||||
|
while (bytes_remaining > 0) {
|
||||||
|
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
||||||
|
|
||||||
|
clearCommandBuffer();
|
||||||
|
|
||||||
|
char fdata[32 + bytes_in_packet];
|
||||||
|
memset(fdata, 0, sizeof(fdata));
|
||||||
|
memcpy(fdata, destfn, 32);
|
||||||
|
memcpy(fdata + 32, data + bytes_sent, bytes_in_packet);
|
||||||
|
|
||||||
|
if (bytes_sent > 0)
|
||||||
|
append = 1;
|
||||||
|
|
||||||
|
SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet);
|
||||||
|
|
||||||
|
bytes_remaining -= bytes_in_packet;
|
||||||
|
bytes_sent += bytes_in_packet;
|
||||||
|
|
||||||
|
PacketResponseNG resp;
|
||||||
|
|
||||||
|
uint8_t retry = 3;
|
||||||
|
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
||||||
|
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
||||||
|
retry--;
|
||||||
|
if (retry == 0) {
|
||||||
|
ret_val = PM3_ETIMEOUT;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t isok = resp.oldarg[0] & 0xFF;
|
||||||
|
if (!isok) {
|
||||||
|
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
|
||||||
|
ret_val = PM3_EFLASH;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
clearCommandBuffer();
|
||||||
|
|
||||||
|
// turn off fast push mode
|
||||||
|
conn.block_after_ACK = false;
|
||||||
|
|
||||||
|
// We want to unmount after these to set things back to normal but more than this
|
||||||
|
// unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory
|
||||||
|
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
||||||
|
|
||||||
|
return ret_val;
|
||||||
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSMount(const char *Cmd) {
|
static int CmdFlashMemSpiFFSMount(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs mount",
|
||||||
|
"Mount the SPIFFS file system if not already mounted",
|
||||||
|
"mem spiffs mount");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSUnmount(const char *Cmd) {
|
static int CmdFlashMemSpiFFSUnmount(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs unmount",
|
||||||
|
"Un-mount the SPIFFS file system",
|
||||||
|
"mem spiffs unmount");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSTest(const char *Cmd) {
|
static int CmdFlashMemSpiFFSTest(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs test",
|
||||||
|
"Test SPIFFS Operations, require wiping pages 0 and 1",
|
||||||
|
"mem spiffs test");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_SPIFFS_TEST, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_TEST, NULL, 0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSCheck(const char *Cmd) {
|
static int CmdFlashMemSpiFFSCheck(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs check",
|
||||||
|
"Check/try to defrag faulty/fragmented SPIFFS file system",
|
||||||
|
"mem spiffs check");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_SPIFFS_CHECK, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_CHECK, NULL, 0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSTree(const char *Cmd) {
|
static int CmdFlashMemSpiFFSTree(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs tree",
|
||||||
|
"Print the Flash memory file system tree",
|
||||||
|
"mem spiffs tree");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_SPIFFS_PRINT_TREE, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_PRINT_TREE, NULL, 0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSInfo(const char *Cmd) {
|
static int CmdFlashMemSpiFFSInfo(const char *Cmd) {
|
||||||
(void)Cmd; // Cmd is not used so far
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs info",
|
||||||
|
"Print file system info and usage statistics",
|
||||||
|
"mem spiffs info");
|
||||||
|
|
||||||
|
void *argtable[] = {
|
||||||
|
arg_param_begin,
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||||
|
CLIParserFree(ctx);
|
||||||
clearCommandBuffer();
|
clearCommandBuffer();
|
||||||
SendCommandNG(CMD_SPIFFS_PRINT_FSINFO, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_PRINT_FSINFO, NULL, 0);
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSRemove(const char *Cmd) {
|
static int CmdFlashMemSpiFFSRemove(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs remove",
|
||||||
|
"Remove a file from SPIFFS filesystem",
|
||||||
|
"mem spiffs remove -f lasttag.bin"
|
||||||
|
);
|
||||||
|
|
||||||
int len = strlen(Cmd);
|
void *argtable[] = {
|
||||||
if (len < 1) {
|
arg_param_begin,
|
||||||
return usage_flashmemspiffs_remove();
|
arg_str1("f", "filename", "<fn>", "file to remove"),
|
||||||
}
|
arg_param_end
|
||||||
|
};
|
||||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
if (len == 1 && ctmp == 'h') {
|
|
||||||
return usage_flashmemspiffs_remove();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
int fnlen = 0;
|
||||||
char filename[32] = {0};
|
char filename[32] = {0};
|
||||||
bool errors = false;
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, 32, &fnlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (param_getstr(Cmd, 0, filename, 32) >= 32) {
|
PrintAndLogEx(DEBUG, "Removing `" _YELLOW_("%s") "`", filename);
|
||||||
PrintAndLogEx(FAILED, "Filename too long");
|
struct {
|
||||||
errors = true;
|
uint8_t len;
|
||||||
}
|
uint8_t fn[32];
|
||||||
|
} PACKED payload;
|
||||||
|
payload.len = fnlen;
|
||||||
|
memcpy(payload.fn, filename, fnlen);
|
||||||
|
|
||||||
// check null filename ?
|
PacketResponseNG resp;
|
||||||
if (errors) {
|
clearCommandBuffer();
|
||||||
usage_flashmemspiffs_remove();
|
SendCommandNG(CMD_SPIFFS_REMOVE, (uint8_t *)&payload, sizeof(payload));
|
||||||
return PM3_EINVARG;
|
WaitForResponse(CMD_SPIFFS_REMOVE, &resp);
|
||||||
}
|
if (resp.status == PM3_SUCCESS)
|
||||||
|
PrintAndLogEx(INFO, "Done!");
|
||||||
|
|
||||||
SendCommandMIX(CMD_SPIFFS_REMOVE, 0, 0, 0, (uint8_t *)filename, 32);
|
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSRename(const char *Cmd) {
|
static int CmdFlashMemSpiFFSRename(const char *Cmd) {
|
||||||
|
CLIParserContext *ctx;
|
||||||
|
CLIParserInit(&ctx, "mem spiffs rename",
|
||||||
|
"Rename/move a file from SPIFFS filesystem.",
|
||||||
|
"mem spiffs rename -s aaa.bin -d bbb.bin"
|
||||||
|
);
|
||||||
|
|
||||||
int len = strlen(Cmd);
|
void *argtable[] = {
|
||||||
if (len < 1) {
|
arg_param_begin,
|
||||||
return usage_flashmemspiffs_rename();
|
arg_str1("s", "src", "<fn>", "source file name"),
|
||||||
}
|
arg_str1("d", "dest", "<fn>", "destination file name"),
|
||||||
|
arg_param_end
|
||||||
|
};
|
||||||
|
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||||
|
|
||||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
int slen = 0;
|
||||||
if (len == 1 && ctmp == 'h') {
|
char src[32] = {0};
|
||||||
return usage_flashmemspiffs_rename();
|
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)src, 32, &slen);
|
||||||
}
|
|
||||||
|
|
||||||
char srcfilename[32] = {0};
|
int dlen = 0;
|
||||||
char destfilename[32] = {0};
|
char dest[32] = {0};
|
||||||
bool errors = false;
|
CLIParamStrToBuf(arg_get_str(ctx, 2), (uint8_t *)dest, 32, &dlen);
|
||||||
|
CLIParserFree(ctx);
|
||||||
|
|
||||||
if (param_getstr(Cmd, 0, srcfilename, 32) >= 32) {
|
PrintAndLogEx(DEBUG, "Rename from `" _YELLOW_("%s") "` -> `" _YELLOW_("%s") "`", src, dest);
|
||||||
PrintAndLogEx(FAILED, "Source Filename too long");
|
|
||||||
errors = true;
|
|
||||||
}
|
|
||||||
if (srcfilename[0] == '\0') {
|
|
||||||
PrintAndLogEx(FAILED, "Source Filename missing or invalid");
|
|
||||||
errors = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (param_getstr(Cmd, 1, destfilename, 32) >= 32) {
|
struct {
|
||||||
PrintAndLogEx(FAILED, "Source Filename too long");
|
uint8_t slen;
|
||||||
errors = true;
|
uint8_t src[32];
|
||||||
}
|
uint8_t dlen;
|
||||||
if (destfilename[0] == '\0') {
|
uint8_t dest[32];
|
||||||
PrintAndLogEx(FAILED, "Source Filename missing or invalid");
|
} PACKED payload;
|
||||||
errors = true;
|
payload.slen = slen;
|
||||||
}
|
payload.dlen = dlen;
|
||||||
|
|
||||||
// check null filename ?
|
memcpy(payload.src, src, slen);
|
||||||
if (errors) {
|
memcpy(payload.dest, dest, dlen);
|
||||||
usage_flashmemspiffs_rename();
|
|
||||||
return PM3_EINVARG;
|
|
||||||
}
|
|
||||||
|
|
||||||
char data[65];
|
PacketResponseNG resp;
|
||||||
sprintf(data, "%s,%s", srcfilename, destfilename);
|
clearCommandBuffer();
|
||||||
SendCommandMIX(CMD_SPIFFS_RENAME, 0, 0, 0, (uint8_t *)data, 65);
|
SendCommandNG(CMD_SPIFFS_RENAME, (uint8_t *)&payload, sizeof(payload));
|
||||||
|
WaitForResponse(CMD_SPIFFS_RENAME, &resp);
|
||||||
|
if (resp.status == PM3_SUCCESS)
|
||||||
|
PrintAndLogEx(INFO, "Done!");
|
||||||
|
|
||||||
|
PrintAndLogEx(HINT, "Try `" _YELLOW_("mem spiffs tree") "` to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -353,73 +473,6 @@ static int CmdFlashMemSpiFFSDump(const char *Cmd) {
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
int flashmem_spiffs_load(uint8_t *destfn, uint8_t *data, size_t datalen) {
|
|
||||||
|
|
||||||
int ret_val = PM3_SUCCESS;
|
|
||||||
|
|
||||||
// We want to mount before multiple operation so the lazy writes/append will not
|
|
||||||
// trigger a mount + umount each loop iteration (lazy ops device side)
|
|
||||||
SendCommandNG(CMD_SPIFFS_MOUNT, NULL, 0);
|
|
||||||
|
|
||||||
// Send to device
|
|
||||||
uint32_t bytes_sent = 0;
|
|
||||||
uint32_t bytes_remaining = datalen;
|
|
||||||
uint32_t append = 0;
|
|
||||||
|
|
||||||
// fast push mode
|
|
||||||
conn.block_after_ACK = true;
|
|
||||||
|
|
||||||
while (bytes_remaining > 0) {
|
|
||||||
uint32_t bytes_in_packet = MIN(FLASH_MEM_BLOCK_SIZE, bytes_remaining);
|
|
||||||
|
|
||||||
clearCommandBuffer();
|
|
||||||
|
|
||||||
char fdata[32 + bytes_in_packet];
|
|
||||||
memset(fdata, 0, sizeof(fdata));
|
|
||||||
memcpy(fdata, destfn, 32);
|
|
||||||
memcpy(fdata + 32, data + bytes_sent, bytes_in_packet);
|
|
||||||
|
|
||||||
if (bytes_sent > 0)
|
|
||||||
append = 1;
|
|
||||||
|
|
||||||
SendCommandOLD(CMD_SPIFFS_WRITE, append, bytes_in_packet, 0, fdata, 32 + bytes_in_packet);
|
|
||||||
|
|
||||||
bytes_remaining -= bytes_in_packet;
|
|
||||||
bytes_sent += bytes_in_packet;
|
|
||||||
|
|
||||||
PacketResponseNG resp;
|
|
||||||
|
|
||||||
uint8_t retry = 3;
|
|
||||||
while (!WaitForResponseTimeout(CMD_ACK, &resp, 2000)) {
|
|
||||||
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
|
|
||||||
retry--;
|
|
||||||
if (retry == 0) {
|
|
||||||
ret_val = PM3_ETIMEOUT;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t isok = resp.oldarg[0] & 0xFF;
|
|
||||||
if (!isok) {
|
|
||||||
PrintAndLogEx(FAILED, "Flash write fail [offset %u]", bytes_sent);
|
|
||||||
ret_val = PM3_EFLASH;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out:
|
|
||||||
clearCommandBuffer();
|
|
||||||
|
|
||||||
// turn off fast push mode
|
|
||||||
conn.block_after_ACK = false;
|
|
||||||
|
|
||||||
// We want to unmount after these to set things back to normal but more than this
|
|
||||||
// unmouting ensure that SPIFFS CACHES are all flushed so our file is actually written on memory
|
|
||||||
SendCommandNG(CMD_SPIFFS_UNMOUNT, NULL, 0);
|
|
||||||
|
|
||||||
return ret_val;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int CmdFlashMemSpiFFSWipe(const char *Cmd) {
|
static int CmdFlashMemSpiFFSWipe(const char *Cmd) {
|
||||||
|
|
||||||
char ctmp = tolower(param_getchar(Cmd, 0));
|
char ctmp = tolower(param_getchar(Cmd, 0));
|
||||||
|
@ -433,7 +486,7 @@ static int CmdFlashMemSpiFFSWipe(const char *Cmd) {
|
||||||
SendCommandNG(CMD_SPIFFS_WIPE, NULL, 0);
|
SendCommandNG(CMD_SPIFFS_WIPE, NULL, 0);
|
||||||
WaitForResponse(CMD_SPIFFS_WIPE, &resp);
|
WaitForResponse(CMD_SPIFFS_WIPE, &resp);
|
||||||
PrintAndLogEx(INFO, "Done!");
|
PrintAndLogEx(INFO, "Done!");
|
||||||
PrintAndLogEx(HINT, "Try use '" _YELLOW_("mem spiffs tree") "' to verify.");
|
PrintAndLogEx(HINT, "Try `" _YELLOW_("mem spiffs tree") "` to verify");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -495,20 +548,19 @@ static int CmdFlashMemSpiFFSLoad(const char *Cmd) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static command_t CommandTable[] = {
|
static command_t CommandTable[] = {
|
||||||
|
|
||||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||||
{"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS FileSystem in FlashMEM (spiffs)"},
|
{"copy", CmdFlashMemSpiFFSCopy, IfPm3Flash, "Copy a file to another (destructively) in SPIFFS file system"},
|
||||||
{"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented Filesystem"},
|
{"check", CmdFlashMemSpiFFSCheck, IfPm3Flash, "Check/try to defrag faulty/fragmented file system"},
|
||||||
{"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS FileSystem in FlashMEM (spiffs)"},
|
{"dump", CmdFlashMemSpiFFSDump, IfPm3Flash, "Dump a file from SPIFFS file system"},
|
||||||
{"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print filesystem info and usage statistics (spiffs)"},
|
{"info", CmdFlashMemSpiFFSInfo, IfPm3Flash, "Print file system info and usage statistics"},
|
||||||
{"load", CmdFlashMemSpiFFSLoad, IfPm3Flash, "Upload file into SPIFFS Filesystem (spiffs)"},
|
{"load", CmdFlashMemSpiFFSLoad, IfPm3Flash, "Upload file into SPIFFS file system"},
|
||||||
{"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS Filesystem if not already mounted (spiffs)"},
|
{"mount", CmdFlashMemSpiFFSMount, IfPm3Flash, "Mount the SPIFFS file system if not already mounted"},
|
||||||
{"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS FileSystem in FlashMEM (spiffs)"},
|
{"remove", CmdFlashMemSpiFFSRemove, IfPm3Flash, "Remove a file from SPIFFS file system"},
|
||||||
{"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS FileSystem in FlashMEM (spiffs)"},
|
{"rename", CmdFlashMemSpiFFSRename, IfPm3Flash, "Rename/move a file in SPIFFS file system"},
|
||||||
{"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Operations (require wiping pages 0 and 1)"},
|
{"test", CmdFlashMemSpiFFSTest, IfPm3Flash, "Test SPIFFS Operations"},
|
||||||
{"tree", CmdFlashMemSpiFFSTree, IfPm3Flash, "Print the Flash Memory FileSystem Tree (spiffs)"},
|
{"tree", CmdFlashMemSpiFFSTree, IfPm3Flash, "Print the Flash memory file system tree"},
|
||||||
{"unmount", CmdFlashMemSpiFFSUnmount, IfPm3Flash, "Un-mount the SPIFFS Filesystem if not already mounted (spiffs)"},
|
{"unmount", CmdFlashMemSpiFFSUnmount, IfPm3Flash, "Un-mount the SPIFFS file system"},
|
||||||
{"wipe", CmdFlashMemSpiFFSWipe, IfPm3Flash, "Wipe all files from SPIFFS FileSystem." _RED_("* dangerous *") },
|
{"wipe", CmdFlashMemSpiFFSWipe, IfPm3Flash, "Wipe all files from SPIFFS file system. * " _RED_("dangerous") " *" },
|
||||||
{NULL, NULL, NULL, NULL}
|
{NULL, NULL, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue