summaryrefslogtreecommitdiff
path: root/openpicc/application/iso14443a_miller.c
diff options
context:
space:
mode:
Diffstat (limited to 'openpicc/application/iso14443a_miller.c')
-rw-r--r--openpicc/application/iso14443a_miller.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/openpicc/application/iso14443a_miller.c b/openpicc/application/iso14443a_miller.c
new file mode 100644
index 0000000..deb9a8a
--- /dev/null
+++ b/openpicc/application/iso14443a_miller.c
@@ -0,0 +1,112 @@
+/* ISO14443A Manchester encoder for OpenPICC
+ * (C) 2007 by Henryk Plötz <henryk@ploetzli.ch>
+ *
+ * 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
+ *
+ */
+
+#include <openpicc.h>
+#include <FreeRTOS.h>
+
+#include <string.h>
+
+#include "iso14443_layer3a.h"
+#include "usb_print.h"
+#include "cmd.h"
+
+#ifdef FOUR_TIMES_OVERSAMPLING
+#define OVERSAMPLING_RATE 4
+
+/* definitions for four-times oversampling */
+#define SEQ_X 0x4
+#define SEQ_Y 0x0
+#define SEQ_Z 0x1
+#else
+#define OVERSAMPLING_RATE 2
+#define SEQ_X 0x2
+#define SEQ_Y 0x0
+#define SEQ_Z 0x1
+#endif
+
+enum miller_sequence {
+ SEQUENCE_X,
+ SEQUENCE_Y,
+ SEQUENCE_Z,
+};
+
+#define BIT_ENDMARKER -1
+
+int iso14443a_decode_miller(iso14443_frame *frame,
+ const u_int8_t *sample_buf, const u_int16_t sample_buf_len)
+{
+ signed int i, j, bit = 0, last_bit = 0;
+ enum miller_sequence current_seq;
+ unsigned int bitpos = 0;
+
+ memset(frame, 0, sizeof(frame));
+ frame->type = TYPE_A;
+ frame->parameters.a.parity = GIVEN_PARITY;
+
+ for(i=0; i<sample_buf_len && bit != BIT_ENDMARKER; i++) {
+ for(j=0; j<(signed)(sizeof(sample_buf[0])*8)/OVERSAMPLING_RATE && bit != BIT_ENDMARKER; j++) {
+ int sample = (sample_buf[i]>>(j*OVERSAMPLING_RATE)) & ~(~0 << OVERSAMPLING_RATE);
+ switch(sample) {
+ case SEQ_X: current_seq = SEQUENCE_X; break;
+ case SEQ_Y: current_seq = SEQUENCE_Y; break;
+ case SEQ_Z: current_seq = SEQUENCE_Z; break;
+ default: current_seq = SEQUENCE_Y;
+ }
+
+ switch(current_seq) {
+ case SEQ_X:
+ DumpStringToUSB("X");
+ bit = 1; break;
+ case SEQ_Y: /* Fall-through to SEQ_Z */
+ DumpStringToUSB("Y");
+ if(last_bit == 0) {
+ bit = BIT_ENDMARKER;
+ break;
+ }
+ case SEQ_Z:
+ DumpStringToUSB("Z");
+ bit = 0; break;
+ }
+
+ switch(bit) {
+ case BIT_ENDMARKER:
+ bitpos--;
+ break;
+ case 0: /* Fall-through */
+ case 1: {
+ int bytepos = bitpos/9;
+ if(bitpos % 9 == 8) { /* Parity bit */
+ frame->parity[ bytepos/8 ] |= (bit<<(bytepos%8));
+ } else {
+ frame->data[ bytepos ] |= (bit<<(bitpos%9));
+ }
+ }
+ }
+
+ last_bit = bit;
+ bitpos++;
+ }
+ }
+
+ frame->numbytes = bitpos/9;
+ frame->numbits = bitpos%9;
+ DumpStringToUSB("\n\r");
+
+ return 0;
+}
personal git repositories of Harald Welte. Your mileage may vary