mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-08-19 21:03:23 -07:00
Fix 15 snoop (#752)
* fixing hf 15: implement hf 15 snoop * rename hf 15 record to hf 15 snoop * speedup sampling / decoding: * new FPGA mode FPGA_HF_READER_RX_XCORR_AMPLITUDE implements amplitude(ci, cq) on FPGA * inlining the decoders in iso15693.c * inlining memcpy/memset in LogTrace() * giving up the moving correlator for SOF in Handle15693SamplesFromTag * decode more of EOF in Handle15693SamplesFromTag() * some refactoring
This commit is contained in:
parent
9f596ec7ac
commit
d9de20fa4b
17 changed files with 715 additions and 574 deletions
|
@ -13,6 +13,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
### Fixed
|
### Fixed
|
||||||
- AC-Mode decoding for HitagS
|
- AC-Mode decoding for HitagS
|
||||||
- Wrong UID at HitagS simulation
|
- Wrong UID at HitagS simulation
|
||||||
|
- 'hf 15 sim' now works as expected (piwi)
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
- Support Standard Communication Mode in HITAG S
|
- Support Standard Communication Mode in HITAG S
|
||||||
|
@ -24,6 +25,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
||||||
- Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (Merlok)
|
- Added `hf fido` `assert` and `make` commands from fido2 protocol (authenticatorMakeCredential and authenticatorGetAssertion) (Merlok)
|
||||||
- Added `lf paradox clone` to clone a Paradox card
|
- Added `lf paradox clone` to clone a Paradox card
|
||||||
- Added `emv` commmands working for both contactless and smart cards (Merlok)
|
- Added `emv` commmands working for both contactless and smart cards (Merlok)
|
||||||
|
- Added 'hf 15 snoop' (piwi)
|
||||||
|
|
||||||
|
|
||||||
## [v3.1.0][2018-10-10]
|
## [v3.1.0][2018-10-10]
|
||||||
|
|
|
@ -36,8 +36,8 @@ static uint16_t BigBuf_hi = BIGBUF_SIZE;
|
||||||
static uint8_t *emulator_memory = NULL;
|
static uint8_t *emulator_memory = NULL;
|
||||||
|
|
||||||
// trace related variables
|
// trace related variables
|
||||||
static uint16_t traceLen = 0;
|
static uint32_t traceLen = 0;
|
||||||
int tracing = 1; //Last global one.. todo static?
|
static bool tracing = true;
|
||||||
|
|
||||||
// get the address of BigBuf
|
// get the address of BigBuf
|
||||||
uint8_t *BigBuf_get_addr(void)
|
uint8_t *BigBuf_get_addr(void)
|
||||||
|
@ -66,7 +66,7 @@ void BigBuf_Clear(void)
|
||||||
// clear ALL of BigBuf
|
// clear ALL of BigBuf
|
||||||
void BigBuf_Clear_ext(bool verbose)
|
void BigBuf_Clear_ext(bool verbose)
|
||||||
{
|
{
|
||||||
memset(BigBuf,0,BIGBUF_SIZE);
|
memset(BigBuf, 0, BIGBUF_SIZE);
|
||||||
if (verbose)
|
if (verbose)
|
||||||
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
Dbprintf("Buffer cleared (%i bytes)",BIGBUF_SIZE);
|
||||||
}
|
}
|
||||||
|
@ -76,7 +76,7 @@ void BigBuf_Clear_EM(void){
|
||||||
|
|
||||||
void BigBuf_Clear_keep_EM(void)
|
void BigBuf_Clear_keep_EM(void)
|
||||||
{
|
{
|
||||||
memset(BigBuf,0,BigBuf_hi);
|
memset(BigBuf, 0, BigBuf_hi);
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
// allocate a chunk of memory from BigBuf. We allocate high memory first. The unallocated memory
|
||||||
|
@ -162,8 +162,8 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||||
|
|
||||||
uint8_t *trace = BigBuf_get_addr();
|
uint8_t *trace = BigBuf_get_addr();
|
||||||
|
|
||||||
uint16_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
uint32_t num_paritybytes = (iLen-1)/8 + 1; // number of valid paritybytes in *parity
|
||||||
uint16_t duration = timestamp_end - timestamp_start;
|
uint32_t duration = timestamp_end - timestamp_start;
|
||||||
|
|
||||||
// Return when trace is full
|
// Return when trace is full
|
||||||
uint16_t max_traceLen = BigBuf_max_traceLen();
|
uint16_t max_traceLen = BigBuf_max_traceLen();
|
||||||
|
@ -200,19 +200,23 @@ bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t iLen, uint32_t timestamp_
|
||||||
|
|
||||||
// data bytes
|
// data bytes
|
||||||
if (btBytes != NULL && iLen != 0) {
|
if (btBytes != NULL && iLen != 0) {
|
||||||
memcpy(trace + traceLen, btBytes, iLen);
|
for (int i = 0; i < iLen; i++) {
|
||||||
|
trace[traceLen++] = *btBytes++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
traceLen += iLen;
|
|
||||||
|
|
||||||
// parity bytes
|
// parity bytes
|
||||||
if (num_paritybytes != 0) {
|
if (num_paritybytes != 0) {
|
||||||
if (parity != NULL) {
|
if (parity != NULL) {
|
||||||
memcpy(trace + traceLen, parity, num_paritybytes);
|
for (int i = 0; i < num_paritybytes; i++) {
|
||||||
|
trace[traceLen++] = *parity++;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
memset(trace + traceLen, 0x00, num_paritybytes);
|
for (int i = 0; i < num_paritybytes; i++) {
|
||||||
|
trace[traceLen++] = 0x00;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
traceLen += num_paritybytes;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -259,8 +263,9 @@ int LogTraceHitag(const uint8_t * btBytes, int iBits, int iSamples, uint32_t dwP
|
||||||
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
trace[traceLen++] = ((dwParity >> 24) & 0xff);
|
||||||
trace[traceLen++] = iBits;
|
trace[traceLen++] = iBits;
|
||||||
|
|
||||||
memcpy(trace + traceLen, btBytes, iLen);
|
for (int i = 0; i < iLen; i++) {
|
||||||
traceLen += iLen;
|
trace[traceLen++] = *btBytes++;
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@
|
||||||
#include "legicrfsim.h"
|
#include "legicrfsim.h"
|
||||||
#include "hitag2.h"
|
#include "hitag2.h"
|
||||||
#include "hitagS.h"
|
#include "hitagS.h"
|
||||||
|
#include "iso15693.h"
|
||||||
#include "lfsampling.h"
|
#include "lfsampling.h"
|
||||||
#include "BigBuf.h"
|
#include "BigBuf.h"
|
||||||
#include "mifareutil.h"
|
#include "mifareutil.h"
|
||||||
|
@ -1115,8 +1116,9 @@ void UsbPacketReceived(uint8_t *packet, int len)
|
||||||
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
|
case CMD_ACQUIRE_RAW_ADC_SAMPLES_ISO_15693:
|
||||||
AcquireRawAdcSamplesIso15693();
|
AcquireRawAdcSamplesIso15693();
|
||||||
break;
|
break;
|
||||||
case CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693:
|
|
||||||
RecordRawAdcSamplesIso15693();
|
case CMD_SNOOP_ISO_15693:
|
||||||
|
SnoopIso15693();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_ISO_15693_COMMAND:
|
case CMD_ISO_15693_COMMAND:
|
||||||
|
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
extern const uint8_t OddByteParity[256];
|
extern const uint8_t OddByteParity[256];
|
||||||
extern int rsamples; // = 0;
|
extern int rsamples; // = 0;
|
||||||
extern int tracing; // = TRUE;
|
|
||||||
extern uint8_t trigger;
|
extern uint8_t trigger;
|
||||||
|
|
||||||
// This may be used (sparingly) to declare a function to be copied to
|
// This may be used (sparingly) to declare a function to be copied to
|
||||||
|
@ -101,7 +100,6 @@ void RAMFUNC SnoopIso14443b(void);
|
||||||
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
|
void SendRawCommand14443B(uint32_t, uint32_t, uint8_t, uint8_t[]);
|
||||||
|
|
||||||
// Also used in iclass.c
|
// Also used in iclass.c
|
||||||
bool RAMFUNC LogTrace(const uint8_t *btBytes, uint16_t len, uint32_t timestamp_start, uint32_t timestamp_end, uint8_t *parity, bool readerToTag);
|
|
||||||
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
|
void GetParity(const uint8_t *pbtCmd, uint16_t len, uint8_t *parity);
|
||||||
|
|
||||||
void RAMFUNC SniffMifare(uint8_t param);
|
void RAMFUNC SniffMifare(uint8_t param);
|
||||||
|
@ -150,15 +148,6 @@ void OnSuccess();
|
||||||
void OnError(uint8_t reason);
|
void OnError(uint8_t reason);
|
||||||
|
|
||||||
|
|
||||||
/// iso15693.h
|
|
||||||
void RecordRawAdcSamplesIso15693(void);
|
|
||||||
void AcquireRawAdcSamplesIso15693(void);
|
|
||||||
void ReaderIso15693(uint32_t parameter); // Simulate an ISO15693 reader - greg
|
|
||||||
void SimTagIso15693(uint32_t parameter, uint8_t *uid); // simulate an ISO15693 tag - greg
|
|
||||||
void BruteforceIso15693Afi(uint32_t speed); // find an AFI of a tag - atrox
|
|
||||||
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]); // send arbitrary commands from CLI - atrox
|
|
||||||
void SetDebugIso15693(uint32_t flag);
|
|
||||||
|
|
||||||
/// iclass.h
|
/// iclass.h
|
||||||
void RAMFUNC SnoopIClass(void);
|
void RAMFUNC SnoopIClass(void);
|
||||||
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
void SimulateIClass(uint32_t arg0, uint32_t arg1, uint32_t arg2, uint8_t *datain);
|
||||||
|
|
|
@ -61,6 +61,7 @@ void SetAdcMuxFor(uint32_t whichGpio);
|
||||||
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
#define FPGA_HF_READER_RX_XCORR_848_KHZ (1<<0)
|
||||||
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
#define FPGA_HF_READER_RX_XCORR_SNOOP (1<<1)
|
||||||
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
#define FPGA_HF_READER_RX_XCORR_QUARTER_FREQ (1<<2)
|
||||||
|
#define FPGA_HF_READER_RX_XCORR_AMPLITUDE (1<<3)
|
||||||
// Options for the HF simulated tag, how to modulate
|
// Options for the HF simulated tag, how to modulate
|
||||||
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
|
#define FPGA_HF_SIMULATOR_NO_MODULATION (0<<0)
|
||||||
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
#define FPGA_HF_SIMULATOR_MODULATE_BPSK (1<<0)
|
||||||
|
|
|
@ -751,12 +751,9 @@ void RAMFUNC SnoopIClass(void)
|
||||||
|
|
||||||
//if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,true)) break;
|
//if(!LogTrace(Uart.output,Uart.byteCnt, rsamples, Uart.parityBits,true)) break;
|
||||||
//if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, true)) break;
|
//if(!LogTrace(NULL, 0, Uart.endTime*16 - DELAY_READER_AIR2ARM_AS_SNIFFER, 0, true)) break;
|
||||||
if(tracing) {
|
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
GetParity(Uart.output, Uart.byteCnt, parity);
|
GetParity(Uart.output, Uart.byteCnt, parity);
|
||||||
LogTrace(Uart.output,Uart.byteCnt, time_start, time_stop, parity, true);
|
LogTrace(Uart.output,Uart.byteCnt, time_start, time_stop, parity, true);
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* And ready to receive another command. */
|
/* And ready to receive another command. */
|
||||||
Uart.state = STATE_UNSYNCD;
|
Uart.state = STATE_UNSYNCD;
|
||||||
|
@ -779,11 +776,9 @@ void RAMFUNC SnoopIClass(void)
|
||||||
rsamples = samples - Demod.samples;
|
rsamples = samples - Demod.samples;
|
||||||
LED_B_ON();
|
LED_B_ON();
|
||||||
|
|
||||||
if(tracing) {
|
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
GetParity(Demod.output, Demod.len, parity);
|
GetParity(Demod.output, Demod.len, parity);
|
||||||
LogTrace(Demod.output, Demod.len, time_start, time_stop, parity, false);
|
LogTrace(Demod.output, Demod.len, time_start, time_stop, parity, false);
|
||||||
}
|
|
||||||
|
|
||||||
// And ready to receive another response.
|
// And ready to receive another response.
|
||||||
memset(&Demod, 0, sizeof(Demod));
|
memset(&Demod, 0, sizeof(Demod));
|
||||||
|
@ -1322,7 +1317,6 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf)
|
||||||
t2r_time = GetCountSspClk();
|
t2r_time = GetCountSspClk();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracing) {
|
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
GetParity(receivedCmd, len, parity);
|
GetParity(receivedCmd, len, parity);
|
||||||
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, true);
|
LogTrace(receivedCmd,len, (r2t_time-time_0)<< 4, (r2t_time-time_0) << 4, parity, true);
|
||||||
|
@ -1331,12 +1325,10 @@ int doIClassSimulation( int simulationMode, uint8_t *reader_mac_buf)
|
||||||
GetParity(trace_data, trace_data_size, parity);
|
GetParity(trace_data, trace_data_size, parity);
|
||||||
LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, false);
|
LogTrace(trace_data, trace_data_size, (t2r_time-time_0) << 4, (t2r_time-time_0) << 4, parity, false);
|
||||||
}
|
}
|
||||||
if(!tracing) {
|
if(!get_tracing()) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
//break;
|
//break;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//Dbprintf("%x", cmdsRecvd);
|
//Dbprintf("%x", cmdsRecvd);
|
||||||
|
@ -1509,11 +1501,9 @@ void ReaderTransmitIClass(uint8_t* frame, int len)
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
// Store reader command in buffer
|
// Store reader command in buffer
|
||||||
if (tracing) {
|
|
||||||
uint8_t par[MAX_PARITY_SIZE];
|
uint8_t par[MAX_PARITY_SIZE];
|
||||||
GetParity(frame, len, par);
|
GetParity(frame, len, par);
|
||||||
LogTrace(frame, len, rsamples, rsamples, par, true);
|
LogTrace(frame, len, rsamples, rsamples, par, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
|
@ -1569,11 +1559,9 @@ int ReaderReceiveIClass(uint8_t* receivedAnswer)
|
||||||
int samples = 0;
|
int samples = 0;
|
||||||
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return false;
|
if (!GetIClassAnswer(receivedAnswer,160,&samples,0)) return false;
|
||||||
rsamples += samples;
|
rsamples += samples;
|
||||||
if (tracing) {
|
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
uint8_t parity[MAX_PARITY_SIZE];
|
||||||
GetParity(receivedAnswer, Demod.len, parity);
|
GetParity(receivedAnswer, Demod.len, parity);
|
||||||
LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,false);
|
LogTrace(receivedAnswer,Demod.len,rsamples,rsamples,parity,false);
|
||||||
}
|
|
||||||
if(samples == 0) return false;
|
if(samples == 0) return false;
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
@ -1715,7 +1703,7 @@ void ReaderIClass(uint8_t arg0) {
|
||||||
// if only looking for one card try 2 times if we missed it the first time
|
// if only looking for one card try 2 times if we missed it the first time
|
||||||
if (try_once && tryCnt > 2) break;
|
if (try_once && tryCnt > 2) break;
|
||||||
tryCnt++;
|
tryCnt++;
|
||||||
if(!tracing) {
|
if(!get_tracing()) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1828,7 +1816,7 @@ void ReaderIClass_Replay(uint8_t arg0, uint8_t *MAC) {
|
||||||
|
|
||||||
WDT_HIT();
|
WDT_HIT();
|
||||||
|
|
||||||
if(!tracing) {
|
if(!get_tracing()) {
|
||||||
DbpString("Trace full");
|
DbpString("Trace full");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ void SimulateIso14443aTag(int tagType, int uid_1st, int uid_2nd, byte_t* data)
|
||||||
EmSendPrecompiledCmd(p_response);
|
EmSendPrecompiledCmd(p_response);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!tracing) {
|
if (!get_tracing()) {
|
||||||
Dbprintf("Trace Full. Simulation stopped.");
|
Dbprintf("Trace Full. Simulation stopped.");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1619,9 +1619,7 @@ void ReaderTransmitBitsPar(uint8_t* frame, uint16_t bits, uint8_t *par, uint32_t
|
||||||
LED_A_ON();
|
LED_A_ON();
|
||||||
|
|
||||||
// Log reader command in trace buffer
|
// Log reader command in trace buffer
|
||||||
if (tracing) {
|
|
||||||
LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
|
LogTrace(frame, nbytes(bits), LastTimeProxToAirStart*16 + DELAY_ARM2AIR_AS_READER, (LastTimeProxToAirStart + LastProxToAirDuration)*16 + DELAY_ARM2AIR_AS_READER, par, true);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -1652,9 +1650,7 @@ void ReaderTransmit(uint8_t* frame, uint16_t len, uint32_t *timing)
|
||||||
static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
|
static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t *parity)
|
||||||
{
|
{
|
||||||
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return false;
|
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, offset)) return false;
|
||||||
if (tracing) {
|
|
||||||
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
|
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
|
||||||
}
|
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1662,9 +1658,7 @@ static int ReaderReceiveOffset(uint8_t* receivedAnswer, uint16_t offset, uint8_t
|
||||||
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
|
int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
|
||||||
{
|
{
|
||||||
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return false;
|
if (!GetIso14443aAnswerFromTag(receivedAnswer, parity, 0)) return false;
|
||||||
if (tracing) {
|
|
||||||
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
|
LogTrace(receivedAnswer, Demod.len, Demod.startTime*16 - DELAY_AIR2ARM_AS_READER, Demod.endTime*16 - DELAY_AIR2ARM_AS_READER, parity, false);
|
||||||
}
|
|
||||||
return Demod.len;
|
return Demod.len;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -386,10 +386,7 @@ void SimulateIso14443bTag(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tracing) {
|
LogTrace(receivedCmd, len, 0, 0, NULL, true);
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
|
||||||
LogTrace(receivedCmd, len, 0, 0, parity, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Good, look at the command now.
|
// Good, look at the command now.
|
||||||
if ( (len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len) == 0)
|
if ( (len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len) == 0)
|
||||||
|
@ -463,10 +460,7 @@ void SimulateIso14443bTag(void)
|
||||||
}
|
}
|
||||||
|
|
||||||
// trace the response:
|
// trace the response:
|
||||||
if (tracing) {
|
LogTrace(resp, respLen, 0, 0, NULL, false);
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
|
||||||
LogTrace(resp, respLen, 0, 0, parity, false);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -763,9 +757,8 @@ static void GetSamplesFor14443bDemod(int n, bool quiet)
|
||||||
|
|
||||||
if (!quiet) Dbprintf("max behindby = %d, samples = %d, gotFrame = %d, Demod.len = %d, Demod.sumI = %d, Demod.sumQ = %d", maxBehindBy, samples, gotFrame, Demod.len, Demod.sumI, Demod.sumQ);
|
if (!quiet) Dbprintf("max behindby = %d, samples = %d, gotFrame = %d, Demod.len = %d, Demod.sumI = %d, Demod.sumQ = %d", maxBehindBy, samples, gotFrame, Demod.len, Demod.sumI, Demod.sumQ);
|
||||||
//Tracing
|
//Tracing
|
||||||
if (tracing && Demod.len > 0) {
|
if (Demod.len > 0) {
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
LogTrace(Demod.output, Demod.len, 0, 0, NULL, false);
|
||||||
LogTrace(Demod.output, Demod.len, 0, 0, parity, false);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -858,10 +851,7 @@ static void CodeAndTransmit14443bAsReader(const uint8_t *cmd, int len)
|
||||||
{
|
{
|
||||||
CodeIso14443bAsReader(cmd, len);
|
CodeIso14443bAsReader(cmd, len);
|
||||||
TransmitFor14443b();
|
TransmitFor14443b();
|
||||||
if (tracing) {
|
LogTrace(cmd,len, 0, 0, NULL, true);
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
|
||||||
LogTrace(cmd,len, 0, 0, parity, true);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Sends an APDU to the tag
|
/* Sends an APDU to the tag
|
||||||
|
@ -1153,7 +1143,6 @@ void RAMFUNC SnoopIso14443b(void)
|
||||||
upTo = dmaBuf;
|
upTo = dmaBuf;
|
||||||
lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
|
lastRxCounter = ISO14443B_DMA_BUFFER_SIZE;
|
||||||
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
|
FpgaSetupSscDma((uint8_t*) dmaBuf, ISO14443B_DMA_BUFFER_SIZE);
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
|
||||||
|
|
||||||
bool TagIsActive = false;
|
bool TagIsActive = false;
|
||||||
bool ReaderIsActive = false;
|
bool ReaderIsActive = false;
|
||||||
|
@ -1198,9 +1187,7 @@ void RAMFUNC SnoopIso14443b(void)
|
||||||
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
|
if (!TagIsActive) { // no need to try decoding reader data if the tag is sending
|
||||||
if(Handle14443bUartBit(ci & 0x01)) {
|
if(Handle14443bUartBit(ci & 0x01)) {
|
||||||
triggered = true;
|
triggered = true;
|
||||||
if(tracing) {
|
LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, true);
|
||||||
LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, true);
|
|
||||||
}
|
|
||||||
/* And ready to receive another command. */
|
/* And ready to receive another command. */
|
||||||
UartReset();
|
UartReset();
|
||||||
/* And also reset the demod code, which might have been */
|
/* And also reset the demod code, which might have been */
|
||||||
|
@ -1209,9 +1196,7 @@ void RAMFUNC SnoopIso14443b(void)
|
||||||
}
|
}
|
||||||
if(Handle14443bUartBit(cq & 0x01)) {
|
if(Handle14443bUartBit(cq & 0x01)) {
|
||||||
triggered = true;
|
triggered = true;
|
||||||
if(tracing) {
|
LogTrace(Uart.output, Uart.byteCnt, samples, samples, NULL, true);
|
||||||
LogTrace(Uart.output, Uart.byteCnt, samples, samples, parity, true);
|
|
||||||
}
|
|
||||||
/* And ready to receive another command. */
|
/* And ready to receive another command. */
|
||||||
UartReset();
|
UartReset();
|
||||||
/* And also reset the demod code, which might have been */
|
/* And also reset the demod code, which might have been */
|
||||||
|
@ -1223,13 +1208,8 @@ void RAMFUNC SnoopIso14443b(void)
|
||||||
|
|
||||||
if(!ReaderIsActive && triggered) { // no need to try decoding tag data if the reader is sending or not yet triggered
|
if(!ReaderIsActive && triggered) { // no need to try decoding tag data if the reader is sending or not yet triggered
|
||||||
if(Handle14443bSamplesDemod(ci/2, cq/2)) {
|
if(Handle14443bSamplesDemod(ci/2, cq/2)) {
|
||||||
|
|
||||||
//Use samples as a time measurement
|
//Use samples as a time measurement
|
||||||
if(tracing)
|
LogTrace(Demod.output, Demod.len, samples, samples, NULL, false);
|
||||||
{
|
|
||||||
uint8_t parity[MAX_PARITY_SIZE];
|
|
||||||
LogTrace(Demod.output, Demod.len, samples, samples, parity, false);
|
|
||||||
}
|
|
||||||
// And ready to receive another response.
|
// And ready to receive another response.
|
||||||
DemodReset();
|
DemodReset();
|
||||||
}
|
}
|
||||||
|
|
File diff suppressed because it is too large
Load diff
24
armsrc/iso15693.h
Normal file
24
armsrc/iso15693.h
Normal file
|
@ -0,0 +1,24 @@
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Piwi - October 2018
|
||||||
|
//
|
||||||
|
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||||
|
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||||
|
// the license.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
// Routines to support ISO 15693.
|
||||||
|
//-----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
#ifndef __ISO15693_H
|
||||||
|
#define __ISO15693_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
void SnoopIso15693(void);
|
||||||
|
void AcquireRawAdcSamplesIso15693(void);
|
||||||
|
void ReaderIso15693(uint32_t parameter);
|
||||||
|
void SimTagIso15693(uint32_t parameter, uint8_t *uid);
|
||||||
|
void BruteforceIso15693Afi(uint32_t speed);
|
||||||
|
void DirectTag15693Command(uint32_t datalen,uint32_t speed, uint32_t recv, uint8_t data[]);
|
||||||
|
void SetDebugIso15693(uint32_t flag);
|
||||||
|
|
||||||
|
#endif
|
|
@ -264,7 +264,7 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||||
|
|
||||||
uint8_t parityBits = parityBytes[j>>3];
|
uint8_t parityBits = parityBytes[j>>3];
|
||||||
if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
if (protocol != ISO_14443B && (isResponse || protocol == ISO_14443A) && (oddparity8(frame[j]) != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||||
snprintf(line[j/16]+(( j % 16) * 4),110, "%02x! ", frame[j]);
|
snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x!", frame[j]);
|
||||||
} else {
|
} else {
|
||||||
snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);
|
snprintf(line[j/16]+(( j % 16) * 4), 110, " %02x ", frame[j]);
|
||||||
}
|
}
|
||||||
|
@ -281,14 +281,11 @@ uint16_t printTraceLine(uint16_t tracepos, uint16_t traceLen, uint8_t *trace, ui
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(data_len == 0)
|
if (data_len == 0) {
|
||||||
{
|
sprintf(line[0]," <empty trace - possible error>");
|
||||||
if(data_len == 0){
|
|
||||||
sprintf(line[0],"<empty trace - possible error>");
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
//--- Draw the CRC column
|
|
||||||
|
|
||||||
|
//--- Draw the CRC column
|
||||||
char *crc = (crcStatus == 0 ? "!crc" : (crcStatus == 1 ? " ok " : " "));
|
char *crc = (crcStatus == 0 ? "!crc" : (crcStatus == 1 ? " ok " : " "));
|
||||||
|
|
||||||
EndOfTransmissionTimestamp = timestamp + duration;
|
EndOfTransmissionTimestamp = timestamp + duration;
|
||||||
|
|
|
@ -38,15 +38,54 @@
|
||||||
#include "protocols.h"
|
#include "protocols.h"
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
|
|
||||||
#define FrameSOF Iso15693FrameSOF
|
|
||||||
#define Logic0 Iso15693Logic0
|
|
||||||
#define Logic1 Iso15693Logic1
|
|
||||||
#define FrameEOF Iso15693FrameEOF
|
|
||||||
|
|
||||||
#define Crc(data,datalen) Iso15693Crc(data,datalen)
|
#define Crc(data,datalen) Iso15693Crc(data,datalen)
|
||||||
#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
|
#define AddCrc(data,datalen) Iso15693AddCrc(data,datalen)
|
||||||
#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
|
#define sprintUID(target,uid) Iso15693sprintUID(target,uid)
|
||||||
|
|
||||||
|
// SOF defined as
|
||||||
|
// 1) Unmodulated time of 56.64us
|
||||||
|
// 2) 24 pulses of 423.75khz
|
||||||
|
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
|
||||||
|
|
||||||
|
static const int Iso15693FrameSOF[] = {
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
-1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1
|
||||||
|
};
|
||||||
|
static const int Iso15693Logic0[] = {
|
||||||
|
1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1,
|
||||||
|
-1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1
|
||||||
|
};
|
||||||
|
static const int Iso15693Logic1[] = {
|
||||||
|
-1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1
|
||||||
|
};
|
||||||
|
|
||||||
|
// EOF defined as
|
||||||
|
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
|
||||||
|
// 2) 24 pulses of 423.75khz
|
||||||
|
// 3) Unmodulated time of 56.64us
|
||||||
|
|
||||||
|
static const int Iso15693FrameEOF[] = {
|
||||||
|
1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1,
|
||||||
|
-1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
||||||
|
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
||||||
|
};
|
||||||
|
|
||||||
// structure and database for uid -> tagtype lookups
|
// structure and database for uid -> tagtype lookups
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint64_t uid;
|
uint64_t uid;
|
||||||
|
@ -293,8 +332,8 @@ int CmdHF15Demod(const char *Cmd)
|
||||||
// First, correlate for SOF
|
// First, correlate for SOF
|
||||||
for (i = 0; i < 200; i++) {
|
for (i = 0; i < 200; i++) {
|
||||||
int corr = 0;
|
int corr = 0;
|
||||||
for (j = 0; j < arraylen(FrameSOF); j += skip) {
|
for (j = 0; j < arraylen(Iso15693FrameSOF); j += skip) {
|
||||||
corr += FrameSOF[j] * GraphBuffer[i + (j / skip)];
|
corr += Iso15693FrameSOF[j] * GraphBuffer[i + (j / skip)];
|
||||||
}
|
}
|
||||||
if (corr > max) {
|
if (corr > max) {
|
||||||
max = corr;
|
max = corr;
|
||||||
|
@ -302,28 +341,28 @@ int CmdHF15Demod(const char *Cmd)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PrintAndLog("SOF at %d, correlation %d", maxPos,
|
PrintAndLog("SOF at %d, correlation %d", maxPos,
|
||||||
max / (arraylen(FrameSOF) / skip));
|
max / (arraylen(Iso15693FrameSOF) / skip));
|
||||||
|
|
||||||
i = maxPos + arraylen(FrameSOF) / skip;
|
i = maxPos + arraylen(Iso15693FrameSOF) / skip;
|
||||||
int k = 0;
|
int k = 0;
|
||||||
uint8_t outBuf[20];
|
uint8_t outBuf[20];
|
||||||
memset(outBuf, 0, sizeof(outBuf));
|
memset(outBuf, 0, sizeof(outBuf));
|
||||||
uint8_t mask = 0x01;
|
uint8_t mask = 0x01;
|
||||||
for (;;) {
|
for (;;) {
|
||||||
int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
|
int corr0 = 0, corr00 = 0, corr01 = 0, corr1 = 0, corrEOF = 0;
|
||||||
for(j = 0; j < arraylen(Logic0); j += skip) {
|
for(j = 0; j < arraylen(Iso15693Logic0); j += skip) {
|
||||||
corr0 += Logic0[j]*GraphBuffer[i+(j/skip)];
|
corr0 += Iso15693Logic0[j]*GraphBuffer[i+(j/skip)];
|
||||||
}
|
}
|
||||||
corr01 = corr00 = corr0;
|
corr01 = corr00 = corr0;
|
||||||
for(j = 0; j < arraylen(Logic0); j += skip) {
|
for(j = 0; j < arraylen(Iso15693Logic0); j += skip) {
|
||||||
corr00 += Logic0[j]*GraphBuffer[i+arraylen(Logic0)/skip+(j/skip)];
|
corr00 += Iso15693Logic0[j]*GraphBuffer[i+arraylen(Iso15693Logic0)/skip+(j/skip)];
|
||||||
corr01 += Logic1[j]*GraphBuffer[i+arraylen(Logic0)/skip+(j/skip)];
|
corr01 += Iso15693Logic1[j]*GraphBuffer[i+arraylen(Iso15693Logic0)/skip+(j/skip)];
|
||||||
}
|
}
|
||||||
for(j = 0; j < arraylen(Logic1); j += skip) {
|
for(j = 0; j < arraylen(Iso15693Logic1); j += skip) {
|
||||||
corr1 += Logic1[j]*GraphBuffer[i+(j/skip)];
|
corr1 += Iso15693Logic1[j]*GraphBuffer[i+(j/skip)];
|
||||||
}
|
}
|
||||||
for(j = 0; j < arraylen(FrameEOF); j += skip) {
|
for(j = 0; j < arraylen(Iso15693FrameEOF); j += skip) {
|
||||||
corrEOF += FrameEOF[j]*GraphBuffer[i+(j/skip)];
|
corrEOF += Iso15693FrameEOF[j]*GraphBuffer[i+(j/skip)];
|
||||||
}
|
}
|
||||||
// Even things out by the length of the target waveform.
|
// Even things out by the length of the target waveform.
|
||||||
corr00 *= 2;
|
corr00 *= 2;
|
||||||
|
@ -335,17 +374,17 @@ int CmdHF15Demod(const char *Cmd)
|
||||||
PrintAndLog("EOF at %d", i);
|
PrintAndLog("EOF at %d", i);
|
||||||
break;
|
break;
|
||||||
} else if (corr1 > corr0) {
|
} else if (corr1 > corr0) {
|
||||||
i += arraylen(Logic1) / skip;
|
i += arraylen(Iso15693Logic1) / skip;
|
||||||
outBuf[k] |= mask;
|
outBuf[k] |= mask;
|
||||||
} else {
|
} else {
|
||||||
i += arraylen(Logic0) / skip;
|
i += arraylen(Iso15693Logic0) / skip;
|
||||||
}
|
}
|
||||||
mask <<= 1;
|
mask <<= 1;
|
||||||
if (mask == 0) {
|
if (mask == 0) {
|
||||||
k++;
|
k++;
|
||||||
mask = 0x01;
|
mask = 0x01;
|
||||||
}
|
}
|
||||||
if ((i + (int)arraylen(FrameEOF)) >= GraphTraceLen) {
|
if ((i + (int)arraylen(Iso15693FrameEOF)) >= GraphTraceLen) {
|
||||||
PrintAndLog("ran off end!");
|
PrintAndLog("ran off end!");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -374,10 +413,9 @@ int CmdHF15Read(const char *Cmd)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Record Activity without enabling carrier
|
// Record Activity without enabling carrier
|
||||||
// TODO: currently it DOES enable the carrier
|
int CmdHF15Snoop(const char *Cmd)
|
||||||
int CmdHF15Record(const char *Cmd)
|
|
||||||
{
|
{
|
||||||
UsbCommand c = {CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693};
|
UsbCommand c = {CMD_SNOOP_ISO_15693};
|
||||||
SendCommand(&c);
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -514,7 +552,7 @@ static command_t CommandTable15[] =
|
||||||
{"help", CmdHF15Help, 1, "This help"},
|
{"help", CmdHF15Help, 1, "This help"},
|
||||||
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
|
{"demod", CmdHF15Demod, 1, "Demodulate ISO15693 from tag"},
|
||||||
{"read", CmdHF15Read, 0, "Read HF tag (ISO 15693)"},
|
{"read", CmdHF15Read, 0, "Read HF tag (ISO 15693)"},
|
||||||
{"record", CmdHF15Record, 0, "Record Samples (ISO 15693)"}, // atrox
|
{"snoop", CmdHF15Snoop, 0, "Eavesdrop ISO 15693 communications"},
|
||||||
{"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
|
{"reader", CmdHF15Reader, 0, "Act like an ISO15693 reader"},
|
||||||
{"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
|
{"sim", CmdHF15Sim, 0, "Fake an ISO15693 tag"},
|
||||||
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
|
{"cmd", CmdHF15Cmd, 0, "Send direct commands to ISO15693 tag"},
|
||||||
|
|
|
@ -14,57 +14,4 @@ int Iso15693AddCrc(uint8_t *req, int n);
|
||||||
char* Iso15693sprintUID(char *target,uint8_t *uid);
|
char* Iso15693sprintUID(char *target,uint8_t *uid);
|
||||||
unsigned short iclass_crc16(char *data_p, unsigned short length);
|
unsigned short iclass_crc16(char *data_p, unsigned short length);
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
// Map a sequence of octets (~layer 2 command) into the set of bits to feed
|
|
||||||
// to the FPGA, to transmit that command to the tag.
|
|
||||||
// Mode: highspeed && one subcarrier (ASK)
|
|
||||||
//-----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
// The sampling rate is 106.353 ksps/s, for T = 18.8 us
|
|
||||||
|
|
||||||
// SOF defined as
|
|
||||||
// 1) Unmodulated time of 56.64us
|
|
||||||
// 2) 24 pulses of 423.75khz
|
|
||||||
// 3) logic '1' (unmodulated for 18.88us followed by 8 pulses of 423.75khz)
|
|
||||||
|
|
||||||
static const int Iso15693FrameSOF[] = {
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
-1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1,
|
|
||||||
1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1
|
|
||||||
};
|
|
||||||
static const int Iso15693Logic0[] = {
|
|
||||||
1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1,
|
|
||||||
-1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1
|
|
||||||
};
|
|
||||||
static const int Iso15693Logic1[] = {
|
|
||||||
-1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1,
|
|
||||||
1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1
|
|
||||||
};
|
|
||||||
|
|
||||||
// EOF defined as
|
|
||||||
// 1) logic '0' (8 pulses of 423.75khz followed by unmodulated for 18.88us)
|
|
||||||
// 2) 24 pulses of 423.75khz
|
|
||||||
// 3) Unmodulated time of 56.64us
|
|
||||||
|
|
||||||
static const int Iso15693FrameEOF[] = {
|
|
||||||
1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1,
|
|
||||||
-1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
|
|
||||||
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
|
|
||||||
};
|
|
||||||
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
BIN
fpga/fpga_hf.bit
BIN
fpga/fpga_hf.bit
Binary file not shown.
|
@ -75,6 +75,8 @@ wire hi_read_rx_xcorr_848 = conf_word[0];
|
||||||
wire hi_read_rx_xcorr_snoop = conf_word[1];
|
wire hi_read_rx_xcorr_snoop = conf_word[1];
|
||||||
// divide subcarrier frequency by 4
|
// divide subcarrier frequency by 4
|
||||||
wire hi_read_rx_xcorr_quarter = conf_word[2];
|
wire hi_read_rx_xcorr_quarter = conf_word[2];
|
||||||
|
// send amplitude only instead of ci/cq pair
|
||||||
|
wire hi_read_rx_xcorr_amplitude = conf_word[3];
|
||||||
|
|
||||||
// For the high-frequency simulated tag: what kind of modulation to use.
|
// For the high-frequency simulated tag: what kind of modulation to use.
|
||||||
wire [2:0] hi_simulate_mod_type = conf_word[2:0];
|
wire [2:0] hi_simulate_mod_type = conf_word[2:0];
|
||||||
|
@ -102,7 +104,7 @@ hi_read_rx_xcorr hrxc(
|
||||||
hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
|
hrxc_ssp_frame, hrxc_ssp_din, ssp_dout, hrxc_ssp_clk,
|
||||||
cross_hi, cross_lo,
|
cross_hi, cross_lo,
|
||||||
hrxc_dbg,
|
hrxc_dbg,
|
||||||
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter
|
hi_read_rx_xcorr_848, hi_read_rx_xcorr_snoop, hi_read_rx_xcorr_quarter, hi_read_rx_xcorr_amplitude
|
||||||
);
|
);
|
||||||
|
|
||||||
hi_simulate hs(
|
hi_simulate hs(
|
||||||
|
|
|
@ -10,7 +10,7 @@ module hi_read_rx_xcorr(
|
||||||
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
ssp_frame, ssp_din, ssp_dout, ssp_clk,
|
||||||
cross_hi, cross_lo,
|
cross_hi, cross_lo,
|
||||||
dbg,
|
dbg,
|
||||||
xcorr_is_848, snoop, xcorr_quarter_freq
|
xcorr_is_848, snoop, xcorr_quarter_freq, hi_read_rx_xcorr_amplitude
|
||||||
);
|
);
|
||||||
input pck0, ck_1356meg, ck_1356megb;
|
input pck0, ck_1356meg, ck_1356megb;
|
||||||
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
output pwr_lo, pwr_hi, pwr_oe1, pwr_oe2, pwr_oe3, pwr_oe4;
|
||||||
|
@ -20,7 +20,7 @@ module hi_read_rx_xcorr(
|
||||||
output ssp_frame, ssp_din, ssp_clk;
|
output ssp_frame, ssp_din, ssp_clk;
|
||||||
input cross_hi, cross_lo;
|
input cross_hi, cross_lo;
|
||||||
output dbg;
|
output dbg;
|
||||||
input xcorr_is_848, snoop, xcorr_quarter_freq;
|
input xcorr_is_848, snoop, xcorr_quarter_freq, hi_read_rx_xcorr_amplitude;
|
||||||
|
|
||||||
// Carrier is steady on through this, unless we're snooping.
|
// Carrier is steady on through this, unless we're snooping.
|
||||||
assign pwr_hi = ck_1356megb & (~snoop);
|
assign pwr_hi = ck_1356megb & (~snoop);
|
||||||
|
@ -83,11 +83,46 @@ reg signed [13:0] corr_q_accum;
|
||||||
// we will report maximum 8 significant bits
|
// we will report maximum 8 significant bits
|
||||||
reg signed [7:0] corr_i_out;
|
reg signed [7:0] corr_i_out;
|
||||||
reg signed [7:0] corr_q_out;
|
reg signed [7:0] corr_q_out;
|
||||||
|
|
||||||
// clock and frame signal for communication to ARM
|
// clock and frame signal for communication to ARM
|
||||||
reg ssp_clk;
|
reg ssp_clk;
|
||||||
reg ssp_frame;
|
reg ssp_frame;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// the amplitude of the subcarrier is sqrt(ci^2 + cq^2).
|
||||||
|
// approximate by amplitude = max(|ci|,|cq|) + 1/2*min(|ci|,|cq|)
|
||||||
|
reg [13:0] corr_amplitude, abs_ci, abs_cq, max_ci_cq, min_ci_cq;
|
||||||
|
|
||||||
|
|
||||||
|
always @(corr_i_accum or corr_q_accum)
|
||||||
|
begin
|
||||||
|
if (corr_i_accum[13] == 1'b0)
|
||||||
|
abs_ci <= corr_i_accum;
|
||||||
|
else
|
||||||
|
abs_ci <= -corr_i_accum;
|
||||||
|
|
||||||
|
if (corr_q_accum[13] == 1'b0)
|
||||||
|
abs_cq <= corr_q_accum;
|
||||||
|
else
|
||||||
|
abs_cq <= -corr_q_accum;
|
||||||
|
|
||||||
|
if (abs_ci > abs_cq)
|
||||||
|
begin
|
||||||
|
max_ci_cq <= abs_ci;
|
||||||
|
min_ci_cq <= abs_cq;
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
max_ci_cq <= abs_cq;
|
||||||
|
min_ci_cq <= abs_ci;
|
||||||
|
end
|
||||||
|
|
||||||
|
corr_amplitude <= max_ci_cq + min_ci_cq/2;
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
// The subcarrier reference signals
|
// The subcarrier reference signals
|
||||||
reg subcarrier_I;
|
reg subcarrier_I;
|
||||||
reg subcarrier_Q;
|
reg subcarrier_Q;
|
||||||
|
@ -111,17 +146,26 @@ begin
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
// ADC data appears on the rising edge, so sample it on the falling edge
|
// ADC data appears on the rising edge, so sample it on the falling edge
|
||||||
always @(negedge adc_clk)
|
always @(negedge adc_clk)
|
||||||
begin
|
begin
|
||||||
// These are the correlators: we correlate against in-phase and quadrature
|
// These are the correlators: we correlate against in-phase and quadrature
|
||||||
// versions of our reference signal, and keep the (signed) result to
|
// versions of our reference signal, and keep the (signed) results or the
|
||||||
// send out later over the SSP.
|
// resulting amplitude to send out later over the SSP.
|
||||||
if(corr_i_cnt == 6'd0)
|
if(corr_i_cnt == 6'd0)
|
||||||
begin
|
begin
|
||||||
if(snoop)
|
if(snoop)
|
||||||
begin
|
begin
|
||||||
// Send 7 most significant bits of tag signal (signed), plus 1 bit reader signal
|
if (hi_read_rx_xcorr_amplitude)
|
||||||
|
begin
|
||||||
|
// send amplitude plus 2 bits reader signal
|
||||||
|
corr_i_out <= corr_amplitude[13:6];
|
||||||
|
corr_q_out <= {corr_amplitude[5:0], after_hysteresis_prev_prev, after_hysteresis_prev};
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// Send 7 most significant bits of in phase tag signal (signed), plus 1 bit reader signal
|
||||||
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
|
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
|
||||||
corr_i_out <= {corr_i_accum[11:5], after_hysteresis_prev_prev};
|
corr_i_out <= {corr_i_accum[11:5], after_hysteresis_prev_prev};
|
||||||
else // truncate to maximum value
|
else // truncate to maximum value
|
||||||
|
@ -129,6 +173,7 @@ begin
|
||||||
corr_i_out <= {7'b0111111, after_hysteresis_prev_prev};
|
corr_i_out <= {7'b0111111, after_hysteresis_prev_prev};
|
||||||
else
|
else
|
||||||
corr_i_out <= {7'b1000000, after_hysteresis_prev_prev};
|
corr_i_out <= {7'b1000000, after_hysteresis_prev_prev};
|
||||||
|
// Send 7 most significant bits of quadrature phase tag signal (signed), plus 1 bit reader signal
|
||||||
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
|
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
|
||||||
corr_q_out <= {corr_q_accum[11:5], after_hysteresis_prev};
|
corr_q_out <= {corr_q_accum[11:5], after_hysteresis_prev};
|
||||||
else // truncate to maximum value
|
else // truncate to maximum value
|
||||||
|
@ -136,11 +181,19 @@ begin
|
||||||
corr_q_out <= {7'b0111111, after_hysteresis_prev};
|
corr_q_out <= {7'b0111111, after_hysteresis_prev};
|
||||||
else
|
else
|
||||||
corr_q_out <= {7'b1000000, after_hysteresis_prev};
|
corr_q_out <= {7'b1000000, after_hysteresis_prev};
|
||||||
after_hysteresis_prev_prev <= after_hysteresis;
|
end
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
// Send 8 bits of tag signal
|
if (hi_read_rx_xcorr_amplitude)
|
||||||
|
begin
|
||||||
|
// send amplitude
|
||||||
|
corr_i_out <= {2'b00, corr_amplitude[13:8]};
|
||||||
|
corr_q_out <= corr_amplitude[7:0];
|
||||||
|
end
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
// Send 8 bits of in phase tag signal
|
||||||
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
|
if (corr_i_accum[13:11] == 3'b000 || corr_i_accum[13:11] == 3'b111)
|
||||||
corr_i_out <= corr_i_accum[11:4];
|
corr_i_out <= corr_i_accum[11:4];
|
||||||
else // truncate to maximum value
|
else // truncate to maximum value
|
||||||
|
@ -148,6 +201,7 @@ begin
|
||||||
corr_i_out <= 8'b01111111;
|
corr_i_out <= 8'b01111111;
|
||||||
else
|
else
|
||||||
corr_i_out <= 8'b10000000;
|
corr_i_out <= 8'b10000000;
|
||||||
|
// Send 8 bits of quadrature phase tag signal
|
||||||
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
|
if (corr_q_accum[13:11] == 3'b000 || corr_q_accum[13:11] == 3'b111)
|
||||||
corr_q_out <= corr_q_accum[11:4];
|
corr_q_out <= corr_q_accum[11:4];
|
||||||
else // truncate to maximum value
|
else // truncate to maximum value
|
||||||
|
@ -156,6 +210,10 @@ begin
|
||||||
else
|
else
|
||||||
corr_q_out <= 8'b10000000;
|
corr_q_out <= 8'b10000000;
|
||||||
end
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// for each Q/I pair report two reader signal samples when sniffing. Store the 1st.
|
||||||
|
after_hysteresis_prev_prev <= after_hysteresis;
|
||||||
// Initialize next correlation.
|
// Initialize next correlation.
|
||||||
// Both I and Q reference signals are high when corr_i_nct == 0. Therefore need to accumulate.
|
// Both I and Q reference signals are high when corr_i_nct == 0. Therefore need to accumulate.
|
||||||
corr_i_accum <= $signed({1'b0,adc_d});
|
corr_i_accum <= $signed({1'b0,adc_d});
|
||||||
|
@ -172,16 +230,16 @@ begin
|
||||||
corr_q_accum <= corr_q_accum + $signed({1'b0,adc_d});
|
corr_q_accum <= corr_q_accum + $signed({1'b0,adc_d});
|
||||||
else
|
else
|
||||||
corr_q_accum <= corr_q_accum - $signed({1'b0,adc_d});
|
corr_q_accum <= corr_q_accum - $signed({1'b0,adc_d});
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
// for each Q/I pair report two reader signal samples when sniffing
|
// for each Q/I pair report two reader signal samples when sniffing. Store the 2nd.
|
||||||
if(corr_i_cnt == 6'd32)
|
if(corr_i_cnt == 6'd32)
|
||||||
after_hysteresis_prev <= after_hysteresis;
|
after_hysteresis_prev <= after_hysteresis;
|
||||||
|
|
||||||
// Then the result from last time is serialized and send out to the ARM.
|
// Then the result from last time is serialized and send out to the ARM.
|
||||||
// We get one report each cycle, and each report is 16 bits, so the
|
// We get one report each cycle, and each report is 16 bits, so the
|
||||||
// ssp_clk should be the adc_clk divided by 64/16 = 4.
|
// ssp_clk should be the adc_clk divided by 64/16 = 4.
|
||||||
|
// ssp_clk frequency = 13,56MHz / 4 = 3.39MHz
|
||||||
|
|
||||||
if(corr_i_cnt[1:0] == 2'b10)
|
if(corr_i_cnt[1:0] == 2'b10)
|
||||||
ssp_clk <= 1'b0;
|
ssp_clk <= 1'b0;
|
||||||
|
|
|
@ -125,7 +125,7 @@ typedef struct{
|
||||||
#define CMD_ISO_14443B_COMMAND 0x0305
|
#define CMD_ISO_14443B_COMMAND 0x0305
|
||||||
#define CMD_READER_ISO_15693 0x0310
|
#define CMD_READER_ISO_15693 0x0310
|
||||||
#define CMD_SIMTAG_ISO_15693 0x0311
|
#define CMD_SIMTAG_ISO_15693 0x0311
|
||||||
#define CMD_RECORD_RAW_ADC_SAMPLES_ISO_15693 0x0312
|
#define CMD_SNOOP_ISO_15693 0x0312
|
||||||
#define CMD_ISO_15693_COMMAND 0x0313
|
#define CMD_ISO_15693_COMMAND 0x0313
|
||||||
#define CMD_ISO_15693_COMMAND_DONE 0x0314
|
#define CMD_ISO_15693_COMMAND_DONE 0x0314
|
||||||
#define CMD_ISO_15693_FIND_AFI 0x0315
|
#define CMD_ISO_15693_FIND_AFI 0x0315
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue