mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2024-12-29 20:06:06 +08:00
Add option to define extra symbols for 'lf cmdread', required e.g. for Hitag Micro and for talking to HT2 in emulation mode
This commit is contained in:
parent
5a109122d3
commit
4ec7bca270
5 changed files with 65 additions and 32 deletions
|
@ -770,13 +770,15 @@ static void PacketReceived(PacketCommandNG *packet) {
|
||||||
case CMD_LF_MOD_THEN_ACQ_RAW_ADC: {
|
case CMD_LF_MOD_THEN_ACQ_RAW_ADC: {
|
||||||
struct p {
|
struct p {
|
||||||
uint32_t delay;
|
uint32_t delay;
|
||||||
uint16_t ones;
|
uint16_t period_0;
|
||||||
uint16_t zeros;
|
uint16_t period_1;
|
||||||
|
uint8_t symbol_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
|
||||||
|
uint16_t period_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
|
||||||
uint32_t samples : 31;
|
uint32_t samples : 31;
|
||||||
bool verbose : 1;
|
bool verbose : 1;
|
||||||
} PACKED;
|
} PACKED;
|
||||||
struct p *payload = (struct p *)packet->data.asBytes;
|
struct p *payload = (struct p *)packet->data.asBytes;
|
||||||
ModThenAcquireRawAdcSamples125k(payload->delay, payload->zeros, payload->ones, packet->data.asBytes + sizeof(struct p), payload->verbose, payload->samples);
|
ModThenAcquireRawAdcSamples125k(payload->delay, payload->period_0, payload->period_1, payload->symbol_extra, payload->period_extra, packet->data.asBytes + sizeof(struct p), payload->verbose, payload->samples);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case CMD_LF_SNIFF_RAW_ADC: {
|
case CMD_LF_SNIFF_RAW_ADC: {
|
||||||
|
|
|
@ -383,13 +383,15 @@ void loadT55xxConfig(void) {
|
||||||
* @param period_1
|
* @param period_1
|
||||||
* @param command (in binary char array)
|
* @param command (in binary char array)
|
||||||
*/
|
*/
|
||||||
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command, bool verbose, uint32_t samples) {
|
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint16_t period_1, uint8_t *symbol_extra, uint16_t *period_extra, uint8_t *command, bool verbose, uint32_t samples) {
|
||||||
|
|
||||||
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
FpgaDownloadAndGo(FPGA_BITSTREAM_LF);
|
||||||
|
|
||||||
// use lf config settings
|
// use lf config settings
|
||||||
sample_config *sc = getSamplingConfig();
|
sample_config *sc = getSamplingConfig();
|
||||||
|
|
||||||
|
LFSetupFPGAForADC(sc->divisor, true);
|
||||||
|
// this causes the field to turn on for uncontrolled amount of time, so we'll turn it off
|
||||||
|
|
||||||
// Make sure the tag is reset
|
// Make sure the tag is reset
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
|
@ -402,15 +404,14 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
|
||||||
// clear read buffer
|
// clear read buffer
|
||||||
BigBuf_Clear_keep_EM();
|
BigBuf_Clear_keep_EM();
|
||||||
|
|
||||||
LFSetupFPGAForADC(sc->divisor, true);
|
|
||||||
|
|
||||||
// little more time for the tag to fully power up
|
|
||||||
WaitMS(20);
|
|
||||||
|
|
||||||
// if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods.
|
// if delay_off = 0 then just bitbang 1 = antenna on 0 = off for respective periods.
|
||||||
bool bitbang = (delay_off == 0);
|
bool bitbang = (delay_off == 0);
|
||||||
// now modulate the reader field
|
// now modulate the reader field
|
||||||
|
|
||||||
|
// Some tags need to be interrogated very soon after activation else they enter their emulation mode
|
||||||
|
// Therefore it's up to the caller to add an initial symbol of adequate duration, except for bitbang mode.
|
||||||
if (bitbang) {
|
if (bitbang) {
|
||||||
|
TurnReadLFOn(20000);
|
||||||
// HACK it appears the loop and if statements take up about 7us so adjust waits accordingly...
|
// HACK it appears the loop and if statements take up about 7us so adjust waits accordingly...
|
||||||
uint8_t hack_cnt = 7;
|
uint8_t hack_cnt = 7;
|
||||||
if (period_0 < hack_cnt || period_1 < hack_cnt) {
|
if (period_0 < hack_cnt || period_1 < hack_cnt) {
|
||||||
|
@ -459,11 +460,19 @@ void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint
|
||||||
} else { // old mode of cmd read using delay as off period
|
} else { // old mode of cmd read using delay as off period
|
||||||
while (*command != '\0' && *command != ' ') {
|
while (*command != '\0' && *command != ' ') {
|
||||||
LED_D_ON();
|
LED_D_ON();
|
||||||
if (*(command++) == '0')
|
if (*command == '0') {
|
||||||
TurnReadLFOn(period_0);
|
TurnReadLFOn(period_0);
|
||||||
else
|
} else if (*command == '1') {
|
||||||
TurnReadLFOn(period_1);
|
TurnReadLFOn(period_1);
|
||||||
|
} else {
|
||||||
|
for (uint8_t i=0; i < LF_CMDREAD_MAX_EXTRA_SYMBOLS; i++) {
|
||||||
|
if (*command == symbol_extra[i]) {
|
||||||
|
TurnReadLFOn(period_extra[i]);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
command++;
|
||||||
LED_D_OFF();
|
LED_D_OFF();
|
||||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||||
WaitUS(delay_off);
|
WaitUS(delay_off);
|
||||||
|
|
|
@ -15,7 +15,7 @@
|
||||||
|
|
||||||
#include "pm3_cmd.h" // struct
|
#include "pm3_cmd.h" // struct
|
||||||
|
|
||||||
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint32_t period_0, uint32_t period_1, uint8_t *command, bool verbose, uint32_t samples);
|
void ModThenAcquireRawAdcSamples125k(uint32_t delay_off, uint16_t period_0, uint16_t period_1, uint8_t *symbol_extra, uint16_t *period_extra, uint8_t *command, bool verbose, uint32_t samples);
|
||||||
void ReadTItag(void);
|
void ReadTItag(void);
|
||||||
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
|
void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc);
|
||||||
|
|
||||||
|
|
|
@ -56,29 +56,36 @@
|
||||||
#include "cmdlfmotorola.h" // for Motorola menu
|
#include "cmdlfmotorola.h" // for Motorola menu
|
||||||
#include "cmdlfgallagher.h" // for GALLAGHER menu
|
#include "cmdlfgallagher.h" // for GALLAGHER menu
|
||||||
|
|
||||||
|
#define LF_CMDREAD_MAX_EXTRA_SYMBOLS 4
|
||||||
static bool g_lf_threshold_set = false;
|
static bool g_lf_threshold_set = false;
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
|
||||||
static int usage_lf_cmdread(void) {
|
static int usage_lf_cmdread(void) {
|
||||||
PrintAndLogEx(NORMAL, "Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [q] [s #samples] [@]");
|
PrintAndLogEx(NORMAL, "Usage: lf cmdread d <delay duration> z <zero duration> o <one duration> [e <symbol> <duration>] c <cmd symbols> [q] [s #samples] [@]");
|
||||||
PrintAndLogEx(NORMAL, "Options:");
|
PrintAndLogEx(NORMAL, "Options:");
|
||||||
PrintAndLogEx(NORMAL, " h This help");
|
PrintAndLogEx(NORMAL, " h This help");
|
||||||
PrintAndLogEx(NORMAL, " d <delay> delay OFF period, (0 for bitbang mode) (decimal)");
|
PrintAndLogEx(NORMAL, " d <duration> delay OFF period, (0 for bitbang mode)");
|
||||||
PrintAndLogEx(NORMAL, " z <zero> ZERO time period (decimal)");
|
PrintAndLogEx(NORMAL, " z <duration> ZERO time period");
|
||||||
PrintAndLogEx(NORMAL, " o <one> ONE time period (decimal)");
|
PrintAndLogEx(NORMAL, " o <duration> ONE time period");
|
||||||
PrintAndLogEx(NORMAL, " c <cmd> Command bytes (in ones and zeros)");
|
PrintAndLogEx(NORMAL, " e <symbol> <duration> Extra symbol definition and duration (up to %i)", LF_CMDREAD_MAX_EXTRA_SYMBOLS);
|
||||||
PrintAndLogEx(NORMAL, " q silent (optional)");
|
PrintAndLogEx(NORMAL, " b <duration> B period");
|
||||||
PrintAndLogEx(NORMAL, " s #samples number of samples to collect (optional)");
|
PrintAndLogEx(NORMAL, " c <cmd> Command symbols (0/1/...)");
|
||||||
PrintAndLogEx(NORMAL, " @ run continuously until a key is pressed (optional)");
|
PrintAndLogEx(NORMAL, " q silent (optional)");
|
||||||
|
PrintAndLogEx(NORMAL, " s #samples number of samples to collect (optional)");
|
||||||
|
PrintAndLogEx(NORMAL, " @ run continuously until a key is pressed (optional)");
|
||||||
PrintAndLogEx(NORMAL, "");
|
PrintAndLogEx(NORMAL, "");
|
||||||
PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in microseconds (us)"));
|
PrintAndLogEx(NORMAL, " ************* " _YELLOW_("All periods in decimal and in microseconds (μs)"));
|
||||||
PrintAndLogEx(NORMAL, "Examples:");
|
PrintAndLogEx(NORMAL, "Examples:");
|
||||||
PrintAndLogEx(NORMAL, "- probing for HT2:");
|
PrintAndLogEx(NORMAL, "- probing for Hitag 1/Hitag S:");
|
||||||
PrintAndLogEx(NORMAL, " lf cmdread d 50 z 116 o 166 c 011000");
|
PrintAndLogEx(NORMAL, " lf cmdread d 50 z 116 o 166 e W 3000 c W00110");
|
||||||
PrintAndLogEx(NORMAL, "- probing for HT2, oscilloscope style:");
|
PrintAndLogEx(NORMAL, "- probing for Hitag 2:");
|
||||||
|
PrintAndLogEx(NORMAL, " lf cmdread d 50 z 116 o 166 e W 3000 c W11000");
|
||||||
|
PrintAndLogEx(NORMAL, "- probing for Hitag 2, oscilloscope style:");
|
||||||
PrintAndLogEx(NORMAL, " data plot");
|
PrintAndLogEx(NORMAL, " data plot");
|
||||||
PrintAndLogEx(NORMAL, " lf cmdread d 50 z 116 o 166 c 011000 q s 2000 @");
|
PrintAndLogEx(NORMAL, " lf cmdread d 50 z 116 o 166 e W 3000 c W11000 q s 2000 @");
|
||||||
|
PrintAndLogEx(NORMAL, "- probing for Hitag μ:");
|
||||||
|
PrintAndLogEx(NORMAL, " lf cmdread d 48 z 112 o 176 e W 3000 e S 240 e E 336 c W0S00000010000E");
|
||||||
PrintAndLogEx(NORMAL, "Extras:");
|
PrintAndLogEx(NORMAL, "Extras:");
|
||||||
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
|
PrintAndLogEx(NORMAL, " use " _YELLOW_("'lf config'")" to set parameters.");
|
||||||
return PM3_SUCCESS;
|
return PM3_SUCCESS;
|
||||||
|
@ -324,17 +331,20 @@ int CmdLFCommandRead(const char *Cmd) {
|
||||||
uint32_t samples = 0;
|
uint32_t samples = 0;
|
||||||
uint16_t datalen = 0;
|
uint16_t datalen = 0;
|
||||||
|
|
||||||
const uint8_t payload_header_size = 12;
|
const uint8_t payload_header_size = 12 + (3 * LF_CMDREAD_MAX_EXTRA_SYMBOLS);
|
||||||
struct p {
|
struct p {
|
||||||
uint32_t delay;
|
uint32_t delay;
|
||||||
uint16_t ones;
|
uint16_t period_0;
|
||||||
uint16_t zeros;
|
uint16_t period_1;
|
||||||
|
uint8_t symbol_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
|
||||||
|
uint16_t period_extra[LF_CMDREAD_MAX_EXTRA_SYMBOLS];
|
||||||
uint32_t samples : 31;
|
uint32_t samples : 31;
|
||||||
bool verbose : 1;
|
bool verbose : 1;
|
||||||
uint8_t data[PM3_CMD_DATA_SIZE - payload_header_size];
|
uint8_t data[PM3_CMD_DATA_SIZE - payload_header_size];
|
||||||
} PACKED payload;
|
} PACKED payload;
|
||||||
payload.samples = samples;
|
payload.samples = samples;
|
||||||
payload.verbose = verbose;
|
payload.verbose = verbose;
|
||||||
|
uint8_t index_extra = 0;
|
||||||
|
|
||||||
uint8_t cmdp = 0;
|
uint8_t cmdp = 0;
|
||||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||||
|
@ -350,13 +360,24 @@ int CmdLFCommandRead(const char *Cmd) {
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'z': // zero
|
case 'z': // zero
|
||||||
payload.zeros = param_get32ex(Cmd, cmdp + 1, 0, 10) & 0xFFFF;
|
payload.period_0 = param_get32ex(Cmd, cmdp + 1, 0, 10) & 0xFFFF;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
case 'o': // ones
|
case 'o': // ones
|
||||||
payload.ones = param_get32ex(Cmd, cmdp + 1, 0, 10) & 0xFFFF;
|
payload.period_1 = param_get32ex(Cmd, cmdp + 1, 0, 10) & 0xFFFF;
|
||||||
cmdp += 2;
|
cmdp += 2;
|
||||||
break;
|
break;
|
||||||
|
case 'e': // extra symbol definition
|
||||||
|
if (index_extra < LF_CMDREAD_MAX_EXTRA_SYMBOLS - 1) {
|
||||||
|
payload.symbol_extra[index_extra] = param_getchar(Cmd, cmdp + 1);
|
||||||
|
payload.period_extra[index_extra] = param_get32ex(Cmd, cmdp + 2, 0, 10) & 0xFFFF;
|
||||||
|
index_extra++;
|
||||||
|
cmdp += 3;
|
||||||
|
} else {
|
||||||
|
PrintAndLogEx(WARNING, "Too many extra symbols, please define up to %i symbols", LF_CMDREAD_MAX_EXTRA_SYMBOLS);
|
||||||
|
errors = true;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case 's':
|
case 's':
|
||||||
samples = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
samples = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||||
payload.samples = samples;
|
payload.samples = samples;
|
||||||
|
@ -380,7 +401,7 @@ int CmdLFCommandRead(const char *Cmd) {
|
||||||
|
|
||||||
// bitbang mode
|
// bitbang mode
|
||||||
if (payload.delay == 0) {
|
if (payload.delay == 0) {
|
||||||
if (payload.zeros < 7 || payload.ones < 7) {
|
if (payload.period_0 < 7 || payload.period_1 < 7) {
|
||||||
PrintAndLogEx(WARNING, "warning periods cannot be less than 7us in bit bang mode");
|
PrintAndLogEx(WARNING, "warning periods cannot be less than 7us in bit bang mode");
|
||||||
return PM3_EINVARG;
|
return PM3_EINVARG;
|
||||||
}
|
}
|
||||||
|
|
|
@ -786,6 +786,7 @@ typedef struct {
|
||||||
#define LF_DIVISOR_125 LF_FREQ2DIV(125)
|
#define LF_DIVISOR_125 LF_FREQ2DIV(125)
|
||||||
#define LF_DIVISOR_134 LF_FREQ2DIV(134.2)
|
#define LF_DIVISOR_134 LF_FREQ2DIV(134.2)
|
||||||
#define LF_DIV2FREQ(d) (12000.0/((d)+1))
|
#define LF_DIV2FREQ(d) (12000.0/((d)+1))
|
||||||
|
#define LF_CMDREAD_MAX_EXTRA_SYMBOLS 4
|
||||||
|
|
||||||
// Receiving from USART need more than 30ms as we used on USB
|
// Receiving from USART need more than 30ms as we used on USB
|
||||||
// else we get errors about partial packet reception
|
// else we get errors about partial packet reception
|
||||||
|
|
Loading…
Reference in a new issue