1 //-----------------------------------------------------------------------------
2 // Copyright (C) Proxmark3 contributors. See AUTHORS.md for details.
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.
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 AWID26/50 commands
17 // FSK2a, RF/50, 96 bits (complete)
18 //-----------------------------------------------------------------------------
19 #include "cmdlfawid.h" // AWID function declarations
23 #include "commonutil.h" // ARRAYLEN
24 #include "cmdparser.h" // command_t
28 #include "ui.h" // PrintAndLog
29 #include "lfdemod.h" // parityTest
30 #include "cmdlf.h" // lf read
31 #include "protocols.h" // for T55xx config register definitions
32 #include "util_posix.h"
33 #include "cmdlft55xx.h" // verifywrite
34 #include "cliparser.h"
35 #include "cmdlfem4x05.h" // EM defines
37 static int CmdHelp(const char *Cmd
);
39 static int sendPing(void) {
40 SendCommandNG(CMD_BREAK_LOOP
, NULL
, 0);
41 SendCommandNG(CMD_PING
, NULL
, 0);
43 PacketResponseNG resp
;
44 if (WaitForResponseTimeout(CMD_PING
, &resp
, 1000) == false) {
50 static int sendTry(uint8_t fmtlen
, uint32_t fc
, uint32_t cn
, uint32_t delay
, uint8_t *bits
, size_t bs_len
, bool verbose
) {
53 PrintAndLogEx(INFO
, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fc
, cn
);
56 if (getAWIDBits(fmtlen
, fc
, cn
, bits
) != PM3_SUCCESS
) {
57 PrintAndLogEx(ERR
, "Error with tag bitstream generation.");
61 lf_fsksim_t
*payload
= calloc(1, sizeof(lf_fsksim_t
) + bs_len
);
64 payload
->separator
= 1;
66 memcpy(payload
->data
, bits
, bs_len
);
69 SendCommandNG(CMD_LF_FSK_SIMULATE
, (uint8_t *)payload
, sizeof(lf_fsksim_t
) + bs_len
);
76 static void verify_values(uint8_t *fmtlen
, uint32_t *fc
, uint32_t *cn
) {
79 if ((*fc
& 0xFFFF) != *fc
) {
81 PrintAndLogEx(INFO
, "Facility-Code Truncated to 16-bits (AWID50): %u", *fc
);
85 if ((*fc
& 0x1FFF) != *fc
) {
87 PrintAndLogEx(INFO
, "Facility-Code Truncated to 13-bits (AWID37): %u", *fc
);
89 if ((*cn
& 0x3FFFF) != *cn
) {
91 PrintAndLogEx(INFO
, "Card Number Truncated to 18-bits (AWID37): %u", *cn
);
95 if ((*fc
& 0xFF) != *fc
) {
97 PrintAndLogEx(INFO
, "Facility-Code Truncated to 8-bits (AWID34): %u", *fc
);
99 if ((*cn
& 0xFFFFFF) != *cn
) {
101 PrintAndLogEx(INFO
, "Card Number Truncated to 24-bits (AWID34): %u", *cn
);
107 if ((*fc
& 0xFF) != *fc
) {
109 PrintAndLogEx(INFO
, "Facility-Code Truncated to 8-bits (AWID26): %u", *fc
);
111 if ((*cn
& 0xFFFF) != *cn
) {
113 PrintAndLogEx(INFO
, "Card Number Truncated to 16-bits (AWID26): %u", *cn
);
119 // this read loops on device side.
120 // uses the demod in lfops.c
121 static int CmdAWIDWatch(const char *Cmd
) {
122 CLIParserContext
*ctx
;
123 CLIParserInit(&ctx
, "lf awid watch",
124 "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.\n"
125 "Run until the button is pressed or another USB command is issued.",
133 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
136 PrintAndLogEx(SUCCESS
, "Watching for AWID cards - place tag on antenna");
137 PrintAndLogEx(INFO
, "Press " _GREEN_("pm3 button") " to stop reading cards");
138 clearCommandBuffer();
139 SendCommandNG(CMD_LF_AWID_WATCH
, NULL
, 0);
140 return lfsim_wait_check(CMD_LF_AWID_WATCH
);
144 //AWID Prox demod - FSK2a RF/50 with preamble of 00000001 (always a 96 bit data stream)
145 //print full AWID Prox ID and some bit format details if found
146 int demodAWID(bool verbose
) {
147 (void) verbose
; // unused so far
148 uint8_t *bits
= calloc(MAX_GRAPH_TRACE_LEN
, sizeof(uint8_t));
150 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID failed to allocate memory");
154 size_t size
= getFromGraphBuffer(bits
);
156 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID not enough samples");
160 //get binary from fsk wave
162 int idx
= detectAWID(bits
, &size
, &waveIdx
);
166 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID not enough samples");
168 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID only noise found");
170 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID problem during FSK demod");
172 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID preamble not found");
174 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID size not correct, size %zu", size
);
176 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID error demoding fsk %d", idx
);
182 setDemodBuff(bits
, size
, idx
);
183 setClockGrid(50, waveIdx
+ (idx
* 50));
187 // 0 10 20 30 40 50 60
189 // 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
190 // -----------------------------------------------------------------------------
191 // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
192 // premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
193 // |---26 bit---| |-----117----||-------------142-------------|
194 // b = format bit len, o = odd parity of last 3 bits
195 // f = facility code, c = card number
196 // w = wiegand parity
197 // (26 bit format shown)
199 //get raw ID before removing parities
200 uint32_t rawLo
= bytebits_to_byte(bits
+ idx
+ 64, 32);
201 uint32_t rawHi
= bytebits_to_byte(bits
+ idx
+ 32, 32);
202 uint32_t rawHi2
= bytebits_to_byte(bits
+ idx
, 32);
204 size
= removeParity(bits
, idx
+ 8, 4, 1, 88);
206 PrintAndLogEx(DEBUG
, "DEBUG: Error - AWID at parity check-tag size does not match AWID format");
211 char binstr
[68] = {0};
212 binarray_2_binstr(binstr
, (char *)bits
, size
);
213 PrintAndLogEx(DEBUG
, "no parity... %s", binstr
);
215 // ok valid card found!
218 // 0 10 20 30 40 50 60
220 // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
221 // -----------------------------------------------------------------------------
222 // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
223 // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
224 // |26 bit| |-117--| |-----142------|
226 // 00110010 0 0000111110100000 00000000000100010010100010000111 1 000000000
227 // bbbbbbbb w ffffffffffffffff cccccccccccccccccccccccccccccccc w xxxxxxxxx
228 // |50 bit| |----4000------| |-----------2248975------------|
229 // b = format bit len, o = odd parity of last 3 bits
230 // f = facility code, c = card number
231 // w = wiegand parity
234 uint32_t cardnum
= 0;
237 uint8_t fmtLen
= bytebits_to_byte(bits
, 8);
241 fc
= bytebits_to_byte(bits
+ 9, 8);
242 cardnum
= bytebits_to_byte(bits
+ 17, 16);
243 code1
= bytebits_to_byte(bits
+ 8, fmtLen
);
244 PrintAndLogEx(SUCCESS
, "AWID - len: " _GREEN_("%d") " FC: " _GREEN_("%d") " Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x") ", Raw: %08x%08x%08x", fmtLen
, fc
, cardnum
, code1
, rawHi2
, rawHi
, rawLo
);
248 fc
= bytebits_to_byte(bits
+ 9, 8);
249 cardnum
= bytebits_to_byte(bits
+ 17, 24);
250 code1
= bytebits_to_byte(bits
+ 8, (fmtLen
- 32));
251 code2
= bytebits_to_byte(bits
+ 8 + (fmtLen
- 32), 32);
252 PrintAndLogEx(SUCCESS
, "AWID - len: " _GREEN_("%d") " FC: " _GREEN_("%d") " Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen
, fc
, cardnum
, code1
, code2
, rawHi2
, rawHi
, rawLo
);
256 fc
= bytebits_to_byte(bits
+ 14, 11);
257 cardnum
= bytebits_to_byte(bits
+ 25, 18);
258 code1
= bytebits_to_byte(bits
+ 8, (fmtLen
- 32));
259 code2
= bytebits_to_byte(bits
+ 8 + (fmtLen
- 32), 32);
260 PrintAndLogEx(SUCCESS
, "AWID - len: " _GREEN_("%d") " FC: " _GREEN_("%d") " Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen
, fc
, cardnum
, code1
, code2
, rawHi2
, rawHi
, rawLo
);
264 fc
= bytebits_to_byte(bits
+ 9, 13);
265 cardnum
= bytebits_to_byte(bits
+ 22, 18);
266 code1
= bytebits_to_byte(bits
+ 8, (fmtLen
- 32));
267 code2
= bytebits_to_byte(bits
+ 8 + (fmtLen
- 32), 32);
268 PrintAndLogEx(SUCCESS
, "AWID - len: " _GREEN_("%d")" FC: " _GREEN_("%d")" Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen
, fc
, cardnum
, code1
, code2
, rawHi2
, rawHi
, rawLo
);
274 fc
= bytebits_to_byte(bits
+ 9, 16);
275 cardnum
= bytebits_to_byte(bits
+ 25, 32);
276 code1
= bytebits_to_byte(bits
+ 8, (fmtLen
- 32));
277 code2
= bytebits_to_byte(bits
+ 8 + (fmtLen
- 32), 32);
278 PrintAndLogEx(SUCCESS
, "AWID - len: " _GREEN_("%d") " FC: " _GREEN_("%d") " Card: " _GREEN_("%u") " - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen
, fc
, cardnum
, code1
, code2
, rawHi2
, rawHi
, rawLo
);
283 cardnum
= bytebits_to_byte(bits
+ 8 + (fmtLen
- 17), 16);
284 code1
= bytebits_to_byte(bits
+ 8, fmtLen
- 32);
285 code2
= bytebits_to_byte(bits
+ 8 + (fmtLen
- 32), 32);
286 PrintAndLogEx(SUCCESS
, "AWID - len: " _GREEN_("%d") " -unknown- (%u) - Wiegand: " _GREEN_("%x%08x") ", Raw: %08x%08x%08x", fmtLen
, cardnum
, code1
, code2
, rawHi2
, rawHi
, rawLo
);
288 cardnum
= bytebits_to_byte(bits
+ 8 + (fmtLen
- 17), 16);
289 code1
= bytebits_to_byte(bits
+ 8, fmtLen
);
290 PrintAndLogEx(SUCCESS
, "AWID - len: " _GREEN_("%d") " -unknown- (%u) - Wiegand: " _GREEN_("%x") ", Raw: %08x%08x%08x", fmtLen
, cardnum
, code1
, rawHi2
, rawHi
, rawLo
);
296 PrintAndLogEx(DEBUG
, "DEBUG: AWID idx: %d, Len: %zu", idx
, size
);
297 PrintAndLogEx(DEBUG
, "DEBUG: Printing DemodBuffer:");
299 printDemodBuff(0, false, false, true);
300 printDemodBuff(0, false, false, false);
306 static int CmdAWIDDemod(const char *Cmd
) {
307 CLIParserContext
*ctx
;
308 CLIParserInit(&ctx
, "lf awid demod",
309 "Try to find AWID Prox preamble, if found decode / descramble data",
311 "lf awid demod --raw "
319 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
321 return demodAWID(true);
324 // this read is the "normal" read, which download lf signal and tries to demod here.
325 static int CmdAWIDReader(const char *Cmd
) {
326 CLIParserContext
*ctx
;
327 CLIParserInit(&ctx
, "lf awid reader",
328 "read a AWID Prox tag",
329 "lf awid reader -@ -> continuous reader mode"
334 arg_lit0("@", NULL
, "optional - continuous reader mode"),
337 CLIExecWithReturn(ctx
, Cmd
, argtable
, true);
338 bool cm
= arg_get_lit(ctx
, 1);
342 PrintAndLogEx(INFO
, "Press " _GREEN_("<Enter>") " to exit");
346 lf_read(false, 12000);
348 } while (cm
&& !kbd_enter_pressed());
353 static int CmdAWIDClone(const char *Cmd
) {
355 CLIParserContext
*ctx
;
356 CLIParserInit(&ctx
, "lf awid clone",
357 "clone a AWID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag",
358 "lf awid clone --fmt 26 --fc 123 --cn 1337 -> encode for T55x7 tag\n"
359 "lf awid clone --fmt 50 --fc 2001 --cn 13371337 -> encode long fmt for T55x7 tag\n"
360 "lf awid clone --fmt 26 --fc 123 --cn 1337 --q5 -> encode for Q5/T5555 tag\n"
361 "lf awid clone --fmt 26 --fc 123 --cn 1337 --em -> encode for EM4305/4469"
366 arg_u64_1(NULL
, "fmt", "<dec>", "format length 26|34|37|50"),
367 arg_u64_1(NULL
, "fc", "<dec>", "8|16bit value facility code"),
368 arg_u64_1(NULL
, "cn", "<dec>", "16|32-bit value card number"),
369 arg_lit0(NULL
, "q5", "optional - specify writing to Q5/T5555 tag"),
370 arg_lit0(NULL
, "em", "optional - specify writing to EM4305/4469 tag"),
373 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
375 uint8_t fmtlen
= arg_get_u32_def(ctx
, 1, 0);
376 uint32_t fc
= arg_get_u32_def(ctx
, 2, 0);
377 uint32_t cn
= arg_get_u32_def(ctx
, 3, 0);
378 bool q5
= arg_get_lit(ctx
, 4);
379 bool em
= arg_get_lit(ctx
, 5);
383 PrintAndLogEx(FAILED
, "Can't specify both Q5 and EM4305 at the same time");
387 uint32_t blocks
[4] = {T55x7_MODULATION_FSK2a
| T55x7_BITRATE_RF_50
| 3 << T55x7_MAXBLOCK_SHIFT
, 0, 0, 0};
388 char cardtype
[16] = {"T55x7"};
391 //t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
392 blocks
[0] = T5555_FIXED
| T5555_MODULATION_FSK2
| T5555_INVERT_OUTPUT
| T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT
;
393 snprintf(cardtype
, sizeof(cardtype
), "Q5/T5555");
398 PrintAndLogEx(WARNING
, "Beware some EM4305 tags don't support FSK and datarate = RF/50, check your tag copy!");
399 blocks
[0] = EM4305_AWID_CONFIG_BLOCK
;
400 snprintf(cardtype
, sizeof(cardtype
), "EM4305/4469");
403 verify_values(&fmtlen
, &fc
, &cn
);
405 uint8_t *bits
= calloc(96, sizeof(uint8_t));
407 if (getAWIDBits(fmtlen
, fc
, cn
, bits
) != PM3_SUCCESS
) {
408 PrintAndLogEx(ERR
, "Error with tag bitstream generation.");
413 blocks
[1] = bytebits_to_byte(bits
, 32);
414 blocks
[2] = bytebits_to_byte(bits
+ 32, 32);
415 blocks
[3] = bytebits_to_byte(bits
+ 64, 32);
420 for (uint8_t i
= 1; i
< ARRAYLEN(blocks
) ; i
++) {
421 blocks
[i
] = blocks
[i
] ^ 0xFFFFFFFF;
427 PrintAndLogEx(INFO
, "Preparing to clone AWID %u to " _YELLOW_("%s") " with FC: " _GREEN_("%u") " CN: " _GREEN_("%u"), fmtlen
, cardtype
, fc
, cn
);
428 print_blocks(blocks
, ARRAYLEN(blocks
));
432 res
= em4x05_clone_tag(blocks
, ARRAYLEN(blocks
), 0, false);
434 res
= clone_t55xx_tag(blocks
, ARRAYLEN(blocks
));
436 PrintAndLogEx(SUCCESS
, "Done!");
437 PrintAndLogEx(HINT
, "Hint: try " _YELLOW_("`lf awid reader`") " to verify");
441 static int CmdAWIDSim(const char *Cmd
) {
443 CLIParserContext
*ctx
;
444 CLIParserInit(&ctx
, "lf awid sim",
445 "Enables simulation of AWID card with specified facility-code and card number.\n"
446 "Simulation runs until the button is pressed or another USB command is issued.",
447 "lf awid sim --fmt 26 --fc 123 --cn 1337\n"
448 "lf awid sim --fmt 50 --fc 2001 --cn 13371337"
453 arg_u64_1(NULL
, "fmt", "<dec>", "format length 26|32|36|40"),
454 arg_u64_1(NULL
, "fc", "<dec>", "8-bit value facility code"),
455 arg_u64_1(NULL
, "cn", "<dec>", "16-bit value card number"),
458 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
460 uint8_t fmtlen
= arg_get_u32_def(ctx
, 1, 0);
461 uint32_t fc
= arg_get_u32_def(ctx
, 2, 0);
462 uint32_t cn
= arg_get_u32_def(ctx
, 3, 0);
466 memset(bs
, 0x00, sizeof(bs
));
468 verify_values(&fmtlen
, &fc
, &cn
);
470 if (getAWIDBits(fmtlen
, fc
, cn
, bs
) != PM3_SUCCESS
) {
471 PrintAndLogEx(ERR
, "Error with tag bitstream generation.");
475 PrintAndLogEx(SUCCESS
, "Simulating "_YELLOW_("AWID %u") " -- FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fmtlen
, fc
, cn
);
477 // AWID uses: FSK2a fcHigh: 10, fcLow: 8, clk: 50, invert: 1
478 // arg1 --- fcHigh<<8 + fcLow
479 // arg2 --- Inversion and clk setting
480 // 96 --- Bitstream length: 96-bits == 12 bytes
481 lf_fsksim_t
*payload
= calloc(1, sizeof(lf_fsksim_t
) + sizeof(bs
));
482 payload
->fchigh
= 10;
484 payload
->separator
= 1;
486 memcpy(payload
->data
, bs
, sizeof(bs
));
488 clearCommandBuffer();
489 SendCommandNG(CMD_LF_FSK_SIMULATE
, (uint8_t *)payload
, sizeof(lf_fsksim_t
) + sizeof(bs
));
492 return lfsim_wait_check(CMD_LF_FSK_SIMULATE
);
495 static int CmdAWIDBrute(const char *Cmd
) {
496 CLIParserContext
*ctx
;
497 CLIParserInit(&ctx
, "lf awid brute",
498 "Enables bruteforce of AWID reader with specified facility-code.\n"
499 "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
500 "if cardnumber is not given, it starts with 1 and goes up to 65535",
501 "lf awid brute --fmt 26 --fc 224\n"
502 "lf awid brute --fmt 50 --fc 2001 --delay 2000\n"
503 "lf awid brute --fmt 50 --fc 2001 --cn 200 --delay 2000 -v"
508 arg_u64_1(NULL
, "fmt", "<dec>", "format length 26|50"),
509 arg_u64_1(NULL
, "fc", "<dec>", "8|16bit value facility code"),
510 arg_u64_0(NULL
, "cn", "<dec>", "optional - card number to start with, max 65535"),
511 arg_u64_0(NULL
, "delay", "<dec>", "optional - delay betweens attempts in ms. Default 1000ms"),
512 arg_lit0("v", "verbose", "verbose output"),
515 CLIExecWithReturn(ctx
, Cmd
, argtable
, false);
517 uint8_t fmtlen
= arg_get_u32_def(ctx
, 1, 0);
518 uint32_t fc
= arg_get_u32_def(ctx
, 2, 0);
519 uint32_t cn
= arg_get_u32_def(ctx
, 3, 0);
520 uint32_t delay
= arg_get_u32_def(ctx
, 4, 1000);
521 bool verbose
= arg_get_lit(ctx
, 5);
524 // limit fc according to selected format
527 if ((fc
& 0xFFFF) != fc
) {
529 PrintAndLogEx(INFO
, "Facility-code truncated to 16-bits (AWID50): %u", fc
);
533 if ((fc
& 0xFF) != fc
) {
535 PrintAndLogEx(INFO
, "Facility-code truncated to 8-bits (AWID26): %u", fc
);
541 // truncate card number
542 if ((cn
& 0xFFFF) != cn
) {
544 PrintAndLogEx(INFO
, "Card number truncated to 16-bits : %u", cn
);
547 PrintAndLogEx(SUCCESS
, "Bruteforceing AWID %d reader", fmtlen
);
548 PrintAndLogEx(SUCCESS
, "Press " _GREEN_("pm3 button") " or " _GREEN_("<Enter>") " to abort simulation");
554 size_t size
= sizeof(bits
);
555 memset(bits
, 0x00, size
);
560 if (!g_session
.pm3_present
) {
561 PrintAndLogEx(WARNING
, "Device offline\n");
564 if (kbd_enter_pressed()) {
565 PrintAndLogEx(WARNING
, "aborted via keyboard!");
571 if (sendTry(fmtlen
, fc
, up
++, delay
, bits
, size
, verbose
) != PM3_SUCCESS
) {
576 // Do one down (if cardnumber is given)
579 if (sendTry(fmtlen
, fc
, --down
, delay
, bits
, size
, verbose
) != PM3_SUCCESS
) {
588 static command_t CommandTable
[] = {
589 {"help", CmdHelp
, AlwaysAvailable
, "this help"},
590 {"brute", CmdAWIDBrute
, IfPm3Lf
, "bruteforce card number against reader"},
591 {"clone", CmdAWIDClone
, IfPm3Lf
, "clone AWID tag to T55x7, Q5/T5555 or EM4305/4469"},
592 {"demod", CmdAWIDDemod
, AlwaysAvailable
, "demodulate an AWID FSK tag from the GraphBuffer"},
593 {"reader", CmdAWIDReader
, IfPm3Lf
, "attempt to read and extract tag data"},
594 {"sim", CmdAWIDSim
, IfPm3Lf
, "simulate AWID tag"},
595 {"brute", CmdAWIDBrute
, IfPm3Lf
, "bruteforce card number against reader"},
596 {"watch", CmdAWIDWatch
, IfPm3Lf
, "continuously watch for cards. Reader mode"},
597 {NULL
, NULL
, NULL
, NULL
}
600 static int CmdHelp(const char *Cmd
) {
601 (void)Cmd
; // Cmd is not used so far
602 CmdsHelp(CommandTable
);
606 int CmdLFAWID(const char *Cmd
) {
607 clearCommandBuffer();
608 return CmdsParse(CommandTable
, Cmd
);
611 //refactored by marshmellow
612 int getAWIDBits(uint8_t fmtlen
, uint32_t fc
, uint32_t cn
, uint8_t *bits
) {
614 // the return bits, preamble 0000 0001
618 memset(pre
, 0, sizeof(pre
));
621 num_to_bytebits(fmtlen
, 8, pre
);
623 // add facilitycode, cardnumber and wiegand parity bits
627 num_to_bytebits(fc
, 8, wiegand
);
628 num_to_bytebits(cn
, 16, wiegand
+ 8);
629 wiegand_add_parity(pre
+ 8, wiegand
, sizeof(wiegand
));
634 num_to_bytebits(fc
, 8, wiegand
);
635 num_to_bytebits(cn
, 24, wiegand
+ 8);
636 wiegand_add_parity(pre
+ 8, wiegand
, sizeof(wiegand
));
641 num_to_bytebits(fc
, 13, wiegand
);
642 num_to_bytebits(cn
, 18, wiegand
+ 13);
643 wiegand_add_parity(pre
+ 8, wiegand
, sizeof(wiegand
));
648 num_to_bytebits(fc
, 16, wiegand
);
649 num_to_bytebits(cn
, 32, wiegand
+ 16);
650 wiegand_add_parity(pre
+ 8, wiegand
, sizeof(wiegand
));
655 // add AWID 4bit parity
656 size_t bitLen
= addParity(pre
, bits
+ 8, 66, 4, 1);
661 PrintAndLogEx(DEBUG
, "awid raw bits:\n %s \n", sprint_bytebits_bin(bits
, bitLen
));