mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 21:03:48 -07:00
Fix: 'lf config' - calling without param messes up all device settings.
This commit is contained in:
parent
1d6ef96d12
commit
0869cbc6ad
5 changed files with 116 additions and 85 deletions
|
@ -155,7 +155,7 @@ void lf_init(bool reader) {
|
|||
AT91C_BASE_TC0->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC0->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK;
|
||||
|
||||
// Enable peripheral Clock for TIMER_CLOCK0
|
||||
// Enable peripheral Clock for TIMER_CLOCK 1
|
||||
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC1);
|
||||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKDIS;
|
||||
AT91C_BASE_TC1->TC_CMR = AT91C_TC_CLKS_TIMER_DIV4_CLOCK;
|
||||
|
@ -168,7 +168,7 @@ void lf_init(bool reader) {
|
|||
AT91C_BASE_TC1->TC_CCR = AT91C_TC_CLKEN | AT91C_TC_SWTRG;
|
||||
|
||||
// Prepare data trace
|
||||
if (logging) initSamplingBuffer(NULL);
|
||||
if (logging) initSampleBuffer(NULL);
|
||||
|
||||
}
|
||||
|
||||
|
|
|
@ -42,25 +42,40 @@ void printConfig() {
|
|||
|
||||
/**
|
||||
* Called from the USB-handler to set the sampling configuration
|
||||
* The sampling config is used for std reading and sniffing.
|
||||
* The sampling config is used for standard reading and sniffing.
|
||||
*
|
||||
* Other functions may read samples and ignore the sampling config,
|
||||
* such as functions to read the UID from a prox tag or similar.
|
||||
*
|
||||
* Values set to '0' implies no change (except for averaging)
|
||||
* Values set to '-1' implies no change
|
||||
* @brief setSamplingConfig
|
||||
* @param sc
|
||||
*/
|
||||
void setSamplingConfig(sample_config *sc) {
|
||||
if (sc->divisor != 0) config.divisor = sc->divisor;
|
||||
if (sc->bits_per_sample != 0) config.bits_per_sample = sc->bits_per_sample;
|
||||
if (sc->trigger_threshold != -1) config.trigger_threshold = sc->trigger_threshold;
|
||||
// if (sc->samples_to_skip == 0xffffffff) // if needed to not update if not supplied
|
||||
|
||||
// decimation (1-8) how many bits of adc sample value to save
|
||||
if (sc->decimation > 0 && sc->decimation < 8)
|
||||
config.decimation = sc->decimation;
|
||||
|
||||
// bits per sample (1-8)
|
||||
if (sc->bits_per_sample > 0 && sc->bits_per_sample < 8)
|
||||
config.bits_per_sample = sc->bits_per_sample;
|
||||
|
||||
//
|
||||
if (sc->averaging > -1)
|
||||
config.averaging = (sc->averaging > 0) ? 1 : 0;
|
||||
|
||||
// Frequency divisor (19 - 255)
|
||||
if (sc->divisor > 18 && sc->divisor < 256)
|
||||
config.divisor = sc->divisor;
|
||||
|
||||
// Start saving samples when adc value larger than trigger_threshold
|
||||
if (sc->trigger_threshold > -1)
|
||||
config.trigger_threshold = sc->trigger_threshold;
|
||||
|
||||
// Skip n adc samples before saving
|
||||
if (sc->samples_to_skip > -1)
|
||||
config.samples_to_skip = sc->samples_to_skip;
|
||||
config.decimation = (sc->decimation != 0) ? sc->decimation : 1;
|
||||
config.averaging = sc->averaging;
|
||||
if (config.bits_per_sample > 8) config.bits_per_sample = 8;
|
||||
|
||||
if (sc->verbose)
|
||||
printConfig();
|
||||
|
@ -113,7 +128,7 @@ uint32_t getSampleCounter() {
|
|||
return samples.total_saved;
|
||||
}
|
||||
|
||||
void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg) {
|
||||
void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg) {
|
||||
|
||||
if (!data.buffer) return;
|
||||
|
||||
|
@ -207,8 +222,8 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) {
|
|||
* @param verbose - is true, dbprints the status, else no outputs
|
||||
* @return the number of bits occupied by the samples.
|
||||
*/
|
||||
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold,
|
||||
bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip) {
|
||||
uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold,
|
||||
bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip) {
|
||||
|
||||
initSampleBuffer(&sample_size);
|
||||
|
||||
|
|
|
@ -42,8 +42,8 @@ uint32_t SampleLF(bool verbose, uint32_t sample_size);
|
|||
**/
|
||||
uint32_t SniffLF();
|
||||
|
||||
uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool avg, int trigger_threshold,
|
||||
bool verbose, uint32_t sample_size, uint32_t cancel_after, uint32_t samples_to_skip);
|
||||
uint32_t DoAcquisition(uint8_t decimation, uint8_t bits_per_sample, bool avg, int16_t trigger_threshold,
|
||||
bool verbose, uint32_t sample_size, uint32_t cancel_after, int32_t samples_to_skip);
|
||||
|
||||
// adds sample size to default options
|
||||
uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after);
|
||||
|
@ -69,8 +69,8 @@ uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size);
|
|||
/**
|
||||
* Refactoring of lf sampling buffer
|
||||
*/
|
||||
void initSamplingBuffer(uint32_t *sample_size);
|
||||
void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool avg);
|
||||
void initSampleBuffer(uint32_t *sample_size);
|
||||
void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg);
|
||||
uint32_t getSampleCounter();
|
||||
|
||||
/**
|
||||
|
|
130
client/cmdlf.c
130
client/cmdlf.c
|
@ -68,9 +68,10 @@ static int usage_lf_cmdread(void) {
|
|||
PrintAndLogEx(NORMAL, " c <cmd> Command bytes (in ones and zeros)");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in microseconds (us)"));
|
||||
PrintAndLogEx(NORMAL, " ************* Use " _YELLOW_("'lf config'") "to configure options.");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf cmdread d 80 z 100 o 200 c 11000");
|
||||
PrintAndLogEx(NORMAL, "Extras:");
|
||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_lf_read(void) {
|
||||
|
@ -79,16 +80,16 @@ static int usage_lf_read(void) {
|
|||
PrintAndLogEx(NORMAL, " h This help");
|
||||
PrintAndLogEx(NORMAL, " d #samples # samples to collect (optional)");
|
||||
PrintAndLogEx(NORMAL, " s silent");
|
||||
PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000 samples silent");
|
||||
PrintAndLogEx(NORMAL, " lf read");
|
||||
PrintAndLogEx(NORMAL, "Extras:");
|
||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_lf_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Simulate low frequence tag from graphbuffer.");
|
||||
PrintAndLogEx(NORMAL, "Use " _YELLOW_("'lf config'")" to set parameters.");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf sim [h] <gap>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h This help");
|
||||
|
@ -96,16 +97,19 @@ static int usage_lf_sim(void) {
|
|||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf sim 240 - start simulating with 240ms gap");
|
||||
PrintAndLogEx(NORMAL, " lf sim");
|
||||
PrintAndLogEx(NORMAL, "Extras:");
|
||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_lf_sniff(void) {
|
||||
PrintAndLogEx(NORMAL, "Sniff low frequence signal.");
|
||||
PrintAndLogEx(NORMAL, "Use " _YELLOW_("'lf config'")" to set parameters.");
|
||||
PrintAndLogEx(NORMAL, "Use " _YELLOW_("'data samples'")" command to download from device, and " _YELLOW_("'data plot'")" to look at it");
|
||||
|
||||
PrintAndLogEx(NORMAL, "Usage: lf sniff [h]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h This help");
|
||||
PrintAndLogEx(NORMAL, "Extras:");
|
||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")"to set parameters.");
|
||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'data samples'")"command to download from device");
|
||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'data plot'")"to look at it");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_lf_config(void) {
|
||||
|
@ -117,22 +121,17 @@ static int usage_lf_config(void) {
|
|||
PrintAndLogEx(NORMAL, " q <divisor> Manually set freq divisor. %d -> 134 kHz, %d -> 125 kHz", LF_DIVISOR_134, LF_DIVISOR_125);
|
||||
PrintAndLogEx(NORMAL, " f <freq> Manually set frequency in kHz");
|
||||
PrintAndLogEx(NORMAL, " b <bps> Sets resolution of bits per sample. Default (max): 8");
|
||||
PrintAndLogEx(NORMAL, " d <decim> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
|
||||
PrintAndLogEx(NORMAL, " d <decimate> Sets decimation. A value of N saves only 1 in N samples. Default: 1");
|
||||
PrintAndLogEx(NORMAL, " a [0|1] Averaging - if set, will average the stored sample value when decimating. Default: 1");
|
||||
PrintAndLogEx(NORMAL, " t <threshold> Sets trigger threshold. 0 means no threshold (range: 0-128)");
|
||||
PrintAndLogEx(NORMAL, " s <samplestoskip> Sets a number of samples to skip before capture. Default: 0");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, " lf config");
|
||||
PrintAndLogEx(NORMAL, " Shows current config");
|
||||
PrintAndLogEx(NORMAL, " lf config b 8 L");
|
||||
PrintAndLogEx(NORMAL, " Samples at 125 kHz, 8bps.");
|
||||
PrintAndLogEx(NORMAL, " lf config H b 4 d 3");
|
||||
PrintAndLogEx(NORMAL, " Samples at 134 kHz, averages three samples into one, stored with ");
|
||||
PrintAndLogEx(NORMAL, " lf config - shows current config");
|
||||
PrintAndLogEx(NORMAL, " lf config b 8 L - samples at 125 kHz, 8bps.");
|
||||
PrintAndLogEx(NORMAL, " lf config H b 4 d 3 - samples at 134 kHz, averages three samples into one, stored with ");
|
||||
PrintAndLogEx(NORMAL, " a resolution of 4 bits per sample.");
|
||||
PrintAndLogEx(NORMAL, " lf read");
|
||||
PrintAndLogEx(NORMAL, " Performs a read (active field)");
|
||||
PrintAndLogEx(NORMAL, " lf sniff");
|
||||
PrintAndLogEx(NORMAL, " Performs a sniff (no active field)");
|
||||
PrintAndLogEx(NORMAL, " lf read - performs a read (active field)");
|
||||
PrintAndLogEx(NORMAL, " lf sniff - performs a sniff (no active field)");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int usage_lf_simfsk(void) {
|
||||
|
@ -457,7 +456,11 @@ int lf_config(sample_config *config) {
|
|||
if (!session.pm3_present) return PM3_ENOTTY;
|
||||
|
||||
clearCommandBuffer();
|
||||
if (config != NULL)
|
||||
SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config));
|
||||
else
|
||||
SendCommandNG(CMD_LF_SAMPLING_GET_CONFIG, NULL, 0);
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
@ -465,15 +468,22 @@ int CmdLFConfig(const char *Cmd) {
|
|||
|
||||
if (!session.pm3_present) return PM3_ENOTTY;
|
||||
|
||||
uint8_t divisor = 0;//Frequency divisor
|
||||
uint8_t bps = 0; // Bits per sample
|
||||
uint8_t decimation = 0; //How many to keep
|
||||
bool averaging = 1; // Defaults to true
|
||||
bool errors = false;
|
||||
int trigger_threshold = -1;//Means no change
|
||||
uint8_t unsigned_trigg = 0;
|
||||
uint32_t samples_to_skip = 0; // will return offset to 0 if not supplied. Could set to 0xffffffff if needed to not update
|
||||
// if called with no params, just print the device config
|
||||
if (strlen(Cmd) == 0) {
|
||||
return lf_config(NULL);
|
||||
}
|
||||
|
||||
sample_config config = {
|
||||
.decimation = -1,
|
||||
.bits_per_sample = -1,
|
||||
.averaging = -1,
|
||||
.divisor = -1,
|
||||
.trigger_threshold = -1,
|
||||
.samples_to_skip = -1,
|
||||
.verbose = true
|
||||
};
|
||||
|
||||
bool errors = false;
|
||||
|
||||
uint8_t cmdp = 0;
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
|
@ -481,16 +491,16 @@ int CmdLFConfig(const char *Cmd) {
|
|||
case 'h':
|
||||
return usage_lf_config();
|
||||
case 'H':
|
||||
divisor = LF_DIVISOR_134;
|
||||
config.divisor = LF_DIVISOR_134;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'L':
|
||||
divisor = LF_DIVISOR_125;
|
||||
config.divisor = LF_DIVISOR_125;
|
||||
cmdp++;
|
||||
break;
|
||||
case 'q':
|
||||
errors |= param_getdec(Cmd, cmdp + 1, &divisor);
|
||||
if (divisor < 19) {
|
||||
config.divisor = param_get8ex(Cmd, cmdp + 1, 95, 10);
|
||||
if (config.divisor < 19) {
|
||||
PrintAndLogEx(ERR, "divisor must be between 19 and 255");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
@ -498,36 +508,50 @@ int CmdLFConfig(const char *Cmd) {
|
|||
break;
|
||||
case 'f': {
|
||||
int freq = param_get32ex(Cmd, cmdp + 1, 125, 10);
|
||||
divisor = LF_FREQ2DIV(freq);
|
||||
if (divisor < 19) {
|
||||
config.divisor = LF_FREQ2DIV(freq);
|
||||
if (config.divisor < 19) {
|
||||
PrintAndLogEx(ERR, "freq must be between 47 and 600");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
case 't':
|
||||
errors |= param_getdec(Cmd, cmdp + 1, &unsigned_trigg);
|
||||
case 't': {
|
||||
uint8_t trigg = 0;
|
||||
errors |= param_getdec(Cmd, cmdp + 1, &trigg);
|
||||
cmdp += 2;
|
||||
if (!errors) {
|
||||
trigger_threshold = unsigned_trigg;
|
||||
g_lf_threshold_set = (trigger_threshold > 0);
|
||||
config.trigger_threshold = trigg;
|
||||
g_lf_threshold_set = (config.trigger_threshold > 0);
|
||||
}
|
||||
break;
|
||||
case 'b':
|
||||
errors |= param_getdec(Cmd, cmdp + 1, &bps);
|
||||
}
|
||||
case 'b': {
|
||||
config.bits_per_sample = param_get8ex(Cmd, cmdp + 1, 8, 10);
|
||||
|
||||
// bps is limited to 8
|
||||
if (config.bits_per_sample >> 4)
|
||||
config.bits_per_sample = 8;
|
||||
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'd':
|
||||
errors |= param_getdec(Cmd, cmdp + 1, &decimation);
|
||||
}
|
||||
case 'd': {
|
||||
config.decimation = param_get8ex(Cmd, cmdp + 1, 1, 10);
|
||||
|
||||
// decimation is limited to 255
|
||||
if (config.decimation >> 4)
|
||||
config.decimation = 8;
|
||||
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
case 'a':
|
||||
averaging = param_getchar(Cmd, cmdp + 1) == '1';
|
||||
config.averaging = (param_getchar(Cmd, cmdp + 1) == '1');
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 's':
|
||||
samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||
config.samples_to_skip = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
|
@ -540,15 +564,6 @@ int CmdLFConfig(const char *Cmd) {
|
|||
// validations
|
||||
if (errors) return usage_lf_config();
|
||||
|
||||
// print current settings.
|
||||
if (cmdp == 0)
|
||||
return lf_config(NULL);
|
||||
|
||||
// bps is limited to 8
|
||||
if (bps >> 4) bps = 8;
|
||||
|
||||
sample_config config = { decimation, bps, averaging, divisor, trigger_threshold, samples_to_skip, true };
|
||||
|
||||
return lf_config(&config);
|
||||
}
|
||||
|
||||
|
@ -1334,13 +1349,14 @@ static command_t CommandTable[] = {
|
|||
{"visa2000", CmdLFVisa2k, AlwaysAvailable, "{ Visa2000 RFIDs... }"},
|
||||
{"", CmdHelp, AlwaysAvailable, ""},
|
||||
{"config", CmdLFConfig, IfPm3Lf, "Get/Set config for LF sampling, bit/sample, decimation, frequency"},
|
||||
{"cmdread", CmdLFCommandRead, IfPm3Lf, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
|
||||
{"read", CmdLFRead, IfPm3Lf, "['s' silent] Read 125/134 kHz LF ID-only tag. Do 'lf read h' for help"},
|
||||
{"search", CmdLFfind, AlwaysAvailable, "[offline] ['u'] Read and Search for valid known tag (in offline mode it you can load first then search) \n\t\t-- 'u' to search for unknown tags"},
|
||||
{"sim", CmdLFSim, IfPm3Lf, "[GAP] -- Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, IfPm3Lf, "[clock] [invert <1|0>] [biphase/manchester/raw <'b'|'m'|'r'>] [msg separator 's'] [d <hexdata>] \n\t\t-- Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, IfPm3Lf, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, IfPm3Lf, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"},
|
||||
{"cmdread", CmdLFCommandRead, IfPm3Lf, "Modulate LF reader field to send command before read (all periods in microseconds)"},
|
||||
{"read", CmdLFRead, IfPm3Lf, "Read LF tag"},
|
||||
{"search", CmdLFfind, AlwaysAvailable, "Read and Search for valid known tag (in offline mode it you can load first then search)"},
|
||||
{"sim", CmdLFSim, IfPm3Lf, "Simulate LF tag from buffer with optional GAP (in microseconds)"},
|
||||
{"simask", CmdLFaskSim, IfPm3Lf, "Simulate LF ASK tag from demodbuffer or input"},
|
||||
{"simfsk", CmdLFfskSim, IfPm3Lf, "Simulate LF FSK tag from demodbuffer or input"},
|
||||
{"simpsk", CmdLFpskSim, IfPm3Lf, "Simulate LF PSK tag from demodbuffer or input"},
|
||||
// {"simpsk", CmdLFnrzSim, IfPm3Lf, "Simulate LF NRZ tag from demodbuffer or input"},
|
||||
{"simbidir", CmdLFSimBidir, IfPm3Lf, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
|
||||
{"sniff", CmdLFSniff, IfPm3Lf, "Sniff LF traffic between reader and tag"},
|
||||
{"tune", CmdLFTune, IfPm3Lf, "Continuously measure LF antenna tuning"},
|
||||
|
|
|
@ -113,12 +113,12 @@ typedef struct {
|
|||
|
||||
// A struct used to send sample-configs over USB
|
||||
typedef struct {
|
||||
uint8_t decimation;
|
||||
uint8_t bits_per_sample;
|
||||
bool averaging;
|
||||
int divisor;
|
||||
int trigger_threshold;
|
||||
uint32_t samples_to_skip;
|
||||
int8_t decimation;
|
||||
int8_t bits_per_sample;
|
||||
int8_t averaging;
|
||||
int16_t divisor;
|
||||
int16_t trigger_threshold;
|
||||
int32_t samples_to_skip;
|
||||
bool verbose;
|
||||
} PACKED sample_config;
|
||||
/*
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue