Project

General

Profile

Download (10.9 KB) Statistics
| Branch: | Tag: | Revision:
1
/* ISO14443A Miller decoder for OpenPICC, working with differential time samples
2
 *  
3
 * Copyright 2007 Milosch Meriac <meriac@bitmanufaktur.de>
4
 * Copyright 2007 Karsten Nohl <honk98@web.de>
5
 * Copyright 2007,2008 Henryk Plötz <henryk@ploetzli.ch>
6
 *
7
 *  This program is free software; you can redistribute it and/or modify
8
 *  it under the terms of the GNU General Public License as published by 
9
 *  the Free Software Foundation; either version 2 of the License, or
10
 *  (at your option) any later version.
11
 *
12
 *  This program is distributed in the hope that it will be useful,
13
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
14
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15
 *  GNU General Public License for more details.
16
 *
17
 *  You should have received a copy of the GNU General Public License
18
 *  along with this program; if not, write to the Free Software
19
 *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
20
 *
21
 */
22

    
23
#include <openpicc.h>
24
#include <FreeRTOS.h>
25

    
26
#include <errno.h>
27
#include <stdlib.h>
28
#include <string.h>
29

    
30
#include "iso14443.h"
31
#include "iso14443a_diffmiller.h"
32
#include "usb_print.h"
33

    
34
#include "performance.h"
35

    
36
#define DEBUGP (void)
37
#define printf usb_print_string
38

    
39
/*
40
 * Decoding Methodology: We'll only see the edges for the start of modulation pauses and not
41
 * all symbols generate modulation pauses at all. Two phases:
42
 *  + Old state and next edge delta to sequence of symbols (might be more than one symbol per edge)
43
 *  + Symbols to EOF/SOF marker and bits
44
 * 
45
 * These are the possible old-state/delta combinations and the symbols they yield:
46
 * 
47
 * old_state  delta (in bit_len/4)  symbol(s)
48
 * none       3                     ZZ
49
 * none       5                     ZX
50
 * X          3                     X
51
 * X          5                     YZ
52
 * X          7                     YX
53
 * X          >=9                   YY
54
 * Y          3                     ZZ
55
 * Y          5                     ZX
56
 * Z          3                     Z
57
 * Z          5                     X
58
 * Z          >=7                   Y
59
 * 
60
 * All other combinations are invalid and likely en- or decoding errors. (Note that old_state
61
 * Y is exactly the same as old_state none.)
62
 * 
63
 * The mapping from symbol sequences to SOF/EOF/bit is as follows:
64
 *         X: 1
65
 * 0, then Y: EOF
66
 *   other Y: 0
67
 *   first Z: SOF
68
 *   other Z: 0
69
 */
70

    
71
#define BIT_LEN 128
72
/* The theoretical error margin for the timing measurement is about 7 (note: that is a jitter of 7 in
73
 * total, e.g. +/- 3.5), but we'll round that up to +/- 8. However, the specification allows pause
74
 * times from 2us to 3us, e.g. 1us difference, so we'll add another 13.
75
 */ 
76
#define BIT_LEN_ERROR_MAX (8+13)
77
#define PAUSE_LEN 20
78
/* Subtract the mean error margin (about 4, see comment above) from the bit length
79
 * Also subtract the pause length for the case when the clock is not counting during
80
 * a pause. Will subtract this length below for the when the clock *is* counting during
81
 * pauses.
82
 */
