ADD: @pwpivi latest fixes.

ADD: @marshmellows fixes.
This commit is contained in:
iceman1001 2015-06-21 21:56:44 +02:00
parent c9216a92aa
commit 36f84d4748
3 changed files with 88 additions and 95 deletions

View file

@ -122,8 +122,7 @@ static struct {
STATE_UNSYNCD,
STATE_GOT_FALLING_EDGE_OF_SOF,
STATE_AWAITING_START_BIT,
STATE_RECEIVING_DATA,
STATE_ERROR_WAIT
STATE_RECEIVING_DATA
} state;
uint16_t shiftReg;
int bitCnt;
@ -145,7 +144,7 @@ static struct {
* Returns: true if we received a EOF
* false if we are still waiting for some more
*/
static int Handle14443bUartBit(int bit)
static RAMFUNC int Handle14443bUartBit(uint8_t bit)
{
switch(Uart.state) {
case STATE_UNSYNCD:
@ -172,7 +171,7 @@ static int Handle14443bUartBit(int bit)
} else {
// didn't stay down long enough
// before going high, error
Uart.state = STATE_ERROR_WAIT;
Uart.state = STATE_UNSYNCD;
}
} else {
// do nothing, keep waiting
@ -183,7 +182,8 @@ static int Handle14443bUartBit(int bit)
if(Uart.bitCnt > 12) {
// Give up if we see too many zeros without
// a one, too.
Uart.state = STATE_ERROR_WAIT;
LED_A_OFF();
Uart.state = STATE_UNSYNCD;
}
break;
@ -193,7 +193,7 @@ static int Handle14443bUartBit(int bit)
if(Uart.posCnt > 50/2) { // max 57us between characters = 49 1/fs, max 3 etus after low phase of SOF = 24 1/fs
// stayed high for too long between
// characters, error
Uart.state = STATE_ERROR_WAIT;
Uart.state = STATE_UNSYNCD;
}
} else {
// falling edge, this starts the data byte
@ -227,8 +227,8 @@ static int Handle14443bUartBit(int bit)
if(Uart.byteCnt >= Uart.byteCntMax) {
// Buffer overflowed, give up
Uart.posCnt = 0;
Uart.state = STATE_ERROR_WAIT;
LED_A_OFF();
Uart.state = STATE_UNSYNCD;
} else {
// so get the next byte now
Uart.posCnt = 0;
@ -237,31 +237,20 @@ static int Handle14443bUartBit(int bit)
} else if(Uart.shiftReg == 0x000) {
// this is an EOF byte
LED_A_OFF(); // Finished receiving
Uart.state = STATE_UNSYNCD;
if (Uart.byteCnt != 0) {
return TRUE;
}
Uart.posCnt = 0;
Uart.state = STATE_ERROR_WAIT;
} else {
// this is an error
Uart.posCnt = 0;
Uart.state = STATE_ERROR_WAIT;
LED_A_OFF();
Uart.state = STATE_UNSYNCD;
}
}
break;
case STATE_ERROR_WAIT:
// We're all screwed up, so wait a little while
// for whatever went wrong to finish, and then
// start over.
Uart.posCnt++;
if(Uart.posCnt > 10) {
Uart.state = STATE_UNSYNCD;
LED_A_OFF();
}
break;
default:
LED_A_OFF();
Uart.state = STATE_UNSYNCD;
break;
}
@ -269,6 +258,23 @@ static int Handle14443bUartBit(int bit)
return FALSE;
}
static void UartReset()
{
Uart.byteCntMax = MAX_FRAME_SIZE;
Uart.state = STATE_UNSYNCD;
Uart.byteCnt = 0;
Uart.bitCnt = 0;
}
static void UartInit(uint8_t *data)
{
Uart.output = data;
UartReset();
}
//-----------------------------------------------------------------------------
// Receive a command (from the reader to us, where we are the simulated tag),
// and store it in the given buffer, up to the given maximum length. Keeps
@ -278,44 +284,34 @@ static int Handle14443bUartBit(int bit)
// Assume that we're called with the SSC (to the FPGA) and ADC path set
// correctly.
//-----------------------------------------------------------------------------
static int GetIso14443bCommandFromReader(uint8_t *received, int *len, int maxLen)
static int GetIso14443bCommandFromReader(uint8_t *received, uint16_t *len)
{
uint8_t mask;
int i, bit;
// Set FPGA mode to "simulated ISO 14443B tag", no modulation (listen
// only, since we are receiving, not transmitting).
// Signal field is off with the appropriate LED
LED_D_OFF();
FpgaWriteConfWord(FPGA_MAJOR_MODE_HF_SIMULATOR | FPGA_HF_SIMULATOR_NO_MODULATION);
// Now run a `software UART' on the stream of incoming samples.
Uart.output = received;
Uart.byteCntMax = maxLen;
Uart.state = STATE_UNSYNCD;
UartInit(received);
for(;;) {
WDT_HIT();
if(BUTTON_PRESS()) return FALSE;
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
AT91C_BASE_SSC->SSC_THR = 0x00;
}
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_RXRDY)) {
uint8_t b = (uint8_t)AT91C_BASE_SSC->SSC_RHR;
mask = 0x80;
for(i = 0; i < 8; i++, mask >>= 1) {
bit = (b & mask);
if(Handle14443bUartBit(bit)) {
for(uint8_t mask = 0x80; mask != 0x00; mask >>= 1) {
if(Handle14443bUartBit(b & mask)) {
*len = Uart.byteCnt;
return TRUE;
}
}
}
}
return FALSE;
}
//-----------------------------------------------------------------------------
@ -324,9 +320,12 @@ static int GetIso14443bCommandFromReader(uint8_t *received, int *len, int maxLen
//-----------------------------------------------------------------------------
void SimulateIso14443bTag(void)
{
// the only command we understand is REQB, AFI=0, Select All, N=0:
// the only commands we understand is REQB, AFI=0, Select All, N=0:
static const uint8_t cmd1[] = { 0x05, 0x00, 0x08, 0x39, 0x73 };
// ... and we respond with ATQB, PUPI = 820de174, Application Data = 0x20381922,
// ... and REQB, AFI=0, Normal Request, N=0:
static const uint8_t cmd2[] = { 0x05, 0x00, 0x00, 0x71, 0xFF };
// ... and we always respond with ATQB, PUPI = 820de174, Application Data = 0x20381922,
// supports only 106kBit/s in both directions, max frame size = 32Bytes,
// supports ISO14443-4, FWI=8 (77ms), NAD supported, CID not supported:
static const uint8_t response1[] = {
@ -334,25 +333,27 @@ void SimulateIso14443bTag(void)
0x00, 0x21, 0x85, 0x5e, 0xd7
};
uint8_t *resp;
int respLen;
clear_trace();
set_tracing(TRUE);
const uint8_t *resp;
uint8_t *respCode;
uint16_t respLen, respCodeLen;
// allocate command receive buffer
BigBuf_free();
uint8_t *receivedCmd = BigBuf_malloc(MAX_FRAME_SIZE);
int len;
int i;
int cmdsRecvd = 0;
uint16_t len;
uint16_t cmdsRecvd = 0;
FpgaDownloadAndGo(FPGA_BITSTREAM_HF);
// prepare the (only one) tag answer:
CodeIso14443bAsTag(response1, sizeof(response1));
uint8_t *resp1 = BigBuf_malloc(ToSendMax);
memcpy(resp1, ToSend, ToSendMax);
uint16_t resp1Len = ToSendMax;
uint8_t *resp1Code = BigBuf_malloc(ToSendMax);
memcpy(resp1Code, ToSend, ToSendMax);
uint16_t resp1CodeLen = ToSendMax;
// We need to listen to the high-frequency, peak-detected path.
SetAdcMuxFor(GPIO_MUXSEL_HIPKD);
@ -361,20 +362,28 @@ void SimulateIso14443bTag(void)
cmdsRecvd = 0;
for(;;) {
uint8_t b1, b2;
if(!GetIso14443bCommandFromReader(receivedCmd, &len, 100)) {
if(!GetIso14443bCommandFromReader(receivedCmd, &len)) {
Dbprintf("button pressed, received %d commands", cmdsRecvd);
break;
}
// Good, look at the command now.
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(receivedCmd, len, 0, 0, parity, TRUE);
}
if(len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len)==0) {
resp = resp1; respLen = resp1Len;
// Good, look at the command now.
if ( (len == sizeof(cmd1) && memcmp(receivedCmd, cmd1, len) == 0)
|| (len == sizeof(cmd2) && memcmp(receivedCmd, cmd2, len) == 0) ) {
resp = response1;
respLen = sizeof(response1);
respCode = resp1Code;
respCodeLen = resp1CodeLen;
} else {
Dbprintf("new cmd from reader: len=%d, cmdsRecvd=%d", len, cmdsRecvd);
// And print whether the CRC fails, just for good measure
uint8_t b1, b2;
ComputeCrc14443(CRC_14443_B, receivedCmd, len-2, &b1, &b2);
if(b1 != receivedCmd[len-2] || b2 != receivedCmd[len-1]) {
// Not so good, try again.
@ -392,7 +401,7 @@ void SimulateIso14443bTag(void)
break;
}
if(respLen <= 0) continue;
if(respCodeLen <= 0) continue;
// Modulate BPSK
// Signal field is off with the appropriate LED
@ -402,15 +411,15 @@ void SimulateIso14443bTag(void)
FpgaSetupSsc();
// Transmit the response.
i = 0;
uint16_t i = 0;
for(;;) {
if(AT91C_BASE_SSC->SSC_SR & (AT91C_SSC_TXRDY)) {
uint8_t b = resp[i];
uint8_t b = respCode[i];
AT91C_BASE_SSC->SSC_THR = b;
i++;
if(i > respLen) {
if(i > respCodeLen) {
break;
}
}
@ -419,6 +428,13 @@ void SimulateIso14443bTag(void)
(void)b;
}
}
// trace the response:
if (tracing) {
uint8_t parity[MAX_PARITY_SIZE];
LogTrace(resp, respLen, 0, 0, parity, FALSE);
}
}
}
@ -436,8 +452,7 @@ static struct {
DEMOD_AWAITING_FALLING_EDGE_OF_SOF,
DEMOD_GOT_FALLING_EDGE_OF_SOF,
DEMOD_AWAITING_START_BIT,
DEMOD_RECEIVING_DATA,
DEMOD_ERROR_WAIT
DEMOD_RECEIVING_DATA
} state;
int bitCount;
int posCount;
@ -684,22 +699,6 @@ static void DemodInit(uint8_t *data)
}
static void UartReset()
{
Uart.byteCntMax = MAX_FRAME_SIZE;
Uart.state = STATE_UNSYNCD;
Uart.byteCnt = 0;
Uart.bitCnt = 0;
}
static void UartInit(uint8_t *data)
{
Uart.output = data;
UartReset();
}
/*
* Demodulate the samples we received from the tag, also log to tracebuffer
* quiet: set to 'TRUE' to disable debug output
@ -1165,11 +1164,11 @@ void RAMFUNC SnoopIso14443b(void)
/* false-triggered by the commands from the reader. */
DemodReset();
}
ReaderIsActive = (Uart.state != STATE_UNSYNCD);
ReaderIsActive = (Uart.state > STATE_GOT_FALLING_EDGE_OF_SOF);
}
if(!ReaderIsActive) { // no need to try decoding tag data if the reader is sending - and we cannot afford the time
if(Handle14443bSamplesDemod(ci, cq)) {
if(Handle14443bSamplesDemod(ci | 0x01, cq | 0x01)) {
//Use samples as a time measurement
if(tracing)

Binary file not shown.

View file

@ -28,22 +28,12 @@ assign pwr_oe1 = 1'b0;
assign pwr_oe3 = 1'b0;
assign pwr_oe4 = 1'b0;
(* clock_signal = "yes" *) reg fc_div_2;
wire adc_clk = ck_1356megb;
reg fc_div_2;
always @(negedge ck_1356megb)
fc_div_2 <= fc_div_2 + 1;
(* clock_signal = "yes" *) reg adc_clk;
always @(xcorr_is_848, ck_1356megb, fc_div_2)
if(xcorr_is_848)
// The subcarrier frequency is fc/16; we will sample at fc, so that
// means the subcarrier is 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 ...
adc_clk <= ck_1356megb;
else
// The subcarrier frequency is fc/32; we will sample at fc/2, and
// the subcarrier will look identical.
adc_clk <= fc_div_2;
// When we're a reader, we just need to do the BPSK demod; but when we're an
// eavesdropper, we also need to pick out the commands sent by the reader,
// using AM. Do this the same way that we do it for the simulated tag.
@ -85,12 +75,16 @@ reg ssp_clk;
reg ssp_frame;
always @(negedge adc_clk)
begin
if (xcorr_is_848 | fc_div_2)
corr_i_cnt <= corr_i_cnt + 1;
end
// ADC data appears on the rising edge, so sample it on the falling edge
always @(negedge adc_clk)
begin
corr_i_cnt <= corr_i_cnt + 1;
// These are the correlators: we correlate against in-phase and quadrature
// versions of our reference signal, and keep the (signed) result to
// send out later over the SSP.
@ -98,7 +92,7 @@ begin
begin
if(snoop)
begin
// 7 most significant bits of tag signal (signed), 1 bit reader signal:
// Send only 7 most significant bits of tag signal (signed), LSB is reader signal:
corr_i_out <= {corr_i_accum[13:7], after_hysteresis_prev_prev};
corr_q_out <= {corr_q_accum[13:7], after_hysteresis_prev};
after_hysteresis_prev_prev <= after_hysteresis;