This commit is contained in:
iceman1001
2020-01-09 20:08:40 +01:00
48 changed files with 869 additions and 627 deletions
+4
View File
@@ -3,6 +3,10 @@ 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]
- Fix `lf config` - when called with no params, it no longer mess up all device lf config settings. (@iceman1001)
- Change `lf indala clone` - new option `--Q5` writes to q5/T5555 tags. (@iceman1001)
- Change `lf indala clone` - new option `-c <card id>` allows cloning INDALA tag from Heden2L/Hedengren ID format (@iceman1001) - Thanks to @randomdude42 for solution
- Change `lf indala demod` - added decode Heden2L/Hedengren format (@iceman1001) - Thanks to @randomdude42 for solution
- Add `commands.md` - document with all proxmark client commands. Generated with XX_internal_command_dump_markdown_XX. (@iceman1001)
- Change `lf pac clone` - new option `c <card id>` to allow cloning PAC/Stanley tag from card ID (@danshuk)
- Change `lf pac read` - decoded PAC/Stanley card ID (@danshuk)
+4 -4
View File
@@ -730,11 +730,11 @@ static void PacketReceived(PacketCommandNG *packet) {
}
case CMD_LF_ACQ_RAW_ADC: {
struct p {
uint8_t silent;
uint8_t verbose;
uint32_t samples;
} PACKED;
struct p *payload = (struct p *)packet->data.asBytes;
uint32_t bits = SampleLF(payload->silent, payload->samples);
uint32_t bits = SampleLF(payload->verbose, payload->samples);
reply_ng(CMD_LF_ACQ_RAW_ADC, PM3_SUCCESS, (uint8_t *)&bits, sizeof(bits));
break;
}
@@ -780,7 +780,7 @@ static void PacketReceived(PacketCommandNG *packet) {
}
case CMD_LF_NRZ_SIMULATE: {
lf_nrzsim_t *payload = (lf_nrzsim_t *)packet->data.asBytes;
CmdNRZsimTAG(payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_asksim_t), payload->data, true);
CmdNRZsimTAG(payload->invert, payload->separator, payload->clock, packet->length - sizeof(lf_nrzsim_t), payload->data, true);
break;
}
case CMD_LF_HID_CLONE: {
@@ -1603,7 +1603,7 @@ static void PacketReceived(PacketCommandNG *packet) {
BigBuf_Clear_ext(false);
BigBuf_free();
}
// 40 000 - (512-3) 509 = 39491
uint16_t offset = MIN(BIGBUF_SIZE - PM3_CMD_DATA_SIZE - 3, payload->offset);
+7 -7
View File
@@ -1299,13 +1299,13 @@ void ReadHitagS(hitag_function htf, hitag_data *htd) {
tag.pages[pageNum][i] = 0x0;
for (i = 0; i < 4; i++) { // set page bytes from recieved bits
tag.pages[pageNum][i] += ((pageData[i * 8] << 7)
| (pageData[1 + (i * 8)] << 6)
| (pageData[2 + (i * 8)] << 5)
| (pageData[3 + (i * 8)] << 4)
| (pageData[4 + (i * 8)] << 3)
| (pageData[5 + (i * 8)] << 2)
| (pageData[6 + (i * 8)] << 1)
| pageData[7 + (i * 8)]);
| (pageData[1 + (i * 8)] << 6)
| (pageData[2 + (i * 8)] << 5)
| (pageData[3 + (i * 8)] << 4)
| (pageData[4 + (i * 8)] << 3)
| (pageData[5 + (i * 8)] << 2)
| (pageData[6 + (i * 8)] << 1)
| pageData[7 + (i * 8)]);
}
if (tag.auth && tag.LKP && pageNum == 1) {
Dbprintf("Page[%2d]: %02X %02X %02X %02X", pageNum, pwdh0,
+20 -8
View File
@@ -61,7 +61,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
adc_val = AT91C_BASE_SSC->SSC_RHR;
periods++;
if (logging) logSample(adc_val, 1, 8, 0, 0);
if (logging) logSample(adc_val, 1, 8, 0);
// Only test field changes if state of adc values matter
if (!wait) {
@@ -91,7 +91,7 @@ size_t lf_count_edge_periods_ex(size_t max, bool wait, bool detect_gap) {
if (periods == max) return 0;
}
}
if (logging) logSample(255, 1, 8, 0, 0);
if (logging) logSample(255, 1, 8, 0);
return 0;
}
@@ -150,12 +150,12 @@ void lf_init(bool reader) {
AT91C_BASE_PIOA->PIO_OER = GPIO_SSC_DOUT;
LOW(GPIO_SSC_DOUT);
// Enable peripheral Clock for TIMER_CLOCK0
// Enable peripheral Clock for TIMER_CLOCK 0
AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_TC0);
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();
if (logging) initSampleBuffer(NULL);
}
@@ -189,9 +189,21 @@ void lf_finalize() {
size_t lf_detect_field_drop(size_t max) {
size_t periods = 0;
volatile uint8_t adc_val;
int16_t checked = 0;
while (true) {
// only every 1000th times, in order to save time when collecting samples.
if (checked == 1000) {
if (BUTTON_PRESS() || data_available()) {
checked = -1;
break;
} else {
checked = 0;
}
}
++checked;
// usb check?
while (!BUTTON_PRESS()) {
// Watchdog hit
WDT_HIT();
@@ -199,7 +211,7 @@ size_t lf_detect_field_drop(size_t max) {
periods++;
adc_val = AT91C_BASE_SSC->SSC_RHR;
if (logging) logSample(adc_val, 1, 8, 0, 0);
if (logging) logSample(adc_val, 1, 8, 0);
if (adc_val == 0) {
rising_edge = false;
+17 -17
View File
@@ -473,7 +473,7 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_READER | FPGA_LF_ADC_READER_FIELD);
// now do the read
DoAcquisition_config(false, 0);
DoAcquisition_config(true, 0);
// Turn off antenna
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1182,7 +1182,7 @@ static void nrzSimBit(uint8_t c, int *n, uint8_t clock) {
*n += clock;
}
// args clock,
// args clock,
void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size, uint8_t *bits, bool ledcontrol) {
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
@@ -1198,7 +1198,7 @@ void CmdNRZsimTAG(uint8_t invert, uint8_t separator, uint8_t clk, uint16_t size,
nrzSimBit(bits[i] ^ invert, &n, clk);
}
if (bits[0] == bits[size - 1]) { //run a second set inverted (for ask/raw || biphase phase)
if (bits[0] == bits[size - 1]) {
for (i = 0; i < size; i++) {
nrzSimBit(bits[i] ^ invert ^ 1, &n, clk);
}
@@ -1239,7 +1239,7 @@ void CmdHIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1, true);
DoAcquisition_default(-1, false);
// FSK demodulator
size = 50 * 128 * 2; //big enough to catch 2 sequences of largest format
int idx = HIDdemodFSK(dest, &size, &hi2, &hi, &lo, &dummyIdx);
@@ -1330,7 +1330,7 @@ void CmdAWIDdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol)
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1, true);
DoAcquisition_default(-1, false);
// FSK demodulator
size = MIN(12800, BigBuf_max_traceLen());
@@ -1421,11 +1421,11 @@ void CmdEM410xdemod(int findone, uint32_t *high, uint64_t *low, int ledcontrol)
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1, true);
DoAcquisition_default(-1, false);
size = MIN(16385, BigBuf_max_traceLen());
//askdemod and manchester decode
//askdemod and manchester decode
int errCnt = askdemod(dest, &size, &clk, &invert, maxErr, 0, 1);
WDT_HIT();
@@ -1486,10 +1486,10 @@ void CmdIOdemodFSK(int findone, uint32_t *high, uint32_t *low, int ledcontrol) {
WDT_HIT();
if (ledcontrol) LED_A_ON();
DoAcquisition_default(-1, true);
DoAcquisition_default(-1, false);
size = MIN(12000, BigBuf_max_traceLen());
//fskdemod and get start index
int idx = detectIOProx(dest, &size, &dummyIdx);
if (idx < 0) continue;
@@ -1772,7 +1772,7 @@ void T55xxResetRead(uint8_t flags) {
TurnReadLFOn(T55xx_Timing.m[downlink_mode].read_gap);
// Acquisition
DoPartialAcquisition(0, true, BigBuf_max_traceLen(), 0);
DoPartialAcquisition(0, false, BigBuf_max_traceLen(), 0);
// Turn the field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1869,7 +1869,7 @@ void T55xxWriteBlock(uint8_t *data) {
// response should be (for t55x7) a 0 bit then (ST if on)
// block data written in on repeat until reset.
//DoPartialAcquisition(20, true, 12000);
//DoPartialAcquisition(20, false, 12000);
}
// turn field off
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
@@ -1930,7 +1930,7 @@ bool brute_mem = (flags & 0x0100) >> 8;
// Acquisition
// Now do the acquisition
DoPartialAcquisition(0, true, samples, 0);
DoPartialAcquisition(0, false, samples, 0);
// Turn the field off
if (!brute_mem) {
@@ -1990,7 +1990,7 @@ void T55xxReadBlock(uint8_t page, bool pwd_mode, bool brute_mem, uint8_t block,
// Acquisition
// Now do the acquisition
DoPartialAcquisition(0, true, samples, 0);
DoPartialAcquisition(0, false, samples, 0);
// Turn the field off
if (!brute_mem) {
@@ -2447,7 +2447,7 @@ void EM4xReadWord(uint8_t addr, uint32_t pwd, uint8_t usepwd) {
WaitUS(400);
DoPartialAcquisition(20, true, 6000, 1000);
DoPartialAcquisition(20, false, 6000, 1000);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_LF_EM4X_READWORD, PM3_SUCCESS, NULL, 0);
@@ -2480,7 +2480,7 @@ void EM4xWriteWord(uint8_t addr, uint32_t data, uint32_t pwd, uint8_t usepwd) {
//Wait 20ms for write to complete?
WaitMS(7);
DoPartialAcquisition(20, true, 6000, 1000);
DoPartialAcquisition(20, false, 6000, 1000);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
reply_ng(CMD_LF_EM4X_WRITEWORD, PM3_SUCCESS, NULL, 0);
@@ -2550,7 +2550,7 @@ void Cotag(uint32_t arg0) {
doCotagAcquisitionManchester();
break;
case 2:
DoAcquisition_config(true, 0);
DoAcquisition_config(true, true);
break;
}
+170 -111
View File
@@ -15,6 +15,7 @@
#include "dbprint.h"
#include "util.h"
#include "lfdemod.h"
#include "string.h" // memset
/*
Default LF config is set to:
@@ -32,7 +33,7 @@ void printConfig() {
uint32_t d = config.divisor;
DbpString(_BLUE_("LF Sampling config"));
Dbprintf(" [q] divisor.............%d ( "_GREEN_("%d.%02d kHz")")", d, 12000 / (d + 1), ((1200000 + (d + 1) / 2) / (d + 1)) - ((12000 / (d + 1)) * 100));
Dbprintf(" [b] bps.................%d", config.bits_per_sample);
Dbprintf(" [b] bits per sample.....%d", config.bits_per_sample);
Dbprintf(" [d] decimation..........%d", config.decimation);
Dbprintf(" [a] averaging...........%s", (config.averaging) ? "Yes" : "No");
Dbprintf(" [t] trigger threshold...%d", config.trigger_threshold);
@@ -41,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
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;
// 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;
if (sc->verbose)
printConfig();
@@ -69,12 +85,6 @@ sample_config *getSamplingConfig() {
return &config;
}
struct BitstreamOut {
uint8_t *buffer;
uint32_t numbits;
uint32_t position;
};
/**
* @brief Pushes bit onto the stream
* @param stream
@@ -88,6 +98,87 @@ void pushBit(BitstreamOut *stream, uint8_t bit) {
stream->numbits++;
}
// Holds bit packed struct of samples.
BitstreamOut data = {0, 0, 0};
// internal struct to keep track of samples gathered
sampling_t samples = {0, 0, 0, 0};
void initSampleBuffer(uint32_t *sample_size) {
if (sample_size == NULL || *sample_size == 0) {
*sample_size = BigBuf_max_traceLen();
} else {
*sample_size = MIN(*sample_size, BigBuf_max_traceLen());
}
// use a bitstream to handle the output
data.buffer = BigBuf_get_addr();
memset(data.buffer, 0, *sample_size);
//
samples.dec_counter = 0;
samples.sum = 0;
samples.counter = 0;
samples.total_saved = 0;
}
uint32_t getSampleCounter() {
return samples.total_saved;
}
void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg) {
if (!data.buffer) return;
if (bits_per_sample == 0) bits_per_sample = 1;
if (bits_per_sample > 8) bits_per_sample = 8;
if (decimation == 0) decimation = 1;
// keep track of total gather samples regardless how many was discarded.
samples.counter++;
if (avg) {
samples.sum += sample;
}
// check decimation
if (decimation > 1) {
samples.dec_counter++;
if (samples.dec_counter < decimation) return;
samples.dec_counter = 0;
}
// averaging
if (avg && decimation > 1) {
sample = samples.sum / decimation;
samples.sum = 0;
}
// store the sample
samples.total_saved++;
if (bits_per_sample == 8) {
data.buffer[samples.total_saved - 1] = sample;
// add number of bits.
data.numbits = samples.total_saved << 3;
} else {
pushBit(&data, sample & 0x80);
if (bits_per_sample > 1) pushBit(&data, sample & 0x40);
if (bits_per_sample > 2) pushBit(&data, sample & 0x20);
if (bits_per_sample > 3) pushBit(&data, sample & 0x10);
if (bits_per_sample > 4) pushBit(&data, sample & 0x08);
if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
if (bits_per_sample > 6) pushBit(&data, sample & 0x02);
}
}
/**
* Setup the FPGA to listen for samples. This method downloads the FPGA bitstream
* if not already loaded, sets divisor and starts up the antenna.
@@ -128,45 +219,39 @@ void LFSetupFPGAForADC(int divisor, bool lf_field) {
* value that will be used is the average value of the three samples.
* @param trigger_threshold - a threshold. The sampling won't commence until this threshold has been reached. Set
* to -1 to ignore threshold.
* @param silent - is true, now outputs are made. If false, dbprints the status
* @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 averaging, int trigger_threshold, bool silent, int bufsize, 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) {
uint8_t *dest = BigBuf_get_addr();
bufsize = (bufsize > 0 && bufsize < BigBuf_max_traceLen()) ? bufsize : BigBuf_max_traceLen();
initSampleBuffer(&sample_size);
if (bits_per_sample < 1) bits_per_sample = 1;
if (bits_per_sample > 8) bits_per_sample = 8;
if (decimation < 1) decimation = 1;
// use a bit stream to handle the output
BitstreamOut data = { dest, 0, 0};
int sample_counter = 0;
uint8_t sample;
// if we want to do averaging
uint32_t sample_sum = 0 ;
uint32_t sample_total_numbers = 0;
uint32_t sample_total_saved = 0;
uint32_t cancel_counter = 0;
uint16_t checked = 0;
int16_t checked = 0;
while (true) {
// only every 1000th times, in order to save time when collecting samples.
if (checked == 1000) {
if (BUTTON_PRESS() || data_available())
if (BUTTON_PRESS() || data_available()) {
checked = -1;
break;
else
} else {
checked = 0;
}
}
++checked;
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
// AT91C_BASE_SSC->SSC_THR = 0x43;
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// Testpoint 8 (TP8) can be used to trigger oscilliscope
LED_D_OFF();
@@ -188,57 +273,23 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
continue;
}
sample_total_numbers++;
logSample(sample, decimation, bits_per_sample, avg);
if (averaging)
sample_sum += sample;
// check decimation
if (decimation > 1) {
sample_counter++;
if (sample_counter < decimation) continue;
sample_counter = 0;
}
// averaging
if (averaging && decimation > 1) {
sample = sample_sum / decimation;
sample_sum = 0;
}
// store the sample
sample_total_saved ++;
if (bits_per_sample == 8) {
dest[sample_total_saved - 1] = sample;
// Get the return value correct
data.numbits = sample_total_saved << 3;
if (sample_total_saved >= bufsize) break;
} else {
pushBit(&data, sample & 0x80);
if (bits_per_sample > 1) pushBit(&data, sample & 0x40);
if (bits_per_sample > 2) pushBit(&data, sample & 0x20);
if (bits_per_sample > 3) pushBit(&data, sample & 0x10);
if (bits_per_sample > 4) pushBit(&data, sample & 0x08);
if (bits_per_sample > 5) pushBit(&data, sample & 0x04);
if (bits_per_sample > 6) pushBit(&data, sample & 0x02);
if ((data.numbits >> 3) + 1 >= bufsize) break;
}
if (samples.total_saved >= sample_size) break;
}
}
if (!silent) {
Dbprintf("Done, saved " _YELLOW_("%d")"out of " _YELLOW_("%d")"seen samples at " _YELLOW_("%d")"bits/sample", sample_total_saved, sample_total_numbers, bits_per_sample);
Dbprintf("buffer samples: %02x %02x %02x %02x %02x %02x %02x %02x ...",
dest[0], dest[1], dest[2], dest[3], dest[4], dest[5], dest[6], dest[7]);
if (checked == -1 && verbose) {
Dbprintf("lf sampling aborted");
}
if (verbose) {
Dbprintf("Done, saved " _YELLOW_("%d")"out of " _YELLOW_("%d")"seen samples at " _YELLOW_("%d")"bits/sample", samples.total_saved, samples.counter, bits_per_sample);
}
// Ensure that DC offset removal and noise check is performed for any device-side processing
removeSignalOffset(dest, bufsize);
computeSignalProperties(dest, bufsize);
removeSignalOffset(data.buffer, samples.total_saved);
computeSignalProperties(data.buffer, samples.total_saved);
return data.numbits;
}
@@ -247,32 +298,33 @@ uint32_t DoAcquisition(uint8_t decimation, uint32_t bits_per_sample, bool averag
* This method is typically used by tag-specific readers who just wants to read the samples
* the normal way
* @param trigger_threshold
* @param silent
* @param verbose
* @return number of bits sampled
*/
uint32_t DoAcquisition_default(int trigger_threshold, bool silent) {
return DoAcquisition(1, 8, 0, trigger_threshold, silent, 0, 0, 0);
uint32_t DoAcquisition_default(int trigger_threshold, bool verbose) {
return DoAcquisition(1, 8, 0, trigger_threshold, verbose, 0, 0, 0);
}
uint32_t DoAcquisition_config(bool silent, int sample_size) {
uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size) {
return DoAcquisition(config.decimation
, config.bits_per_sample
, config.averaging
, config.trigger_threshold
, silent
, verbose
, sample_size
, 0
, config.samples_to_skip);
}
uint32_t DoPartialAcquisition(int trigger_threshold, bool silent, int sample_size, uint32_t cancel_after) {
return DoAcquisition(1, 8, 0, trigger_threshold, silent, sample_size, cancel_after, 0);
uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after) {
return DoAcquisition(1, 8, 0, trigger_threshold, verbose, sample_size, cancel_after, 0);
}
uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
if (!silent)
uint32_t ReadLF(bool activeField, bool verbose, uint32_t sample_size) {
if (verbose)
printConfig();
LFSetupFPGAForADC(config.divisor, activeField);
uint32_t ret = DoAcquisition_config(silent, sample_size);
uint32_t ret = DoAcquisition_config(verbose, sample_size);
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
return ret;
}
@@ -281,9 +333,9 @@ uint32_t ReadLF(bool activeField, bool silent, int sample_size) {
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SampleLF(bool silent, int sample_size) {
uint32_t SampleLF(bool verbose, uint32_t sample_size) {
BigBuf_Clear_ext(false);
return ReadLF(true, silent, sample_size);
return ReadLF(true, verbose, sample_size);
}
/**
* Initializes the FPGA for sniffer-mode (field off), and acquires the samples.
@@ -310,7 +362,7 @@ void doT55x7Acquisition(size_t sample_size) {
if (bufsize > sample_size)
bufsize = sample_size;
uint8_t curSample, lastSample = 0;
uint8_t lastSample = 0;
uint16_t i = 0, skipCnt = 0;
bool startFound = false;
bool highFound = false;
@@ -330,24 +382,24 @@ void doT55x7Acquisition(size_t sample_size) {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
curSample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
LED_D_OFF();
// skip until the first high sample above threshold
if (!startFound && curSample > T55xx_READ_UPPER_THRESHOLD) {
//if (curSample > lastSample)
// lastSample = curSample;
if (!startFound && sample > T55xx_READ_UPPER_THRESHOLD) {
highFound = true;
} else if (!highFound) {
skipCnt++;
continue;
}
// skip until the first low sample below threshold
if (!startFound && curSample < T55xx_READ_LOWER_THRESHOLD) {
//if (curSample > lastSample)
lastSample = curSample;
if (!startFound && sample < T55xx_READ_LOWER_THRESHOLD) {
lastSample = sample;
lowFound = true;
} else if (!lowFound) {
skipCnt++;
@@ -355,14 +407,14 @@ void doT55x7Acquisition(size_t sample_size) {
}
// skip until first high samples begin to change
if (startFound || curSample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL) {
if (startFound || sample > T55xx_READ_LOWER_THRESHOLD + T55xx_READ_TOL) {
// if just found start - recover last sample
if (!startFound) {
dest[i++] = lastSample;
startFound = true;
}
// collect samples
dest[i++] = curSample;
dest[i++] = sample;
}
}
}
@@ -388,7 +440,7 @@ void doCotagAcquisition(size_t sample_size) {
bufsize = sample_size;
dest[0] = 0;
uint8_t sample, firsthigh = 0, firstlow = 0;
uint8_t firsthigh = 0, firstlow = 0;
uint16_t i = 0;
uint16_t noise_counter = 0;
@@ -406,8 +458,12 @@ void doCotagAcquisition(size_t sample_size) {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// find first peak
if (!firsthigh) {
@@ -441,7 +497,6 @@ void doCotagAcquisition(size_t sample_size) {
// Ensure that DC offset removal and noise check is performed for any device-side processing
removeSignalOffset(dest, bufsize);
computeSignalProperties(dest, bufsize);
}
uint32_t doCotagAcquisitionManchester() {
@@ -453,7 +508,7 @@ uint32_t doCotagAcquisitionManchester() {
bufsize = COTAG_BITS;
dest[0] = 0;
uint8_t sample, firsthigh = 0, firstlow = 0;
uint8_t firsthigh = 0, firstlow = 0;
uint16_t sample_counter = 0, period = 0;
uint8_t curr = 0, prev = 0;
uint16_t noise_counter = 0;
@@ -471,8 +526,12 @@ uint32_t doCotagAcquisitionManchester() {
WDT_HIT();
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_TXRDY) {
LED_D_ON();
}
if (AT91C_BASE_SSC->SSC_SR & AT91C_SSC_RXRDY) {
sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
volatile uint8_t sample = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
// find first peak
if (!firsthigh) {
+23 -9
View File
@@ -4,7 +4,18 @@
#include "common.h"
#include "pm3_cmd.h"
typedef struct BitstreamOut BitstreamOut;
typedef struct {
uint8_t *buffer;
uint32_t numbits;
uint32_t position;
} BitstreamOut;
typedef struct {
int dec_counter;
uint32_t sum;
uint32_t counter;
uint32_t total_saved;
} sampling_t;
/**
* acquisition of Cotag LF signal. Similar to other LF, since the Cotag has such long datarate RF/384
@@ -23,7 +34,7 @@ void doT55x7Acquisition(size_t sample_size);
* Initializes the FPGA for reader-mode (field on), and acquires the samples.
* @return number of bits sampled
**/
uint32_t SampleLF(bool silent, int sample_size);
uint32_t SampleLF(bool verbose, uint32_t sample_size);
/**
* Initializes the FPGA for sniff-mode (field off), and acquires the samples.
@@ -31,32 +42,35 @@ uint32_t SampleLF(bool silent, int sample_size);
**/
uint32_t SniffLF();
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 silent, int sample_size, uint32_t cancel_after);
uint32_t DoPartialAcquisition(int trigger_threshold, bool verbose, uint32_t sample_size, uint32_t cancel_after);
/**
* @brief Does sample acquisition, ignoring the config values set in the sample_config.
* This method is typically used by tag-specific readers who just wants to read the samples
* the normal way
* @param trigger_threshold
* @param silent
* @param verbose
* @return number of bits sampled
*/
uint32_t DoAcquisition_default(int trigger_threshold, bool silent);
uint32_t DoAcquisition_default(int trigger_threshold, bool verbose);
/**
* @brief Does sample acquisition, using the config values set in the sample_config.
* @param trigger_threshold
* @param silent
* @param verbose
* @return number of bits sampled
*/
uint32_t DoAcquisition_config(bool silent, int sample_size);
uint32_t DoAcquisition_config(bool verbose, uint32_t sample_size);
/**
* Refactoring of lf sampling buffer
*/
void initSamplingBuffer(void);
void logSample(uint8_t sample, uint8_t decimation, uint32_t bits_per_sample, bool averaging, int trigger_threshold);
void initSampleBuffer(uint32_t *sample_size);
void logSample(uint8_t sample, uint8_t decimation, uint8_t bits_per_sample, bool avg);
uint32_t getSampleCounter();
/**
+20 -30
View File
@@ -3421,7 +3421,7 @@ TRexBool trex_searchrange(TRex *exp, const TRexChar *text_begin, const TRexChar
if (!cur)
break;
node = exp->_nodes[node].next;
}
}
text_begin++;
} while (cur == NULL && text_begin != text_end);
@@ -3484,8 +3484,12 @@ TRexBool trex_getsubexp(TRex *exp, int n, TRexMatch *subexp) {
static void arg_str_resetfn(struct arg_str *parent) {
int i;
ARG_TRACE(("%s:resetfn(%p)\n", __FILE__, parent));
parent->count = 0;
for (i = 0; i < parent->count; i++) {
parent->sval[i] = "";
}
}
@@ -3671,8 +3675,7 @@ void arg_register_error(struct arg_end *end,
* Return index of first table entry with a matching short option
* or -1 if no match was found.
*/
static
int find_shortoption(struct arg_hdr * *table, char shortopt) {
static int find_shortoption(struct arg_hdr** table, char shortopt) {
int tabindex;
for (tabindex = 0; !(table[tabindex]->flag & ARG_TERMINATOR); tabindex++) {
if (table[tabindex]->shortopts &&
@@ -3682,7 +3685,6 @@ int find_shortoption(struct arg_hdr * *table, char shortopt) {
return -1;
}
struct longoptions {
int getoptval;
int noptions;
@@ -3706,8 +3708,7 @@ void dump_longoptions(struct longoptions *longoptions) {
}
#endif
static
struct longoptions *alloc_longoptions(struct arg_hdr * *table) {
static struct longoptions* alloc_longoptions(struct arg_hdr** table) {
struct longoptions *result;
size_t nbytes;
int noptions = 1;
@@ -3789,8 +3790,7 @@ struct longoptions *alloc_longoptions(struct arg_hdr * *table) {
return result;
}
static
char *alloc_shortoptions(struct arg_hdr * *table) {
static char* alloc_shortoptions(struct arg_hdr** table) {
char *result;
size_t len = 2;
int tabindex;
@@ -3830,8 +3830,7 @@ char *alloc_shortoptions(struct arg_hdr * *table) {
/* return index of the table terminator entry */
static
int arg_endindex(struct arg_hdr * *table) {
static int arg_endindex(struct arg_hdr** table) {
int tabindex = 0;
while (!(table[tabindex]->flag & ARG_TERMINATOR))
tabindex++;
@@ -3839,10 +3838,9 @@ int arg_endindex(struct arg_hdr * *table) {
}
static
void arg_parse_tagged(int argc,
char * *argv,
struct arg_hdr * *table,
static void arg_parse_tagged(int argc,
char **argv,
struct arg_hdr **table,
struct arg_end *endtable) {
struct longoptions *longoptions;
char *shortoptions;
@@ -3953,10 +3951,9 @@ void arg_parse_tagged(int argc,
}
static
void arg_parse_untagged(int argc,
char * *argv,
struct arg_hdr * *table,
static void arg_parse_untagged(int argc,
char **argv,
struct arg_hdr **table,
struct arg_end *endtable) {
int tabindex = 0;
int errorlast = 0;
@@ -4010,7 +4007,6 @@ void arg_parse_untagged(int argc,
optarglast = argv[optind];
parentlast = parent;
}
}
/* if a tenative error still remains at this point then register it as a proper error */
@@ -4030,8 +4026,7 @@ void arg_parse_untagged(int argc,
}
static
void arg_parse_check(struct arg_hdr * *table, struct arg_end *endtable) {
static void arg_parse_check(struct arg_hdr **table, struct arg_end *endtable) {
int tabindex = 0;
/* printf("arg_parse_check()\n"); */
do {
@@ -4045,8 +4040,7 @@ void arg_parse_check(struct arg_hdr * *table, struct arg_end *endtable) {
}
static
void arg_reset(void * *argtable) {
static void arg_reset(void **argtable) {
struct arg_hdr * *table = (struct arg_hdr * *)argtable;
int tabindex = 0;
/*printf("arg_reset(%p)\n",argtable);*/
@@ -4138,8 +4132,7 @@ int arg_parse(int argc, char * *argv, void * *argtable) {
* dest[] == "goodbye cruel world!"
* ndest == 10
*/
static
void arg_cat(char * *pdest, const char *src, size_t *pndest) {
static void arg_cat(char **pdest, const char *src, size_t *pndest) {
char *dest = *pdest;
char *end = dest + *pndest;
@@ -4160,8 +4153,7 @@ void arg_cat(char * *pdest, const char *src, size_t *pndest) {
}
static
void arg_cat_option(char *dest,
static void arg_cat_option(char *dest,
size_t ndest,
const char *shortopts,
const char *longopts,
@@ -4219,8 +4211,7 @@ void arg_cat_option(char *dest,
}
}
static
void arg_cat_optionv(char *dest,
static void arg_cat_optionv(char *dest,
size_t ndest,
const char *shortopts,
const char *longopts,
@@ -4666,7 +4657,6 @@ int arg_nullcheck(void * *argtable) {
return 0;
}
/*
* arg_free() is deprecated in favour of arg_freetable() due to a flaw in its design.
* The flaw results in memory leak in the (very rare) case that an intermediate
+16
View File
@@ -1,4 +1,6 @@
/*******************************************************************************
* argtable3: Declares the main interfaces of the library
*
* This file is part of the argtable3 library.
*
* Copyright (C) 1998-2001,2003-2011,2013 Stewart Heitmann
@@ -39,6 +41,13 @@ extern "C" {
#endif
#define ARG_REX_ICASE 1
#define ARG_DSTR_SIZE 200
#define ARG_CMD_NAME_LEN 100
#define ARG_CMD_DESCRIPTION_LEN 256
#ifndef ARG_REPLACE_GETOPT
#define ARG_REPLACE_GETOPT 1 /* use the embedded getopt as the system getopt(3) */
#endif /* ARG_REPLACE_GETOPT */
/* bit masks for arg_hdr.flag */
enum {
@@ -143,6 +152,13 @@ struct arg_end {
const char **argval; /* Array of pointers to offending argv[] string */
};
/*
typedef struct arg_cmd_info {
char name[ARG_CMD_NAME_LEN];
char description[ARG_CMD_DESCRIPTION_LEN];
arg_cmdfn* proc;
} arg_cmd_info_t;
*/
/**** arg_xxx constructor functions *********************************/
+7 -7
View File
@@ -13,16 +13,16 @@
#include "argtable3.h"
#include "util.h"
#define arg_param_begin arg_lit0("hH", "help", "print this help and exit")
#define arg_param_begin arg_lit0("hH", "help", "This help")
#define arg_param_end arg_end(20)
#define arg_getsize(a) (sizeof(a) / sizeof(a[0]))
#define arg_get_lit(n)(((struct arg_lit*)argtable[n])->count)
#define arg_getsize(a) (sizeof(a) / sizeof(a[0]))
#define arg_get_lit(n) (((struct arg_lit*)argtable[n])->count)
#define arg_get_int_count(n)(((struct arg_int*)argtable[n])->count)
#define arg_get_int(n)(((struct arg_int*)argtable[n])->ival[0])
#define arg_get_int_def(n,def)(arg_get_int_count(n)?(arg_get_int(n)):(def))
#define arg_get_str(n)((struct arg_str*)argtable[n])
#define arg_get_str_len(n)(strlen(((struct arg_str*)argtable[n])->sval[0]))
#define arg_get_int(n) (((struct arg_int*)argtable[n])->ival[0])
#define arg_get_int_def(n, def)(arg_get_int_count(n) ? (arg_get_int(n)) : (def))
#define arg_get_str(n) ((struct arg_str*)argtable[n])
#define arg_get_str_len(n) (strlen(((struct arg_str*)argtable[n])->sval[0]))
#define arg_strx1(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 1, 250, (glossary)))
#define arg_strx0(shortopts, longopts, datatype, glossary) (arg_strn((shortopts), (longopts), (datatype), 0, 250, (glossary)))
+6 -6
View File
@@ -1589,7 +1589,7 @@ static uint8_t getByte(uint8_t bits_per_sample, BitstreamOut *b) {
return val;
}
int getSamples(uint32_t n, bool silent) {
int getSamples(uint32_t n, bool verbose) {
//If we get all but the last byte in bigbuf,
// we don't have to worry about remaining trash
// in the last byte in case the bits-per-sample
@@ -1599,7 +1599,7 @@ int getSamples(uint32_t n, bool silent) {
if (n == 0 || n > sizeof(got))
n = sizeof(got);
if (!silent) PrintAndLogEx(NORMAL, "Reading %d bytes from device memory\n", n);
if (verbose) PrintAndLogEx(NORMAL, "Reading %d bytes from device memory\n", n);
PacketResponseNG response;
if (!GetFromDevice(BIG_BUF, got, n, 0, NULL, 0, &response, 10000, true)) {
@@ -1607,20 +1607,20 @@ int getSamples(uint32_t n, bool silent) {
return PM3_ETIMEOUT;
}
if (!silent) PrintAndLogEx(NORMAL, "Data fetched");
if (verbose) PrintAndLogEx(NORMAL, "Data fetched");
uint8_t bits_per_sample = 8;
//Old devices without this feature would send 0 at arg[0]
if (response.oldarg[0] > 0) {
sample_config *sc = (sample_config *) response.data.asBytes;
if (!silent) PrintAndLogEx(NORMAL, "Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation);
if (verbose) PrintAndLogEx(NORMAL, "Samples @ %d bits/smpl, decimation 1:%d ", sc->bits_per_sample, sc->decimation);
bits_per_sample = sc->bits_per_sample;
}
if (bits_per_sample < 8) {
if (!silent) PrintAndLogEx(NORMAL, "Unpacking...");
if (verbose) PrintAndLogEx(NORMAL, "Unpacking...");
BitstreamOut bout = { got, bits_per_sample * n, 0};
int j = 0;
@@ -1630,7 +1630,7 @@ int getSamples(uint32_t n, bool silent) {
}
GraphTraceLen = j;
if (!silent) PrintAndLogEx(NORMAL, "Unpacked %d samples", j);
if (verbose) PrintAndLogEx(NORMAL, "Unpacked %d samples", j);
} else {
for (int j = 0; j < n; j++) {
+1 -1
View File
@@ -68,7 +68,7 @@ void setDemodBuff(uint8_t *buff, size_t size, size_t start_idx);
bool getDemodBuff(uint8_t *buff, size_t *size);
void save_restoreDB(uint8_t saveOpt);// option '1' to save DemodBuffer any other to restore
int AutoCorrelate(const int *in, int *out, size_t len, size_t window, bool SaveGrph, bool verbose);
int getSamples(uint32_t n, bool silent);
int getSamples(uint32_t n, bool verbose);
void setClockGrid(uint32_t clk, int offset);
int directionalThreshold(const int *in, int *out, size_t len, int8_t up, int8_t down);
int AskEdgeDetect(const int *in, int *out, int len, int threshold);
+3 -3
View File
@@ -633,7 +633,7 @@ static int CmdHF15Samples(const char *Cmd) {
clearCommandBuffer();
SendCommandNG(CMD_HF_ISO15693_ACQ_RAW_ADC, NULL, 0);
getSamples(0, false);
getSamples(0, true);
return PM3_SUCCESS;
}
@@ -684,9 +684,9 @@ static int NxpSysInfo(uint8_t *uid) {
return PM3_EWRONGANSVER;
}
bool support_signature = (recv[5] & 0x01);
bool support_signature = (recv[5] & 0x01);
bool support_easmode = (recv[4] & 0x03);
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, " NXP SYSINFO : %s", sprint_hex(recv, 8));
PrintAndLogEx(NORMAL, " Password protection configuration:");
+13 -13
View File
@@ -440,10 +440,10 @@ static void clear_and_send_command(uint8_t flags, uint16_t datalen, uint8_t *dat
*/
static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_t dataPosition, uint8_t length) {
if (param_getlength(Cmd, paramCount) == length) {
if (param_gethex(Cmd, paramCount, data + dataPosition, length) == 1)
return false;
else
return false;
else
return true;
} else {
@@ -460,7 +460,7 @@ static bool add_param(const char *Cmd, uint8_t paramCount, uint8_t *data, uint8_
static void print_rd_noEncrpytion_response(felica_read_without_encryption_response_t *rd_noCry_resp) {
if (rd_noCry_resp->status_flags.status_flag1[0] == 00 &&
rd_noCry_resp->status_flags.status_flag2[0] == 00) {
rd_noCry_resp->status_flags.status_flag2[0] == 00) {
char *temp = sprint_hex(rd_noCry_resp->block_data, sizeof(rd_noCry_resp->block_data));
@@ -653,7 +653,7 @@ static int CmdHFFelicaAuthentication1(const char *Cmd) {
mbedtls_des3_set3key_enc(&des3_ctx, master_key);
PrintAndLogEx(INFO, "3DES Master Secret: %s", sprint_hex(master_key, 24));
} else if (param_getlength(Cmd, paramCount) == 32) {
if (param_gethex(Cmd, paramCount, master_key, 32) == 1) {
PrintAndLogEx(ERR, "Failed param key");
return PM3_EINVARG;
@@ -781,7 +781,7 @@ static int CmdHFFelicaAuthentication2(const char *Cmd) {
mbedtls_des3_init(&des3_ctx);
unsigned char p3c[8];
if (param_getlength(Cmd, paramCount) == 32) {
if (param_gethex(Cmd, paramCount, master_key, 32) == 1) {
PrintAndLogEx(ERR, "Failed param key");
return PM3_EINVARG;
@@ -1131,7 +1131,7 @@ static int CmdHFFelicaRequestSpecificationVersion(const char *Cmd) {
} else {
felica_request_spec_response_t spec_response;
memcpy(&spec_response, (felica_request_spec_response_t *)resp.data.asBytes, sizeof(felica_request_spec_response_t));
if (spec_response.frame_response.IDm[0] != 0) {
PrintAndLogEx(SUCCESS, "\nGot Request Response:");
PrintAndLogEx(SUCCESS, "\nIDm: %s", sprint_hex(spec_response.frame_response.IDm, sizeof(spec_response.frame_response.IDm)));
@@ -1336,12 +1336,12 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
if (!all_nodes) {
// Node Number
if (param_getlength(Cmd, paramCount) == 2) {
if (param_gethex(Cmd, paramCount++, data + 10, 2) == 1) {
PrintAndLogEx(ERR, "Failed param key");
return PM3_EINVARG;
}
} else {
PrintAndLogEx(ERR, "Incorrect Node number length!");
return PM3_EINVARG;
@@ -1349,7 +1349,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
}
if (param_getlength(Cmd, paramCount) == 4) {
if (param_gethex(Cmd, paramCount++, data + 11, 4) == 1) {
PrintAndLogEx(ERR, "Failed param key");
return PM3_EINVARG;
@@ -1372,7 +1372,7 @@ static int CmdHFFelicaRequestService(const char *Cmd) {
if (!custom_IDm && !check_last_idm(data, datalen)) {
return PM3_EINVARG;
}
data[0] = int_to_hex(&datalen);
data[1] = 0x02; // Service Request Command ID
if (all_nodes) {
@@ -1435,12 +1435,12 @@ static int CmdHFFelicaSniff(const char *Cmd) {
}
i++;
}
if (samples2skip == 0) {
samples2skip = 10;
PrintAndLogEx(INFO, "Set default samples2skip: %" PRIu64, samples2skip);
}
if (triggers2skip == 0) {
triggers2skip = 5000;
PrintAndLogEx(INFO, "Set default triggers2skip: %" PRIu64, triggers2skip);
+91 -75
View File
@@ -68,27 +68,28 @@ 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) {
PrintAndLogEx(NORMAL, "Usage: lf read [h] [s] [d numofsamples]");
PrintAndLogEx(NORMAL, "Options:");
PrintAndLogEx(NORMAL, " h This help");
PrintAndLogEx(NORMAL, " s silent run, no printout");
PrintAndLogEx(NORMAL, " d #samples # samples to collect (optional)");
PrintAndLogEx(NORMAL, "Use 'lf config' to set parameters.");
PrintAndLogEx(NORMAL, " s silent");
PrintAndLogEx(NORMAL, "");
PrintAndLogEx(NORMAL, "Examples:");
PrintAndLogEx(NORMAL, " lf read s d 12000 - collects 12000samples silent");
PrintAndLogEx(NORMAL, " lf read s");
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, " 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 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 - performs a read (active field)");
PrintAndLogEx(NORMAL, " lf sniff - performs a sniff (no active field)");
return PM3_SUCCESS;
}
static int usage_lf_simfsk(void) {
@@ -367,7 +366,7 @@ int CmdLFCommandRead(const char *Cmd) {
if (resp.status == PM3_SUCCESS) {
if (i) {
PrintAndLogEx(SUCCESS, "Downloading response signal data");
getSamples(0, true);
getSamples(0, false);
return PM3_SUCCESS;
} else {
PrintAndLogEx(WARNING, "timeout while waiting for reply.");
@@ -457,7 +456,11 @@ int lf_config(sample_config *config) {
if (!session.pm3_present) return PM3_ENOTTY;
clearCommandBuffer();
SendCommandNG(CMD_LF_SAMPLING_SET_CONFIG, (uint8_t *)config, sizeof(sample_config));
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,28 +564,19 @@ 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);
}
int lf_read(bool silent, uint32_t samples) {
int lf_read(bool verbose, uint32_t samples) {
if (!session.pm3_present) return PM3_ENOTTY;
struct p {
uint8_t silent;
uint8_t verbose;
uint32_t samples;
} PACKED;
struct p payload;
payload.silent = silent;
payload.verbose = verbose;
payload.samples = samples;
clearCommandBuffer();
@@ -579,7 +594,7 @@ int lf_read(bool silent, uint32_t samples) {
// resp.oldarg[0] is bits read not bytes read.
uint32_t bits = (resp.data.asDwords[0] / 8);
getSamples(bits, silent);
getSamples(bits, verbose);
return PM3_SUCCESS;
}
@@ -589,21 +604,21 @@ int CmdLFRead(const char *Cmd) {
if (!session.pm3_present) return PM3_ENOTTY;
bool errors = false;
bool silent = false;
bool verbose = true;
uint32_t samples = 0;
uint8_t cmdp = 0;
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
switch (tolower(param_getchar(Cmd, cmdp))) {
case 'h':
return usage_lf_read();
case 's':
silent = true;
cmdp++;
break;
case 'd':
samples = param_get32ex(Cmd, cmdp + 1, 0, 10);
cmdp += 2;
break;
case 's':
verbose = false;
cmdp++;
break;
default:
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
@@ -614,7 +629,7 @@ int CmdLFRead(const char *Cmd) {
//Validations
if (errors) return usage_lf_read();
return lf_read(silent, samples);
return lf_read(verbose, samples);
}
int CmdLFSniff(const char *Cmd) {
@@ -627,7 +642,7 @@ int CmdLFSniff(const char *Cmd) {
clearCommandBuffer();
SendCommandNG(CMD_LF_SNIFF_RAW_ADC, NULL, 0);
WaitForResponse(CMD_ACK, NULL);
getSamples(0, false);
getSamples(0, true);
return PM3_SUCCESS;
}
@@ -1183,7 +1198,7 @@ int CmdLFfind(const char *Cmd) {
bool isOnline = (session.pm3_present && (cmdp != '1'));
if (isOnline)
lf_read(true, 30000);
lf_read(false, 30000);
if (GraphTraceLen < minLength) {
PrintAndLogEx(FAILED, "Data in Graphbuffer was too small.");
@@ -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"},
+1 -1
View File
@@ -32,7 +32,7 @@ int CmdLFSniff(const char *Cmd);
int CmdVchDemod(const char *Cmd);
int CmdLFfind(const char *Cmd);
int lf_read(bool silent, uint32_t samples);
int lf_read(bool verbose, uint32_t samples);
int lf_config(sample_config *config);
#endif
+1 -1
View File
@@ -333,7 +333,7 @@ static int CmdAWIDDemod(const char *Cmd) {
// this read is the "normal" read, which download lf signal and tries to demod here.
static int CmdAWIDRead(const char *Cmd) {
lf_read(true, 12000);
lf_read(false, 12000);
return CmdAWIDDemod(Cmd);
}
+1 -1
View File
@@ -96,7 +96,7 @@ static int CmdCOTAGRead(const char *Cmd) {
case 2: {
CmdPlot("");
CmdGrid("384");
getSamples(0, true);
getSamples(0, false);
break;
}
case 1: {
+1 -1
View File
@@ -258,7 +258,7 @@ static int CmdFdxDemod(const char *Cmd) {
}
static int CmdFdxRead(const char *Cmd) {
lf_read(true, 10000);
lf_read(false, 10000);
return CmdFdxDemod(Cmd);
}
+1 -1
View File
@@ -135,7 +135,7 @@ static int CmdGallagherDemod(const char *Cmd) {
}
static int CmdGallagherRead(const char *Cmd) {
lf_read(true, 4096 * 2 + 20);
lf_read(false, 4096 * 2 + 20);
return CmdGallagherDemod(Cmd);
}

Some files were not shown because too many files have changed in this diff Show More