1 //-----------------------------------------------------------------------------
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
7 //-----------------------------------------------------------------------------
8 // Low frequency COTAG commands
9 //-----------------------------------------------------------------------------
10 #include "cmdlfcotag.h" // COTAG function declarations
13 #include "cmdparser.h" // command_t
16 #include "cmddata.h" // getSamples
17 #include "ui.h" // PrintAndLog
18 #include "ctype.h" // tolower
19 #include "cliparser.h"
21 static int CmdHelp(const char *Cmd
);
23 // COTAG demod should be able to use GraphBuffer,
24 // when data load samples
25 int demodCOTAG(bool verbose
) {
26 (void) verbose
; // unused so far
28 uint8_t bits
[COTAG_BITS
] = {0};
29 size_t bitlen
= COTAG_BITS
;
30 memcpy(bits
, DemodBuffer
, COTAG_BITS
);
33 uint16_t err
= manrawdecode(bits
, &bitlen
, 1, &alignPos
);
35 PrintAndLogEx(DEBUG
, "DEBUG: Error - COTAG too many errors: %d", err
);
39 setDemodBuff(bits
, bitlen
, 0);
42 uint16_t cn
= bytebits_to_byteLSBF(bits
+ 1, 16);
43 uint32_t fc
= bytebits_to_byteLSBF(bits
+ 1 + 16, 8);
45 uint32_t raw1
= bytebits_to_byteLSBF(bits
, 32);
46 uint32_t raw2
= bytebits_to_byteLSBF(bits
+ 32, 32);
47 uint32_t raw3
= bytebits_to_byteLSBF(bits
+ 64, 32);
48 uint32_t raw4
= bytebits_to_byteLSBF(bits
+ 96, 32);
51 fc 161: 1010 0001 -> LSB 1000 0101
52 cn 33593 1000 0011 0011 1001 -> LSB 1001 1100 1100 0001
53 cccc cccc cccc cccc ffffffff
54 0 1001 1100 1100 0001 1000 0101 0000 0000 100001010000000001111011100000011010000010000000000000000000000000000000000000000000000000000000100111001100000110000101000
55 1001 1100 1100 0001 10000101
57 PrintAndLogEx(SUCCESS
, "COTAG Found: FC %u, CN: %u Raw: %08X%08X%08X%08X", fc
, cn
, raw1
, raw2
, raw3
, raw4
);
61 static int CmdCOTAGDemod(const char *Cmd
) {
62 CLIParserContext
*ctx
;
63 CLIParserInit(&ctx
, "lf cotag demod",
64 "Try to find COTAG preamble, if found decode / descramble data",
72 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
74 return demodCOTAG(true);
77 // When reading a COTAG.
78 // 0 = HIGH/LOW signal - maxlength bigbuff
79 // 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
80 // 2 = raw signal - maxlength bigbuff
81 static int CmdCOTAGReader(const char *Cmd
) {
83 CLIParserContext
*ctx
;
84 CLIParserInit(&ctx
, "lf cotag reader",
85 "read a COTAG tag, the current support for COTAG is limited. ",
91 arg_lit0("1", NULL
, "HIGH/LOW signal; maxlength bigbuff"),
92 arg_lit0("2", NULL
, "translation of HIGH/LOW into bytes with manchester 0,1"),
93 arg_lit0("3", NULL
, "raw signal; maxlength bigbuff"),
97 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
98 bool mode0
= arg_get_lit(ctx
, 1);
99 bool mode1
= arg_get_lit(ctx
, 2);
100 bool mode2
= arg_get_lit(ctx
, 3);
103 if ((mode0
+ mode1
+ mode2
) > 1) {
104 PrintAndLogEx(ERR
, "You can only use one option at a time");
120 PacketResponseNG resp
;
121 clearCommandBuffer();
122 SendCommandNG(CMD_LF_COTAG_READ
, (uint8_t *)&payload
, sizeof(payload
));
125 int res
= PM3_SUCCESS
;
126 while (!WaitForResponseTimeout(CMD_LF_COTAG_READ
, &resp
, 1000)) {
128 PrintAndLogEx(NORMAL
, "." NOLF
);
130 PrintAndLogEx(NORMAL
, "");
131 PrintAndLogEx(WARNING
, "command execution time out");
132 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
137 if (res
!= PM3_SUCCESS
) {
142 PrintAndLogEx(NORMAL
, "");
144 switch (payload
.mode
) {
149 getSamples(0, false);
153 memcpy(DemodBuffer
, resp
.data
.asBytes
, resp
.length
);
154 DemodBufferLen
= resp
.length
;
155 return demodCOTAG(true);
161 static command_t CommandTable
[] = {
162 {"help", CmdHelp
, AlwaysAvailable
, "This help"},
163 {"demod", CmdCOTAGDemod
, AlwaysAvailable
, "demodulate an COTAG tag"},
164 {"reader", CmdCOTAGReader
, IfPm3Lf
, "attempt to read and extract tag data"},
165 {NULL
, NULL
, NULL
, NULL
}
167 static int CmdHelp(const char *Cmd
) {
168 (void)Cmd
; // Cmd is not used so far
169 CmdsHelp(CommandTable
);
173 int CmdLFCOTAG(const char *Cmd
) {
174 clearCommandBuffer();
175 return CmdsParse(CommandTable
, Cmd
);
178 int readCOTAGUid(void) {
179 return (CmdCOTAGReader("-2") == PM3_SUCCESS
);