1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
/* ISO14443A Manchester encoder for OpenPICC
* (C) 2006 by Harald Welte <hwelte@hmw-consulting.de>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*
* Definitions for 106kBps, at sampling clock 1695kHz
*
* bit sample pattern for one bit cycle
* MSB first LSB first hex LSB first
* Sequence D 1010101000000000 0000000001010101 0x0055
* Sequence E 0000000010101010 0101010100000000 0x5500
* Sequence F 0000000000000000 0000000000000000 0x0000
*
* Logic 1 Sequence D
* Logic 0 Sequence E
* SOF Sequence D
* EOF Sequence F
*
* 212/424/848kBps: BPSK.
*
* SOF: 32 subcarrier clocks + bit '0'
*
* SOF: hex LSB first: 0x55555555 55555555 + bit '0'
*
* EOF: even parity of last byte (!)
*
*/
#define MANCHESTER_SEQ_D 0x0055
#define MANCHESTER_SEQ_E 0x5500
#define MANCHESTER_SEQ_F 0x0000
#include <errno.h>
#include <string.h>
#include "openpicc.h"
#include "iso14443_layer3a.h"
#include "iso14443a_manchester.h"
enum parity {
PARITY_NONE, /* Don't add a parity bit */
ODD_PARITY, EVEN_PARITY, /* Calculate parity */
PARITY_0, PARITY_1 /* Set fixed parity */
};
static void manchester_enc_byte(u_int16_t **s16, u_int8_t data, enum parity parity)
{
int i;
u_int8_t sum_1 = 0;
u_int16_t *samples16 = *s16;
/* append 8 sample blobs, one for each bit */
for (i = 0; i < 8; i++) {
if (data & (1 << i)) {
*(samples16) = MANCHESTER_SEQ_D;
sum_1++;
} else {
*(samples16) = MANCHESTER_SEQ_E;
}
samples16++;
}
if(parity != PARITY_NONE) {
/* Append parity */
u_int8_t par=0;
switch(parity) {
case PARITY_NONE: break;
case PARITY_0: par = 0; break;
case PARITY_1: par = 1; break;
case ODD_PARITY: par = (sum_1 & 0x1) ? 0 : 1; break;
case EVEN_PARITY: par = (sum_1 & 0x1) ? 1 : 0; break;
}
if (par)
*(samples16) = MANCHESTER_SEQ_D;
else
*(samples16) = MANCHESTER_SEQ_E;
samples16++;
}
*s16 = samples16;
}
int manchester_encode(u_int8_t *sample_buf, u_int16_t sample_buf_len,
const iso14443_frame *frame)
{
unsigned int i, enc_size;
u_int16_t *samples16;
if(frame->type != TYPE_A) return -EINVAL;
if(frame->parameters.a.format != STANDARD_FRAME) return -EINVAL; /* AC not implemented yet */
/* One bit data is 16 bit/2 byte modulation data */
enc_size = 2*2 /* SOF and EOF */
+ frame->numbytes * 8 * 2
+ ((frame->parameters.a.parity != NO_PARITY) ? 1 : 0)*8*2;
if (sample_buf_len < enc_size)
return -EINVAL;
samples16 = (u_int16_t*)sample_buf;
/* SOF */
*(samples16++) = MANCHESTER_SEQ_D;
if(frame->parameters.a.parity == NO_PARITY)
for (i = 0; i < frame->numbytes; i++)
manchester_enc_byte(&samples16, frame->data[i], PARITY_NONE);
else if(frame->parameters.a.parity == GIVEN_PARITY)
for (i = 0; i < frame->numbytes; i++)
manchester_enc_byte(&samples16, frame->data[i], frame->parity[i]?PARITY_1:PARITY_0);
else if(frame->parameters.a.parity == PARITY)
for (i = 0; i < frame->numbytes; i++)
manchester_enc_byte(&samples16, frame->data[i], ODD_PARITY);
/* EOF */
*(samples16++) = MANCHESTER_SEQ_F;
return enc_size;
}
#if 0
/* Broken? */
#define BPSK_SPEED_212
static u_int32_t bpsk_sample_size(u_int8_t frame_bytelen);
int bpsk_encode(char *sample_buf, u_int16_t sample_buf_len,
const char *data, u_int8_t data_len)
{
/* burst of 32 sub carrier cycles */
memset(sample_buf, 0x55, 8);
}
#endif
|