/* decode_openpicc - decode the ISO14443 data gathered by OpenPICC * * (C) 2006 by Milosch Meriac * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 * as published by the Free Software Foundation * * 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 #include #define PAUSE_MINIMUM_COUNT 32 typedef enum { MILLER_X = 0, MILLER_Y, MILLER_Z } TMillerState; int counter, byte, parity, crc; TMillerState MillerStatePrev; void Error (const char *message) { printf ("ERROR: %s\n", message); exit (1); } void ProcessBit (int bit, int edges) { printf ("[%02i]%i ", edges, bit); if (counter < 8) { byte = (byte >> 1) | (bit << 7); if (bit) parity++; } else putchar ((((~parity) & 1) == bit) ? ' ' : '!'); if (++counter == 9) { counter = 0; printf (" ==0x%02X\n", byte); byte = (byte ^ crc) & 0xFF; byte = (byte ^ byte << 4) & 0xFF; crc = ((crc >> 8) ^ (byte << 8) ^ (byte << 3) ^ (byte >> 4)) & 0xFFFF; // printf(" [%04X]\n",crc); byte = 0; parity = 0; } } void ProcessEdges (int Edges) { int bit; if (Edges > PAUSE_MINIMUM_COUNT) { if (!crc) printf ("CRC OK"); putchar ('\n'); counter = 0; byte = 0; parity = 0; crc = 0x6363; MillerStatePrev = MILLER_Y; } else { putchar ('X' + (char) MillerStatePrev); switch (MillerStatePrev) { case MILLER_X: if (Edges < 10) bit = 1; else if (Edges > 12) { ProcessBit (0, 0); putchar (' '); bit = 1; } else { MillerStatePrev = MILLER_Z; bit = 0; } break; case MILLER_Y: putchar ('\n'); if (Edges < 10) { MillerStatePrev = MILLER_Z; bit = -1; } else { MillerStatePrev = MILLER_X; bit = 1; } break; case MILLER_Z: if (Edges < 10) bit = 0; else if (Edges > 12) { printf ("[encoding error]"); bit = -1; } else { ProcessBit (0, 0); putchar (' '); MillerStatePrev = MILLER_X; bit = 1; } break; } if (bit >= 0) ProcessBit (bit, Edges); } } int main (int argc, char *argv[]) { int d, i, bit, bitprev, zeros; FILE *f; if (argc != 2) Error ("command line is 'decode datafile.bin'\n"); if ((f = fopen (argv[1], "rb")) == NULL) Error ("can't open data file"); crc = 1; bitprev = zeros = 0; while ((d = fgetc (f)) != EOF) { for (i = 0; i < 8; i++) { bit = d & 1; d >>= 1; // find raising edge if (bit && (bit != bitprev)) { ProcessEdges (zeros ? zeros : PAUSE_MINIMUM_COUNT + 1); zeros = 0; } else zeros++; bitprev = bit; } } fclose (f); printf ("\n\n"); return 0; }