diff --git a/CHANGELOG.md b/CHANGELOG.md index baa9edc3d..0bc8e9ece 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ All notable changes to this project will be documented in this file. This project uses the changelog in accordance with [keepchangelog](http://keepachangelog.com/). Please use this to write notable changes, which is not the same as git commit log... ## [unreleased][unreleased] + - Added `hf sniff --smode` skip/group adc data to consume less memory. Now it can sniff very long signals (@merlokk) - Added `hf fudan` skeleton commands (@iceman1001) - Added `--reboot-to-bootloader` arg to pm3 - Changed `hf 14b raw` - now supports selecting Fuji/Xerox tag (@horror) diff --git a/armsrc/appmain.c b/armsrc/appmain.c index 106fe3903..330bf2c48 100644 --- a/armsrc/appmain.c +++ b/armsrc/appmain.c @@ -1784,11 +1784,13 @@ static void PacketReceived(PacketCommandNG *packet) { struct p { uint32_t samplesToSkip; uint32_t triggersToSkip; + uint8_t skipMode; + uint8_t skipRatio; } PACKED; struct p *payload = (struct p *)packet->data.asBytes; uint16_t len = 0; - int res = HfSniff(payload->samplesToSkip, payload->triggersToSkip, &len); + int res = HfSniff(payload->samplesToSkip, payload->triggersToSkip, &len, payload->skipMode, payload->skipRatio); struct { uint16_t len; diff --git a/armsrc/hfsnoop.c b/armsrc/hfsnoop.c index ba9ef0740..08860da9d 100644 --- a/armsrc/hfsnoop.c +++ b/armsrc/hfsnoop.c @@ -36,7 +36,56 @@ static void RAMFUNC optimizedSniff(uint16_t *dest, uint16_t dsize) { } } -int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len) { +static void RAMFUNC skipSniff(uint8_t *dest, uint16_t dsize, uint8_t skipMode, uint8_t skipRatio) { + uint32_t accum = (skipMode == HF_SNOOP_SKIP_MIN) ? 0xffffffff : 0; + uint8_t ratioindx = 0; + while (dsize > 0) { + if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) { + volatile uint16_t val = (uint16_t)(AT91C_BASE_SSC->SSC_RHR); + switch (skipMode) { + case HF_SNOOP_SKIP_MAX: + if (accum < (val & 0xff)) + accum = val & 0xff; + if (accum < (val >> 8)) + accum = val >> 8; + break; + case HF_SNOOP_SKIP_MIN: + if (accum > (val & 0xff)) + accum = val & 0xff; + if (accum > (val >> 8)) + accum = val >> 8; + break; + case HF_SNOOP_SKIP_AVG: + accum += (val & 0xff) + (val & 0xff); + break; + default: { // HF_SNOOP_SKIP_DROP and the rest + if (ratioindx == 0) + accum = val & 0xff; + } + } + + ratioindx++; + if (ratioindx >= skipRatio) { + if (skipMode == HF_SNOOP_SKIP_AVG && skipRatio > 0) { + accum = accum / (skipRatio * 2); + if (accum <= 0xff) + *dest = accum; + else + *dest = 0xff; + } else { + *dest = accum; + } + + dest++; + dsize --; + accum = (skipMode == HF_SNOOP_SKIP_MIN) ? 0xffffffff : 0; + ratioindx = 0; + } + } + } +} + +int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint8_t skipMode, uint8_t skipRatio) { BigBuf_free(); BigBuf_Clear_ext(false); @@ -105,7 +154,10 @@ int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len) { } } - optimizedSniff((uint16_t *)mem, *len); + if (skipMode == 0) + optimizedSniff((uint16_t *)mem, *len); + else + skipSniff(mem, *len, skipMode, skipRatio); if (g_dbglevel >= DBG_INFO) { Dbprintf("Trigger kicked in (%d >= 180)", r); diff --git a/armsrc/hfsnoop.h b/armsrc/hfsnoop.h index 4b715753d..a68d28a79 100644 --- a/armsrc/hfsnoop.h +++ b/armsrc/hfsnoop.h @@ -18,6 +18,13 @@ #include "proxmark3_arm.h" -int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len); +// what to do with skipped data +#define HF_SNOOP_SKIP_NONE (0) +#define HF_SNOOP_SKIP_DROP (1) +#define HF_SNOOP_SKIP_MAX (2) +#define HF_SNOOP_SKIP_MIN (3) +#define HF_SNOOP_SKIP_AVG (4) + +int HfSniff(uint32_t samplesToSkip, uint32_t triggersToSkip, uint16_t *len, uint8_t skipMode, uint8_t skipRatio); void HfPlotDownload(void); #endif diff --git a/client/src/cmdhf.c b/client/src/cmdhf.c index 37560f785..cd58e1647 100644 --- a/client/src/cmdhf.c +++ b/client/src/cmdhf.c @@ -301,6 +301,23 @@ int CmdHFTune(const char *Cmd) { return PM3_SUCCESS; } +typedef enum { + HF_SNOOP_SKIP_NONE = 0x00, + HF_SNOOP_SKIP_DROP = 0x01, + HF_SNOOP_SKIP_MAX = 0x02, + HF_SNOOP_SKIP_MIN = 0x03, + HF_SNOOP_SKIP_AVG = 0x04 +} HFSnoopSkipMode; + +const CLIParserOption HFSnoopSkipModeOpts[] = { + {HF_SNOOP_SKIP_NONE, "none"}, + {HF_SNOOP_SKIP_DROP, "drop"}, + {HF_SNOOP_SKIP_MAX, "min"}, + {HF_SNOOP_SKIP_MIN, "max"}, + {HF_SNOOP_SKIP_AVG, "avg"}, + {0, NULL}, +}; + // Collects pars of u8, // uses 16bit transfers from FPGA for speed // Takes all available bigbuff memory @@ -317,8 +334,10 @@ int CmdHFSniff(const char *Cmd) { ); void *argtable[] = { arg_param_begin, - arg_u64_0(NULL, "sp", "", "skip sample pairs"), - arg_u64_0(NULL, "st", "", "skip number of triggers"), + arg_u64_0(NULL, "sp", "", "skip sample pairs"), + arg_u64_0(NULL, "st", "", "skip number of triggers"), + arg_str0(NULL, "smode", "[none|drop|min|max|avg]", "Skip mode. It switches on the function that applies to several samples before they saved to memory"), + arg_int0(NULL, "sratio", "", "Skip ratio. It applied the function above to (ratio * 2) samples. For ratio = 1 it 2 samples."), arg_param_end }; CLIExecWithReturn(ctx, Cmd, argtable, true); @@ -326,12 +345,26 @@ int CmdHFSniff(const char *Cmd) { struct { uint32_t samplesToSkip; uint32_t triggersToSkip; + uint8_t skipMode; + uint8_t skipRatio; } PACKED params; params.samplesToSkip = arg_get_u32_def(ctx, 1, 0); params.triggersToSkip = arg_get_u32_def(ctx, 2, 0); + int smode = 0; + if (CLIGetOptionList(arg_get_str(ctx, 3), HFSnoopSkipModeOpts, &smode)) + return PM3_EINVARG; + + if (smode > 0) + params.skipMode = smode; + + params.skipRatio = arg_get_int_def(ctx, 4, 0); CLIParserFree(ctx); + if (params.skipMode != HF_SNOOP_SKIP_NONE) + PrintAndLogEx(INFO, "Skip mode. Function: %s, each: %d sample", + CLIGetOptionListStr(HFSnoopSkipModeOpts, params.skipMode), params.skipRatio * 2); + clearCommandBuffer(); SendCommandNG(CMD_HF_SNIFF, (uint8_t *)¶ms, sizeof(params));