]> git.zerfleddert.de Git - proxmark3-svn/blob - client/cmdhf14a.c
Fix FMCN setting so it actually matches datasheet
[proxmark3-svn] / client / cmdhf14a.c
1 //-----------------------------------------------------------------------------
2 // Copyright (C) 2010 iZsh <izsh at fail0verflow.com>
3 //
4 // This code is licensed to you under the terms of the GNU GPL, version 2 or,
5 // at your option, any later version. See the LICENSE.txt file for the text of
6 // the license.
7 //-----------------------------------------------------------------------------
8 // High frequency ISO14443A commands
9 //-----------------------------------------------------------------------------
10
11 #include <stdio.h>
12 #include <stdlib.h>
13 #include <string.h>
14 #include "iso14443crc.h"
15 #include "data.h"
16 #include "proxusb.h"
17 #include "ui.h"
18 #include "cmdparser.h"
19 #include "cmdhf14a.h"
20
21 static int CmdHelp(const char *Cmd);
22
23 int CmdHF14AList(const char *Cmd)
24 {
25 uint8_t got[1920];
26 GetFromBigBuf(got, sizeof(got));
27
28 PrintAndLog("recorded activity:");
29 PrintAndLog(" ETU :rssi: who bytes");
30 PrintAndLog("---------+----+----+-----------");
31
32 int i = 0;
33 int prev = -1;
34
35 for (;;) {
36 if(i >= 1900) {
37 break;
38 }
39
40 bool isResponse;
41 int timestamp = *((uint32_t *)(got+i));
42 if (timestamp & 0x80000000) {
43 timestamp &= 0x7fffffff;
44 isResponse = 1;
45 } else {
46 isResponse = 0;
47 }
48
49 int metric = 0;
50 int parityBits = *((uint32_t *)(got+i+4));
51 // 4 bytes of additional information...
52 // maximum of 32 additional parity bit information
53 //
54 // TODO:
55 // at each quarter bit period we can send power level (16 levels)
56 // or each half bit period in 256 levels.
57
58
59 int len = got[i+8];
60
61 if (len > 100) {
62 break;
63 }
64 if (i + len >= 1900) {
65 break;
66 }
67
68 uint8_t *frame = (got+i+9);
69
70 // Break and stick with current result if buffer was not completely full
71 if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
72
73 char line[1000] = "";
74 int j;
75 for (j = 0; j < len; j++) {
76 int oddparity = 0x01;
77 int k;
78
79 for (k=0;k<8;k++) {
80 oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
81 }
82
83 //if((parityBits >> (len - j - 1)) & 0x01) {
84 if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
85 sprintf(line+(j*4), "%02x! ", frame[j]);
86 }
87 else {
88 sprintf(line+(j*4), "%02x ", frame[j]);
89 }
90 }
91
92 char *crc;
93 crc = "";
94 if (len > 2) {
95 uint8_t b1, b2;
96 for (j = 0; j < (len - 1); j++) {
97 // gives problems... search for the reason..
98 /*if(frame[j] == 0xAA) {
99 switch(frame[j+1]) {
100 case 0x01:
101 crc = "[1] Two drops close after each other";
102 break;
103 case 0x02:
104 crc = "[2] Potential SOC with a drop in second half of bitperiod";
105 break;
106 case 0x03:
107 crc = "[3] Segment Z after segment X is not possible";
108 break;
109 case 0x04:
110 crc = "[4] Parity bit of a fully received byte was wrong";
111 break;
112 default:
113 crc = "[?] Unknown error";
114 break;
115 }
116 break;
117 }*/
118 }
119
120 if (strlen(crc)==0) {
121 ComputeCrc14443(CRC_14443_A, frame, len-2, &b1, &b2);
122 if (b1 != frame[len-2] || b2 != frame[len-1]) {
123 crc = (isResponse & (len < 6)) ? "" : " !crc";
124 } else {
125 crc = "";
126 }
127 }
128 } else {
129 crc = ""; // SHORT
130 }
131
132 char metricString[100];
133 if (isResponse) {
134 sprintf(metricString, "%3d", metric);
135 } else {
136 strcpy(metricString, " ");
137 }
138
139 PrintAndLog(" +%7d: %s: %s %s %s",
140 (prev < 0 ? 0 : (timestamp - prev)),
141 metricString,
142 (isResponse ? "TAG" : " "), line, crc);
143
144 prev = timestamp;
145 i += (len + 9);
146 }
147 return 0;
148 }
149
150 int CmdHF14AMifare(const char *Cmd)
151 {
152 UsbCommand c = {CMD_READER_MIFARE, {strtol(Cmd, NULL, 0), 0, 0}};
153 SendCommand(&c);
154 return 0;
155 }
156
157 int CmdHF14AReader(const char *Cmd)
158 {
159 UsbCommand c = {CMD_READER_ISO_14443a, {strtol(Cmd, NULL, 0), 0, 0}};
160 SendCommand(&c);
161 return 0;
162 }
163
164 // ## simulate iso14443a tag
165 // ## greg - added ability to specify tag UID
166 int CmdHF14ASim(const char *Cmd)
167 {
168
169 unsigned int hi = 0, lo = 0;
170 int n = 0, i = 0;
171 while (sscanf(&Cmd[i++], "%1x", &n ) == 1) {
172 hi= (hi << 4) | (lo >> 28);
173 lo= (lo << 4) | (n & 0xf);
174 }
175
176 // c.arg should be set to *Cmd or convert *Cmd to the correct format for a uid
177 UsbCommand c = {CMD_SIMULATE_TAG_ISO_14443a, {hi, lo, 0}};
178 PrintAndLog("Emulating 14443A TAG with UID %x%16x", hi, lo);
179 SendCommand(&c);
180 return 0;
181 }
182
183 int CmdHF14ASnoop(const char *Cmd)
184 {
185 UsbCommand c = {CMD_SNOOP_ISO_14443a};
186 SendCommand(&c);
187 return 0;
188 }
189
190 static command_t CommandTable[] =
191 {
192 {"help", CmdHelp, 1, "This help"},
193 {"list", CmdHF14AList, 0, "List ISO 14443a history"},
194 {"mifare", CmdHF14AMifare, 0, "Read out sector 0 parity error messages"},
195 {"reader", CmdHF14AReader, 0, "Act like an ISO14443 Type A reader"},
196 {"sim", CmdHF14ASim, 0, "<UID> -- Fake ISO 14443a tag"},
197 {"snoop", CmdHF14ASnoop, 0, "Eavesdrop ISO 14443 Type A"},
198 {NULL, NULL, 0, NULL}
199 };
200
201 int CmdHF14A(const char *Cmd)
202 {
203 CmdsParse(CommandTable, Cmd);
204 return 0;
205 }
206
207 int CmdHelp(const char *Cmd)
208 {
209 CmdsHelp(CommandTable);
210 return 0;
211 }
Impressum, Datenschutz