83
#define BIT_OFFSET (-4 -PAUSE_LEN)
84
#define BIT_LEN_3 ((BIT_LEN*3)/4 +BIT_OFFSET)
85
#define BIT_LEN_5 ((BIT_LEN*5)/4 +BIT_OFFSET)
86
#define BIT_LEN_7 ((BIT_LEN*7)/4 +BIT_OFFSET)
87
#define BIT_LEN_9 ((BIT_LEN*9)/4 +BIT_OFFSET)
88

    
89
#define ALMOST_EQUAL(a,b) ( abs(a-b) <= BIT_LEN_ERROR_MAX )
90
#define MUCH_GREATER_THAN(a,b) ( a > (b+BIT_LEN_ERROR_MAX) )
91
#define ALMOST_GREATER_THAN_OR_EQUAL(a,b) (a >= (b-BIT_LEN_ERROR_MAX))
92

    
93
enum symbol {NO_SYM=0, sym_x, sym_y, sym_z};
94
enum bit { BIT_ERROR, BIT_SOF, BIT_0, BIT_1, BIT_EOF };
95

    
96
#define PERFORMANCE_COUNTS 10
97
struct diffmiller_state {
98
	int initialized, pauses_count;
99
	enum symbol old_state;
100
	enum bit last_bit;
101
	iso14443_frame *frame;
102
	u_int32_t counter;
103
	u_int16_t byte,crc;
104
	u_int8_t parity;
105
	u_int8_t last_data_bit;
106
	u_int32_t performance[PERFORMANCE_COUNTS][2];
107
	size_t perf_index;
108
	struct {
109
		u_int8_t in_frame:1;
110
		u_int8_t frame_finished:1;
111
		u_int8_t overflow:1;
112
		u_int8_t error:1;
113
	} flags;
114
};
115

    
116
struct diffmiller_state _state;
117

    
118
inline void start_frame(struct diffmiller_state * const state)
119
{
120
	state->byte=0;
121
	state->parity=0;
122
	state->crc=0x6363;
123
	
124
	performance_set_checkpoint("start_frame before memset");
125
	memset(&state->flags, 0, sizeof(state->flags));
126
	state->flags.in_frame = 1;
127
	
128
	//memset(state->frame, 0, sizeof(*state->frame));
129
	memset(state->frame, 0, (u_int32_t)&(((iso14443_frame*)0)->data) );
130
	performance_set_checkpoint("start_frame after memset");
131
	state->frame->state = FRAME_PENDING;
132
}
133

    
134
static inline void append_to_frame(struct diffmiller_state *const state,
135
		u_int8_t byte, const u_int8_t parity, const u_int8_t valid_bits) {
136

    
137
	iso14443_frame * const f = state->frame;
138

    
139
	if(f->numbytes >= sizeof(f->data)/sizeof(f->data[0])-1) { /* -1, because the last byte may be half filled */
140
		state->flags.overflow = 1;
141
		return;
142
	}
143

    
144
	if(f->numbits != 0) {
145
		DEBUGP("Appending to a frame with incomplete byte");
146
	}
147

    
148
	f->data[f->numbytes] = byte & 0xff;
149
	f->parity[f->numbytes/8] |= ((parity&1)<<(f->numbytes%8));
150

    
151
	if(valid_bits == 8) {
152
		f->numbytes++;
153
		byte=(byte ^ state->crc)&0xFF;
154
		byte=(byte ^ byte<<4)&0xFF;
155
		state->crc=((state->crc>>8)^(byte<<8)^(byte<<3)^(byte>>4))&0xFFFF;
156
	} else {
157
		f->numbits += valid_bits;
158
	}
159
}
160

    
161

    
162
static inline void end_frame(struct diffmiller_state * const state, const u_int32_t counter, const int last_data_bit)
163
{
164
	if(state->frame != NULL) {
165
		if(counter > 0) {
166
			append_to_frame(state, state->byte, 0, counter);
167
		}
168
		
169
		state->frame->parameters.a.parity = GIVEN_PARITY;
170
		if(!state->crc)
171
			state->frame->parameters.a.crc = CRC_OK;
172
		else
173
			state->frame->parameters.a.crc = CRC_ERROR;
174
		
175
		if(last_data_bit)
176
			state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_1;
177
		else
178
			state->frame->parameters.a.last_bit = ISO14443A_LAST_BIT_0;
179
		
180
		state->flags.frame_finished = 1;
181
	}
182
}
183

    
184
#define PRINT_BIT(a) if(0){(void)a;}
185
//#define PRINT_BIT(a) usb_print_string_f(a,0)
186

    
187
#define DO_BIT_0 { \
188
	last_data_bit = 0; \
189
	if(++counter==9) { \
190
	    	append_to_frame(state, state->byte, 0, 8); \
191
	    	counter=state->byte=state->parity=0; \
192
	    } \
