code.ino
1 // SPDX-FileCopyrightText: 2019 Anne Barela for Adafruit Industries 2 // 3 // SPDX-License-Identifier: MIT 4 5 #define PIEZO 3 6 #define CLOCK2 10 7 #define DATA2 9 8 #define CARD2 23 9 10 #define TRACK1_LEN 79 11 #define BUFF 30 12 uint8_t track1[TRACK1_LEN+BUFF]; 13 uint8_t scratch[TRACK1_LEN+BUFF]; 14 15 #define RIGHT 1 16 #define LEFT 0 17 18 #define BYTELENGTH 7 // 6 + 1 parity 19 20 //#define _SERIAL 1 21 #define _KEYBOARD 1 22 23 void shifttrack(byte track[], byte shiftbuffer[], uint8_t dir); 24 uint8_t verifycard(byte track[]); 25 26 void beep(uint8_t pin, long freq, long dur) { 27 long d = 500000/ freq; 28 29 for (long i=0; i< freq * dur / 2000; i++) { 30 digitalWrite(pin, HIGH); 31 delayMicroseconds(d); 32 digitalWrite(pin, LOW); 33 delayMicroseconds(d); 34 } 35 } 36 37 38 void setup() 39 { 40 #ifdef _SERIAL 41 Serial.begin(9600); // USB is always 12 Mbit/sec 42 #endif 43 44 pinMode(5, OUTPUT); 45 pinMode(PIEZO, OUTPUT); 46 digitalWrite(5, LOW); 47 48 beep(PIEZO, 4000, 200); 49 } 50 51 //http://stripesnoop.sourceforge.net/devel/magtek-app.pdf 52 53 void loop() 54 { 55 while (digitalRead(CARD2)); 56 uint8_t zeros = 0; 57 58 // card was swiped! 59 // check clocked in data 60 for (uint8_t t1 = 0; t1 < TRACK1_LEN; t1++) { 61 track1[t1] = 0; 62 for (uint8_t b=0; b < BYTELENGTH; b++) { 63 64 // wait while clock is high 65 while (digitalRead(CLOCK2) && !digitalRead(CARD2)); 66 // we sample on the falling edge! 67 uint8_t x = digitalRead(DATA2); 68 if (!x) { 69 // data is LSB and inverted! 70 track1[t1] |= _BV(b); 71 } 72 // heep hanging out while its low 73 while (!digitalRead(CLOCK2) && !digitalRead(CARD2)); 74 75 } 76 77 if ((t1 == 0) && (track1[t1] == 0)) { 78 // get rid of leading 0's 79 zeros++; 80 t1--; 81 continue; 82 } 83 84 if (zeros < 4) { 85 t1--; 86 continue; 87 } 88 if ((t1 == 1) && (track1[t1] == 0)) { 89 t1 = -1; 90 zeros = 1; 91 continue; 92 } 93 } 94 95 // shift left until we have no more starting zero bits! 96 while ((track1[0] & 0x1) == 0 ) { 97 shifttrack(track1, scratch, LEFT); 98 } 99 100 if (!verifycard(track1)) { 101 // Serial.println("flippy?"); 102 103 // didnt pass verification, perhaps we can try flipping it around? 104 for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) 105 scratch[i] = 0; // clear out the scratch 106 107 for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) { 108 // for each bit starting with the MSB of the LAST 'byte' to the LSB of the first byte 109 for (int8_t j=0; j < 7; j++) { 110 if (track1[TRACK1_LEN+BUFF-1-i] & _BV(6-j)) 111 scratch[i] |= _BV(j); 112 } 113 } 114 115 for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) { 116 track1[i] = scratch[i]; 117 } 118 119 // get rid of leading zero bits and possible single bit flips 120 while (((track1[0] & 0x1) == 0) || track1[1] == 0) 121 shifttrack(track1, scratch, LEFT); 122 } 123 124 if (verifycard(track1)) { 125 126 #ifdef _SERIAL 127 Serial.println("Swiped!"); 128 for (uint8_t i = 0; i < TRACK1_LEN; i++) { 129 Serial.print(track1[i], HEX); 130 Serial.print(" "); 131 } 132 Serial.println(); 133 for (uint8_t i = 0; i < TRACK1_LEN; i++) { 134 #if ARDUINO >= 100 135 Serial.write((track1[i] & 0x3F)+0x20); 136 #else 137 Serial.print((track1[i] & 0x3F)+0x20, BYTE); 138 #endif 139 Serial.print(" "); 140 } 141 Serial.println(); 142 for (uint8_t i = 0; i < 6; i++) { 143 for (uint8_t j = 0; j < 7; j++) { 144 if (track1[i] & _BV(j)) { 145 Serial.print('1'); 146 } else { 147 Serial.print('0'); 148 } 149 } 150 } 151 Serial.println(); 152 #endif 153 154 // FIND PAN 155 uint8_t i=2; 156 while ((track1[i] & 0x3F) != 0x3E) { 157 #if ARDUINO >= 100 158 #ifdef _SERIAL 159 Serial.write((track1[i] & 0x3F)+0x20); 160 #endif 161 #ifdef _KEYBOARD 162 Keyboard.write((track1[i] & 0x3F)+0x20); 163 #endif 164 #else 165 #ifdef _SERIAL 166 Serial.print((track1[i] & 0x3F)+0x20, BYTE); 167 #endif 168 #ifdef _KEYBOARD 169 Keyboard.print((track1[i] & 0x3F)+0x20, BYTE); 170 #endif 171 #endif 172 i++; 173 } 174 i++; 175 char fname[26], lname[26]; 176 177 // LAST NAME 178 uint8_t j=0; 179 while ((track1[i] & 0x3F) != 0xF) { 180 #ifdef _SERIAL 181 #if ARDUINO >= 100 182 Serial.write((track1[i] & 0x3F)+0x20); 183 #else 184 Serial.print((track1[i] & 0x3F)+0x20, BYTE); 185 #endif 186 #endif 187 lname[j++] = (track1[i] & 0x3F)+0x20; 188 i++; 189 } 190 lname[j] = 0; 191 i++; 192 j=0; 193 // FIRST NAME 194 while ((track1[i] & 0x3F) != 0x3E) { 195 #ifdef _SERIAL 196 #if ARDUINO >= 100 197 Serial.write((track1[i] & 0x3F)+0x20); 198 #else 199 Serial.print((track1[i] & 0x3F)+0x20, BYTE); 200 #endif 201 #endif 202 203 fname[j++] = (track1[i] & 0x3F)+0x20; 204 205 i++; 206 } 207 fname[j] = 0; 208 i++; 209 char y1, y2, m1, m2; 210 y1 = (track1[i++] & 0x3F)+0x20; 211 y2 = (track1[i++] & 0x3F)+0x20; 212 m1 = (track1[i++] & 0x3F)+0x20; 213 m2 = (track1[i++] & 0x3F)+0x20; 214 215 #ifdef _KEYBOARD 216 Keyboard.print('\t'); 217 #if ARDUINO >= 100 218 Keyboard.write(m1); 219 Keyboard.write(m2); 220 Keyboard.write(y1); 221 Keyboard.write(y2); 222 #else 223 Keyboard.print(m1, BYTE); 224 Keyboard.print(m2, BYTE); 225 Keyboard.print(y1, BYTE); 226 Keyboard.print(y2, BYTE); 227 #endif 228 229 Keyboard.print('\t'); // tab to amount 230 Keyboard.print('\t'); // tab to invoice 231 Keyboard.print('\t'); // tab to description 232 Keyboard.print("HOPE conference kits from Adafruit.com"); 233 Keyboard.print('\t'); // tab to customer ID 234 Keyboard.print('\t'); // tab to first name 235 Keyboard.print(fname); 236 Keyboard.print('\t'); // tab to last name 237 Keyboard.print(lname); 238 239 for (uint8_t i=0; i<5; i++) { 240 Keyboard.set_modifier(MODIFIERKEY_SHIFT); 241 Keyboard.set_key1(KEY_TAB); 242 Keyboard.send_now(); 243 Keyboard.set_modifier(0); 244 Keyboard.set_key1(0); 245 Keyboard.send_now(); 246 } 247 248 #endif 249 250 beep(PIEZO, 4000, 200); 251 } else { 252 beep(PIEZO, 1000, 200); 253 254 #ifdef _SERIAL 255 Serial.println("Failed!"); 256 for (uint8_t i = 0; i < TRACK1_LEN; i++) { 257 Serial.print(track1[i], HEX); 258 Serial.print(" "); 259 } 260 Serial.println(); 261 for (uint8_t i = 0; i < 6; i++) { 262 for (uint8_t j = 0; j < 7; j++) { 263 if (track1[i] & _BV(j)) { 264 Serial.print('1'); 265 } else { 266 Serial.print('0'); 267 } 268 } 269 } 270 } 271 Serial.println(); 272 #endif 273 274 //Serial.println(zeros, DEC); 275 276 for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) { 277 track1[i] = scratch[i] = 0; 278 } 279 280 while (! digitalRead(CARD2)); 281 return; 282 } 283 284 uint8_t verifycard(byte track[]) { 285 uint8_t parityok = 1; 286 287 // calculate parity for each byte 288 for (uint8_t i = 0; i < TRACK1_LEN; i++) { 289 uint8_t p = 1; 290 for (uint8_t j = 0; j < 6; j++) { 291 if (track1[i] & _BV(j)) 292 p++; 293 } 294 p %= 2; 295 if (p != track1[i] >> 6) { 296 //Serial.print("Bad parity on "); 297 //Serial.println(track1[i], HEX); 298 parityok = 0; 299 } 300 if (track1[i] == 0x1F) break; 301 } 302 303 if ((track1[0] == 0x45) && (track1[1] == 0x62) && parityok) { 304 return 1; 305 } 306 return 0; 307 } 308 309 // We use this to s 310 void shifttrack(byte track[], byte shiftbuffer[], uint8_t dir) { 311 if (dir == RIGHT) { 312 // shift right 313 uint8_t x =0; 314 315 for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) { 316 shiftbuffer[i] = ((track[i] << 1) | x) & 0x3F; 317 x = (track[i]>>6) & 0x1; // snag the parity bit 318 } 319 } else { 320 // left 321 uint8_t x =0; 322 323 for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) { 324 x = track[i+1] & 0x1; // snag the bit 325 shiftbuffer[i] = ((track[i] >> 1) | (x << 6)); 326 327 } 328 } 329 330 for (uint8_t i = 0; i < TRACK1_LEN+BUFF; i++) { 331 track[i] = shiftbuffer[i]; 332 } 333 }