Merge pull request #2654 from Antiklesys/master
[RRG-proxmark3.git] / client / src / cmdlfzx8211.c
blob03fcd6053fe697b1984b71234f3079e49c964f13
1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
3 //
4 // This program is free software: you can redistribute it and/or modify
5 // it under the terms of the GNU General Public License as published by
6 // the Free Software Foundation, either version 3 of the License, or
7 // (at your option) any later version.
8 //
9 // This program is distributed in the hope that it will be useful,
10 // but WITHOUT ANY WARRANTY; without even the implied warranty of
11 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 // GNU General Public License for more details.
14 // See LICENSE.txt for the text of the license.
15 //-----------------------------------------------------------------------------
16 // Low frequency ZX8211 tag commands
17 //-----------------------------------------------------------------------------
19 #include "cmdlfzx8211.h"
20 #include <string.h>
21 #include <ctype.h>
22 #include <stdlib.h>
23 #include <inttypes.h>
24 #include <stdio.h>
25 #include "commonutil.h" // ARRAYLEN
26 #include "common.h"
27 #include "cmdparser.h" // command_t
28 #include "comms.h"
29 #include "ui.h"
30 #include "graph.h"
31 #include "cmddata.h"
32 #include "cmdlf.h"
33 #include "protocols.h" // for T55xx config register definitions
34 #include "lfdemod.h" // parityTest
35 #include "cmdlft55xx.h" // write verify
36 #include "cliparser.h"
37 #include "zx8211.h"
39 static int CmdHelp(const char *Cmd);
41 // see ASKDemod for what args are accepted
42 int demodzx(bool verbose) {
43 (void) verbose; // unused so far
44 buffer_savestate_t saveState = save_bufferS32(g_GraphBuffer, g_GraphTraceLen);
45 saveState.offset = g_GridOffset;
47 // CmdAskEdgeDetect("");
49 // ASK / Manchester
50 bool st = true;
51 if (ASKDemod_ext(64, 0, 0, 0, false, false, false, 1, &st) != PM3_SUCCESS) {
52 PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ASK/Manchester Demod failed");
53 restore_bufferS32(saveState, g_GraphBuffer);
54 g_GridOffset = saveState.offset;
55 return PM3_ESOFT;
57 size_t size = g_DemodBufferLen;
58 int ans = detectzx(g_DemodBuffer, &size);
59 if (ans < 0) {
60 if (ans == -1)
61 PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: too few bits found");
62 else if (ans == -2)
63 PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: preamble not found");
64 else if (ans == -3)
65 PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: Size not correct: %zu", size);
66 else
67 PrintAndLogEx(DEBUG, "DEBUG: Error - ZX: ans: %d", ans);
69 restore_bufferS32(saveState, g_GraphBuffer);
70 g_GridOffset = saveState.offset;
71 return PM3_ESOFT;
73 setDemodBuff(g_DemodBuffer, 96, ans);
74 setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock));
76 // got a good demod
77 uint32_t raw1 = bytebits_to_byte(g_DemodBuffer, 32);
79 // chksum
81 // test checksums
83 PrintAndLogEx(SUCCESS, "ZX8211 - Card " _GREEN_("%u"), raw1);
84 return PM3_SUCCESS;
87 static int lf_Zx_read(void) {
89 PacketResponseNG resp;
90 clearCommandBuffer();
92 SendCommandNG(CMD_LF_ZX_READ, NULL, 0);
94 if (WaitForResponseTimeout(CMD_LF_ZX_READ, &resp, 1000) == false) {
95 PrintAndLogEx(ERR, "Error occurred, device did not respond during read operation.");
96 return PM3_ETIMEOUT;
99 return PM3_SUCCESS;
102 static int CmdZxDemod(const char *Cmd) {
103 CLIParserContext *ctx;
104 CLIParserInit(&ctx, "lf zx demod",
105 "Try to find zx8211 preamble, if found decode / descramble data",
106 "lf zx demod"
109 void *argtable[] = {
110 arg_param_begin,
111 arg_param_end
113 CLIExecWithReturn(ctx, Cmd, argtable, true);
114 CLIParserFree(ctx);
115 return demodzx(true);
118 static int CmdzxReader(const char *Cmd) {
119 CLIParserContext *ctx;
120 CLIParserInit(&ctx, "lf zx reader",
121 "read a zx tag",
122 "lf zx reader -@ -> continuous reader mode"
125 void *argtable[] = {
126 arg_param_begin,
127 arg_lit0("@", NULL, "optional - continuous reader mode"),
128 arg_param_end
130 CLIExecWithReturn(ctx, Cmd, argtable, true);
131 bool cm = arg_get_lit(ctx, 1);
132 CLIParserFree(ctx);
134 if (cm) {
135 PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
138 do {
139 lf_Zx_read();
140 demodzx(!cm);
141 } while (cm && !kbd_enter_pressed());
142 return PM3_SUCCESS;
146 static command_t CommandTable[] = {
147 {"help", CmdHelp, AlwaysAvailable, "This help"},
148 {"demod", CmdZxDemod, AlwaysAvailable, "demodulate an ZX 8211 tag from the GraphBuffer"},
149 {"reader", CmdzxReader, IfPm3Lf, "attempt to read and extract tag data"},
150 {NULL, NULL, NULL, NULL}
153 static int CmdHelp(const char *Cmd) {
154 (void)Cmd; // Cmd is not used so far
155 CmdsHelp(CommandTable);
156 return PM3_SUCCESS;
159 int CmdLFZx8211(const char *Cmd) {
160 clearCommandBuffer();
161 return CmdsParse(CommandTable, Cmd);
164 int detectzx(uint8_t *dest, size_t *size) {
165 if (*size < 96) return -1; // make sure buffer has data
166 size_t startIdx = 0;
167 uint8_t preamble[] = {0, 1, 0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 0};
168 if (!preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx))
169 return -2; // preamble not found
170 if (*size != 96) return -3; // wrong demoded size
171 // return start position
172 return (int)startIdx;