193
	PRINT_BIT(" 0"); \
194
}
195

    
196
#define DO_BIT_1 { \
197
	last_data_bit = 1; \
198
	if(counter<8)  { \
199
    	state->byte |= (1<<counter); \
200
    	state->parity ^= 1; \
201
    } \
202
	if(++counter==9) { \
203
	    	append_to_frame(state, state->byte, 1, 8); \
204
	    	counter=state->byte=state->parity=0; \
205
	} \
206
	PRINT_BIT(" 1"); \
207
}
208

    
209
#define DO_SYMBOL_X \
210
	PRINT_BIT("(X)"); \
211
	if(!in_frame) { \
212
		if(last_bit == BIT_0) DO_BIT_0; \
213
		error = 1; \
214
		PRINT_BIT(" ERROR\n"); \
215
		last_bit = BIT_ERROR; \
216
		in_frame = 0; \
217
	} else { \
218
		if(last_bit == BIT_0) DO_BIT_0; \
219
		DO_BIT_1; \
220
		last_bit = BIT_1; \
221
	}
222

    
223
#define DO_SYMBOL_Y \
224
	PRINT_BIT("(Y)"); \
225
	if(!in_frame) { \
226
		if(last_bit == BIT_0) DO_BIT_0; \
227
		error = 1; \
228
		PRINT_BIT(" ERROR\n"); \
229
		last_bit = BIT_ERROR; \
230
		in_frame = 0; \
231
	} else { \
232
		if(last_bit == BIT_0) { \
233
			end_frame(state, counter, last_data_bit); \
234
			PRINT_BIT(" EOF\n"); \
235
			last_bit = BIT_EOF; \
236
			in_frame = 0; \
237
		} else { \
238
			last_bit = BIT_0; \
239
		} \
240
	}
241

    
242
#define DO_SYMBOL_Z \
243
	PRINT_BIT("(Z)"); \
244
	if(!in_frame) { \
245
		if(last_bit == BIT_0) DO_BIT_0; \
246
		counter = 0; \
247
		start_frame(state); \
248
		PRINT_BIT("SOF"); \
249
		in_frame = 1; \
250
		last_bit = BIT_ERROR; \
251
		last_bit = BIT_SOF; \
252
	} else { \
253
		if(last_bit == BIT_0) DO_BIT_0; \
254
		last_bit = BIT_0; \
255
	}
256

    
257

    
258
int __ramfunc iso14443a_decode_diffmiller(struct diffmiller_state * const state, iso14443_frame * const frame, 
259
	const u_int32_t buffer[], unsigned int * const offset, const unsigned int buflen)
260
{
261
	if(state == NULL || !state->initialized) return -EINVAL;
262
	if(state->frame != NULL && state->frame != frame) return -EINVAL;
263
	state->frame = frame;
264
	
265
	enum symbol old_state = state->old_state;
266
	enum bit last_bit = state->last_bit;
267
	int in_frame = state->flags.in_frame;
268
	int error = state->flags.error;
269
	int counter = state->counter;
270
	int last_data_bit = state->last_data_bit;
271
	
272
	if(state->perf_index < PERFORMANCE_COUNTS) {
273
		state->performance[state->perf_index][0] = *offset;
274
		state->performance[state->perf_index++][1] = buflen;
275
	}
276
	
277
	for(; *offset < buflen; ) {
278
		int delta;
279
		if(state->pauses_count)
280
			delta = buffer[(*offset)++] - PAUSE_LEN;
281
		else
282
			delta = buffer[(*offset)++];
283

    
284
		switch(old_state) {
285
		case sym_x:
286
			if( ALMOST_EQUAL(delta, BIT_LEN_3) ) {
287
				DO_SYMBOL_X;
288
				old_state = sym_x;
289
			} else if( ALMOST_EQUAL(delta, BIT_LEN_5) ) {
290
				DO_SYMBOL_Y;
291
				DO_SYMBOL_Z;
292
				old_state = sym_z;
293
			} else if( ALMOST_EQUAL(delta, BIT_LEN_7) ) {
294
				DO_SYMBOL_Y;
295
				DO_SYMBOL_X;
296
				old_state = sym_x;
297
			} else if( ALMOST_GREATER_THAN_OR_EQUAL(delta, BIT_LEN_9)) {
298
				DO_SYMBOL_Y;
299
				DO_SYMBOL_Y;
300
				old_state = sym_y;
301
			}
302
			break;
303
		case NO_SYM: /* Fall-Through */
304
		case sym_y:
305
			if( ALMOST_EQUAL(delta, BIT_LEN_3) ) {
306
				DO_SYMBOL_Z;
307
				DO_SYMBOL_Z;
308
				old_state = sym_z;
309
			} else if( ALMOST_EQUAL(delta, BIT_LEN_5) ) {
310
				DO_SYMBOL_Z;
311
				DO_SYMBOL_X;
312
				old_state = sym_x;
313
			} 
314
			break;
315
		case sym_z:
316
			if( ALMOST_EQUAL(delta, BIT_LEN_3) ) {
317
				DO_SYMBOL_Z;
318
				old_state = sym_z;
319
			} else if( ALMOST_EQUAL(delta, BIT_LEN_5) ) {
320
				DO_SYMBOL_X;
321
				old_state = sym_x;
322
			} else if( ALMOST_GREATER_THAN_OR_EQUAL(delta, BIT_LEN_7)) {
323
				DO_SYMBOL_Y;
324
				old_state = sym_y;
325
			}
326
			break;
327
		}
328
		
329
		if(state->flags.frame_finished)  {
330
			state->flags.frame_finished = 0;
331
			state->old_state = sym_y;
332
			state->last_bit = last_bit;
333
			state->counter = counter;
334
			state->flags.in_frame = in_frame;
335
			state->flags.error = error;
336
			state->frame = NULL;
337
			performance_set_checkpoint("frame finished");
338
			return 0;
339
		}
340
	}
341
	
342
	state->old_state = old_state;
343
	state->last_bit = last_bit;
344
	state->counter = counter;
345
	state->last_data_bit = last_data_bit;
346
	state->flags.in_frame = in_frame;
347
	state->flags.error = error;
348
	
349
	return -EBUSY;
350
}
351

    
352
int iso14443a_diffmiller_assert_frame_ended(struct diffmiller_state * const state, 
353
		iso14443_frame * const frame)
354
{
355
	if(state == NULL || !state->initialized) return -EINVAL;
356
	if(!state->flags.in_frame) return -EBUSY;
357
	if(state->frame != NULL && state->frame != frame) return -EINVAL;
358
	state->frame = frame;
359

    
360
	end_frame(state, state->counter, state->last_data_bit);
361
	PRINT_BIT(" EOF2\n");
362
	state->flags.in_frame = 0;
363
	
364
	if(state->flags.frame_finished)  {
365
		state->flags.frame_finished = 0;
366
		state->old_state = sym_y;
367
		state->last_bit = BIT_EOF;
368
		state->counter = 0;
369
		state->frame = NULL;
370
		performance_set_checkpoint("frame finished2");
371
		return 0;
372
	}
373
	
374
	return -EBUSY;
375
}
376

    
377
struct diffmiller_state *iso14443a_init_diffmiller(int pauses_count)
378
{
379
	if(_state.initialized) return NULL;
380
	struct diffmiller_state *state = &_state;
381
	state->initialized = 1;
382
	state->pauses_count = pauses_count;
383
	state->frame = NULL;
384
	state->old_state = sym_y;
385
	state->flags.frame_finished = 0;
386
	
387
	return state;
388
}
389

    
390

    
391
#include "cmd.h"
392
void iso14443a_diffmiller_print_performance(struct diffmiller_state * const state)
393
{
394
	DumpStringToUSB("`");
395
	unsigned int i; for(i=0; i<state->perf_index; i++) {
396
		if(i>0)DumpStringToUSB(";");
397
		DumpUIntToUSB(state->performance[i][0]); DumpStringToUSB(":"); DumpUIntToUSB(state->performance[i][1]);
398
	}
399
	DumpStringToUSB("'");
400
	state->perf_index=0;
401
}
(25-25/59)
Add picture from clipboard (Maximum size: 48.8 MB)