mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-19 13:00:42 -07:00
Merge branch 'master' into update_4x50
update 201130
This commit is contained in:
commit
efd6c04b7e
49 changed files with 5965 additions and 5685 deletions
2
Makefile
2
Makefile
|
@ -251,7 +251,7 @@ print-%: ; @echo $* = $($*)
|
|||
|
||||
cliparser:
|
||||
# Get list of all commands
|
||||
cat doc/commands.md | grep -e ^\|\` | cut -f 2 -d "\`" | grep -v help | awk '{$$1=$$1};1' > cliparser_all_commands.tmp
|
||||
cat doc/commands.md | grep -e ^\|\` | cut -f 2 -d "\`" | grep -v 'help\|list\|mem spiffs\|quit\|exit' | awk '{$$1=$$1};1' > cliparser_all_commands.tmp
|
||||
# Get list of cliparserized commands
|
||||
grep -r CLIParserInit ./client/src/ | cut -f 2 -d "\"" | awk '{$$1=$$1};1' > cliparser_done.tmp
|
||||
# Determine commands that still need cliparser conversion
|
||||
|
|
|
@ -907,7 +907,13 @@ static void PacketReceived(PacketCommandNG *packet) {
|
|||
break;
|
||||
}
|
||||
case CMD_LF_TI_WRITE: {
|
||||
WriteTItag(packet->oldarg[0], packet->oldarg[1], packet->oldarg[2]);
|
||||
struct p {
|
||||
uint32_t high;
|
||||
uint32_t low;
|
||||
uint16_t crc;
|
||||
} PACKED;
|
||||
struct p *payload = (struct p *)packet->data.asBytes;
|
||||
WriteTItag(payload->high, payload->low, packet->crc);
|
||||
break;
|
||||
}
|
||||
case CMD_LF_SIMULATE: {
|
||||
|
|
|
@ -803,7 +803,7 @@ void WriteTItag(uint32_t idhi, uint32_t idlo, uint16_t crc) {
|
|||
AcquireTiType();
|
||||
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
DbpString("Now use `lf ti read` to check");
|
||||
DbpString("Now use `lf ti reader` to check");
|
||||
StopTicks();
|
||||
}
|
||||
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
#include "cliparser.h"
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "cmdtrace.h"
|
||||
|
@ -36,62 +37,6 @@
|
|||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lto_info(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf lto info [h]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h this help");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto info"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lto_rdbl(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf lto rdbl [h] s <start block> e <end block>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h this help");
|
||||
PrintAndLogEx(NORMAL, " s start block in decimal >= 0");
|
||||
PrintAndLogEx(NORMAL, " e end block in decimal <= 254");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto rdbl s 0 e 254") " - Read data block from 0 to 254");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lto_wrbl(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf lto wrbl [h] b <block> d <data>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h this help");
|
||||
PrintAndLogEx(NORMAL, " b block address (decimal, 0 - 254) ");
|
||||
PrintAndLogEx(NORMAL, " d 32 bytes of data to write (64 hex characters, no space)");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto wrbl b 128 d 0001020304050607080910111213141516171819202122232425262728293031") " - write 00..31 to block address 128");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lto_dump(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf lto dump [h|p] f <filename>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h this help");
|
||||
PrintAndLogEx(NORMAL, " f file name");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto dump f myfile"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lto_restore(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: hf lto restore [h] f <filename>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h this help");
|
||||
PrintAndLogEx(NORMAL, " f file name [.bin|.eml]");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" hf lto restore f hf_lto_92C7842CFF.bin|.eml"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void lto_switch_off_field(void) {
|
||||
SendCommandMIX(CMD_HF_ISO14443A_READER, 0, 0, 0, NULL, 0);
|
||||
}
|
||||
|
@ -173,24 +118,16 @@ static int lto_select(uint8_t *id_response, uint8_t id_len, uint8_t *type_respon
|
|||
}
|
||||
|
||||
static int CmdHfLTOInfo(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf lto info",
|
||||
"Get info from LTO tags",
|
||||
"hf lto info");
|
||||
|
||||
uint8_t cmdp = 0;
|
||||
bool errors = false;
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lto_info();
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Validations
|
||||
if (errors) {
|
||||
return usage_lto_info();
|
||||
}
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
return infoLTO(true);
|
||||
}
|
||||
|
@ -304,48 +241,31 @@ int rdblLTO(uint8_t st_blk, uint8_t end_blk, bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdHfLTOReadBlock(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf lto rdbl",
|
||||
"Reead blocks from LTO tag",
|
||||
"hf lto rdbl --first 0 --last 254");
|
||||
|
||||
uint8_t cmdp = 0;
|
||||
bool errors = false;
|
||||
uint8_t st_blk = 0;
|
||||
uint8_t end_blk = 254;
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int0(NULL, "first", "<dec>", "The first block number to read as an integer"),
|
||||
arg_int0(NULL, "last", "<dec>", "The last block number to read as an integer"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lto_rdbl();
|
||||
case 's':
|
||||
st_blk = param_get8(Cmd, cmdp + 1);
|
||||
if (end_blk < st_blk) {
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
int startblock = arg_get_int_def(ctx, 1, 0);
|
||||
int endblock = arg_get_int_def(ctx, 2, 254);
|
||||
|
||||
case 'e':
|
||||
end_blk = param_get8(Cmd, cmdp + 1);
|
||||
if (end_blk < st_blk) {
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CLIParserFree(ctx);
|
||||
|
||||
//Validations
|
||||
if (errors) {
|
||||
usage_lto_rdbl();
|
||||
if (endblock < startblock) {
|
||||
PrintAndLogEx(ERR, "First block must be less than last block");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
return rdblLTO(st_blk, end_blk, true);
|
||||
return rdblLTO(startblock, endblock, true);
|
||||
}
|
||||
|
||||
static int lto_wrbl(uint8_t blk, uint8_t *data, bool verbose) {
|
||||
|
@ -407,46 +327,33 @@ int wrblLTO(uint8_t blk, uint8_t *data, bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdHfLTOWriteBlock(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf lto wrbl",
|
||||
"Write data to block on LTO tag",
|
||||
"hf lto wrbl --block 128 -d 0001020304050607080910111213141516171819202122232425262728293031");
|
||||
|
||||
uint8_t cmdp = 0;
|
||||
bool errors = false;
|
||||
bool b_opt_selected = false;
|
||||
bool d_opt_selected = false;
|
||||
uint8_t blk = 128;
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("d", "data", "<hex>", "32 bytes of data to write (64 hex symbols, no spaces)"),
|
||||
arg_int1(NULL, "block", "<dec>", "The block number to write to as an integer"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int block_data_len = 0;
|
||||
uint8_t block_data[32] = {0};
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lto_wrbl();
|
||||
case 'b':
|
||||
blk = param_get8(Cmd, cmdp + 1);
|
||||
b_opt_selected = true;
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'd':
|
||||
if (param_gethex(Cmd, cmdp + 1, block_data, 64)) {
|
||||
PrintAndLogEx(WARNING, "block data must include 64 HEX symbols");
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
d_opt_selected = true;
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
CLIGetHexWithReturn(ctx, 1, block_data, &block_data_len);
|
||||
|
||||
if (block_data_len != 32) {
|
||||
PrintAndLogEx(ERR, "Block data is incorrect length");
|
||||
CLIParserFree(ctx);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
//Validations
|
||||
if (errors) {
|
||||
return usage_lto_wrbl();
|
||||
} else if (b_opt_selected == false || d_opt_selected == false) {
|
||||
PrintAndLogEx(WARNING, "Need to specify block address and data.");
|
||||
return usage_lto_wrbl();
|
||||
}
|
||||
int blk = arg_get_int_def(ctx, 2, 0);
|
||||
|
||||
CLIParserFree(ctx);
|
||||
|
||||
int res = wrblLTO(blk, block_data, true);
|
||||
if (res == PM3_SUCCESS)
|
||||
|
@ -504,35 +411,25 @@ int dumpLTO(uint8_t *dump, bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdHfLTODump(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf lto dump",
|
||||
"Dump data from LTO tag",
|
||||
"hf lto dump -f myfile");
|
||||
|
||||
uint8_t cmdp = 0;
|
||||
bool errors = false;
|
||||
uint32_t dump_len = CM_MEM_MAX_SIZE;
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("f", "file", "<filename>", "specify a filename for dumpfile"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lto_dump();
|
||||
case 'f':
|
||||
if (param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE) >= FILE_PATH_SIZE) {
|
||||
PrintAndLogEx(FAILED, "filename too long");
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (errors) {
|
||||
usage_lto_dump();
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
uint32_t dump_len = CM_MEM_MAX_SIZE;
|
||||
|
||||
uint8_t *dump = calloc(dump_len, sizeof(uint8_t));
|
||||
if (!dump) {
|
||||
|
@ -596,32 +493,23 @@ int restoreLTO(uint8_t *dump, bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdHfLTRestore(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf lto restore",
|
||||
"Restore data from dumpfile to LTO tag",
|
||||
"hf lto restore -f hf-lto-92C7842CFF.bin|.eml");
|
||||
|
||||
uint8_t cmdp = 0;
|
||||
bool errors = false;
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("f", "file", "<filename>", "specify a filename for dumpfile"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int fnlen = 0;
|
||||
char filename[FILE_PATH_SIZE] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 1), (uint8_t *)filename, FILE_PATH_SIZE, &fnlen);
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lto_restore();
|
||||
case 'f':
|
||||
param_getstr(Cmd, cmdp + 1, filename, FILE_PATH_SIZE);
|
||||
if (strlen(filename) < 5)
|
||||
errors = true;
|
||||
|
||||
cmdp += 2;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors || strlen(Cmd) == 0) {
|
||||
return usage_lto_restore();
|
||||
}
|
||||
CLIParserFree(ctx);
|
||||
|
||||
size_t dump_len = 0;
|
||||
char *lowstr = str_dup(filename);
|
||||
|
|
|
@ -266,6 +266,16 @@ static int get_plus_version(uint8_t *version, int *version_len) {
|
|||
}
|
||||
|
||||
static int CmdHFMFPInfo(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "hf mfp info",
|
||||
"Get info from MIFARE Plus tags",
|
||||
"hf mfp info");
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(INFO, "--- " _CYAN_("Tag Information") " ---------------------------");
|
||||
|
|
|
@ -11,96 +11,27 @@
|
|||
// FSK2a, RF/50, 96 bits (complete)
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdlfawid.h" // AWID function declarations
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "graph.h"
|
||||
#include "cmddata.h"
|
||||
|
||||
#include "ui.h" // PrintAndLog
|
||||
#include "lfdemod.h" // parityTest
|
||||
#include "cmdlf.h" // lf read
|
||||
#include "protocols.h" // for T55xx config register definitions
|
||||
#include "util_posix.h"
|
||||
#include "cmdlft55xx.h" // verifywrite
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_awid_watch(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.");
|
||||
PrintAndLogEx(NORMAL, "By default, values are printed and logged until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf awid watch");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid watch"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_awid_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of AWID card with specified facility-code and card number.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf awid sim [h] <format> <facility-code> <card-number>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <format> : format length 26|34|37|50");
|
||||
PrintAndLogEx(NORMAL, " <facility-code> : 8|16bit value facility code");
|
||||
PrintAndLogEx(NORMAL, " <card number> : 16|32-bit value card number");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid sim 26 224 1337"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid sim 50 2001 13371337"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_awid_clone(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables cloning of AWID card with specified facility-code and card number onto T55x7 or Q5/T5555.");
|
||||
PrintAndLogEx(NORMAL, "The T55x7 must be on the antenna when issuing this command. T55x7 blocks are calculated and printed in the process.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf awid clone [h] <format> <facility-code> <card-number> [Q5]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <format> : format length 26|34|37|50");
|
||||
PrintAndLogEx(NORMAL, " <facility-code> : 8|16bit value facility code");
|
||||
PrintAndLogEx(NORMAL, " <card number> : 16|32-bit value card number");
|
||||
PrintAndLogEx(NORMAL, " Q5 : optional - specify writing to Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid clone 26 224 1337"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid clone 50 2001 13371337"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_awid_brute(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables bruteforce of AWID reader with specified facility-code.");
|
||||
PrintAndLogEx(NORMAL, "This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step");
|
||||
PrintAndLogEx(NORMAL, "if cardnumber is not given, it starts with 1 and goes up to 65535");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf awid brute [h] [v] a <format> f <facility-code> c <cardnumber> d <delay>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " a <format> : format length 26|50");
|
||||
PrintAndLogEx(NORMAL, " f <facility-code> : 8|16bit value facility code");
|
||||
PrintAndLogEx(NORMAL, " c <cardnumber> : (optional) cardnumber to start with, max 65535");
|
||||
PrintAndLogEx(NORMAL, " d <delay> : delay betweens attempts in ms. Default 1000ms");
|
||||
PrintAndLogEx(NORMAL, " v : verbose logging, show all tries");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid brute a 26 f 224"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid brute a 50 f 2001 d 2000"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf awid brute v a 50 f 2001 c 200 d 2000"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int sendPing(void) {
|
||||
SendCommandNG(CMD_PING, NULL, 0);
|
||||
SendCommandNG(CMD_PING, NULL, 0);
|
||||
SendCommandNG(CMD_BREAK_LOOP, NULL, 0);
|
||||
SendCommandNG(CMD_PING, NULL, 0);
|
||||
clearCommandBuffer();
|
||||
PacketResponseNG resp;
|
||||
|
@ -112,7 +43,7 @@ static int sendPing(void) {
|
|||
static int sendTry(uint8_t fmtlen, uint32_t fc, uint32_t cn, uint32_t delay, uint8_t *bits, size_t bs_len, bool verbose) {
|
||||
|
||||
if (verbose)
|
||||
PrintAndLogEx(INFO, "Trying FC: %u; CN: %u", fc, cn);
|
||||
PrintAndLogEx(INFO, "Trying FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fc, cn);
|
||||
|
||||
if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
|
@ -180,8 +111,19 @@ static void verify_values(uint8_t *fmtlen, uint32_t *fc, uint32_t *cn) {
|
|||
// this read loops on device side.
|
||||
// uses the demod in lfops.c
|
||||
static int CmdAWIDWatch(const char *Cmd) {
|
||||
uint8_t c = tolower(param_getchar(Cmd, 0));
|
||||
if (c == 'h') return usage_lf_awid_watch();
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf awid watch",
|
||||
"Enables AWID compatible reader mode printing details of scanned AWID26 or AWID50 tags.\n"
|
||||
"Run until the button is pressed or another USB command is issued.",
|
||||
"lf awid watch"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Watching for AWID cards - place tag on antenna");
|
||||
PrintAndLogEx(INFO, "Press pm3-button to stop reading cards");
|
||||
|
@ -339,31 +281,152 @@ int demodAWID(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdAWIDDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf awid demod",
|
||||
"Try to find AWID Prox preamble, if found decode / descramble data",
|
||||
"lf awid demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodAWID(true);
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdAWIDRead(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
static int CmdAWIDReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf awid reader",
|
||||
"read a AWID Prox tag",
|
||||
"lf awid reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 12000);
|
||||
return demodAWID(true);
|
||||
demodAWID(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdAWIDClone(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf awid clone",
|
||||
"clone a AWID Prox tag to a T55x7, Q5/T5555 or EM4305/4469 tag",
|
||||
"lf awid clone --fmt 26 --fc 123 --cn 1337\n"
|
||||
"lf awid clone --fmt 50 --fc 2001 --cn 13371337\n"
|
||||
"lf awid clone --q5 --fmt 26 --fc 123 --cn 1337 -> encode for Q5/T5555 tag\n"
|
||||
"lf awid clone --em --fmt 26 --fc 123 --cn 1337 -> encode for EM4305/4469"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|34|37|50"),
|
||||
arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
|
||||
arg_u64_1(NULL, "cn", "<dec>", "16|32-bit value card number"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
|
||||
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
|
||||
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
|
||||
bool q5 = arg_get_lit(ctx, 4);
|
||||
bool em = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||
char cardtype[16] = {"T55x7"};
|
||||
// Q5
|
||||
if (q5) {
|
||||
//t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
// EM4305
|
||||
if (em) {
|
||||
blocks[0] = EM4305_AWID_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
verify_values(&fmtlen, &fc, &cn);
|
||||
|
||||
uint8_t *bits = calloc(96, sizeof(uint8_t));
|
||||
|
||||
if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
free(bits);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
blocks[1] = bytebits_to_byte(bits, 32);
|
||||
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
||||
blocks[3] = bytebits_to_byte(bits + 64, 32);
|
||||
|
||||
free(bits);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone AWID %u to " _YELLOW_("%s") " with FC: " _GREEN_("%u") " CN: " _GREEN_("%u"), fmtlen, cardtype, fc, cn);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdAWIDSim(const char *Cmd) {
|
||||
uint32_t fc = 0, cn = 0;
|
||||
uint8_t fmtlen = 0;
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf awid sim",
|
||||
"Enables simulation of AWID card with specified facility-code and card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||
"lf awid sim --fmt 26 --fc 123 --cn 1337\n"
|
||||
"lf awid sim --fmt 50 --fc 2001 --cn 13371337"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
|
||||
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
|
||||
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
|
||||
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
|
||||
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint8_t bs[96];
|
||||
memset(bs, 0x00, sizeof(bs));
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_awid_sim();
|
||||
|
||||
fmtlen = param_get8(Cmd, 0);
|
||||
fc = param_get32ex(Cmd, 1, 0, 10);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
if (!fc || !cn) return usage_lf_awid_sim();
|
||||
|
||||
verify_values(&fmtlen, &fc, &cn);
|
||||
|
||||
if (getAWIDBits(fmtlen, fc, cn, bs) != PM3_SUCCESS) {
|
||||
|
@ -371,7 +434,7 @@ static int CmdAWIDSim(const char *Cmd) {
|
|||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating AWID %u -- FC: %u; CN: %u\n", fmtlen, fc, cn);
|
||||
PrintAndLogEx(SUCCESS, "Simulating AWID %u -- FC: " _YELLOW_("%u") " CN: " _YELLOW_("%u"), fmtlen, fc, cn);
|
||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or run another command");
|
||||
|
||||
// AWID uses: FSK2a fcHigh: 10, fcLow: 8, clk: 50, invert: 1
|
||||
|
@ -398,97 +461,34 @@ static int CmdAWIDSim(const char *Cmd) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdAWIDClone(const char *Cmd) {
|
||||
uint32_t fc = 0, cn = 0;
|
||||
uint8_t fmtlen = 0;
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_awid_clone();
|
||||
|
||||
fmtlen = param_get8(Cmd, 0);
|
||||
fc = param_get32ex(Cmd, 1, 0, 10);
|
||||
cn = param_get32ex(Cmd, 2, 0, 10);
|
||||
|
||||
if (!fc || !cn) return usage_lf_awid_clone();
|
||||
|
||||
uint32_t blocks[4] = {T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||
|
||||
bool q5 = tolower(param_getchar(Cmd, 3)) == 'q';
|
||||
if (q5)
|
||||
//t5555 (Q5) BITRATE = (RF-2)/2 (iceman)
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
|
||||
verify_values(&fmtlen, &fc, &cn);
|
||||
|
||||
uint8_t *bits = calloc(96, sizeof(uint8_t));
|
||||
|
||||
if (getAWIDBits(fmtlen, fc, cn, bits) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
free(bits);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
blocks[1] = bytebits_to_byte(bits, 32);
|
||||
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
||||
blocks[3] = bytebits_to_byte(bits + 64, 32);
|
||||
|
||||
free(bits);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone AWID %u to " _YELLOW_("%s") " with FC: %u, CN: %u", fmtlen, (q5) ? "Q5/T5555" : "T55x7", fc, cn);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf awid read`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdAWIDBrute(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf awid brute",
|
||||
"Enables bruteforce of AWID reader with specified facility-code.\n"
|
||||
"This is a attack against reader. if cardnumber is given, it starts with it and goes up / down one step\n"
|
||||
"if cardnumber is not given, it starts with 1 and goes up to 65535",
|
||||
"lf awid brute --fmt 26 --fc 224\n"
|
||||
"lf awid brute --fmt 50 --fc 2001 --delay 2000\n"
|
||||
"lf awid brute --fmt 50 --fc 2001 --cn 200 --delay 2000 -v"
|
||||
);
|
||||
|
||||
bool errors = false, verbose = false;
|
||||
uint32_t fc = 0, cn = 0, delay = 1000;
|
||||
uint8_t fmtlen = 0;
|
||||
uint8_t bits[96];
|
||||
size_t size = sizeof(bits);
|
||||
memset(bits, 0x00, size);
|
||||
uint8_t cmdp = 0;
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|50"),
|
||||
arg_u64_1(NULL, "fc", "<dec>", "8|16bit value facility code"),
|
||||
arg_u64_0(NULL, "cn", "<dec>", "optional - card number to start with, max 65535"),
|
||||
arg_u64_0(NULL, "delay", "<dec>", "optional - delay betweens attempts in ms. Default 1000ms"),
|
||||
arg_lit0("v", "verbose", "verbose logging, show all tries"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lf_awid_brute();
|
||||
case 'f':
|
||||
fc = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||
if (!fc)
|
||||
errors = true;
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'd':
|
||||
// delay between attemps, defaults to 1000ms.
|
||||
delay = param_get32ex(Cmd, cmdp + 1, 1000, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'c':
|
||||
cn = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||
// truncate cardnumber.
|
||||
cn &= 0xFFFF;
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'a':
|
||||
fmtlen = param_get8(Cmd, cmdp + 1);
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 'v':
|
||||
verbose = true;
|
||||
cmdp++;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (fc == 0) errors = true;
|
||||
if (errors) return usage_lf_awid_brute();
|
||||
uint8_t fmtlen = arg_get_u32_def(ctx, 1, 0);
|
||||
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
|
||||
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
|
||||
uint32_t delay = arg_get_u32_def(ctx, 4, 1000);
|
||||
bool verbose = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// limit fc according to selected format
|
||||
switch (fmtlen) {
|
||||
|
@ -506,12 +506,23 @@ static int CmdAWIDBrute(const char *Cmd) {
|
|||
break;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d Reader", fmtlen);
|
||||
|
||||
// truncate card number
|
||||
if ((cn & 0xFFFF) != cn) {
|
||||
cn &= 0xFFFF;
|
||||
PrintAndLogEx(INFO, "Card number truncated to 16-bits : %u", cn);
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Bruteforceing AWID %d reader", fmtlen);
|
||||
PrintAndLogEx(SUCCESS, "Press pm3-button to abort simulation or press Enter");
|
||||
|
||||
uint16_t up = cn;
|
||||
uint16_t down = cn;
|
||||
|
||||
uint8_t bits[96];
|
||||
size_t size = sizeof(bits);
|
||||
memset(bits, 0x00, size);
|
||||
|
||||
// main loop
|
||||
for (;;) {
|
||||
|
||||
|
@ -525,13 +536,20 @@ static int CmdAWIDBrute(const char *Cmd) {
|
|||
}
|
||||
|
||||
// Do one up
|
||||
if (up < 0xFFFF)
|
||||
if (sendTry(fmtlen, fc, up++, delay, bits, size, verbose) != PM3_SUCCESS) return PM3_ESOFT;
|
||||
if (up < 0xFFFF) {
|
||||
if (sendTry(fmtlen, fc, up++, delay, bits, size, verbose) != PM3_SUCCESS) {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
|
||||
// Do one down (if cardnumber is given)
|
||||
if (cn > 1)
|
||||
if (down > 1)
|
||||
if (sendTry(fmtlen, fc, --down, delay, bits, size, verbose) != PM3_SUCCESS) return PM3_ESOFT;
|
||||
if (cn > 1) {
|
||||
if (down > 1) {
|
||||
if (sendTry(fmtlen, fc, --down, delay, bits, size, verbose) != PM3_SUCCESS) {
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
@ -539,7 +557,7 @@ static int CmdAWIDBrute(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||
{"demod", CmdAWIDDemod, AlwaysAvailable, "demodulate an AWID FSK tag from the GraphBuffer"},
|
||||
{"read", CmdAWIDRead, IfPm3Lf, "attempt to read and extract tag data"},
|
||||
{"reader", CmdAWIDReader, IfPm3Lf, "attempt to read and extract tag data"},
|
||||
{"clone", CmdAWIDClone, IfPm3Lf, "clone AWID tag to T55x7 or Q5/T5555"},
|
||||
{"sim", CmdAWIDSim, IfPm3Lf, "simulate AWID tag"},
|
||||
{"brute", CmdAWIDBrute, IfPm3Lf, "Bruteforce card number against reader"},
|
||||
|
|
|
@ -8,33 +8,18 @@
|
|||
// Low frequency COTAG commands
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdlfcotag.h" // COTAG function declarations
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "lfdemod.h"
|
||||
#include "cmddata.h" // getSamples
|
||||
#include "ui.h" // PrintAndLog
|
||||
#include "ctype.h" // tolower
|
||||
#include "cliparser.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_cotag_read(void) {
|
||||
PrintAndLogEx(NORMAL, "Usage: lf COTAG read [h] <signaldata>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <0|1|2> : 0 - HIGH/LOW signal; maxlength bigbuff");
|
||||
PrintAndLogEx(NORMAL, " : 1 - translation of HI/LO into bytes with manchester 0,1");
|
||||
PrintAndLogEx(NORMAL, " : 2 - raw signal; maxlength bigbuff");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Example:");
|
||||
PrintAndLogEx(NORMAL, " lf cotag read 0");
|
||||
PrintAndLogEx(NORMAL, " lf cotag read 1");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// COTAG demod should be able to use GraphBuffer,
|
||||
// when data load samples
|
||||
int demodCOTAG(bool verbose) {
|
||||
|
@ -74,22 +59,63 @@ int demodCOTAG(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdCOTAGDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf cotag demod",
|
||||
"Try to find COTAG preamble, if found decode / descramble data",
|
||||
"lf cotag demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodCOTAG(true);
|
||||
}
|
||||
|
||||
// When reading a COTAG.
|
||||
// 0 = HIGH/LOW signal - maxlength bigbuff
|
||||
// 1 = translation for HI/LO into bytes with manchester 0,1 - length 300
|
||||
// 2 = raw signal - maxlength bigbuff
|
||||
static int CmdCOTAGRead(const char *Cmd) {
|
||||
static int CmdCOTAGReader(const char *Cmd) {
|
||||
|
||||
if (tolower(Cmd[0]) == 'h')
|
||||
return usage_lf_cotag_read();
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf cotag reader",
|
||||
"read a COTAG tag, the current support for COTAG is limited. ",
|
||||
"lf cotag reader -2"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("1", NULL, "HIGH/LOW signal; maxlength bigbuff"),
|
||||
arg_lit0("2", NULL, "translation of HIGH/LOW into bytes with manchester 0,1"),
|
||||
arg_lit0("3", NULL, "raw signal; maxlength bigbuff"),
|
||||
arg_param_end
|
||||
};
|
||||
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
bool mode0 = arg_get_lit(ctx, 1);
|
||||
bool mode1 = arg_get_lit(ctx, 2);
|
||||
bool mode2 = arg_get_lit(ctx, 3);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if ((mode0 + mode1 + mode2) > 1) {
|
||||
PrintAndLogEx(ERR, "You can only use one option at a time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
uint8_t mode = 0xFF;
|
||||
if (mode0)
|
||||
mode = 0;
|
||||
if (mode1)
|
||||
mode = 1;
|
||||
if (mode2)
|
||||
mode = 2;
|
||||
|
||||
struct p {
|
||||
uint8_t mode;
|
||||
} PACKED payload;
|
||||
payload.mode = param_get8ex(Cmd, 0, 1, 10);
|
||||
payload.mode = mode;
|
||||
|
||||
PacketResponseNG resp;
|
||||
clearCommandBuffer();
|
||||
|
@ -128,7 +154,7 @@ static int CmdCOTAGRead(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"demod", CmdCOTAGDemod, AlwaysAvailable, "Tries to decode a COTAG signal"},
|
||||
{"read", CmdCOTAGRead, IfPm3Lf, "Attempt to read and extract tag data"},
|
||||
{"reader", CmdCOTAGReader, IfPm3Lf, "Attempt to read and extract tag data"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
@ -144,5 +170,5 @@ int CmdLFCOTAG(const char *Cmd) {
|
|||
}
|
||||
|
||||
int readCOTAGUid(void) {
|
||||
return (CmdCOTAGRead("") == PM3_SUCCESS);
|
||||
return (CmdCOTAGReader("") == PM3_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -7,7 +7,6 @@
|
|||
// Low frequency FDX-A FECAVA Destron tag commands
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdlfdestron.h"
|
||||
|
||||
#include <ctype.h> // tolower
|
||||
#include <string.h> // memcpy
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
|
@ -21,8 +20,9 @@
|
|||
#include "protocols.h" // t55xx defines
|
||||
#include "cmdlft55xx.h" // clone..
|
||||
#include "cmdlf.h" // cmdlfconfig
|
||||
#include "cliparser.h" // cli parse input
|
||||
#include "parity.h"
|
||||
#include "cliparser.h" // cli parse input
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
#define DESTRON_FRAME_SIZE 96
|
||||
#define DESTRON_PREAMBLE_SIZE 16
|
||||
|
@ -36,6 +36,7 @@ int demodDestron(bool verbose) {
|
|||
PrintAndLogEx(DEBUG, "DEBUG: Error - Destron: FSK Demod failed");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
size_t size = DemodBufferLen;
|
||||
int ans = detectDestron(DemodBuffer, &size);
|
||||
if (ans < 0) {
|
||||
|
@ -50,12 +51,13 @@ int demodDestron(bool verbose) {
|
|||
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
setDemodBuff(DemodBuffer, DESTRON_FRAME_SIZE, ans);
|
||||
setClockGrid(g_DemodClock, g_DemodStartIdx + (ans * g_DemodClock));
|
||||
|
||||
uint8_t bits[DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE] = {0};
|
||||
size_t bitlen = DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE;
|
||||
memcpy(bits, DemodBuffer + 16, DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE);
|
||||
memcpy(bits, DemodBuffer + DESTRON_PREAMBLE_SIZE, DESTRON_FRAME_SIZE - DESTRON_PREAMBLE_SIZE);
|
||||
|
||||
uint8_t alignPos = 0;
|
||||
uint16_t errCnt = manrawdecode(bits, &bitlen, 0, &alignPos);
|
||||
|
@ -75,65 +77,145 @@ int demodDestron(bool verbose) {
|
|||
PrintAndLogEx(DEBUG, "DEBUG: Error - Destron: parity errors: %d", parity_err);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "FDX-A FECAVA Destron: " _GREEN_("%02X%02X%02X%02X%02X"), data[0], data[1], data[2], data[3], data[4]);
|
||||
PrintAndLogEx(SUCCESS, "FDX-A FECAVA Destron: " _GREEN_("%s"), sprint_hex_inrow(data, 5));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdDestronDemod(const char *Cmd) {
|
||||
(void)Cmd;
|
||||
return demodDestron(true);
|
||||
}
|
||||
|
||||
static int CmdDestronRead(const char *Cmd) {
|
||||
lf_read(false, 16000);
|
||||
return demodDestron(true);
|
||||
}
|
||||
|
||||
static int CmdDestronClone(const char *Cmd) {
|
||||
|
||||
uint32_t blocks[4] = {0};
|
||||
uint8_t data[8];
|
||||
int datalen = 0;
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf destron clone",
|
||||
"Enables cloning of Destron card with specified uid onto T55x7",
|
||||
"lf destron clone 1A2B3C4D5E"
|
||||
CLIParserInit(&ctx, "lf destron demod",
|
||||
"Try to find Destron preamble, if found decode / descramble data",
|
||||
"lf destron demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_strx1(NULL, NULL, "<uid (hex)>", NULL),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodDestron(true);
|
||||
}
|
||||
|
||||
static int CmdDestronReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf destron reader",
|
||||
"read a Destron tag",
|
||||
"lf destron reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 16000);
|
||||
demodDestron(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdDestronClone(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf destron clone",
|
||||
"clone a Destron tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
||||
"lf destron clone --uid 1A2B3C4D5E\n"
|
||||
"lf destron clone --q5 --uid 1A2B3C4D5E -> encode for Q5/T5555 tag\n"
|
||||
"lf destron clone --em --uid 1A2B3C4D5E -> encode for EM4305/4469"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_strx1("u", "uid", "<hex>", "5 bytes max"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
|
||||
//TODO add selection of chip for Q5 or T55x7
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint8_t data[8];
|
||||
int datalen = 0;
|
||||
CLIGetHexWithReturn(ctx, 1, data, &datalen);
|
||||
bool q5 = arg_get_lit(ctx, 2);
|
||||
bool em = arg_get_lit(ctx, 3);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
if (datalen > 5) {
|
||||
PrintAndLogEx(FAILED, "Uid is max 5 bytes. (got %u)", datalen);
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t blocks[4] = {0};
|
||||
blocks[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2 | 3 << T55x7_MAXBLOCK_SHIFT;
|
||||
char cardtype[16] = {"T55x7"};
|
||||
// Q5
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_FSK2 | T5555_SET_BITRATE(50) | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
// EM4305
|
||||
if (em) {
|
||||
blocks[0] = EM4305_DESTRON_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
uint8_t data_ex[12 + 24] = {0}; // ManchesterEncode need extra room
|
||||
for (int i = 0; i < datalen; i++) {
|
||||
data_ex[i + 1] = ~data [i] | (evenparity8(data[i]) << 7);
|
||||
data_ex[i + 1] = ~(data [i] | (oddparity8(data[i]) << 7));
|
||||
}
|
||||
|
||||
// manchester encode it
|
||||
for (int i = 0; i < 3; i++) {
|
||||
blocks[i + 1] = manchesterEncode2Bytes((data_ex[i * 2] << 8) + data_ex[i * 2 + 1]);
|
||||
}
|
||||
// inject preamble
|
||||
blocks[1] = (blocks[1] & 0xFFFF) | 0xAAE20000;
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Destron tag with ID: %s", sprint_hex(data, datalen));
|
||||
blocks[0] = T55x7_BITRATE_RF_50 | T55x7_MODULATION_FSK2 | 3 << T55x7_MAXBLOCK_SHIFT;
|
||||
PrintAndLogEx(INFO, "Preparing to clone Destron tag to " _YELLOW_("%s") " with ID: " _YELLOW_("%s")
|
||||
, cardtype
|
||||
, sprint_hex_inrow(data, datalen)
|
||||
);
|
||||
|
||||
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf Destron read`") " to verify");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf destron reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdDestronSim(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf destron sim",
|
||||
"Try to find Destron preamble, if found decode / descramble data",
|
||||
"lf destron sim"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
@ -141,7 +223,7 @@ static int CmdDestronSim(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"demod", CmdDestronDemod, AlwaysAvailable, "Demodulate an Destron tag from the GraphBuffer"},
|
||||
{"read", CmdDestronRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||
{"reader", CmdDestronReader, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||
{"clone", CmdDestronClone, IfPm3Lf, "Clone Destron tag to T55x7"},
|
||||
{"sim", CmdDestronSim, IfPm3Lf, "Simulate Destron tag"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
@ -185,5 +267,5 @@ int detectDestron(uint8_t *dest, size_t *size) {
|
|||
}
|
||||
|
||||
int readDestronUid(void) {
|
||||
return (CmdDestronRead("") == PM3_SUCCESS);
|
||||
return (CmdDestronReader("") == PM3_SUCCESS);
|
||||
}
|
||||
|
|
|
@ -30,7 +30,9 @@
|
|||
#define EM4305_NORALSY_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(3) ) // ASK, data rate 32, 3 data blocks
|
||||
#define EM4305_PRESCO_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(4) ) // ASK/MAN, data rate 32, 4 data blocks
|
||||
#define EM4305_SECURAKEY_CONFIG_BLOCK (EM4x05_SET_BITRATE(40) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(3) ) // ASK/MAN, data rate 40, 3 data blocks
|
||||
#define EM4305_GALLAGHER_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_MANCHESTER | EM4x05_SET_NUM_BLOCKS(3) ) // ASK/MAN, data rate 32, 3 data blocks
|
||||
|
||||
#define EM4305_DESTRON_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
|
||||
#define EM4305_HID_26_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
|
||||
#define EM4305_PARADOX_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
|
||||
#define EM4305_AWID_CONFIG_BLOCK (EM4x05_SET_BITRATE(50) | EM4x05_MODULATION_FSK2 | EM4x05_SET_NUM_BLOCKS(3) ) // FSK2a, hid 26 bit, data rate 50, 3 data blocks
|
||||
|
@ -47,6 +49,7 @@
|
|||
#define EM4305_GUARDPROXII_CONFIG_BLOCK (EM4x05_SET_BITRATE(64) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(3) ) // Biphase, data rate 64, Direct modulation, 3 data blocks
|
||||
#define EM4305_NEDAP_64_CONFIG_BLOCK (EM4x05_SET_BITRATE(64) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(2) ) // Biphase, data rate 64, 2 data blocks
|
||||
#define EM4305_NEDAP_128_CONFIG_BLOCK (EM4x05_SET_BITRATE(64) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // Biphase, data rate 64, 4 data blocks
|
||||
#define EM4305_FDXB_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_BIPHASE | EM4x05_SET_NUM_BLOCKS(4) ) // Biphase, data rate 32, 4 data blocks
|
||||
|
||||
#define EM4305_PAC_CONFIG_BLOCK (EM4x05_SET_BITRATE(32) | EM4x05_MODULATION_NRZ | EM4x05_SET_NUM_BLOCKS(4) ) // NRZ, data rate 32, 4 data blocks
|
||||
#define EM4305_VERICHIP_CONFIG_BLOCK (EM4x05_SET_BITRATE(40) | EM4x05_MODULATION_NRZ | EM4x05_SET_NUM_BLOCKS(4) ) // NRZ, data rate 40, 4 data blocks
|
||||
|
|
|
@ -9,16 +9,13 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlffdxb.h"
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h> // tolower
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "commonutil.h"
|
||||
|
||||
#include "ui.h" // PrintAndLog
|
||||
#include "cmddata.h"
|
||||
#include "cmdlf.h" // lf read
|
||||
|
@ -26,6 +23,8 @@
|
|||
#include "protocols.h" // for T55xx config register definitions
|
||||
#include "lfdemod.h" // parityTest
|
||||
#include "cmdlft55xx.h" // verifywrite
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
/*
|
||||
FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
|
||||
|
@ -48,55 +47,63 @@
|
|||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_fdxb_clone(void) {
|
||||
PrintAndLogEx(NORMAL, "Clone a FDX-B animal tag to a T55x7 or Q5/T5555 tag.");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf fdxb clone [h] [c <country code>] [n <national code>] [e <extended>] <s> <Q5>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " c <country> : (dec) Country code");
|
||||
PrintAndLogEx(NORMAL, " n <national> : (dec) National code");
|
||||
PrintAndLogEx(NORMAL, " e <extended> : (hex) Extended data");
|
||||
PrintAndLogEx(NORMAL, " s : Set animal bit");
|
||||
PrintAndLogEx(NORMAL, " <Q5> : Specify writing to Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb clone c 999 n 112233 s"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb clone c 999 n 112233 e 16a"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint16_t extended, uint8_t *bits) {
|
||||
|
||||
static int usage_lf_fdxb_read(void) {
|
||||
PrintAndLogEx(NORMAL, "Read FDX-B animal tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf fdxb read [h] [@]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " @ : run continuously until a key is pressed (optional)");
|
||||
PrintAndLogEx(NORMAL, "Note that the continuous mode is less verbose");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
bits[10] = 1;
|
||||
|
||||
static int usage_lf_fdxb_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of FDX-B animal tag");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf fdxb sim [h] [c <country code>] [n <national code>] [e <extended>] <s> <Q5>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " c <country> : (dec) Country code");
|
||||
PrintAndLogEx(NORMAL, " n <national> : (dec) National code");
|
||||
PrintAndLogEx(NORMAL, " e <extended> : (hex) Extended data");
|
||||
PrintAndLogEx(NORMAL, " s : Set animal bit");
|
||||
PrintAndLogEx(NORMAL, " <Q5> : Specify writing to Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb sim c 999 n 112233 s"));
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf fdxb sim c 999 n 112233 e 16a"));
|
||||
// 128bits
|
||||
// every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite
|
||||
memset(bits, 0x01, 128);
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
|
||||
// add reserved
|
||||
num_to_bytebitsLSBF(0x00, 7, bits + 66);
|
||||
num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74);
|
||||
|
||||
// add animal flag - OK
|
||||
bits[81] = is_animal;
|
||||
|
||||
// add extended flag - OK
|
||||
bits[65] = is_extended;
|
||||
|
||||
// add national code 40bits - OK
|
||||
num_to_bytebitsLSBF(national_code >> 0, 8, bits + 11);
|
||||
num_to_bytebitsLSBF(national_code >> 8, 8, bits + 20);
|
||||
num_to_bytebitsLSBF(national_code >> 16, 8, bits + 29);
|
||||
num_to_bytebitsLSBF(national_code >> 24, 8, bits + 38);
|
||||
num_to_bytebitsLSBF(national_code >> 32, 6, bits + 47);
|
||||
|
||||
// add country code - OK
|
||||
num_to_bytebitsLSBF(country_code >> 0, 2, bits + 53);
|
||||
num_to_bytebitsLSBF(country_code >> 2, 8, bits + 56);
|
||||
|
||||
// add crc-16 - OK
|
||||
uint8_t raw[8];
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8);
|
||||
|
||||
init_table(CRC_11784);
|
||||
uint16_t crc = crc16_fdxb(raw, 8);
|
||||
num_to_bytebitsLSBF(crc >> 0, 8, bits + 83);
|
||||
num_to_bytebitsLSBF(crc >> 8, 8, bits + 92);
|
||||
|
||||
// extended data - OK
|
||||
num_to_bytebitsLSBF(extended >> 0, 8, bits + 101);
|
||||
num_to_bytebitsLSBF(extended >> 8, 8, bits + 110);
|
||||
num_to_bytebitsLSBF(extended >> 16, 8, bits + 119);
|
||||
|
||||
// 8 16 24 32 40 48 49
|
||||
// A8 28 0C 92 EA 6F 00 01
|
||||
// A8 28 0C 92 EA 6F 80 00
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// clearing the topbit needed for the preambl detection.
|
||||
static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *extended, uint8_t *is_animal) {
|
||||
static void verify_values(uint64_t *animalid, uint32_t *countryid, uint16_t *extended) {
|
||||
if ((*animalid & 0x3FFFFFFFFF) != *animalid) {
|
||||
*animalid &= 0x3FFFFFFFFF;
|
||||
PrintAndLogEx(INFO, "Animal ID truncated to 38bits: " _YELLOW_("%"PRIx64), *animalid);
|
||||
|
@ -109,8 +116,6 @@ static void verify_values(uint64_t *animalid, uint32_t *countryid, uint32_t *ext
|
|||
*extended &= 0xFFF;
|
||||
PrintAndLogEx(INFO, "Extended truncated to 24bits: " _YELLOW_("0x%03X"), *extended);
|
||||
}
|
||||
|
||||
*is_animal &= 0x01;
|
||||
}
|
||||
|
||||
static inline uint32_t bitcount(uint32_t a) {
|
||||
|
@ -607,71 +612,75 @@ int demodFDXB(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdFdxBDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf fdxb demod",
|
||||
"Try to find FDX-B preamble, if found decode / descramble data",
|
||||
"lf fdxb demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodFDXB(true);
|
||||
}
|
||||
|
||||
static int CmdFdxBRead(const char *Cmd) {
|
||||
static int CmdFdxBReader(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf fdxb reader",
|
||||
"read a FDX-B animal tag\n"
|
||||
"Note that the continuous mode is less verbose",
|
||||
"lf fdxb reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
sample_config config;
|
||||
memset(&config, 0, sizeof(sample_config));
|
||||
int retval = lf_getconfig(&config);
|
||||
if (retval != PM3_SUCCESS) {
|
||||
int res = lf_getconfig(&config);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "failed to get current device LF config");
|
||||
return retval;
|
||||
return res;
|
||||
}
|
||||
|
||||
bool errors = false;
|
||||
bool continuous = false;
|
||||
uint8_t cmdp = 0;
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lf_fdxb_read();
|
||||
case '@':
|
||||
continuous = true;
|
||||
cmdp++;
|
||||
break;
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Validations
|
||||
if (errors) return usage_lf_fdxb_read();
|
||||
int16_t tmp_div = config.divisor;
|
||||
if (tmp_div != LF_DIVISOR_134) {
|
||||
config.divisor = LF_DIVISOR_134;
|
||||
config.verbose = false;
|
||||
retval = lf_config(&config);
|
||||
if (retval != PM3_SUCCESS) {
|
||||
res = lf_config(&config);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "failed to change LF configuration");
|
||||
return retval;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (continuous) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("Enter") " to exit");
|
||||
|
||||
if (cm) {
|
||||
PrintAndLogEx(INFO, "Press " _GREEN_("<Enter>") " to exit");
|
||||
}
|
||||
|
||||
int ret = PM3_SUCCESS;
|
||||
do {
|
||||
retval = lf_read(false, 10000);
|
||||
if (retval != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "failed to get LF read from device");
|
||||
return retval;
|
||||
}
|
||||
ret = demodFDXB(!continuous); // be verbose only if not in continuous mode
|
||||
if (kbd_enter_pressed()) {
|
||||
break;
|
||||
}
|
||||
PrintAndLogEx(INPLACE, "");
|
||||
} while (continuous);
|
||||
lf_read(false, 10000);
|
||||
ret = demodFDXB(!cm); // be verbose only if not in continuous mode
|
||||
//PrintAndLogEx(INPLACE, "");
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
if (tmp_div != LF_DIVISOR_134) {
|
||||
config.divisor = tmp_div;
|
||||
retval = lf_config(&config);
|
||||
if (retval != PM3_SUCCESS) {
|
||||
res = lf_config(&config);
|
||||
if (res != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "failed to restore LF configuration");
|
||||
return retval;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
@ -679,145 +688,159 @@ static int CmdFdxBRead(const char *Cmd) {
|
|||
|
||||
static int CmdFdxBClone(const char *Cmd) {
|
||||
|
||||
uint32_t country_code = 0, extended = 0;
|
||||
uint64_t national_code = 0;
|
||||
uint8_t is_animal = 0, cmdp = 0;
|
||||
bool errors = false, has_extended = false, q5 = false;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf fdxb clone",
|
||||
"clone a FDX-B tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
||||
"lf fdxb clone --country 999 --national 1337 --animal\n"
|
||||
"lf fdxb clone --country 999 --national 1337 --extended 016A\n"
|
||||
"lf fdxb clone --q5 --country 999 --national 1337 -> encode for Q5/T5555 tag\n"
|
||||
"lf fdxb clone --em --country 999 --national 1337 -> encode for EM4305/4469"
|
||||
);
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lf_fdxb_clone();
|
||||
case 'c': {
|
||||
country_code = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1("c", "country", "<dec>", "country code"),
|
||||
arg_u64_1("n", "national", "<dec>", "national code"),
|
||||
arg_str0(NULL, "extended", "<hex>", "extended data"),
|
||||
arg_lit0("a", "animal", "optional - set animal bit"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint32_t country_code = arg_get_u32_def(ctx, 1, 0);
|
||||
uint64_t national_code = arg_get_u64_def(ctx, 2, 0);
|
||||
|
||||
int extended_len = 0;
|
||||
uint8_t edata[2] = {0};
|
||||
CLIGetHexWithReturn(ctx, 3, edata, &extended_len);
|
||||
|
||||
bool is_animal = arg_get_lit(ctx, 4);
|
||||
bool q5 = arg_get_lit(ctx, 5);
|
||||
bool em = arg_get_lit(ctx, 6);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
case 'n': {
|
||||
national_code = param_get64ex(Cmd, cmdp + 1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
case 'e': {
|
||||
extended = param_get32ex(Cmd, cmdp + 1, 0, 16);
|
||||
|
||||
uint16_t extended = 0;
|
||||
bool has_extended = false;
|
||||
if (extended_len) {
|
||||
extended = bytes_to_num(edata, extended_len);
|
||||
has_extended = true;
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
is_animal = 1;
|
||||
cmdp++;
|
||||
break;
|
||||
}
|
||||
case 'q': {
|
||||
q5 = true;
|
||||
cmdp++;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errors || strlen(Cmd) == 0) return usage_lf_fdxb_clone();
|
||||
|
||||
verify_values(&national_code, &country_code, &extended, &is_animal);
|
||||
verify_values(&national_code, &country_code, &extended);
|
||||
|
||||
PrintAndLogEx(INFO, " Country code %"PRIu32, country_code);
|
||||
PrintAndLogEx(INFO, " National code %"PRIu64, national_code);
|
||||
PrintAndLogEx(INFO, " Set animal bit %c", (is_animal) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, "Set data block bit %c", (has_extended) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, " Extended data 0x%"PRIX32, extended);
|
||||
PrintAndLogEx(INFO, " RFU 0");
|
||||
PrintAndLogEx(INFO, "Country code........ %"PRIu32, country_code);
|
||||
PrintAndLogEx(INFO, "National code....... %"PRIu64, national_code);
|
||||
PrintAndLogEx(INFO, "Set animal bit...... %c", (is_animal) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, "Set data block bit.. %c", (has_extended) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, "Extended data....... 0x%"PRIX32, extended);
|
||||
PrintAndLogEx(INFO, "RFU................. 0");
|
||||
|
||||
uint8_t *bits = calloc(128, sizeof(uint8_t));
|
||||
if (getFDXBBits(national_code, country_code, is_animal, has_extended, extended, bits) != PM3_SUCCESS) {
|
||||
uint8_t *bs = calloc(128, sizeof(uint8_t));
|
||||
if (getFDXBBits(national_code, country_code, is_animal, has_extended, extended, bs) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
free(bits);
|
||||
free(bs);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint32_t blocks[5] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_32 | 4 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0, 0};
|
||||
char cardtype[16] = {"T55x7"};
|
||||
|
||||
// Q5
|
||||
if (q5)
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(32) | 4 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
// EM4305
|
||||
if (em) {
|
||||
blocks[0] = EM4305_FDXB_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
// convert from bit stream to block data
|
||||
blocks[1] = bytebits_to_byte(bits, 32);
|
||||
blocks[2] = bytebits_to_byte(bits + 32, 32);
|
||||
blocks[3] = bytebits_to_byte(bits + 64, 32);
|
||||
blocks[4] = bytebits_to_byte(bits + 96, 32);
|
||||
blocks[1] = bytebits_to_byte(bs, 32);
|
||||
blocks[2] = bytebits_to_byte(bs + 32, 32);
|
||||
blocks[3] = bytebits_to_byte(bs + 64, 32);
|
||||
blocks[4] = bytebits_to_byte(bs + 96, 32);
|
||||
|
||||
free(bits);
|
||||
free(bs);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone FDX-B to " _YELLOW_("%s") " with animal ID: " _GREEN_("%04u-%"PRIu64), (q5) ? "Q5/T5555" : "T55x7", country_code, national_code);
|
||||
PrintAndLogEx(INFO, "Preparing to clone FDX-B to " _YELLOW_("%s") " with animal ID: " _GREEN_("%04u-%"PRIu64)
|
||||
, cardtype
|
||||
, country_code
|
||||
, national_code
|
||||
);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf fdxb read`") " to verify");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf fdxb reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdFdxBSim(const char *Cmd) {
|
||||
|
||||
uint32_t country_code = 0, extended = 0;
|
||||
uint64_t national_code = 0;
|
||||
uint8_t is_animal = 0, cmdp = 0;
|
||||
bool errors = false, has_extended = false;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf fdxb sim",
|
||||
"Enables simulation of FDX-B animal tag.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||
"lf fdxb sim --country 999 --national 1337 --animal\n"
|
||||
"lf fdxb sim --country 999 --national 1337 --extended 016A\n"
|
||||
);
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lf_fdxb_sim();
|
||||
case 'c': {
|
||||
country_code = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
case 'n': {
|
||||
national_code = param_get64ex(Cmd, cmdp + 1, 0, 10);
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
case 'e': {
|
||||
extended = param_get32ex(Cmd, cmdp + 1, 0, 10);
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1("c", "country", "<dec>", "country code"),
|
||||
arg_u64_1("n", "national", "<dec>", "national code"),
|
||||
arg_str0(NULL, "extended", "<hex>", "extended data"),
|
||||
arg_lit0("a", "animal", "optional - set animal bit"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint32_t country_code = arg_get_u32_def(ctx, 1, 0);
|
||||
uint64_t national_code = arg_get_u64_def(ctx, 2, 0);
|
||||
int extended_len = 0;
|
||||
uint8_t edata[2] = {0};
|
||||
CLIGetHexWithReturn(ctx, 3, edata, &extended_len);
|
||||
|
||||
bool is_animal = arg_get_lit(ctx, 4);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
uint16_t extended = 0;
|
||||
bool has_extended = false;
|
||||
if (extended_len) {
|
||||
extended = bytes_to_num(edata, extended_len);
|
||||
has_extended = true;
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
case 's': {
|
||||
is_animal = 1;
|
||||
cmdp++;
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (errors) return usage_lf_fdxb_sim();
|
||||
|
||||
verify_values(&national_code, &country_code, &extended, &is_animal);
|
||||
verify_values(&national_code, &country_code, &extended);
|
||||
|
||||
PrintAndLogEx(INFO, " Country code %"PRIu32, country_code);
|
||||
PrintAndLogEx(INFO, " National code %"PRIu64, national_code);
|
||||
PrintAndLogEx(INFO, " Set animal bit %c", (is_animal) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, "Set data block bit %c", (has_extended) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, " Extended data 0x%"PRIX32, extended);
|
||||
PrintAndLogEx(INFO, " RFU 0");
|
||||
PrintAndLogEx(INFO, "Country code........ %"PRIu32, country_code);
|
||||
PrintAndLogEx(INFO, "National code....... %"PRIu64, national_code);
|
||||
PrintAndLogEx(INFO, "Set animal bit...... %c", (is_animal) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, "Set data block bit.. %c", (has_extended) ? 'Y' : 'N');
|
||||
PrintAndLogEx(INFO, "Extended data....... 0x%"PRIX16, extended);
|
||||
PrintAndLogEx(INFO, "RFU................. 0");
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: " _GREEN_("%04u-%"PRIu64), country_code, national_code);
|
||||
PrintAndLogEx(SUCCESS, "Simulating FDX-B animal ID: " _YELLOW_("%04u-%"PRIu64), country_code, national_code);
|
||||
|
||||
uint8_t *bits = calloc(128, sizeof(uint8_t));
|
||||
if (getFDXBBits(national_code, country_code, is_animal, (extended > 0), extended, bits) != PM3_SUCCESS) {
|
||||
uint8_t *bs = calloc(128, sizeof(uint8_t));
|
||||
if (getFDXBBits(national_code, country_code, is_animal, (extended > 0), extended, bs) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
free(bits);
|
||||
free(bs);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
|
@ -827,12 +850,12 @@ static int CmdFdxBSim(const char *Cmd) {
|
|||
payload->invert = 1;
|
||||
payload->separator = 0;
|
||||
payload->clock = 32;
|
||||
memcpy(payload->data, bits, 128);
|
||||
memcpy(payload->data, bs, 128);
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + 128);
|
||||
|
||||
free(bits);
|
||||
free(bs);
|
||||
free(payload);
|
||||
|
||||
PacketResponseNG resp;
|
||||
|
@ -848,7 +871,7 @@ static int CmdFdxBSim(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||
{"demod", CmdFdxBDemod, AlwaysAvailable, "demodulate a FDX-B ISO11784/85 tag from the GraphBuffer"},
|
||||
{"read", CmdFdxBRead, IfPm3Lf, "attempt to read at 134kHz and extract tag data"},
|
||||
{"reader", CmdFdxBReader, IfPm3Lf, "attempt to read at 134kHz and extract tag data"},
|
||||
{"clone", CmdFdxBClone, IfPm3Lf, "clone animal ID tag to T55x7 or Q5/T5555"},
|
||||
{"sim", CmdFdxBSim, IfPm3Lf, "simulate Animal ID tag"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
@ -878,59 +901,3 @@ int detectFDXB(uint8_t *dest, size_t *size) {
|
|||
//return start position
|
||||
return (int)startIdx;
|
||||
}
|
||||
|
||||
int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits) {
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
bits[10] = 1;
|
||||
|
||||
// 128bits
|
||||
// every 9th bit is 0x01, but we can just fill the rest with 0x01 and overwrite
|
||||
memset(bits, 0x01, 128);
|
||||
|
||||
// add preamble ten 0x00 and one 0x01
|
||||
memset(bits, 0x00, 10);
|
||||
|
||||
// add reserved
|
||||
num_to_bytebitsLSBF(0x00, 7, bits + 66);
|
||||
num_to_bytebitsLSBF(0x00 >> 7, 7, bits + 74);
|
||||
|
||||
// add animal flag - OK
|
||||
bits[81] = is_animal;
|
||||
|
||||
// add extended flag - OK
|
||||
bits[65] = is_extended;
|
||||
|
||||
// add national code 40bits - OK
|
||||
num_to_bytebitsLSBF(national_code >> 0, 8, bits + 11);
|
||||
num_to_bytebitsLSBF(national_code >> 8, 8, bits + 20);
|
||||
num_to_bytebitsLSBF(national_code >> 16, 8, bits + 29);
|
||||
num_to_bytebitsLSBF(national_code >> 24, 8, bits + 38);
|
||||
num_to_bytebitsLSBF(national_code >> 32, 6, bits + 47);
|
||||
|
||||
// add country code - OK
|
||||
num_to_bytebitsLSBF(country_code >> 0, 2, bits + 53);
|
||||
num_to_bytebitsLSBF(country_code >> 2, 8, bits + 56);
|
||||
|
||||
// add crc-16 - OK
|
||||
uint8_t raw[8];
|
||||
for (uint8_t i = 0; i < 8; ++i)
|
||||
raw[i] = bytebits_to_byte(bits + 11 + i * 9, 8);
|
||||
|
||||
init_table(CRC_11784);
|
||||
uint16_t crc = crc16_fdxb(raw, 8);
|
||||
num_to_bytebitsLSBF(crc >> 0, 8, bits + 83);
|
||||
num_to_bytebitsLSBF(crc >> 8, 8, bits + 92);
|
||||
|
||||
// extended data - OK
|
||||
num_to_bytebitsLSBF(extended >> 0, 8, bits + 101);
|
||||
num_to_bytebitsLSBF(extended >> 8, 8, bits + 110);
|
||||
num_to_bytebitsLSBF(extended >> 16, 8, bits + 119);
|
||||
|
||||
// 8 16 24 32 40 48 49
|
||||
// A8 28 0C 92 EA 6F 00 01
|
||||
// A8 28 0C 92 EA 6F 80 00
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ typedef struct {
|
|||
int CmdLFFdxB(const char *Cmd);
|
||||
int detectFDXB(uint8_t *dest, size_t *size);
|
||||
int demodFDXB(bool verbose);
|
||||
int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint32_t extended, uint8_t *bits);
|
||||
//int getFDXBBits(uint64_t national_code, uint16_t country_code, uint8_t is_animal, uint8_t is_extended, uint16_t extended, uint8_t *bits);
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@
|
|||
// sample Q5 , ASK RF/32, STT, 96 bits (3blocks) ( 0x9000F006)
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdlfgallagher.h"
|
||||
|
||||
#include <string.h> // memcpy
|
||||
#include <ctype.h> // tolower
|
||||
#include <stdio.h>
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
|
@ -24,22 +24,11 @@
|
|||
#include "protocols.h" // t55xx defines
|
||||
#include "cmdlft55xx.h" // clone..
|
||||
#include "crc.h" // CRC8/Cardx
|
||||
#include "cmdlfem4x05.h" //
|
||||
#include "cliparser.h"
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_gallagher_clone(void) {
|
||||
PrintAndLogEx(NORMAL, "clone a GALLAGHER tag to a T55x7 tag.");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf gallagher clone [h] [b <raw hex>]");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : this help");
|
||||
PrintAndLogEx(NORMAL, " b <raw hex> : raw hex data. 12 bytes max");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf gallagher clone b 0FFD5461A9DA1346B2D1AC32"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static void descramble(uint8_t *arr, uint8_t len) {
|
||||
|
||||
uint8_t lut[] = {
|
||||
|
@ -134,71 +123,163 @@ int demodGallagher(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdGallagherDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gallagher demod",
|
||||
"Try to find GALLAGHER preamble, if found decode / descramble data",
|
||||
"lf gallagher demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodGallagher(true);
|
||||
}
|
||||
|
||||
static int CmdGallagherRead(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
static int CmdGallagherReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gallagher reader",
|
||||
"read a GALLAGHER tag",
|
||||
"lf gallagher reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 4096 * 2 + 20);
|
||||
return demodGallagher(true);
|
||||
demodGallagher(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdGallagherClone(const char *Cmd) {
|
||||
|
||||
uint32_t blocks[4];
|
||||
bool errors = false;
|
||||
uint8_t cmdp = 0;
|
||||
int datalen = 0;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gallagher clone",
|
||||
"clone a GALLAGHER tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
||||
"lf gallagher clone --raw 0FFD5461A9DA1346B2D1AC32\n"
|
||||
"lf gallagher clone --q5 --raw 0FFD5461A9DA1346B2D1AC32 -> encode for Q5/T5555 tag\n"
|
||||
"lf gallagher clone --em --raw 0FFD5461A9DA1346B2D1AC32 -> encode for EM4305/4469"
|
||||
);
|
||||
|
||||
while (param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch (tolower(param_getchar(Cmd, cmdp))) {
|
||||
case 'h':
|
||||
return usage_lf_gallagher_clone();
|
||||
case 'b': {
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("r", "raw", "<hex>", "raw hex data. 12 bytes max"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int raw_len = 0;
|
||||
// skip first block, 3*4 = 12 bytes left
|
||||
uint8_t rawhex[12] = {0};
|
||||
int res = param_gethex_to_eol(Cmd, cmdp + 1, rawhex, sizeof(rawhex), &datalen);
|
||||
if (res != 0)
|
||||
errors = true;
|
||||
uint8_t raw[12] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
|
||||
bool q5 = arg_get_lit(ctx, 2);
|
||||
bool em = arg_get_lit(ctx, 3);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t blocks[4];
|
||||
for (uint8_t i = 1; i < ARRAYLEN(blocks); i++) {
|
||||
blocks[i] = bytes_to_num(rawhex + ((i - 1) * 4), sizeof(uint32_t));
|
||||
blocks[i] = bytes_to_num(raw + ((i - 1) * 4), sizeof(uint32_t));
|
||||
}
|
||||
cmdp += 2;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
PrintAndLogEx(WARNING, "Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (errors || cmdp == 0) return usage_lf_gallagher_clone();
|
||||
|
||||
//Pac - compat mode, NRZ, data rate 40, 3 data blocks
|
||||
blocks[0] = T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 3 << T55x7_MAXBLOCK_SHIFT;
|
||||
char cardtype[16] = {"T55x7"};
|
||||
// Q5
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_MANCHESTER | T5555_SET_BITRATE(32) | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Gallagher to T55x7 with raw hex");
|
||||
// EM4305
|
||||
if (em) {
|
||||
blocks[0] = EM4305_GALLAGHER_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Gallagher to " _YELLOW_("%s") " with raw hex", cardtype);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gallagher read`") " to verify");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gallagher reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdGallagherSim(const char *Cmd) {
|
||||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gallagher sim",
|
||||
"Enables simulation of GALLAGHER card with specified card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.\n",
|
||||
"lf gallagher sim --raw 0FFD5461A9DA1346B2D1AC32"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("r", "raw", "<hex>", "raw hex data. 12 bytes max"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
int raw_len = 0;
|
||||
// skip first block, 3*4 = 12 bytes left
|
||||
uint8_t raw[12] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// ASK/MAN sim.
|
||||
PrintAndLogEx(INFO, " To be implemented, feel free to contribute!");
|
||||
PrintAndLogEx(SUCCESS, "Simulating Gallagher - raw " _YELLOW_("%s"), sprint_hex_inrow(raw, sizeof(raw)));
|
||||
|
||||
uint8_t bs[sizeof(raw) * 8];
|
||||
bytes_to_bytebits(raw, sizeof(raw), bs);
|
||||
|
||||
lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + sizeof(bs));
|
||||
payload->encoding = 1;
|
||||
payload->invert = 0;
|
||||
payload->separator = 0;
|
||||
payload->clock = 32;
|
||||
memcpy(payload->data, bs, sizeof(bs));
|
||||
|
||||
clearCommandBuffer();
|
||||
SendCommandNG(CMD_LF_ASK_SIMULATE, (uint8_t *)payload, sizeof(lf_asksim_t) + sizeof(bs));
|
||||
free(payload);
|
||||
|
||||
PacketResponseNG resp;
|
||||
WaitForResponse(CMD_LF_ASK_SIMULATE, &resp);
|
||||
|
||||
PrintAndLogEx(INFO, "Done");
|
||||
if (resp.status != PM3_EOPABORTED)
|
||||
return resp.status;
|
||||
|
||||
return PM3_SUCCESS;
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"demod", CmdGallagherDemod, AlwaysAvailable, "Demodulate an GALLAGHER tag from the GraphBuffer"},
|
||||
{"read", CmdGallagherRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||
{"reader", CmdGallagherReader, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||
{"clone", CmdGallagherClone, IfPm3Lf, "clone GALLAGHER tag to T55x7"},
|
||||
{"sim", CmdGallagherSim, IfPm3Lf, "simulate GALLAGHER tag"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
// Marshmellow
|
||||
//
|
||||
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
|
||||
// at your option, any later version. See the LICENSE.txt file for the text of
|
||||
|
@ -8,12 +9,10 @@
|
|||
// Biphase, rf/ , 96 bits (unknown key calc + some bits)
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdlfguard.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
|
@ -23,44 +22,11 @@
|
|||
#include "protocols.h" // for T55xx config register definitions
|
||||
#include "lfdemod.h" // parityTest
|
||||
#include "cmdlft55xx.h" // verifywrite
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_guard_clone(void) {
|
||||
PrintAndLogEx(NORMAL, "clone a Guardall tag to a T55x7 or Q5/T5555 tag.");
|
||||
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. ");
|
||||
PrintAndLogEx(NORMAL, "Currently work only on 26bit");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf gprox clone [h] <format> <Facility-Code> <Card-Number> <Q5>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " <format> : format length 26|32|36|40");
|
||||
PrintAndLogEx(NORMAL, " <Facility-Code> : 8-bit value facility code");
|
||||
PrintAndLogEx(NORMAL, " <Card Number> : 16-bit value card number");
|
||||
PrintAndLogEx(NORMAL, " <Q5> : Specify writing to Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf gprox clone 26 123 11223"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_guard_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of Guardall card with specified card number.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
PrintAndLogEx(NORMAL, "The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.");
|
||||
PrintAndLogEx(NORMAL, "Currently work only on 26bit");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf gprox sim [h] <format> <Facility-Code> <Card-Number>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " <format> : format length 26|32|36|40");
|
||||
PrintAndLogEx(NORMAL, " <Facility-Code> : 8-bit value facility code");
|
||||
PrintAndLogEx(NORMAL, " <Card Number> : 16-bit value card number");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf gprox sim 26 123 11223"));
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
// attempts to demodulate and identify a G_Prox_II verex/chubb card
|
||||
// WARNING: if it fails during some points it will destroy the DemodBuffer data
|
||||
// but will leave the GraphBuffer intact.
|
||||
|
@ -150,43 +116,104 @@ int demodGuard(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdGuardDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gproxii demod",
|
||||
"Try to find Guardall Prox-II preamble, if found decode / descramble data",
|
||||
"lf gproxii demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodGuard(true);
|
||||
}
|
||||
|
||||
static int CmdGuardRead(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
static int CmdGuardReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gproxii reader",
|
||||
"read a Guardall tag",
|
||||
"lf gproxii reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 10000);
|
||||
return demodGuard(true);
|
||||
demodGuard(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdGuardClone(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gproxii clone",
|
||||
"clone a Guardall tag to a T55x7, Q5/T5555 or EM4305/4469 tag.\n"
|
||||
"The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
|
||||
"Currently work only on 26bit",
|
||||
"lf gproxii clone --fmt 26 --fc 123 --cn 1337\n"
|
||||
"lf gproxii clone --q5 --fmt 26 --fc 123 --cn 1337 -> encode for Q5/T5555 tag\n"
|
||||
"lf gproxii clone --em --fmt 26 --fc 123 --cn 1337 -> encode for EM4305/4469"
|
||||
);
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_guard_clone();
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
|
||||
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
|
||||
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
|
||||
uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0);
|
||||
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
|
||||
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
|
||||
bool q5 = arg_get_lit(ctx, 4);
|
||||
bool em = arg_get_lit(ctx, 5);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_clone();
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
fmtlen &= 0x7f;
|
||||
facilitycode = (fc & 0x000000FF);
|
||||
cardnumber = (cn & 0x0000FFFF);
|
||||
uint32_t facilitycode = (fc & 0x000000FF);
|
||||
uint32_t cardnumber = (cn & 0x0000FFFF);
|
||||
|
||||
//GuardProxII - compat mode, ASK/Biphase, data rate 64, 3 data blocks
|
||||
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||
uint8_t *bs = calloc(96, sizeof(uint8_t));
|
||||
|
||||
if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
free(bs);
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
uint32_t blocks[4] = {T55x7_MODULATION_BIPHASE | T55x7_BITRATE_RF_64 | 3 << T55x7_MAXBLOCK_SHIFT, 0, 0, 0};
|
||||
char cardtype[16] = {"T55x7"};
|
||||
// Q5
|
||||
bool q5 = tolower(param_getchar(Cmd, 3)) == 'q';
|
||||
if (q5)
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_SET_BITRATE(64) | 3 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
// EM4305
|
||||
if (em) {
|
||||
blocks[0] = EM4305_GUARDPROXII_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
blocks[1] = bytebits_to_byte(bs, 32);
|
||||
blocks[2] = bytebits_to_byte(bs + 32, 32);
|
||||
|
@ -194,37 +221,65 @@ static int CmdGuardClone(const char *Cmd) {
|
|||
|
||||
free(bs);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: %u, Card Number: %u", (q5) ? "Q5/T5555" : "T55x7", facilitycode, cardnumber);
|
||||
PrintAndLogEx(INFO, "Preparing to clone Guardall to " _YELLOW_("%s") " with Facility Code: " _GREEN_("%u") " Card Number: " _GREEN_("%u")
|
||||
, cardtype
|
||||
, facilitycode
|
||||
, cardnumber
|
||||
);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
int res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gprox read`") " to verify");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf gproxii reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdGuardSim(const char *Cmd) {
|
||||
|
||||
uint32_t facilitycode = 0, cardnumber = 0, fc = 0, cn = 0, fmtlen = 0;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf gproxii sim",
|
||||
"Enables simulation of Guardall card with specified card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.\n"
|
||||
"The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated.\n"
|
||||
"Currently work only on 26bit",
|
||||
"lf gproxii sim --fmt 26 --fc 123 --cn 1337\n"
|
||||
);
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_guard_sim();
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_u64_1(NULL, "fmt", "<dec>", "format length 26|32|36|40"),
|
||||
arg_u64_1(NULL, "fc", "<dec>", "8-bit value facility code"),
|
||||
arg_u64_1(NULL, "cn", "<dec>", "16-bit value card number"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
if (sscanf(Cmd, "%u %u %u", &fmtlen, &fc, &cn) != 3) return usage_lf_guard_sim();
|
||||
uint32_t fmtlen = arg_get_u32_def(ctx, 1, 0);
|
||||
uint32_t fc = arg_get_u32_def(ctx, 2, 0);
|
||||
uint32_t cn = arg_get_u32_def(ctx, 3, 0);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
fmtlen &= 0x7F;
|
||||
uint32_t facilitycode = (fc & 0x000000FF);
|
||||
uint32_t cardnumber = (cn & 0x0000FFFF);
|
||||
|
||||
uint8_t bs[96];
|
||||
memset(bs, 0x00, sizeof(bs));
|
||||
|
||||
fmtlen &= 0x7F;
|
||||
facilitycode = (fc & 0x000000FF);
|
||||
cardnumber = (cn & 0x0000FFFF);
|
||||
|
||||
if (getGuardBits(fmtlen, facilitycode, cardnumber, bs) != PM3_SUCCESS) {
|
||||
PrintAndLogEx(ERR, "Error with tag bitstream generation.");
|
||||
return PM3_ESOFT;
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating Guardall - Facility Code: %u, CardNumber: %u", facilitycode, cardnumber);
|
||||
PrintAndLogEx(SUCCESS, "Simulating Guardall Prox - Facility Code: " _YELLOW_("%u") " CardNumber: " _YELLOW_("%u")
|
||||
, facilitycode
|
||||
, cardnumber
|
||||
);
|
||||
|
||||
// Guard uses: clk: 64, invert: 0, encoding: 2 (ASK Biphase)
|
||||
lf_asksim_t *payload = calloc(1, sizeof(lf_asksim_t) + sizeof(bs));
|
||||
|
@ -250,7 +305,7 @@ static int CmdGuardSim(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||
{"demod", CmdGuardDemod, AlwaysAvailable, "demodulate a G Prox II tag from the GraphBuffer"},
|
||||
{"read", CmdGuardRead, IfPm3Lf, "attempt to read and extract tag data from the antenna"},
|
||||
{"reader", CmdGuardReader, IfPm3Lf, "attempt to read and extract tag data from the antenna"},
|
||||
{"clone", CmdGuardClone, IfPm3Lf, "clone Guardall tag to T55x7 or Q5/T5555"},
|
||||
{"sim", CmdGuardSim, IfPm3Lf, "simulate Guardall tag"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
@ -267,7 +322,6 @@ int CmdLFGuard(const char *Cmd) {
|
|||
return CmdsParse(CommandTable, Cmd);
|
||||
}
|
||||
|
||||
// by marshmellow
|
||||
// demod gProxIIDemod
|
||||
// error returns as -x
|
||||
// success returns start position in bitstream
|
||||
|
|
|
@ -19,13 +19,10 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfhid.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
|
@ -38,6 +35,7 @@
|
|||
#include "lfdemod.h"
|
||||
#include "wiegand_formats.h"
|
||||
#include "wiegand_formatutils.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
#ifndef BITS
|
||||
# define BITS 96
|
||||
|
@ -153,15 +151,44 @@ int demodHID(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdHIDDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hid demod",
|
||||
"Try to find HID Prox preamble, if found decode / descramble data",
|
||||
"lf hid demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodHID(true);
|
||||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdHIDRead(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf hid reader",
|
||||
"read a HID Prox tag",
|
||||
"lf hid reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 16000);
|
||||
return demodHID(true);
|
||||
demodHID(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
// this read loops on device side.
|
||||
|
@ -212,7 +239,6 @@ static int CmdHIDSim(const char *Cmd) {
|
|||
arg_int0("i", NULL, "<dec>", "issue level"),
|
||||
arg_int0("o", "oem", "<dec>", "OEM code"),
|
||||
arg_strx0("r", "raw", "<hex>", "raw bytes"),
|
||||
// arg_lit0("q", "Q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
@ -231,8 +257,6 @@ static int CmdHIDSim(const char *Cmd) {
|
|||
int raw_len = 0;
|
||||
char raw[40] = {0};
|
||||
CLIParamStrToBuf(arg_get_str(ctx, 6), (uint8_t *)raw, sizeof(raw), &raw_len);
|
||||
|
||||
//bool q5 = arg_get_lit(ctx, 7);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
wiegand_message_t packed;
|
||||
|
|
|
@ -9,13 +9,10 @@
|
|||
// PSK
|
||||
//-----------------------------------------------------------------------------
|
||||
#include "cmdlfidteck.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "common.h"
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "ui.h"
|
||||
|
@ -23,6 +20,8 @@
|
|||
#include "cmdlf.h"
|
||||
#include "lfdemod.h"
|
||||
#include "commonutil.h" // num_to_bytes
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
@ -87,20 +86,49 @@ int demodIdteck(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdIdteckDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf idteck demod",
|
||||
"Try to find Idteck preamble, if found decode / descramble data",
|
||||
"lf idteck demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodIdteck(true);
|
||||
}
|
||||
|
||||
static int CmdIdteckRead(const char *Cmd) {
|
||||
(void)Cmd;
|
||||
static int CmdIdteckReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf idteck reader",
|
||||
"read a Idteck tag",
|
||||
"lf idteck reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 5000);
|
||||
return demodIdteck(true);
|
||||
demodIdteck(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"demod", CmdIdteckDemod, AlwaysAvailable, "Demodulate an Idteck tag from the GraphBuffer"},
|
||||
{"read", CmdIdteckRead, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
|
||||
{"reader", CmdIdteckReader, IfPm3Lf, "Attempt to read and Extract tag data from the antenna"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -9,13 +9,10 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfindala.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <inttypes.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "graph.h"
|
||||
|
@ -28,6 +25,8 @@
|
|||
#include "cmdlf.h" // lf_read
|
||||
#include "protocols.h" // t55 defines
|
||||
#include "cmdlft55xx.h" // verifywrite
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
#define INDALA_ARR_LEN 64
|
||||
|
||||
|
@ -499,16 +498,33 @@ static int CmdIndalaDemodAlt(const char *Cmd) {
|
|||
}
|
||||
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdIndalaRead(const char *Cmd) {
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (cmdp == 'h') return usage_lf_indala_demod();
|
||||
static int CmdIndalaReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf indala reader",
|
||||
"read a Indala Prox tag",
|
||||
"lf indala reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
int clk = 32, invert = 0, maxErr = 100;
|
||||
if (strlen(Cmd) > 0) {
|
||||
sscanf(Cmd, "%i %i %i", &clk, &invert, &maxErr);
|
||||
}
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_int0(NULL, "clock", "<dec>", "optional - set clock (as integer), if not set, autodetect."),
|
||||
arg_int0(NULL, "maxerr", "<dec>", "optional - set maximum allowed errors, default = 100"),
|
||||
arg_lit0("i", "invert", "optional - invert output"),
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
uint32_t clk = arg_get_u32_def(ctx, 1, 32);
|
||||
uint32_t max_err = arg_get_u32_def(ctx, 2, 100);
|
||||
bool invert = arg_get_lit(ctx, 3);
|
||||
bool cm = arg_get_lit(ctx, 4);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 30000);
|
||||
return demodIndalaEx(clk, invert, maxErr, true);
|
||||
demodIndalaEx(clk, invert, max_err, !cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdIndalaSim(const char *Cmd) {
|
||||
|
@ -699,7 +715,7 @@ static command_t CommandTable[] = {
|
|||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||
{"demod", CmdIndalaDemod, AlwaysAvailable, "demodulate an indala tag (PSK1) from GraphBuffer"},
|
||||
{"altdemod", CmdIndalaDemodAlt, AlwaysAvailable, "alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)"},
|
||||
{"read", CmdIndalaRead, IfPm3Lf, "read an Indala Prox tag from the antenna"},
|
||||
{"reader", CmdIndalaReader, IfPm3Lf, "read an Indala Prox tag from the antenna"},
|
||||
{"clone", CmdIndalaClone, IfPm3Lf, "clone Indala tag to T55x7 or Q5/T5555"},
|
||||
{"sim", CmdIndalaSim, IfPm3Lf, "simulate Indala tag"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
|
|
@ -9,13 +9,10 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfio.h"
|
||||
|
||||
#include <stdio.h> // sscanf
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
|
@ -26,6 +23,8 @@
|
|||
#include "protocols.h" // for T55xx config register definitions
|
||||
#include "cmddata.h"
|
||||
#include "cmdlft55xx.h" // verifywrite
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
|
@ -192,14 +191,43 @@ int demodIOProx(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdIOProxDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf io demod",
|
||||
"Try to find IO Prox preamble, if found decode / descramble data",
|
||||
"lf io demod\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodIOProx(true);
|
||||
}
|
||||
// this read is the "normal" read, which download lf signal and tries to demod here.
|
||||
static int CmdIOProxRead(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
static int CmdIOProxReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf io reader",
|
||||
"read a IO Prox tag",
|
||||
"lf io reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 12000);
|
||||
return demodIOProx(true);
|
||||
demodIOProx(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
static int CmdIOProxSim(const char *Cmd) {
|
||||
uint16_t cn = 0;
|
||||
|
@ -299,7 +327,7 @@ static int CmdIOProxClone(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "this help"},
|
||||
{"demod", CmdIOProxDemod, AlwaysAvailable, "demodulate an IOProx tag from the GraphBuffer"},
|
||||
{"read", CmdIOProxRead, IfPm3Lf, "attempt to read and extract tag data"},
|
||||
{"reader", CmdIOProxReader, IfPm3Lf, "attempt to read and extract tag data"},
|
||||
{"clone", CmdIOProxClone, IfPm3Lf, "clone IOProx tag to T55x7 or Q5/T5555"},
|
||||
{"sim", CmdIOProxSim, IfPm3Lf, "simulate IOProx tag"},
|
||||
{"watch", CmdIOProxWatch, IfPm3Lf, "continuously watch for cards. Reader mode"},
|
||||
|
|
|
@ -9,12 +9,10 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include "cmdlfjablotron.h"
|
||||
|
||||
#include <string.h>
|
||||
#include <inttypes.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "commonutil.h" // ARRAYLEN
|
||||
|
@ -24,25 +22,13 @@
|
|||
#include "protocols.h" // for T55xx config register definitions
|
||||
#include "lfdemod.h" // parityTest
|
||||
#include "cmdlft55xx.h" // verifywrite
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
#define JABLOTRON_ARR_LEN 64
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
||||
static int usage_lf_jablotron_clone(void) {
|
||||
PrintAndLogEx(NORMAL, "clone a Jablotron tag to a T55x7 or Q5/T5555 tag.");
|
||||
PrintAndLogEx(NORMAL, "Usage: lf jablotron clone [h] <card ID> <Q5>");
|
||||
PrintAndLogEx(NORMAL, "Options:");
|
||||
PrintAndLogEx(NORMAL, " h : This help");
|
||||
PrintAndLogEx(NORMAL, " <card ID> : jablotron card ID");
|
||||
PrintAndLogEx(NORMAL, " <Q5> : specify writing to Q5/T5555 tag");
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
PrintAndLogEx(NORMAL, "Examples:");
|
||||
PrintAndLogEx(NORMAL, _YELLOW_(" lf jablotron clone 112233"));
|
||||
PrintAndLogEx(NORMAL, "");
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int usage_lf_jablotron_sim(void) {
|
||||
PrintAndLogEx(NORMAL, "Enables simulation of jablotron card with specified card number.");
|
||||
PrintAndLogEx(NORMAL, "Simulation runs until the button is pressed or another USB command is issued.");
|
||||
|
@ -134,30 +120,93 @@ int demodJablotron(bool verbose) {
|
|||
|
||||
//see ASKDemod for what args are accepted
|
||||
static int CmdJablotronDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf jablotron demod",
|
||||
"Try to find Jablotron preamble, if found decode / descramble data",
|
||||
"lf jablotron demod\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodJablotron(true);
|
||||
}
|
||||
|
||||
static int CmdJablotronRead(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
static int CmdJablotronReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf jablotron reader",
|
||||
"read a jablotron tag",
|
||||
"lf jablotron reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_lit0("@", NULL, "optional - continuous reader mode"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
bool cm = arg_get_lit(ctx, 1);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
do {
|
||||
lf_read(false, 16000);
|
||||
return demodJablotron(true);
|
||||
demodJablotron(!cm);
|
||||
} while (cm && !kbd_enter_pressed());
|
||||
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
static int CmdJablotronClone(const char *Cmd) {
|
||||
|
||||
uint64_t fullcode = 0;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf jablotron clone",
|
||||
"clone a Jablotron tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
||||
"lf jablotron clone --cn 01b669\n"
|
||||
"lf jablotron clone --q5 --cn 01b669 -> encode for Q5/T5555 tag\n"
|
||||
"lf jablotron clone --em --cn 01b669 -> encode for EM4305/4469"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1(NULL, "cn", "<hex>", "Jablotron card ID - 5 bytes max"),
|
||||
arg_lit0(NULL, "q5", "optional - specify writing to Q5/T5555 tag"),
|
||||
arg_lit0(NULL, "em", "optional - specify writing to EM4305/4469 tag"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int raw_len = 0;
|
||||
uint8_t raw[5] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
|
||||
|
||||
bool q5 = arg_get_lit(ctx, 2);
|
||||
bool em = arg_get_lit(ctx, 3);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
if (q5 && em) {
|
||||
PrintAndLogEx(FAILED, "Can't specify both Q5 and EM4305 at the same time");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
|
||||
uint32_t blocks[3] = {T55x7_MODULATION_DIPHASE | T55x7_BITRATE_RF_64 | 2 << T55x7_MAXBLOCK_SHIFT, 0, 0};
|
||||
|
||||
char cmdp = tolower(param_getchar(Cmd, 0));
|
||||
if (strlen(Cmd) == 0 || cmdp == 'h') return usage_lf_jablotron_clone();
|
||||
|
||||
fullcode = param_get64ex(Cmd, 0, 0, 16);
|
||||
|
||||
char cardtype[16] = {"T55x7"};
|
||||
// Q5
|
||||
bool q5 = tolower(param_getchar(Cmd, 1)) == 'q';
|
||||
if (q5)
|
||||
if (q5) {
|
||||
blocks[0] = T5555_FIXED | T5555_MODULATION_BIPHASE | T5555_INVERT_OUTPUT | T5555_SET_BITRATE(64) | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
snprintf(cardtype, sizeof(cardtype), "Q5/T5555");
|
||||
}
|
||||
|
||||
// EM4305
|
||||
if (em) {
|
||||
blocks[0] = EM4305_JABLOTRON_CONFIG_BLOCK;
|
||||
snprintf(cardtype, sizeof(cardtype), "EM4305/4469");
|
||||
}
|
||||
|
||||
|
||||
uint64_t fullcode = bytes_to_num(raw, raw_len);
|
||||
|
||||
// clearing the topbit needed for the preambl detection.
|
||||
if ((fullcode & 0x7FFFFFFFFF) != fullcode) {
|
||||
|
@ -181,10 +230,20 @@ static int CmdJablotronClone(const char *Cmd) {
|
|||
|
||||
free(bits);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Jablotron to " _YELLOW_("%s") " with FullCode: %"PRIx64, (q5) ? "Q5/T5555" : "T55x7", fullcode);
|
||||
uint64_t id = getJablontronCardId(fullcode);
|
||||
|
||||
PrintAndLogEx(INFO, "Preparing to clone Jablotron to " _YELLOW_("%s") " with FullCode: " _GREEN_("%"PRIx64)" id: " _GREEN_("%"PRIx64), cardtype, fullcode, id);
|
||||
print_blocks(blocks, ARRAYLEN(blocks));
|
||||
|
||||
return clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
int res;
|
||||
if (em) {
|
||||
res = em4x05_clone_tag(blocks, ARRAYLEN(blocks), 0, false);
|
||||
} else {
|
||||
res = clone_t55xx_tag(blocks, ARRAYLEN(blocks));
|
||||
}
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf jablotron reader`") " to verify");
|
||||
return res;
|
||||
}
|
||||
|
||||
static int CmdJablotronSim(const char *Cmd) {
|
||||
|
@ -201,7 +260,7 @@ static int CmdJablotronSim(const char *Cmd) {
|
|||
PrintAndLogEx(INFO, "Card Number Truncated to 39bits: %"PRIx64, fullcode);
|
||||
}
|
||||
|
||||
PrintAndLogEx(SUCCESS, "Simulating Jablotron - FullCode: %"PRIx64, fullcode);
|
||||
PrintAndLogEx(SUCCESS, "Simulating Jablotron - FullCode: " _YELLOW_("%"PRIx64), fullcode);
|
||||
|
||||
uint8_t *bs = calloc(JABLOTRON_ARR_LEN, sizeof(uint8_t));
|
||||
if (bs == NULL) {
|
||||
|
@ -236,7 +295,7 @@ static int CmdJablotronSim(const char *Cmd) {
|
|||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"demod", CmdJablotronDemod, AlwaysAvailable, "Demodulate an Jablotron tag from the GraphBuffer"},
|
||||
{"read", CmdJablotronRead, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||
{"reader", CmdJablotronReader, IfPm3Lf, "Attempt to read and extract tag data from the antenna"},
|
||||
{"clone", CmdJablotronClone, IfPm3Lf, "clone jablotron tag to T55x7 or Q5/T5555"},
|
||||
{"sim", CmdJablotronSim, IfPm3Lf, "simulate jablotron tag"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
|
|
@ -175,7 +175,18 @@ int demodKeri(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdKeriDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf keri demod",
|
||||
"Try to find KERI preamble, if found decode / descramble data",
|
||||
"lf keri demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodKeri(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -116,9 +116,19 @@ int demodMotorola(bool verbose) {
|
|||
return PM3_SUCCESS;
|
||||
}
|
||||
|
||||
//see PSKDemod for what args are accepted
|
||||
static int CmdMotorolaDemod(const char *Cmd) {
|
||||
(void)Cmd;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf motorola demod",
|
||||
"Try to find Motorola preamble, if found decode / descramble data",
|
||||
"lf motorola demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodMotorola(true);
|
||||
}
|
||||
|
||||
|
@ -235,6 +245,19 @@ static int CmdMotorolaClone(const char *Cmd) {
|
|||
}
|
||||
|
||||
static int CmdMotorolaSim(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf motorola sim",
|
||||
"Enables simulation of Motorola card with specified card number.\n"
|
||||
"Simulation runs until the button is pressed or another USB command is issued.",
|
||||
"lf motorola sim"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
// PSK sim.
|
||||
PrintAndLogEx(INFO, " PSK1 at 66 kHz... Interesting.");
|
||||
|
|
|
@ -11,10 +11,8 @@
|
|||
|
||||
#define _GNU_SOURCE
|
||||
#include <string.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "cmdparser.h" // command_t
|
||||
#include "comms.h"
|
||||
#include "crc16.h"
|
||||
|
@ -24,6 +22,8 @@
|
|||
#include "cmdlf.h"
|
||||
#include "lfdemod.h"
|
||||
#include "protocols.h"
|
||||
#include "cliparser.h"
|
||||
#include "cmdlfem4x05.h" // EM defines
|
||||
|
||||
#define FIXED_71 0x71
|
||||
#define FIXED_40 0x40
|
||||
|
@ -262,7 +262,18 @@ int demodNedap(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdLFNedapDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf nedap demod",
|
||||
"Try to find Nedap preamble, if found decode / descramble data",
|
||||
"lf nedap demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodNedap(true);
|
||||
}
|
||||
/* Index map E E
|
||||
|
|
|
@ -217,14 +217,25 @@ int demodNexWatch(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdNexWatchDemod(const char *Cmd) {
|
||||
(void)Cmd;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf nexwatch demod",
|
||||
"Try to find Nexwatch preamble, if found decode / descramble data",
|
||||
"lf nexwatch demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodNexWatch(true);
|
||||
}
|
||||
|
||||
static int CmdNexWatchReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf nexwatch reader",
|
||||
"read a nexwatch tag",
|
||||
"read a Nexwatch tag",
|
||||
"lf nexwatch reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
|
|
|
@ -103,14 +103,25 @@ int demodNoralsy(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdNoralsyDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf noralsy demod",
|
||||
"Try to find Noralsy preamble, if found decode / descramble data",
|
||||
"lf noralsy demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodNoralsy(true);
|
||||
}
|
||||
|
||||
static int CmdNoralsyReader(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf noralsy reader",
|
||||
"read a noralsy tag",
|
||||
"read a Noralsy tag",
|
||||
"lf noralsy reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
|
@ -133,7 +144,7 @@ static int CmdNoralsyReader(const char *Cmd) {
|
|||
static int CmdNoralsyClone(const char *Cmd) {
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf noralsy clone",
|
||||
"clone a noralsy tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
||||
"clone a Noralsy tag to a T55x7, Q5/T5555 or EM4305/4469 tag.",
|
||||
"lf noralsy clone --cn 112233\n"
|
||||
"lf noralsy clone --cn 112233 --q5 -> encode for Q5/T5555 tag\n"
|
||||
"lf noralsy clone --cn 112233 --em -> encode for EM4305/4469"
|
||||
|
|
|
@ -157,7 +157,18 @@ int demodPac(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdPacDemod(const char *Cmd) {
|
||||
(void)Cmd;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf pac demod",
|
||||
"Try to find PAC/Stanley preamble, if found decode / descramble data",
|
||||
"lf pac demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodPac(true);
|
||||
}
|
||||
|
||||
|
@ -165,7 +176,7 @@ static int CmdPacReader(const char *Cmd) {
|
|||
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf pac reader",
|
||||
"read a pac tag",
|
||||
"read a PAC/Stanley tag",
|
||||
"lf pac reader -@ -> continuous reader mode"
|
||||
);
|
||||
|
||||
|
|
|
@ -170,7 +170,18 @@ int demodParadox(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdParadoxDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf paradox demod",
|
||||
"Try to find Paradox preamble, if found decode / descramble data",
|
||||
"lf paradox demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodParadox(true);
|
||||
}
|
||||
|
||||
|
@ -323,7 +334,8 @@ static int CmdParadoxSim(const char *Cmd) {
|
|||
if (resp.status != PM3_EOPABORTED)
|
||||
return resp.status;
|
||||
|
||||
return PM3_SUCCESS;}
|
||||
return PM3_SUCCESS;
|
||||
}
|
||||
/*
|
||||
|
||||
if (sscanf(Cmd, "%u %u", &fc, &cn) != 2) return usage_lf_paradox_sim();
|
||||
|
|
|
@ -112,7 +112,18 @@ int demodPresco(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdPrescoDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf presco demod",
|
||||
"Try to find presco preamble, if found decode / descramble data",
|
||||
"lf presco demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodPresco(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -178,7 +178,18 @@ int demodPyramid(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdPyramidDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf pyramid demod",
|
||||
"Try to find Farpoint/Pyramid preamble, if found decode / descramble data",
|
||||
"lf pyramid demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodPyramid(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -114,7 +114,18 @@ int demodSecurakey(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdSecurakeyDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf securakey demod",
|
||||
"Try to find Securakey preamble, if found decode / descramble data",
|
||||
"lf securakey demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodSecurakey(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -272,7 +272,18 @@ out:
|
|||
}
|
||||
|
||||
static int CmdTIDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf ti demod",
|
||||
"Try to find TI preamble, if found decode / descramble data",
|
||||
"lf ti demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodTI(true);
|
||||
}
|
||||
|
||||
|
@ -303,19 +314,43 @@ static int CmdTIReader(const char *Cmd) {
|
|||
|
||||
// write new data to a r/w TI tag
|
||||
static int CmdTIWrite(const char *Cmd) {
|
||||
int res = 0;
|
||||
uint64_t arg0, arg1, arg2;
|
||||
res = sscanf(Cmd, "%012" SCNx64 " %012" SCNx64 " %012" SCNx64 "", &arg0, &arg1, &arg2);
|
||||
|
||||
if (res == 2)
|
||||
arg2 = 0;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf ti write",
|
||||
"write to a r/w TI tag.",
|
||||
"lf ti write --raw 1122334455667788\n"
|
||||
"lf ti write --raw 1122334455667788 --crc 1122\n"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_str1("r", "raw", "<hex>", "raw hex data. 8 bytes max"),
|
||||
arg_str0(NULL, "crc", "<hex>", "optional - crc"),
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, false);
|
||||
|
||||
int raw_len = 0;
|
||||
uint8_t raw[8] = {0};
|
||||
CLIGetHexWithReturn(ctx, 1, raw, &raw_len);
|
||||
|
||||
int crc_len = 0;
|
||||
uint8_t crc[2] = {0};
|
||||
CLIGetHexWithReturn(ctx, 2, crc, &crc_len);
|
||||
CLIParserFree(ctx);
|
||||
|
||||
struct {
|
||||
uint32_t high;
|
||||
uint32_t low;
|
||||
uint16_t crc;
|
||||
} PACKED payload;
|
||||
|
||||
payload.high = bytes_to_num(raw, 4);
|
||||
payload.low = bytes_to_num(raw + 4, 4);
|
||||
payload.crc = bytes_to_num(crc, crc_len);
|
||||
|
||||
if (res < 2) {
|
||||
PrintAndLogEx(WARNING, "Please specify the data as two hex strings, optionally the CRC as a third");
|
||||
return PM3_EINVARG;
|
||||
}
|
||||
clearCommandBuffer();
|
||||
SendCommandMIX(CMD_LF_TI_WRITE, arg0, arg1, arg2, NULL, 0);
|
||||
SendCommandNG(CMD_LF_TI_WRITE, (uint8_t*)&payload, sizeof(payload));
|
||||
PrintAndLogEx(SUCCESS, "Done");
|
||||
PrintAndLogEx(HINT, "Hint: try " _YELLOW_("`lf ti reader`") " to verify");
|
||||
return PM3_SUCCESS;
|
||||
|
@ -323,7 +358,7 @@ static int CmdTIWrite(const char *Cmd) {
|
|||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, AlwaysAvailable, "This help"},
|
||||
{"demod", CmdTIDemod, AlwaysAvailable, "Demodulate raw bits for TI-type LF tag from the GraphBuffer"},
|
||||
{"demod", CmdTIDemod, AlwaysAvailable, "Demodulate raw bits for TI LF tag from the GraphBuffer"},
|
||||
{"reader", CmdTIReader, IfPm3Lf, "Read and decode a TI 134 kHz tag"},
|
||||
{"write", CmdTIWrite, IfPm3Lf, "Write new data to a r/w TI 134 kHz tag"},
|
||||
{NULL, NULL, NULL, NULL}
|
||||
|
|
|
@ -54,7 +54,18 @@ int demodViking(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdVikingDemod(const char *Cmd) {
|
||||
(void)Cmd;
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf viking demod",
|
||||
"Try to find Viking AM preamble, if found decode / descramble data",
|
||||
"lf viking demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodViking(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -133,7 +133,18 @@ int demodVisa2k(bool verbose) {
|
|||
}
|
||||
|
||||
static int CmdVisa2kDemod(const char *Cmd) {
|
||||
(void)Cmd; // Cmd is not used so far
|
||||
CLIParserContext *ctx;
|
||||
CLIParserInit(&ctx, "lf visa2000 demod",
|
||||
"Try to find visa2000 preamble, if found decode / descramble data",
|
||||
"lf visa2000 demod"
|
||||
);
|
||||
|
||||
void *argtable[] = {
|
||||
arg_param_begin,
|
||||
arg_param_end
|
||||
};
|
||||
CLIExecWithReturn(ctx, Cmd, argtable, true);
|
||||
CLIParserFree(ctx);
|
||||
return demodVisa2k(true);
|
||||
}
|
||||
|
||||
|
|
|
@ -502,8 +502,7 @@ SWIG_TypePrettyName(const swig_type_info *type) {
|
|||
for (s = type->str; *s; s++)
|
||||
if (*s == '|') last_name = s + 1;
|
||||
return last_name;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return type->name;
|
||||
}
|
||||
|
||||
|
@ -916,8 +915,7 @@ typedef struct swig_elua_entry {
|
|||
prefixed with the location of the innermost Lua call-point
|
||||
(as formatted by luaL_where). */
|
||||
SWIGRUNTIME void
|
||||
SWIG_Lua_pusherrstring (lua_State *L, const char *str)
|
||||
{
|
||||
SWIG_Lua_pusherrstring(lua_State *L, const char *str) {
|
||||
luaL_where(L, 1);
|
||||
lua_pushstring(L, str);
|
||||
lua_concat(L, 2);
|
||||
|
@ -927,8 +925,7 @@ SWIG_Lua_pusherrstring (lua_State *L, const char *str)
|
|||
the Lua stack, like lua_pushfstring, but prefixed with the
|
||||
location of the innermost Lua call-point (as formatted by luaL_where). */
|
||||
SWIGRUNTIME void
|
||||
SWIG_Lua_pushferrstring (lua_State *L, const char *fmt, ...)
|
||||
{
|
||||
SWIG_Lua_pushferrstring(lua_State *L, const char *fmt, ...) {
|
||||
va_list argp;
|
||||
va_start(argp, fmt);
|
||||
luaL_where(L, 1);
|
||||
|
@ -1106,8 +1103,7 @@ SWIG_Lua_SetModule(lua_State *L, swig_module_info *module) {
|
|||
/* this function is called when trying to set an immutable.
|
||||
default action is to print an error.
|
||||
This can removed with a compile flag SWIGLUA_IGNORE_SET_IMMUTABLE */
|
||||
SWIGINTERN int SWIG_Lua_set_immutable(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_set_immutable(lua_State *L) {
|
||||
/* there should be 1 param passed in: the new value */
|
||||
#ifndef SWIGLUA_IGNORE_SET_IMMUTABLE
|
||||
lua_pop(L, 1); /* remove it */
|
||||
|
@ -1123,8 +1119,7 @@ SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_t
|
|||
static int swig_lua_elua_emulate_unique_key;
|
||||
|
||||
/* This function emulates eLua rotables behaviour. It loads a rotable definition into the usual lua table. */
|
||||
SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_entry *table)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_entry *table) {
|
||||
int i, table_parsed, parsed_tables_array, target_table;
|
||||
assert(lua_istable(L, -1));
|
||||
target_table = lua_gettop(L);
|
||||
|
@ -1141,8 +1136,7 @@ SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_ent
|
|||
lua_rawsetp(L, parsed_tables_array, table);
|
||||
table_parsed = 0;
|
||||
const int SWIGUNUSED pairs_start = lua_gettop(L);
|
||||
for(i = 0;table[i].key.type != LUA_TNIL || table[i].value.type != LUA_TNIL;i++)
|
||||
{
|
||||
for (i = 0; table[i].key.type != LUA_TNIL || table[i].value.type != LUA_TNIL; i++) {
|
||||
const swig_elua_entry *entry = table + i;
|
||||
int is_metatable = 0;
|
||||
switch (entry->key.type) {
|
||||
|
@ -1207,16 +1201,14 @@ SWIGINTERN void SWIG_Lua_elua_emulate_register(lua_State *L, const swig_elua_ent
|
|||
assert(lua_gettop(L) == target_table);
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_Lua_elua_emulate_register_clear(lua_State *L)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_elua_emulate_register_clear(lua_State *L) {
|
||||
lua_pushnil(L);
|
||||
lua_rawsetp(L, LUA_REGISTRYINDEX, &swig_lua_elua_emulate_unique_key);
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L);
|
||||
|
||||
SWIGINTERN int SWIG_Lua_emulate_elua_getmetatable(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_emulate_elua_getmetatable(lua_State *L) {
|
||||
SWIG_check_num_args("getmetatable(SWIG eLua emulation)", 1, 1);
|
||||
SWIG_Lua_get_class_registry(L);
|
||||
lua_getfield(L, -1, "lua_getmetatable");
|
||||
|
@ -1241,8 +1233,7 @@ fail:
|
|||
return 0;
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_Lua_emulate_elua_swap_getmetatable(lua_State *L)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_emulate_elua_swap_getmetatable(lua_State *L) {
|
||||
SWIG_Lua_get_class_registry(L);
|
||||
lua_pushglobaltable(L);
|
||||
lua_pushstring(L, "lua_getmetatable");
|
||||
|
@ -1262,8 +1253,7 @@ SWIGINTERN void SWIG_Lua_emulate_elua_swap_getmetatable(lua_State *L)
|
|||
* global variable support code: namespaces and modules (which are the same thing)
|
||||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L) {
|
||||
/* there should be 2 params passed in
|
||||
(1) table (not the meta table)
|
||||
(2) string name of the attribute
|
||||
|
@ -1277,8 +1267,8 @@ SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
|||
lua_pushvalue(L, 2); /* key */
|
||||
lua_rawget(L, -2);
|
||||
lua_remove(L, -2); /* stack tidy, remove .get table */
|
||||
if (lua_iscfunction(L,-1))
|
||||
{ /* found it so call the fn & return its value */
|
||||
if (lua_iscfunction(L, -1)) {
|
||||
/* found it so call the fn & return its value */
|
||||
lua_call(L, 0, 1); /* 1 value in (userdata),1 out (result) */
|
||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||
return 1;
|
||||
|
@ -1290,8 +1280,8 @@ SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
|||
lua_pushvalue(L, 2); /* key */
|
||||
lua_rawget(L, -2); /* look for the fn */
|
||||
lua_remove(L, -2); /* stack tidy, remove .fn table */
|
||||
if (lua_isfunction(L,-1)) /* note: whether it's a C function or lua function */
|
||||
{ /* found it so return the fn & let lua call it */
|
||||
if (lua_isfunction(L, -1)) { /* note: whether it's a C function or lua function */
|
||||
/* found it so return the fn & let lua call it */
|
||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||
return 1;
|
||||
}
|
||||
|
@ -1299,8 +1289,7 @@ SWIGINTERN int SWIG_Lua_namespace_get(lua_State *L)
|
|||
return 0;
|
||||
}
|
||||
|
||||
SWIGINTERN int SWIG_Lua_namespace_set(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_namespace_set(lua_State *L) {
|
||||
/* there should be 3 params passed in
|
||||
(1) table (not the meta table)
|
||||
(2) string name of the attribute
|
||||
|
@ -1312,13 +1301,12 @@ SWIGINTERN int SWIG_Lua_namespace_set(lua_State *L)
|
|||
assert(lua_istable(L, -1));
|
||||
|
||||
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
if (lua_istable(L, -1)) {
|
||||
/* look for the key in the .set table */
|
||||
lua_pushvalue(L, 2); /* key */
|
||||
lua_rawget(L, -2);
|
||||
if (lua_iscfunction(L,-1))
|
||||
{ /* found it so call the fn & return its value */
|
||||
if (lua_iscfunction(L, -1)) {
|
||||
/* found it so call the fn & return its value */
|
||||
lua_pushvalue(L, 3); /* value */
|
||||
lua_call(L, 1, 0);
|
||||
return 0;
|
||||
|
@ -1337,8 +1325,7 @@ SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFuncti
|
|||
SWIGINTERN void SWIG_Lua_class_register(lua_State *L, swig_lua_class *clss);
|
||||
|
||||
/* helper function - register namespace methods and attributes into namespace */
|
||||
SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State *L, swig_lua_namespace *ns)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State *L, swig_lua_namespace *ns) {
|
||||
int i;
|
||||
/* There must be namespace table (not metatable) at the top of the stack */
|
||||
assert(lua_istable(L, -1));
|
||||
|
@ -1361,8 +1348,7 @@ SWIGINTERN int SWIG_Lua_add_namespace_details(lua_State *L, swig_lua_namespace *
|
|||
}
|
||||
|
||||
/* Register all classes in the namespace */
|
||||
SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State *L, swig_lua_namespace *ns)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State *L, swig_lua_namespace *ns) {
|
||||
swig_lua_class **classes;
|
||||
|
||||
/* There must be a module/namespace table at the top of the stack */
|
||||
|
@ -1383,8 +1369,7 @@ SWIGINTERN void SWIG_Lua_add_namespace_classes(lua_State *L, swig_lua_namespace
|
|||
when function is called).
|
||||
Function always returns newly registered table on top of the stack.
|
||||
*/
|
||||
SWIGINTERN void SWIG_Lua_namespace_register(lua_State *L, swig_lua_namespace *ns, int reg)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_namespace_register(lua_State *L, swig_lua_namespace *ns, int reg) {
|
||||
swig_lua_namespace **sub_namespace;
|
||||
/* 1 argument - table on the top of the stack */
|
||||
const int SWIGUNUSED begin = lua_gettop(L);
|
||||
|
@ -1444,8 +1429,7 @@ SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname);
|
|||
typedef int (*swig_lua_base_iterator_func)(lua_State *, swig_type_info *, int, int *ret);
|
||||
|
||||
SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info *SWIGUNUSED swig_type,
|
||||
int first_arg, swig_lua_base_iterator_func func, int *const ret)
|
||||
{
|
||||
int first_arg, swig_lua_base_iterator_func func, int *const ret) {
|
||||
/* first_arg - position of the object in stack. Everything that is above are arguments
|
||||
* and is passed to every evocation of the func */
|
||||
int last_arg = lua_gettop(L);/* position of last argument */
|
||||
|
@ -1476,8 +1460,7 @@ SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info * SWIGUNUSED
|
|||
|
||||
if (ret)
|
||||
*ret = 0;
|
||||
if(bases_count>0)
|
||||
{
|
||||
if (bases_count > 0) {
|
||||
int to_remove;
|
||||
size_t i;
|
||||
int j;
|
||||
|
@ -1543,8 +1526,7 @@ SWIGINTERN int SWIG_Lua_iterate_bases(lua_State *L, swig_type_info * SWIGUNUSED
|
|||
* It returns an error code. Number of function return values is passed inside 'ret'.
|
||||
* first_arg is not used in this function because function always has 2 arguments.
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret) {
|
||||
/* there should be 2 params passed in
|
||||
(1) userdata (not the meta table)
|
||||
(2) string name of the attribute
|
||||
|
@ -1559,8 +1541,8 @@ SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, i
|
|||
/* NEW: looks for the __getitem() fn
|
||||
this is a user provided get fn */
|
||||
SWIG_Lua_get_table(L, "__getitem"); /* find the __getitem fn */
|
||||
if (lua_iscfunction(L,-1)) /* if its there */
|
||||
{ /* found it so call the fn & return its value */
|
||||
if (lua_iscfunction(L, -1)) { /* if its there */
|
||||
/* found it so call the fn & return its value */
|
||||
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
||||
lua_pushvalue(L, substack_start + 2); /* the parameter */
|
||||
lua_call(L, 2, 1); /* 2 value in (userdata),1 out (result) */
|
||||
|
@ -1581,8 +1563,7 @@ SWIGINTERN int SWIG_Lua_class_do_get_item(lua_State *L, swig_type_info *type, i
|
|||
* It returns an error code. Number of function return values is passed inside 'ret'.
|
||||
* first_arg is not used in this function because function always has 2 arguments.
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SWIGUNUSED first_arg, int *ret) {
|
||||
/* there should be 2 params passed in
|
||||
(1) userdata (not the meta table)
|
||||
(2) string name of the attribute
|
||||
|
@ -1600,8 +1581,8 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW
|
|||
lua_pushvalue(L, substack_start + 2); /* key */
|
||||
lua_rawget(L, -2);
|
||||
lua_remove(L, -2); /* stack tidy, remove .get table */
|
||||
if (lua_iscfunction(L,-1))
|
||||
{ /* found it so call the fn & return its value */
|
||||
if (lua_iscfunction(L, -1)) {
|
||||
/* found it so call the fn & return its value */
|
||||
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
||||
lua_call(L, 1, 1); /* 1 value in (userdata),1 out (result) */
|
||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||
|
@ -1616,8 +1597,8 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW
|
|||
lua_pushvalue(L, substack_start + 2); /* key */
|
||||
lua_rawget(L, -2); /* look for the fn */
|
||||
lua_remove(L, -2); /* stack tidy, remove .fn table */
|
||||
if (lua_isfunction(L,-1)) /* note: if its a C function or lua function */
|
||||
{ /* found it so return the fn & let lua call it */
|
||||
if (lua_isfunction(L, -1)) { /* note: if its a C function or lua function */
|
||||
/* found it so return the fn & let lua call it */
|
||||
lua_remove(L, -2); /* stack tidy, remove metatable */
|
||||
if (ret)
|
||||
*ret = 1;
|
||||
|
@ -1633,8 +1614,7 @@ SWIGINTERN int SWIG_Lua_class_do_get(lua_State *L, swig_type_info *type, int SW
|
|||
|
||||
/* the class.get method, performs the lookup of class attributes
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_get(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_get(lua_State *L) {
|
||||
/* there should be 2 params passed in
|
||||
(1) userdata (not the meta table)
|
||||
(2) string name of the attribute
|
||||
|
@ -1660,8 +1640,7 @@ SWIGINTERN int SWIG_Lua_class_get(lua_State *L)
|
|||
/* helper for the class.set method, performs the lookup of class attributes
|
||||
* It returns error code. Number of function return values is passed inside 'ret'
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int first_arg, int *ret)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int first_arg, int *ret) {
|
||||
/* there should be 3 params passed in
|
||||
(1) table (not the meta table)
|
||||
(2) string name of the attribute
|
||||
|
@ -1678,14 +1657,13 @@ SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int fi
|
|||
*ret = 0; /* it is setter - number of return values is always 0 */
|
||||
|
||||
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
if (lua_istable(L, -1)) {
|
||||
/* look for the key in the .set table */
|
||||
lua_pushvalue(L, substack_start + 2); /* key */
|
||||
lua_rawget(L, -2);
|
||||
lua_remove(L, -2); /* tidy stack, remove .set table */
|
||||
if (lua_iscfunction(L,-1))
|
||||
{ /* found it so call the fn & return its value */
|
||||
if (lua_iscfunction(L, -1)) {
|
||||
/* found it so call the fn & return its value */
|
||||
lua_pushvalue(L, substack_start + 1); /* userdata */
|
||||
lua_pushvalue(L, substack_start + 3); /* value */
|
||||
lua_call(L, 2, 0);
|
||||
|
@ -1699,8 +1677,8 @@ SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int fi
|
|||
/* NEW: looks for the __setitem() fn
|
||||
this is a user provided set fn */
|
||||
SWIG_Lua_get_table(L, "__setitem"); /* find the fn */
|
||||
if (lua_iscfunction(L,-1)) /* if its there */
|
||||
{ /* found it so call the fn & return its value */
|
||||
if (lua_iscfunction(L, -1)) { /* if its there */
|
||||
/* found it so call the fn & return its value */
|
||||
lua_pushvalue(L, substack_start + 1); /* the userdata */
|
||||
lua_pushvalue(L, substack_start + 2); /* the parameter */
|
||||
lua_pushvalue(L, substack_start + 3); /* the value */
|
||||
|
@ -1722,8 +1700,7 @@ SWIGINTERN int SWIG_Lua_class_do_set(lua_State *L, swig_type_info *type, int fi
|
|||
/* This is the actual method exported to Lua. It calls SWIG_Lua_class_do_set and correctly
|
||||
* handles return values.
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_class_set(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_set(lua_State *L) {
|
||||
/* There should be 3 params passed in
|
||||
(1) table (not the meta table)
|
||||
(2) string name of the attribute
|
||||
|
@ -1747,8 +1724,7 @@ SWIGINTERN int SWIG_Lua_class_set(lua_State *L)
|
|||
}
|
||||
|
||||
/* the class.destruct method called by the interpreter */
|
||||
SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L) {
|
||||
/* there should be 1 params passed in
|
||||
(1) userdata (not the meta table) */
|
||||
swig_lua_userdata *usr;
|
||||
|
@ -1756,11 +1732,9 @@ SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L)
|
|||
assert(lua_isuserdata(L, -1)); /* just in case */
|
||||
usr = (swig_lua_userdata *)lua_touserdata(L, -1); /* get it */
|
||||
/* if must be destroyed & has a destructor */
|
||||
if (usr->own) /* if must be destroyed */
|
||||
{
|
||||
if (usr->own) { /* if must be destroyed */
|
||||
clss = (swig_lua_class *)usr->type->clientdata; /* get the class */
|
||||
if (clss && clss->destructor) /* there is a destroy fn */
|
||||
{
|
||||
if (clss && clss->destructor) { /* there is a destroy fn */
|
||||
clss->destructor(usr->ptr); /* bye bye */
|
||||
}
|
||||
}
|
||||
|
@ -1768,8 +1742,7 @@ SWIGINTERN int SWIG_Lua_class_destruct(lua_State *L)
|
|||
}
|
||||
|
||||
/* the class.__tostring method called by the interpreter and print */
|
||||
SWIGINTERN int SWIG_Lua_class_tostring(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_tostring(lua_State *L) {
|
||||
/* there should be 1 param passed in
|
||||
(1) userdata (not the metatable) */
|
||||
swig_lua_userdata *userData;
|
||||
|
@ -1781,8 +1754,7 @@ SWIGINTERN int SWIG_Lua_class_tostring(lua_State *L)
|
|||
}
|
||||
|
||||
/* to manually disown some userdata */
|
||||
SWIGINTERN int SWIG_Lua_class_disown(lua_State *L)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_class_disown(lua_State *L) {
|
||||
/* there should be 1 params passed in
|
||||
(1) userdata (not the meta table) */
|
||||
swig_lua_userdata *usr;
|
||||
|
@ -1796,8 +1768,7 @@ SWIGINTERN int SWIG_Lua_class_disown(lua_State *L)
|
|||
/* lua callable function to compare userdata's value
|
||||
the issue is that two userdata may point to the same thing
|
||||
but to lua, they are different objects */
|
||||
SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L)
|
||||
{
|
||||
SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L) {
|
||||
int result;
|
||||
swig_lua_userdata *usr1, *usr2;
|
||||
if (!lua_isuserdata(L, 1) || !lua_isuserdata(L, 2)) /* just in case */
|
||||
|
@ -1811,8 +1782,7 @@ SWIGRUNTIME int SWIG_Lua_class_equal(lua_State *L)
|
|||
}
|
||||
|
||||
/* populate table at the top of the stack with metamethods that ought to be inherited */
|
||||
SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L) {
|
||||
SWIG_Lua_add_boolean(L, "__add", 1);
|
||||
SWIG_Lua_add_boolean(L, "__sub", 1);
|
||||
SWIG_Lua_add_boolean(L, "__mul", 1);
|
||||
|
@ -1831,8 +1801,7 @@ SWIGINTERN void SWIG_Lua_populate_inheritable_metamethods(lua_State *L)
|
|||
}
|
||||
|
||||
/* creates the swig registry */
|
||||
SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L) {
|
||||
/* create main SWIG registry table */
|
||||
lua_pushstring(L, "SWIG");
|
||||
lua_newtable(L);
|
||||
|
@ -1855,13 +1824,12 @@ SWIGINTERN void SWIG_Lua_create_class_registry(lua_State *L)
|
|||
}
|
||||
|
||||
/* gets the swig registry (or creates it) */
|
||||
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L) {
|
||||
/* add this all into the swig registry: */
|
||||
lua_pushstring(L, "SWIG");
|
||||
lua_rawget(L, LUA_REGISTRYINDEX); /* get the registry */
|
||||
if (!lua_istable(L,-1)) /* not there */
|
||||
{ /* must be first time, so add it */
|
||||
if (!lua_istable(L, -1)) { /* not there */
|
||||
/* must be first time, so add it */
|
||||
lua_pop(L, 1); /* remove the result */
|
||||
SWIG_Lua_create_class_registry(L);
|
||||
/* then get it */
|
||||
|
@ -1870,8 +1838,7 @@ SWIGINTERN void SWIG_Lua_get_class_registry(lua_State *L)
|
|||
}
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L) {
|
||||
SWIG_Lua_get_class_registry(L);
|
||||
lua_pushstring(L, ".library");
|
||||
lua_rawget(L, -2);
|
||||
|
@ -1885,8 +1852,7 @@ SWIGINTERN void SWIG_Lua_get_inheritable_metamethods(lua_State *L)
|
|||
}
|
||||
|
||||
/* Helper function to get the classes metatable from the register */
|
||||
SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L,const char *cname)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_get_class_metatable(lua_State *L, const char *cname) {
|
||||
SWIG_Lua_get_class_registry(L); /* get the registry */
|
||||
lua_pushstring(L, cname); /* get the name */
|
||||
lua_rawget(L, -2); /* get it */
|
||||
|
@ -1900,14 +1866,11 @@ It cannot be done at compile time, as this will not work with hireachies
|
|||
spread over more than one swig file.
|
||||
Therefore it must be done at runtime, querying the SWIG type system.
|
||||
*/
|
||||
SWIGINTERN void SWIG_Lua_init_base_class(lua_State *L,swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_init_base_class(lua_State *L, swig_lua_class *clss) {
|
||||
int i = 0;
|
||||
swig_module_info *module = SWIG_GetModule(L);
|
||||
for(i=0;clss->base_names[i];i++)
|
||||
{
|
||||
if (clss->bases[i]==0) /* not found yet */
|
||||
{
|
||||
for (i = 0; clss->base_names[i]; i++) {
|
||||
if (clss->bases[i] == 0) { /* not found yet */
|
||||
/* lookup and cache the base class */
|
||||
swig_type_info *info = SWIG_TypeQueryModule(module, module, clss->base_names[i]);
|
||||
if (info) clss->bases[i] = (swig_lua_class *) info->clientdata;
|
||||
|
@ -1917,8 +1880,7 @@ SWIGINTERN void SWIG_Lua_init_base_class(lua_State *L,swig_lua_class *clss)
|
|||
|
||||
#if defined(SWIG_LUA_SQUASH_BASES) && (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA)
|
||||
/* Merges two tables */
|
||||
SWIGINTERN void SWIG_Lua_merge_tables_by_index(lua_State *L, int target, int source)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_merge_tables_by_index(lua_State *L, int target, int source) {
|
||||
/* iterating */
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, source) != 0) {
|
||||
|
@ -1933,8 +1895,7 @@ SWIGINTERN void SWIG_Lua_merge_tables_by_index(lua_State *L, int target, int sou
|
|||
}
|
||||
|
||||
/* Merges two tables with given name. original - index of target metatable, base - index of source metatable */
|
||||
SWIGINTERN void SWIG_Lua_merge_tables(lua_State *L, const char* name, int original, int base)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_merge_tables(lua_State *L, const char *name, int original, int base) {
|
||||
/* push original[name], then base[name] */
|
||||
lua_pushstring(L, name);
|
||||
lua_rawget(L, original);
|
||||
|
@ -1948,8 +1909,7 @@ SWIGINTERN void SWIG_Lua_merge_tables(lua_State *L, const char* name, int origin
|
|||
}
|
||||
|
||||
/* Function takes all symbols from base and adds it to derived class. It's just a helper. */
|
||||
SWIGINTERN void SWIG_Lua_class_squash_base(lua_State *L, swig_lua_class *base_cls)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_class_squash_base(lua_State *L, swig_lua_class *base_cls) {
|
||||
/* There is one parameter - original, i.e. 'derived' class metatable */
|
||||
assert(lua_istable(L, -1));
|
||||
int original = lua_gettop(L);
|
||||
|
@ -1962,12 +1922,10 @@ SWIGINTERN void SWIG_Lua_class_squash_base(lua_State *L, swig_lua_class *base_cl
|
|||
}
|
||||
|
||||
/* Function squashes all symbols from 'clss' bases into itself */
|
||||
SWIGINTERN void SWIG_Lua_class_squash_bases(lua_State *L, swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_class_squash_bases(lua_State *L, swig_lua_class *clss) {
|
||||
int i;
|
||||
SWIG_Lua_get_class_metatable(L, clss->fqname);
|
||||
for(i=0;clss->base_names[i];i++)
|
||||
{
|
||||
for (i = 0; clss->base_names[i]; i++) {
|
||||
if (clss->bases[i] == 0) /* Somehow it's not found. Skip it */
|
||||
continue;
|
||||
/* Thing is: all bases are already registered. Thus they have already executed
|
||||
|
@ -1982,15 +1940,13 @@ SWIGINTERN void SWIG_Lua_class_squash_bases(lua_State *L, swig_lua_class *clss)
|
|||
|
||||
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA) /* In elua this is useless */
|
||||
/* helper add a variable to a registered class */
|
||||
SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFunction getFn,lua_CFunction setFn)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_add_variable(lua_State *L, const char *name, lua_CFunction getFn, lua_CFunction setFn) {
|
||||
assert(lua_istable(L, -1)); /* just in case */
|
||||
SWIG_Lua_get_table(L, ".get"); /* find the .get table */
|
||||
assert(lua_istable(L, -1)); /* just in case */
|
||||
SWIG_Lua_add_function(L, name, getFn);
|
||||
lua_pop(L, 1); /* tidy stack (remove table) */
|
||||
if (setFn)
|
||||
{
|
||||
if (setFn) {
|
||||
SWIG_Lua_get_table(L, ".set"); /* find the .set table */
|
||||
assert(lua_istable(L, -1)); /* just in case */
|
||||
SWIG_Lua_add_function(L, name, setFn);
|
||||
|
@ -1999,14 +1955,12 @@ SWIGINTERN void SWIG_Lua_add_variable(lua_State *L,const char *name,lua_CFuncti
|
|||
}
|
||||
|
||||
/* helper to recursively add class static details (static attributes, operations and constants) */
|
||||
SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *clss) {
|
||||
int i = 0;
|
||||
/* The class namespace table must be on the top of the stack */
|
||||
assert(lua_istable(L, -1));
|
||||
/* call all the base classes first: we can then override these later: */
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
for (i = 0; clss->bases[i]; i++) {
|
||||
SWIG_Lua_add_class_static_details(L, clss->bases[i]);
|
||||
}
|
||||
|
||||
|
@ -2016,15 +1970,13 @@ SWIGINTERN void SWIG_Lua_add_class_static_details(lua_State *L, swig_lua_class *
|
|||
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss); /* forward declaration */
|
||||
|
||||
/* helper to recursively add class details (attributes & operations) */
|
||||
SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_add_class_instance_details(lua_State *L, swig_lua_class *clss) {
|
||||
int i;
|
||||
size_t bases_count = 0;
|
||||
/* Add bases to .bases table */
|
||||
SWIG_Lua_get_table(L, ".bases");
|
||||
assert(lua_istable(L, -1)); /* just in case */
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
for (i = 0; clss->bases[i]; i++) {
|
||||
SWIG_Lua_get_class_metatable(L, clss->bases[i]->fqname);
|
||||
/* Base class must be already registered */
|
||||
assert(lua_istable(L, -1));
|
||||
|
@ -2088,8 +2040,7 @@ SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L); /*forward declaration
|
|||
* SWIG_Lua_resolve_metamethod
|
||||
* */
|
||||
SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class *clss, int metamethod_name_idx,
|
||||
int skip_check)
|
||||
{
|
||||
int skip_check) {
|
||||
/* This function is called recursively */
|
||||
int result = 0;
|
||||
int i = 0;
|
||||
|
@ -2110,8 +2061,7 @@ SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class
|
|||
}
|
||||
|
||||
/* Forwarding calls to bases */
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
for (i = 0; clss->bases[i]; i++) {
|
||||
result = SWIG_Lua_do_resolve_metamethod(L, clss->bases[i], metamethod_name_idx, 0);
|
||||
if (result)
|
||||
break;
|
||||
|
@ -2122,8 +2072,7 @@ SWIGINTERN int SWIG_Lua_do_resolve_metamethod(lua_State *L, const swig_lua_class
|
|||
|
||||
/* The proxy function for metamethod. All parameters are passed as cclosure. Searches for actual method
|
||||
* and calls it */
|
||||
SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L)
|
||||
{
|
||||
SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L) {
|
||||
int numargs;
|
||||
int metamethod_name_idx;
|
||||
const swig_lua_class *clss;
|
||||
|
@ -2159,8 +2108,7 @@ SWIGRUNTIME int SWIG_Lua_resolve_metamethod(lua_State *L)
|
|||
* Returns 1 if successfully added, 0 if not added because no base class has it, -1
|
||||
* if method is defined in the class metatable itself
|
||||
*/
|
||||
SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *clss, const int metatable_index)
|
||||
{
|
||||
SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *clss, const int metatable_index) {
|
||||
int key_index;
|
||||
int success = 0;
|
||||
int i = 0;
|
||||
|
@ -2180,8 +2128,7 @@ SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *
|
|||
lua_pop(L, 1);
|
||||
|
||||
/* Iterating over immediate bases */
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
for (i = 0; clss->bases[i]; i++) {
|
||||
const swig_lua_class *base = clss->bases[i];
|
||||
SWIG_Lua_get_class_metatable(L, base->fqname);
|
||||
lua_pushvalue(L, key_index);
|
||||
|
@ -2207,8 +2154,7 @@ SWIGINTERN int SWIG_Lua_add_class_user_metamethod(lua_State *L, swig_lua_class *
|
|||
return success;
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class *clss) {
|
||||
int metatable_index;
|
||||
int metamethods_info_index;
|
||||
int tostring_undefined;
|
||||
|
@ -2264,8 +2210,7 @@ SWIGINTERN void SWIG_Lua_add_class_user_metamethods(lua_State *L, swig_lua_class
|
|||
}
|
||||
|
||||
/* Register class static methods,attributes etc as well as constructor proxy */
|
||||
SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *clss) {
|
||||
const int SWIGUNUSED begin = lua_gettop(L);
|
||||
lua_checkstack(L, 5); /* just in case */
|
||||
assert(lua_istable(L, -1)); /* just in case */
|
||||
|
@ -2279,8 +2224,7 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *cls
|
|||
so you can do MyClass(...) as well as new_MyClass(...)
|
||||
BUT only if a constructor is defined
|
||||
(this overcomes the problem of pure virtual classes without constructors)*/
|
||||
if (clss->constructor)
|
||||
{
|
||||
if (clss->constructor) {
|
||||
lua_getmetatable(L, -1);
|
||||
assert(lua_istable(L, -1)); /* just in case */
|
||||
SWIG_Lua_add_function(L, "__call", clss->constructor);
|
||||
|
@ -2298,8 +2242,7 @@ SWIGINTERN void SWIG_Lua_class_register_static(lua_State *L, swig_lua_class *cls
|
|||
/* Performs the instance (non-static) class registration process. Metatable for class is created
|
||||
* and added to the class registry.
|
||||
*/
|
||||
SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L, swig_lua_class *clss) {
|
||||
const int SWIGUNUSED begin = lua_gettop(L);
|
||||
int i;
|
||||
/* if name already there (class is already registered) then do nothing */
|
||||
|
@ -2313,8 +2256,7 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *c
|
|||
}
|
||||
lua_pop(L, 2); /* tidy stack */
|
||||
/* Recursively initialize all bases */
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
for (i = 0; clss->bases[i]; i++) {
|
||||
SWIG_Lua_class_register_instance(L, clss->bases[i]);
|
||||
}
|
||||
/* Again, get registry and push name */
|
||||
|
@ -2328,8 +2270,7 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *c
|
|||
*/
|
||||
{
|
||||
int new_metatable_index = lua_absindex(L, -1);
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
for (i = 0; clss->bases[i]; i++) {
|
||||
int base_metatable;
|
||||
SWIG_Lua_get_class_metatable(L, clss->bases[i]->fqname);
|
||||
base_metatable = lua_absindex(L, -1);
|
||||
|
@ -2380,8 +2321,7 @@ SWIGINTERN void SWIG_Lua_class_register_instance(lua_State *L,swig_lua_class *c
|
|||
assert(lua_gettop(L) == begin);
|
||||
}
|
||||
|
||||
SWIGINTERN void SWIG_Lua_class_register(lua_State *L,swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_class_register(lua_State *L, swig_lua_class *clss) {
|
||||
int SWIGUNUSED begin;
|
||||
assert(lua_istable(L, -1)); /* This is a table (module or namespace) where classes will be added */
|
||||
SWIG_Lua_class_register_instance(L, clss);
|
||||
|
@ -2418,8 +2358,7 @@ SWIGINTERN void SWIG_Lua_class_register(lua_State *L,swig_lua_class *clss)
|
|||
#endif /* SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_LUA */
|
||||
|
||||
#if (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUA) || (SWIG_LUA_TARGET == SWIG_LUA_FLAVOR_ELUAC)
|
||||
SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_class *clss)
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_class *clss) {
|
||||
const int SWIGUNUSED begin = lua_gettop(L);
|
||||
int i;
|
||||
/* if name already there (class is already registered) then do nothing */
|
||||
|
@ -2433,8 +2372,7 @@ SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_cla
|
|||
}
|
||||
lua_pop(L, 2); /* tidy stack */
|
||||
/* Recursively initialize all bases */
|
||||
for(i=0;clss->bases[i];i++)
|
||||
{
|
||||
for (i = 0; clss->bases[i]; i++) {
|
||||
SWIG_Lua_elua_class_register_instance(L, clss->bases[i]);
|
||||
}
|
||||
/* Again, get registry and push name */
|
||||
|
@ -2453,25 +2391,19 @@ SWIGINTERN void SWIG_Lua_elua_class_register_instance(lua_State *L, swig_lua_cla
|
|||
* ----------------------------------------------------------------------------- */
|
||||
|
||||
/* helper to add metatable to new lua object */
|
||||
SWIGINTERN void SWIG_Lua_AddMetatable(lua_State *L,swig_type_info *type)
|
||||
{
|
||||
if (type->clientdata) /* there is clientdata: so add the metatable */
|
||||
{
|
||||
SWIGINTERN void SWIG_Lua_AddMetatable(lua_State *L, swig_type_info *type) {
|
||||
if (type->clientdata) { /* there is clientdata: so add the metatable */
|
||||
SWIG_Lua_get_class_metatable(L, ((swig_lua_class *)(type->clientdata))->fqname);
|
||||
if (lua_istable(L,-1))
|
||||
{
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_setmetatable(L, -2);
|
||||
}
|
||||
else
|
||||
{
|
||||
} else {
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* pushes a new object into the lua stack */
|
||||
SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *type, int own)
|
||||
{
|
||||
SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L, void *ptr, swig_type_info *type, int own) {
|
||||
swig_lua_userdata *usr;
|
||||
if (!ptr) {
|
||||
lua_pushnil(L);
|
||||
|
@ -2488,31 +2420,25 @@ SWIGRUNTIME void SWIG_Lua_NewPointerObj(lua_State *L,void *ptr,swig_type_info *t
|
|||
|
||||
/* takes a object from the lua stack & converts it into an object of the correct type
|
||||
(if possible) */
|
||||
SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L,int index,void **ptr,swig_type_info *type,int flags)
|
||||
{
|
||||
SWIGRUNTIME int SWIG_Lua_ConvertPtr(lua_State *L, int index, void **ptr, swig_type_info *type, int flags) {
|
||||
swig_lua_userdata *usr;
|
||||
swig_cast_info *cast;
|
||||
/* special case: lua nil => NULL pointer */
|
||||
if (lua_isnil(L,index))
|
||||
{
|
||||
if (lua_isnil(L, index)) {
|
||||
*ptr = 0;
|
||||
return (flags & SWIG_POINTER_NO_NULL) ? SWIG_NullReferenceError : SWIG_OK;
|
||||
}
|
||||
usr = (swig_lua_userdata *)lua_touserdata(L, index); /* get data */
|
||||
if (usr)
|
||||
{
|
||||
if (flags & SWIG_POINTER_DISOWN) /* must disown the object */
|
||||
{
|
||||
if (usr) {
|
||||
if (flags & SWIG_POINTER_DISOWN) { /* must disown the object */
|
||||
usr->own = 0;
|
||||
}
|
||||
if (!type) /* special cast void*, no casting fn */
|
||||
{
|
||||
if (!type) { /* special cast void*, no casting fn */
|
||||
*ptr = usr->ptr;
|
||||
return SWIG_OK; /* ok */
|
||||
}
|
||||
cast = SWIG_TypeCheckStruct(usr->type, type); /* performs normal type checking */
|
||||
if (cast)
|
||||
{
|
||||
if (cast) {
|
||||
int newmemory = 0;
|
||||
*ptr = SWIG_TypeCast(cast, usr->ptr, &newmemory);
|
||||
assert(!newmemory); /* newmemory handling not yet implemented */
|
||||
|
@ -2533,8 +2459,7 @@ SWIGRUNTIME void* SWIG_Lua_MustGetPtr(lua_State *L,int index,swig_type_info *typ
|
|||
}
|
||||
|
||||
/* pushes a packed userdata. user for member fn pointers only */
|
||||
SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_type_info *type)
|
||||
{
|
||||
SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L, void *ptr, size_t size, swig_type_info *type) {
|
||||
swig_lua_rawdata *raw;
|
||||
assert(ptr); /* not acceptable to pass in a NULL value */
|
||||
raw = (swig_lua_rawdata *)lua_newuserdata(L, sizeof(swig_lua_rawdata) - 1 + size); /* alloc data */
|
||||
|
@ -2545,13 +2470,11 @@ SWIGRUNTIME void SWIG_Lua_NewPackedObj(lua_State *L,void *ptr,size_t size,swig_t
|
|||
}
|
||||
|
||||
/* converts a packed userdata. user for member fn pointers only */
|
||||
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State *L,int index,void *ptr,size_t size,swig_type_info *type)
|
||||
{
|
||||
SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State *L, int index, void *ptr, size_t size, swig_type_info *type) {
|
||||
swig_lua_rawdata *raw;
|
||||
raw = (swig_lua_rawdata *)lua_touserdata(L, index); /* get data */
|
||||
if (!raw) return SWIG_ERROR; /* error */
|
||||
if (type==0 || type==raw->type) /* void* or identical type */
|
||||
{
|
||||
if (type == 0 || type == raw->type) { /* void* or identical type */
|
||||
memcpy(ptr, raw->data, size); /* copy it */
|
||||
return SWIG_OK; /* ok */
|
||||
}
|
||||
|
@ -2559,11 +2482,9 @@ SWIGRUNTIME int SWIG_Lua_ConvertPacked(lua_State *L,int index,void *ptr,size_t
|
|||
}
|
||||
|
||||
/* a function to get the typestring of a piece of data */
|
||||
SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp)
|
||||
{
|
||||
SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp) {
|
||||
swig_lua_userdata *usr;
|
||||
if (lua_isuserdata(L,tp))
|
||||
{
|
||||
if (lua_isuserdata(L, tp)) {
|
||||
usr = (swig_lua_userdata *)lua_touserdata(L, tp); /* get data */
|
||||
if (usr && usr->type && usr->type->str)
|
||||
return usr->type->str;
|
||||
|
@ -2573,8 +2494,7 @@ SWIGRUNTIME const char *SWIG_Lua_typename(lua_State *L, int tp)
|
|||
}
|
||||
|
||||
/* lua callable function to get the userdata's type */
|
||||
SWIGRUNTIME int SWIG_Lua_type(lua_State *L)
|
||||
{
|
||||
SWIGRUNTIME int SWIG_Lua_type(lua_State *L) {
|
||||
lua_pushstring(L, SWIG_Lua_typename(L, 1));
|
||||
return 1;
|
||||
}
|
||||
|
@ -2723,7 +2643,8 @@ static int _wrap_new_pm3__SWIG_0(lua_State* L) {
|
|||
|
||||
SWIG_check_num_args("pm3::pm3", 0, 0)
|
||||
result = (pm3 *)new_pm3__SWIG_0();
|
||||
SWIG_NewPointerObj(L,result,SWIGTYPE_p_pm3,1); SWIG_arg++;
|
||||
SWIG_NewPointerObj(L, result, SWIGTYPE_p_pm3, 1);
|
||||
SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
||||
if (0) SWIG_fail;
|
||||
|
@ -2743,7 +2664,8 @@ static int _wrap_new_pm3__SWIG_1(lua_State* L) {
|
|||
if (!SWIG_lua_isnilstring(L, 1)) SWIG_fail_arg("pm3::pm3", 1, "char *");
|
||||
arg1 = (char *)lua_tostring(L, 1);
|
||||
result = (pm3 *)new_pm3__SWIG_1(arg1);
|
||||
SWIG_NewPointerObj(L,result,SWIGTYPE_p_pm3,1); SWIG_arg++;
|
||||
SWIG_NewPointerObj(L, result, SWIGTYPE_p_pm3, 1);
|
||||
SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
||||
if (0) SWIG_fail;
|
||||
|
@ -2778,7 +2700,8 @@ static int _wrap_new_pm3(lua_State* L) {
|
|||
" Possible C/C++ prototypes are:\n"
|
||||
" pm3::pm3()\n"
|
||||
" pm3::pm3(char *)\n");
|
||||
lua_error(L);return 0;
|
||||
lua_error(L);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
@ -2798,7 +2721,8 @@ static int _wrap_pm3_console(lua_State* L) {
|
|||
|
||||
arg2 = (char *)lua_tostring(L, 2);
|
||||
result = (int)pm3_console(arg1, arg2);
|
||||
lua_pushnumber(L, (lua_Number) result); SWIG_arg++;
|
||||
lua_pushnumber(L, (lua_Number) result);
|
||||
SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
||||
if (0) SWIG_fail;
|
||||
|
@ -2822,7 +2746,8 @@ static int _wrap_pm3_name_get(lua_State* L) {
|
|||
}
|
||||
|
||||
result = (char *)pm3_name_get(arg1);
|
||||
lua_pushstring(L,(const char *)result); SWIG_arg++;
|
||||
lua_pushstring(L, (const char *)result);
|
||||
SWIG_arg++;
|
||||
return SWIG_arg;
|
||||
|
||||
if (0) SWIG_fail;
|
||||
|
@ -3154,7 +3079,8 @@ SWIG_PropagateClientData(void) {
|
|||
|
||||
#ifdef __cplusplus
|
||||
#if 0
|
||||
{ /* c-mode */
|
||||
{
|
||||
/* c-mode */
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
@ -3251,8 +3177,7 @@ SWIGEXPORT int SWIG_init(lua_State* L) /* default Lua action */
|
|||
const char *SWIG_LUACODE =
|
||||
"";
|
||||
|
||||
void SWIG_init_user(lua_State* L)
|
||||
{
|
||||
void SWIG_init_user(lua_State *L) {
|
||||
/* exec Lua code if applicable */
|
||||
SWIG_Lua_dostring(L, SWIG_LUACODE);
|
||||
}
|
||||
|
|
|
@ -516,8 +516,7 @@ SWIG_TypePrettyName(const swig_type_info *type) {
|
|||
for (s = type->str; *s; s++)
|
||||
if (*s == '|') last_name = s + 1;
|
||||
return last_name;
|
||||
}
|
||||
else
|
||||
} else
|
||||
return type->name;
|
||||
}
|
||||
|
||||
|
@ -782,8 +781,7 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
|
|||
* so please call SWIG_Python_str_DelForPy3(x) to free the space.
|
||||
*/
|
||||
SWIGINTERN char *
|
||||
SWIG_Python_str_AsChar(PyObject *str)
|
||||
{
|
||||
SWIG_Python_str_AsChar(PyObject *str) {
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
char *newstr = 0;
|
||||
str = PyUnicode_AsUTF8String(str);
|
||||
|
@ -809,8 +807,7 @@ SWIG_Python_str_AsChar(PyObject *str)
|
|||
|
||||
|
||||
SWIGINTERN PyObject *
|
||||
SWIG_Python_str_FromChar(const char *c)
|
||||
{
|
||||
SWIG_Python_str_FromChar(const char *c) {
|
||||
#if PY_VERSION_HEX >= 0x03000000
|
||||
return PyUnicode_FromString(c);
|
||||
#else
|
||||
|
@ -882,8 +879,7 @@ SWIG_Python_ErrorType(int code) {
|
|||
|
||||
|
||||
SWIGRUNTIME void
|
||||
SWIG_Python_AddErrorMsg(const char* mesg)
|
||||
{
|
||||
SWIG_Python_AddErrorMsg(const char *mesg) {
|
||||
PyObject *type = 0;
|
||||
PyObject *value = 0;
|
||||
PyObject *traceback = 0;
|
||||
|
@ -908,8 +904,7 @@ SWIG_Python_AddErrorMsg(const char* mesg)
|
|||
}
|
||||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_TypeErrorOccurred(PyObject *obj)
|
||||
{
|
||||
SWIG_Python_TypeErrorOccurred(PyObject *obj) {
|
||||
PyObject *error;
|
||||
if (obj)
|
||||
return 0;
|
||||
|
@ -918,8 +913,7 @@ SWIG_Python_TypeErrorOccurred(PyObject *obj)
|
|||
}
|
||||
|
||||
SWIGRUNTIME void
|
||||
SWIG_Python_RaiseOrModifyTypeError(const char *message)
|
||||
{
|
||||
SWIG_Python_RaiseOrModifyTypeError(const char *message) {
|
||||
if (SWIG_Python_TypeErrorOccurred(NULL)) {
|
||||
/* Use existing TypeError to preserve stacktrace and enhance with given message */
|
||||
PyObject *newvalue;
|
||||
|
@ -1174,8 +1168,7 @@ SWIG_Python_AppendOutput(PyObject* result, PyObject* obj) {
|
|||
/* Unpack the argument tuple */
|
||||
|
||||
SWIGINTERN Py_ssize_t
|
||||
SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs)
|
||||
{
|
||||
SWIG_Python_UnpackTuple(PyObject *args, const char *name, Py_ssize_t min, Py_ssize_t max, PyObject **objs) {
|
||||
if (!args) {
|
||||
if (!min && !max) {
|
||||
return 1;
|
||||
|
@ -1252,8 +1245,7 @@ extern "C" {
|
|||
/* The python void return value */
|
||||
|
||||
SWIGRUNTIMEINLINE PyObject *
|
||||
SWIG_Py_Void(void)
|
||||
{
|
||||
SWIG_Py_Void(void) {
|
||||
PyObject *none = Py_None;
|
||||
Py_INCREF(none);
|
||||
return none;
|
||||
|
@ -1272,8 +1264,7 @@ typedef struct {
|
|||
} SwigPyClientData;
|
||||
|
||||
SWIGRUNTIMEINLINE int
|
||||
SWIG_Python_CheckImplicit(swig_type_info *ty)
|
||||
{
|
||||
SWIG_Python_CheckImplicit(swig_type_info *ty) {
|
||||
SwigPyClientData *data = (SwigPyClientData *)ty->clientdata;
|
||||
int fail = data ? data->implicitconv : 0;
|
||||
if (fail)
|
||||
|
@ -1290,8 +1281,7 @@ SWIG_Python_ExceptionType(swig_type_info *desc) {
|
|||
|
||||
|
||||
SWIGRUNTIME SwigPyClientData *
|
||||
SwigPyClientData_New(PyObject* obj)
|
||||
{
|
||||
SwigPyClientData_New(PyObject *obj) {
|
||||
if (!obj) {
|
||||
return 0;
|
||||
} else {
|
||||
|
@ -1359,8 +1349,7 @@ typedef struct {
|
|||
#ifdef SWIGPYTHON_BUILTIN
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
|
||||
{
|
||||
SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||
SwigPyObject *sobj = (SwigPyObject *)v;
|
||||
|
||||
if (!sobj->dict)
|
||||
|
@ -1373,14 +1362,12 @@ SwigPyObject_get___dict__(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
|
|||
#endif
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_long(SwigPyObject *v)
|
||||
{
|
||||
SwigPyObject_long(SwigPyObject *v) {
|
||||
return PyLong_FromVoidPtr(v->ptr);
|
||||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_format(const char* fmt, SwigPyObject *v)
|
||||
{
|
||||
SwigPyObject_format(const char *fmt, SwigPyObject *v) {
|
||||
PyObject *res = NULL;
|
||||
PyObject *args = PyTuple_New(1);
|
||||
if (args) {
|
||||
|
@ -1401,20 +1388,17 @@ SwigPyObject_format(const char* fmt, SwigPyObject *v)
|
|||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_oct(SwigPyObject *v)
|
||||
{
|
||||
SwigPyObject_oct(SwigPyObject *v) {
|
||||
return SwigPyObject_format("%o", v);
|
||||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_hex(SwigPyObject *v)
|
||||
{
|
||||
SwigPyObject_hex(SwigPyObject *v) {
|
||||
return SwigPyObject_format("%x", v);
|
||||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_repr(SwigPyObject *v)
|
||||
{
|
||||
SwigPyObject_repr(SwigPyObject *v) {
|
||||
const char *name = SWIG_TypePrettyName(v->ty);
|
||||
PyObject *repr = SWIG_Python_str_FromFormat("<Swig Object of type '%s' at %p>", (name ? name : "unknown"), (void *)v);
|
||||
if (v->next) {
|
||||
|
@ -1434,14 +1418,12 @@ SwigPyObject_repr(SwigPyObject *v)
|
|||
/* We need a version taking two PyObject* parameters so it's a valid
|
||||
* PyCFunction to use in swigobject_methods[]. */
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args))
|
||||
{
|
||||
SwigPyObject_repr2(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||
return SwigPyObject_repr((SwigPyObject *)v);
|
||||
}
|
||||
|
||||
SWIGRUNTIME int
|
||||
SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
|
||||
{
|
||||
SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w) {
|
||||
void *i = v->ptr;
|
||||
void *j = w->ptr;
|
||||
return (i < j) ? -1 : ((i > j) ? 1 : 0);
|
||||
|
@ -1449,8 +1431,7 @@ SwigPyObject_compare(SwigPyObject *v, SwigPyObject *w)
|
|||
|
||||
/* Added for Python 3.x, would it also be useful for Python 2.x? */
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op)
|
||||
{
|
||||
SwigPyObject_richcompare(SwigPyObject *v, SwigPyObject *w, int op) {
|
||||
PyObject *res;
|
||||
if (op != Py_EQ && op != Py_NE) {
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
|
@ -1499,8 +1480,7 @@ SWIGRUNTIME PyObject *
|
|||
SwigPyObject_New(void *ptr, swig_type_info *ty, int own);
|
||||
|
||||
SWIGRUNTIME void
|
||||
SwigPyObject_dealloc(PyObject *v)
|
||||
{
|
||||
SwigPyObject_dealloc(PyObject *v) {
|
||||
SwigPyObject *sobj = (SwigPyObject *) v;
|
||||
PyObject *next = sobj->next;
|
||||
if (sobj->own == SWIG_POINTER_OWN) {
|
||||
|
@ -1550,8 +1530,7 @@ SwigPyObject_dealloc(PyObject *v)
|
|||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_append(PyObject* v, PyObject* next)
|
||||
{
|
||||
SwigPyObject_append(PyObject *v, PyObject *next) {
|
||||
SwigPyObject *sobj = (SwigPyObject *) v;
|
||||
if (!SwigPyObject_Check(next)) {
|
||||
PyErr_SetString(PyExc_TypeError, "Attempt to append a non SwigPyObject");
|
||||
|
@ -1563,8 +1542,7 @@ SwigPyObject_append(PyObject* v, PyObject* next)
|
|||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
||||
{
|
||||
SwigPyObject_next(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||
SwigPyObject *sobj = (SwigPyObject *) v;
|
||||
if (sobj->next) {
|
||||
Py_INCREF(sobj->next);
|
||||
|
@ -1575,24 +1553,21 @@ SwigPyObject_next(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
|||
}
|
||||
|
||||
SWIGINTERN PyObject *
|
||||
SwigPyObject_disown(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
||||
{
|
||||
SwigPyObject_disown(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||
SwigPyObject *sobj = (SwigPyObject *)v;
|
||||
sobj->own = 0;
|
||||
return SWIG_Py_Void();
|
||||
}
|
||||
|
||||
SWIGINTERN PyObject *
|
||||
SwigPyObject_acquire(PyObject* v, PyObject *SWIGUNUSEDPARM(args))
|
||||
{
|
||||
SwigPyObject_acquire(PyObject *v, PyObject *SWIGUNUSEDPARM(args)) {
|
||||
SwigPyObject *sobj = (SwigPyObject *)v;
|
||||
sobj->own = SWIG_POINTER_OWN;
|
||||
return SWIG_Py_Void();
|
||||
}
|
||||
|
||||
SWIGINTERN PyObject *
|
||||
SwigPyObject_own(PyObject *v, PyObject *args)
|
||||
{
|
||||
SwigPyObject_own(PyObject *v, PyObject *args) {
|
||||
PyObject *val = 0;
|
||||
if (!PyArg_UnpackTuple(args, "own", 0, 1, &val)) {
|
||||
return NULL;
|
||||
|
@ -1749,8 +1724,7 @@ SwigPyObject_TypeOnce(void) {
|
|||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyObject_New(void *ptr, swig_type_info *ty, int own)
|
||||
{
|
||||
SwigPyObject_New(void *ptr, swig_type_info *ty, int own) {
|
||||
SwigPyObject *sobj = PyObject_NEW(SwigPyObject, SwigPyObject_type());
|
||||
if (sobj) {
|
||||
sobj->ptr = ptr;
|
||||
|
@ -1773,8 +1747,7 @@ typedef struct {
|
|||
} SwigPyPacked;
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyPacked_repr(SwigPyPacked *v)
|
||||
{
|
||||
SwigPyPacked_repr(SwigPyPacked *v) {
|
||||
char result[SWIG_BUFFER_SIZE];
|
||||
if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
|
||||
return SWIG_Python_str_FromFormat("<Swig Packed at %s%s>", result, v->ty->name);
|
||||
|
@ -1784,8 +1757,7 @@ SwigPyPacked_repr(SwigPyPacked *v)
|
|||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyPacked_str(SwigPyPacked *v)
|
||||
{
|
||||
SwigPyPacked_str(SwigPyPacked *v) {
|
||||
char result[SWIG_BUFFER_SIZE];
|
||||
if (SWIG_PackDataName(result, v->pack, v->size, 0, sizeof(result))) {
|
||||
return SWIG_Python_str_FromFormat("%s%s", result, v->ty->name);
|
||||
|
@ -1795,8 +1767,7 @@ SwigPyPacked_str(SwigPyPacked *v)
|
|||
}
|
||||
|
||||
SWIGRUNTIME int
|
||||
SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w)
|
||||
{
|
||||
SwigPyPacked_compare(SwigPyPacked *v, SwigPyPacked *w) {
|
||||
size_t i = v->size;
|
||||
size_t j = w->size;
|
||||
int s = (i < j) ? -1 : ((i > j) ? 1 : 0);
|
||||
|
@ -1818,8 +1789,7 @@ SwigPyPacked_Check(PyObject *op) {
|
|||
}
|
||||
|
||||
SWIGRUNTIME void
|
||||
SwigPyPacked_dealloc(PyObject *v)
|
||||
{
|
||||
SwigPyPacked_dealloc(PyObject *v) {
|
||||
if (SwigPyPacked_Check(v)) {
|
||||
SwigPyPacked *sobj = (SwigPyPacked *) v;
|
||||
free(sobj->pack);
|
||||
|
@ -1910,8 +1880,7 @@ SwigPyPacked_TypeOnce(void) {
|
|||
}
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
|
||||
{
|
||||
SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty) {
|
||||
SwigPyPacked *sobj = PyObject_NEW(SwigPyPacked, SwigPyPacked_type());
|
||||
if (sobj) {
|
||||
void *pack = malloc(size);
|
||||
|
@ -1929,8 +1898,7 @@ SwigPyPacked_New(void *ptr, size_t size, swig_type_info *ty)
|
|||
}
|
||||
|
||||
SWIGRUNTIME swig_type_info *
|
||||
SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
|
||||
{
|
||||
SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size) {
|
||||
if (SwigPyPacked_Check(obj)) {
|
||||
SwigPyPacked *sobj = (SwigPyPacked *)obj;
|
||||
if (sobj->size != size) return 0;
|
||||
|
@ -1948,8 +1916,7 @@ SwigPyPacked_UnpackData(PyObject *obj, void *ptr, size_t size)
|
|||
static PyObject *Swig_This_global = NULL;
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SWIG_This(void)
|
||||
{
|
||||
SWIG_This(void) {
|
||||
if (Swig_This_global == NULL)
|
||||
Swig_This_global = SWIG_Python_str_FromChar("this");
|
||||
return Swig_This_global;
|
||||
|
@ -1963,8 +1930,7 @@ SWIG_This(void)
|
|||
#endif
|
||||
|
||||
SWIGRUNTIME SwigPyObject *
|
||||
SWIG_Python_GetSwigThis(PyObject *pyobj)
|
||||
{
|
||||
SWIG_Python_GetSwigThis(PyObject *pyobj) {
|
||||
PyObject *obj;
|
||||
|
||||
if (SwigPyObject_Check(pyobj))
|
||||
|
@ -2201,8 +2167,7 @@ SWIG_Python_ConvertPacked(PyObject *obj, void *ptr, size_t sz, swig_type_info *t
|
|||
*/
|
||||
|
||||
SWIGRUNTIME PyObject *
|
||||
SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
|
||||
{
|
||||
SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this) {
|
||||
PyObject *inst = 0;
|
||||
PyObject *newraw = data->newraw;
|
||||
if (newraw) {
|
||||
|
@ -2251,8 +2216,7 @@ SWIG_Python_NewShadowInstance(SwigPyClientData *data, PyObject *swig_this)
|
|||
}
|
||||
|
||||
SWIGRUNTIME void
|
||||
SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this)
|
||||
{
|
||||
SWIG_Python_SetSwigThis(PyObject *inst, PyObject *swig_this) {
|
||||
PyObject *dict;
|
||||
#if !defined(SWIG_PYTHON_SLOW_GETSET_THIS)
|
||||
PyObject **dictptr = _PyObject_GetDictPtr(inst);
|
||||
|
@ -2376,8 +2340,7 @@ SWIG_Python_GetModule(void *SWIGUNUSEDPARM(clientdata)) {
|
|||
}
|
||||
|
||||
SWIGRUNTIME void
|
||||
SWIG_Python_DestroyModule(PyObject *obj)
|
||||
{
|
||||
SWIG_Python_DestroyModule(PyObject *obj) {
|
||||
swig_module_info *swig_module = (swig_module_info *) PyCapsule_GetPointer(obj, SWIGPY_CAPSULE_NAME);
|
||||
swig_type_info **types = swig_module->types;
|
||||
size_t i;
|
||||
|
@ -2417,8 +2380,7 @@ SWIG_Python_TypeCache(void) {
|
|||
}
|
||||
|
||||
SWIGRUNTIME swig_type_info *
|
||||
SWIG_Python_TypeQuery(const char *type)
|
||||
{
|
||||
SWIG_Python_TypeQuery(const char *type) {
|
||||
PyObject *cache = SWIG_Python_TypeCache();
|
||||
PyObject *key = SWIG_Python_str_FromChar(type);
|
||||
PyObject *obj = PyDict_GetItem(cache, key);
|
||||
|
@ -2446,8 +2408,7 @@ SWIG_Python_TypeQuery(const char *type)
|
|||
#define SWIG_MustGetPtr(p, type, argnum, flags) SWIG_Python_MustGetPtr(p, type, argnum, flags)
|
||||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_AddErrMesg(const char* mesg, int infront)
|
||||
{
|
||||
SWIG_Python_AddErrMesg(const char *mesg, int infront) {
|
||||
if (PyErr_Occurred()) {
|
||||
PyObject *type = 0;
|
||||
PyObject *value = 0;
|
||||
|
@ -2474,8 +2435,7 @@ SWIG_Python_AddErrMesg(const char* mesg, int infront)
|
|||
}
|
||||
|
||||
SWIGRUNTIME int
|
||||
SWIG_Python_ArgFail(int argnum)
|
||||
{
|
||||
SWIG_Python_ArgFail(int argnum) {
|
||||
if (PyErr_Occurred()) {
|
||||
/* add information about failing argument */
|
||||
char mesg[256];
|
||||
|
@ -2487,16 +2447,14 @@ SWIG_Python_ArgFail(int argnum)
|
|||
}
|
||||
|
||||
SWIGRUNTIMEINLINE const char *
|
||||
SwigPyObject_GetDesc(PyObject *self)
|
||||
{
|
||||
SwigPyObject_GetDesc(PyObject *self) {
|
||||
SwigPyObject *v = (SwigPyObject *)self;
|
||||
swig_type_info *ty = v ? v->ty : 0;
|
||||
return ty ? ty->str : "";
|
||||
}
|
||||
|
||||
SWIGRUNTIME void
|
||||
SWIG_Python_TypeError(const char *type, PyObject *obj)
|
||||
{
|
||||
SWIG_Python_TypeError(const char *type, PyObject *obj) {
|
||||
if (type) {
|
||||
#if defined(SWIG_COBJECT_TYPES)
|
||||
if (obj && SwigPyObject_Check(obj)) {
|
||||
|
@ -2679,8 +2637,7 @@ SWIGINTERN pm3 *new_pm3__SWIG_0(void){
|
|||
}
|
||||
|
||||
SWIGINTERN swig_type_info *
|
||||
SWIG_pchar_descriptor(void)
|
||||
{
|
||||
SWIG_pchar_descriptor(void) {
|
||||
static int init = 0;
|
||||
static swig_type_info *info = 0;
|
||||
if (!init) {
|
||||
|
@ -2692,8 +2649,7 @@ SWIG_pchar_descriptor(void)
|
|||
|
||||
|
||||
SWIGINTERN int
|
||||
SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
|
||||
{
|
||||
SWIG_AsCharPtrAndSize(PyObject *obj, char **cptr, size_t *psize, int *alloc) {
|
||||
#if PY_VERSION_HEX>=0x03000000
|
||||
#if defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
|
||||
if (PyBytes_Check(obj))
|
||||
|
@ -2704,7 +2660,8 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
|
|||
if (PyString_Check(obj))
|
||||
#endif
|
||||
{
|
||||
char *cstr; Py_ssize_t len;
|
||||
char *cstr;
|
||||
Py_ssize_t len;
|
||||
int ret = SWIG_OK;
|
||||
#if PY_VERSION_HEX>=0x03000000
|
||||
#if !defined(SWIG_PYTHON_STRICT_BYTE_CHAR)
|
||||
|
@ -2760,7 +2717,8 @@ SWIG_AsCharPtrAndSize(PyObject *obj, char** cptr, size_t* psize, int *alloc)
|
|||
#endif
|
||||
#if PY_VERSION_HEX<0x03000000
|
||||
if (PyUnicode_Check(obj)) {
|
||||
char *cstr; Py_ssize_t len;
|
||||
char *cstr;
|
||||
Py_ssize_t len;
|
||||
if (!alloc && cptr) {
|
||||
return SWIG_RuntimeError;
|
||||
}
|
||||
|
@ -2816,15 +2774,13 @@ SWIGINTERN void delete_pm3(pm3 *self){
|
|||
}
|
||||
|
||||
SWIGINTERNINLINE PyObject *
|
||||
SWIG_From_int (int value)
|
||||
{
|
||||
SWIG_From_int(int value) {
|
||||
return PyInt_FromLong((long) value);
|
||||
}
|
||||
|
||||
|
||||
SWIGINTERNINLINE PyObject *
|
||||
SWIG_FromCharPtrAndSize(const char* carray, size_t size)
|
||||
{
|
||||
SWIG_FromCharPtrAndSize(const char *carray, size_t size) {
|
||||
if (carray) {
|
||||
if (size > INT_MAX) {
|
||||
swig_type_info *pchar_descriptor = SWIG_pchar_descriptor();
|
||||
|
@ -2848,8 +2804,7 @@ SWIG_FromCharPtrAndSize(const char* carray, size_t size)
|
|||
|
||||
|
||||
SWIGINTERNINLINE PyObject *
|
||||
SWIG_FromCharPtr(const char *cptr)
|
||||
{
|
||||
SWIG_FromCharPtr(const char *cptr) {
|
||||
return SWIG_FromCharPtrAndSize(cptr, (cptr ? strlen(cptr) : 0));
|
||||
}
|
||||
|
||||
|
@ -3049,7 +3004,8 @@ static swig_cast_info *swig_cast_initial[] = {
|
|||
/* -------- TYPE CONVERSION AND EQUIVALENCE RULES (END) -------- */
|
||||
|
||||
static swig_const_info swig_const_table[] = {
|
||||
{0, 0, 0, 0.0, 0, 0}};
|
||||
{0, 0, 0, 0.0, 0, 0}
|
||||
};
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
|
|
|
@ -143,9 +143,10 @@ PLATFORM_DEFS+=$(STANDALONE_PLATFORM_DEFS)
|
|||
|
||||
$(info $(findstring WITH_STANDALONE_*,$(PLATFORM_DEFS)))
|
||||
|
||||
# Misc
|
||||
# Misc (LCD support)
|
||||
ifneq (,$(findstring WITH_LCD,$(PLATFORM_DEFS)))
|
||||
#PLATFORM_DEFS += -DWITH_LCD
|
||||
|
||||
endif
|
||||
|
||||
# Add flags dependencies :
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
clear
|
||||
pref
|
||||
rem
|
||||
quit
|
||||
exit
|
||||
analyse lcr
|
||||
analyse crc
|
||||
analyse chksum
|
||||
|
@ -13,6 +11,7 @@ analyse a
|
|||
analyse nuid
|
||||
analyse demodbuff
|
||||
analyse freq
|
||||
analyse foo
|
||||
data biphaserawdecode
|
||||
data detectclock
|
||||
data fsktonrz
|
||||
|
@ -44,20 +43,15 @@ data print
|
|||
data samples
|
||||
data setdebugmode
|
||||
data tune
|
||||
emv list
|
||||
hf list
|
||||
hf tune
|
||||
hf search
|
||||
hf sniff
|
||||
hf 14a list
|
||||
hf 14a reader
|
||||
hf 14a cuids
|
||||
hf 14a sim
|
||||
hf 14a sniff
|
||||
hf 14a config
|
||||
hf 14b list
|
||||
hf 14b sriwrite
|
||||
hf 15 list
|
||||
hf 15 dump
|
||||
hf 15 info
|
||||
hf 15 raw
|
||||
|
@ -69,7 +63,6 @@ hf 15 writeafi
|
|||
hf 15 writedsfid
|
||||
hf epa cnonces
|
||||
hf epa preplay
|
||||
hf felica list
|
||||
hf felica reader
|
||||
hf felica sniff
|
||||
hf felica raw
|
||||
|
@ -85,11 +78,9 @@ hf felica rqspecver
|
|||
hf felica resetmode
|
||||
hf felica litesim
|
||||
hf felica litedump
|
||||
hf fido list
|
||||
hf fido info
|
||||
hf iclass info
|
||||
hf iclass list
|
||||
hf legic list
|
||||
hf iclass permutekey
|
||||
hf legic reader
|
||||
hf legic info
|
||||
hf legic dump
|
||||
|
@ -101,13 +92,6 @@ hf legic crc
|
|||
hf legic eload
|
||||
hf legic esave
|
||||
hf legic wipe
|
||||
hf lto dump
|
||||
hf lto restore
|
||||
hf lto info
|
||||
hf lto rdbl
|
||||
hf lto wrbl
|
||||
hf lto list
|
||||
hf mf list
|
||||
hf mf darkside
|
||||
hf mf nested
|
||||
hf mf hardnested
|
||||
|
@ -144,7 +128,6 @@ hf mf gen3uid
|
|||
hf mf gen3blk
|
||||
hf mf gen3freeze
|
||||
hf mf ice
|
||||
hf mfp info
|
||||
hf mfu info
|
||||
hf mfu dump
|
||||
hf mfu restore
|
||||
|
@ -161,12 +144,8 @@ hf mfu otptear
|
|||
hf mfdes enum
|
||||
hf mfdes getuid
|
||||
hf mfdes info
|
||||
hf mfdes list
|
||||
hf st list
|
||||
hf thinfilm info
|
||||
hf thinfilm list
|
||||
hf thinfilm sim
|
||||
hf topaz list
|
||||
hf topaz info
|
||||
hf topaz reader
|
||||
hf topaz sim
|
||||
|
@ -199,17 +178,6 @@ lf simpsk
|
|||
lf simbidir
|
||||
lf sniff
|
||||
lf tune
|
||||
lf awid demod
|
||||
lf awid read
|
||||
lf awid clone
|
||||
lf awid sim
|
||||
lf awid brute
|
||||
lf awid watch
|
||||
lf cotag demod
|
||||
lf cotag read
|
||||
lf destron demod
|
||||
lf destron read
|
||||
lf destron sim
|
||||
lf em 410x_demod
|
||||
lf em 410x_read
|
||||
lf em 410x_sim
|
||||
|
@ -229,21 +197,7 @@ lf em 4x50_write
|
|||
lf em 4x50_write_password
|
||||
lf em 4x50_read
|
||||
lf em 4x50_wipe
|
||||
lf fdxb demod
|
||||
lf fdxb read
|
||||
lf fdxb clone
|
||||
lf fdxb sim
|
||||
lf gallagher demod
|
||||
lf gallagher read
|
||||
lf gallagher clone
|
||||
lf gallagher sim
|
||||
lf gproxii demod
|
||||
lf gproxii read
|
||||
lf gproxii clone
|
||||
lf gproxii sim
|
||||
lf hid demod
|
||||
lf hid read
|
||||
lf hitag list
|
||||
lf hitag info
|
||||
lf hitag reader
|
||||
lf hitag sim
|
||||
|
@ -251,41 +205,20 @@ lf hitag sniff
|
|||
lf hitag writer
|
||||
lf hitag dump
|
||||
lf hitag cc
|
||||
lf idteck demod
|
||||
lf idteck read
|
||||
lf indala demod
|
||||
lf indala altdemod
|
||||
lf indala read
|
||||
lf indala sim
|
||||
lf io demod
|
||||
lf io read
|
||||
lf io clone
|
||||
lf io sim
|
||||
lf io watch
|
||||
lf jablotron demod
|
||||
lf jablotron read
|
||||
lf jablotron clone
|
||||
lf jablotron sim
|
||||
lf keri demod
|
||||
lf motorola demod
|
||||
lf motorola sim
|
||||
lf nedap demod
|
||||
lf nedap generate
|
||||
lf nedap read
|
||||
lf nedap clone
|
||||
lf nedap sim
|
||||
lf nexwatch demod
|
||||
lf noralsy demod
|
||||
lf pac demod
|
||||
lf paradox demod
|
||||
lf pcf7931 read
|
||||
lf pcf7931 write
|
||||
lf pcf7931 config
|
||||
lf presco demod
|
||||
lf pyramid demod
|
||||
lf securakey demod
|
||||
lf ti demod
|
||||
lf ti write
|
||||
lf t55xx config
|
||||
lf t55xx dangerraw
|
||||
lf t55xx detect
|
||||
|
@ -306,17 +239,12 @@ lf t55xx recoverpw
|
|||
lf t55xx sniff
|
||||
lf t55xx special
|
||||
lf t55xx wipe
|
||||
lf viking demod
|
||||
lf visa2000 demod
|
||||
mem spiffs
|
||||
smart list
|
||||
smart info
|
||||
smart reader
|
||||
smart raw
|
||||
smart upgrade
|
||||
smart setclock
|
||||
smart brute
|
||||
script list
|
||||
script run
|
||||
usart btpin
|
||||
usart btfactory
|
||||
|
@ -326,4 +254,3 @@ usart txrx
|
|||
usart txhex
|
||||
usart rxhex
|
||||
usart config
|
||||
wiegand list
|
||||
|
|
|
@ -38,6 +38,7 @@ Check column "offline" for their availability.
|
|||
|`analyse nuid `|Y |`create NUID from 7byte UID`
|
||||
|`analyse demodbuff `|Y |`Load binary string to demodbuffer`
|
||||
|`analyse freq `|Y |`Calc wave lengths`
|
||||
|`analyse foo `|Y |`muxer`
|
||||
|
||||
|
||||
### data
|
||||
|
@ -267,7 +268,7 @@ Check column "offline" for their availability.
|
|||
|`hf iclass encrypt `|Y |`[options..] Encrypt given block data`
|
||||
|`hf iclass decrypt `|Y |`[options..] Decrypt given block data or tag dump file`
|
||||
|`hf iclass managekeys `|Y |`[options..] Manage keys to use with iclass commands`
|
||||
|`hf iclass permute `|N |` Permute function from 'heart of darkness' paper`
|
||||
|`hf iclass permutekey `|N |` Permute function from 'heart of darkness' paper`
|
||||
|`hf iclass view `|Y |`[options..] Display content from tag dump file`
|
||||
|
||||
|
||||
|
@ -538,7 +539,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf awid help `|Y |`this help`
|
||||
|`lf awid demod `|Y |`demodulate an AWID FSK tag from the GraphBuffer`
|
||||
|`lf awid read `|N |`attempt to read and extract tag data`
|
||||
|`lf awid reader `|N |`attempt to read and extract tag data`
|
||||
|`lf awid clone `|N |`clone AWID tag to T55x7 or Q5/T5555`
|
||||
|`lf awid sim `|N |`simulate AWID tag`
|
||||
|`lf awid brute `|N |`Bruteforce card number against reader`
|
||||
|
@ -553,7 +554,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf cotag help `|Y |`This help`
|
||||
|`lf cotag demod `|Y |`Tries to decode a COTAG signal`
|
||||
|`lf cotag read `|N |`Attempt to read and extract tag data`
|
||||
|`lf cotag reader `|N |`Attempt to read and extract tag data`
|
||||
|
||||
|
||||
### lf destron
|
||||
|
@ -564,7 +565,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf destron help `|Y |`This help`
|
||||
|`lf destron demod `|Y |`Demodulate an Destron tag from the GraphBuffer`
|
||||
|`lf destron read `|N |`Attempt to read and extract tag data from the antenna`
|
||||
|`lf destron reader `|N |`Attempt to read and extract tag data from the antenna`
|
||||
|`lf destron clone `|N |`Clone Destron tag to T55x7`
|
||||
|`lf destron sim `|N |`Simulate Destron tag`
|
||||
|
||||
|
@ -609,7 +610,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf fdxb help `|Y |`this help`
|
||||
|`lf fdxb demod `|Y |`demodulate a FDX-B ISO11784/85 tag from the GraphBuffer`
|
||||
|`lf fdxb read `|N |`attempt to read at 134kHz and extract tag data`
|
||||
|`lf fdxb reader `|N |`attempt to read at 134kHz and extract tag data`
|
||||
|`lf fdxb clone `|N |`clone animal ID tag to T55x7 or Q5/T5555`
|
||||
|`lf fdxb sim `|N |`simulate Animal ID tag`
|
||||
|
||||
|
@ -622,7 +623,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf gallagher help `|Y |`This help`
|
||||
|`lf gallagher demod `|Y |`Demodulate an GALLAGHER tag from the GraphBuffer`
|
||||
|`lf gallagher read `|N |`Attempt to read and extract tag data from the antenna`
|
||||
|`lf gallagher reader `|N |`Attempt to read and extract tag data from the antenna`
|
||||
|`lf gallagher clone `|N |`clone GALLAGHER tag to T55x7`
|
||||
|`lf gallagher sim `|N |`simulate GALLAGHER tag`
|
||||
|
||||
|
@ -635,7 +636,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf gproxii help `|Y |`this help`
|
||||
|`lf gproxii demod `|Y |`demodulate a G Prox II tag from the GraphBuffer`
|
||||
|`lf gproxii read `|N |`attempt to read and extract tag data from the antenna`
|
||||
|`lf gproxii reader `|N |`attempt to read and extract tag data from the antenna`
|
||||
|`lf gproxii clone `|N |`clone Guardall tag to T55x7 or Q5/T5555`
|
||||
|`lf gproxii sim `|N |`simulate Guardall tag`
|
||||
|
||||
|
@ -680,7 +681,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf idteck help `|Y |`This help`
|
||||
|`lf idteck demod `|Y |`Demodulate an Idteck tag from the GraphBuffer`
|
||||
|`lf idteck read `|N |`Attempt to read and Extract tag data from the antenna`
|
||||
|`lf idteck reader `|N |`Attempt to read and Extract tag data from the antenna`
|
||||
|
||||
|
||||
### lf indala
|
||||
|
@ -692,7 +693,7 @@ Check column "offline" for their availability.
|
|||
|`lf indala help `|Y |`this help`
|
||||
|`lf indala demod `|Y |`demodulate an indala tag (PSK1) from GraphBuffer`
|
||||
|`lf indala altdemod `|Y |`alternative method to Demodulate samples for Indala 64 bit UID (option '224' for 224 bit)`
|
||||
|`lf indala read `|N |`read an Indala Prox tag from the antenna`
|
||||
|`lf indala reader `|N |`read an Indala Prox tag from the antenna`
|
||||
|`lf indala clone `|N |`clone Indala tag to T55x7 or Q5/T5555`
|
||||
|`lf indala sim `|N |`simulate Indala tag`
|
||||
|
||||
|
@ -705,7 +706,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf io help `|Y |`this help`
|
||||
|`lf io demod `|Y |`demodulate an IOProx tag from the GraphBuffer`
|
||||
|`lf io read `|N |`attempt to read and extract tag data`
|
||||
|`lf io reader `|N |`attempt to read and extract tag data`
|
||||
|`lf io clone `|N |`clone IOProx tag to T55x7 or Q5/T5555`
|
||||
|`lf io sim `|N |`simulate IOProx tag`
|
||||
|`lf io watch `|N |`continuously watch for cards. Reader mode`
|
||||
|
@ -719,7 +720,7 @@ Check column "offline" for their availability.
|
|||
|------- |------- |-----------
|
||||
|`lf jablotron help `|Y |`This help`
|
||||
|`lf jablotron demod `|Y |`Demodulate an Jablotron tag from the GraphBuffer`
|
||||
|`lf jablotron read `|N |`Attempt to read and extract tag data from the antenna`
|
||||
|`lf jablotron reader `|N |`Attempt to read and extract tag data from the antenna`
|
||||
|`lf jablotron clone `|N |`clone jablotron tag to T55x7 or Q5/T5555`
|
||||
|`lf jablotron sim `|N |`simulate jablotron tag`
|
||||
|
||||
|
@ -874,7 +875,7 @@ Check column "offline" for their availability.
|
|||
|command |offline |description
|
||||
|------- |------- |-----------
|
||||
|`lf ti help `|Y |`This help`
|
||||
|`lf ti demod `|Y |`Demodulate raw bits for TI-type LF tag from the GraphBuffer`
|
||||
|`lf ti demod `|Y |`Demodulate raw bits for TI LF tag from the GraphBuffer`
|
||||
|`lf ti reader `|N |`Read and decode a TI 134 kHz tag`
|
||||
|`lf ti write `|N |`Write new data to a r/w TI 134 kHz tag`
|
||||
|
||||
|
|
6
pm3
6
pm3
|
@ -133,7 +133,7 @@ function get_pm3_list_Windows {
|
|||
# Need to look for this first, the call to Win32_serialport "crashes" then native bt serial port. Don't ask why.
|
||||
#BT direct SERIAL PORTS (COM)
|
||||
if $FINDBTRFCOMM; then
|
||||
for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_PnPEntity | Where-Object Caption -like 'Standard Serial over Bluetooth link (COM*' | Select Name" 2> /dev/null | awk 'match($0,/COM([0-9]+)/,m){print m[1]}'); do
|
||||
for DEV in $(wmic /locale:ms_409 path Win32_PnPEntity Where "Caption LIKE '%Bluetooth%(COM%'" Get Name 2> /dev/null | awk -b 'match($0,/(COM[0-9]+)/,m){print m[1]}'); do
|
||||
DEV=${DEV/ */}
|
||||
PM3LIST+=("$DEV")
|
||||
if [ ${#PM3LIST[*]} -ge "$N" ]; then
|
||||
|
@ -143,7 +143,7 @@ function get_pm3_list_Windows {
|
|||
fi
|
||||
|
||||
# Normal SERIAL PORTS (COM)
|
||||
for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_9AC4&PID_4B8F*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
|
||||
for DEV in $(wmic /locale:ms_409 path Win32_SerialPort Where "PNPDeviceID LIKE '%VID_9AC4&PID_4B8F%'" Get DeviceID 2>/dev/null | awk -b '/^COM/{print $1}'); do
|
||||
DEV=${DEV/ */}
|
||||
PM3LIST+=("$DEV")
|
||||
if [ ${#PM3LIST[*]} -ge "$N" ]; then
|
||||
|
@ -153,7 +153,7 @@ function get_pm3_list_Windows {
|
|||
|
||||
#white BT dongle SERIAL PORTS (COM)
|
||||
if $FINDBTDONGLE; then
|
||||
for DEV in $(powershell.exe -command "Get-CimInstance -ClassName Win32_serialport | Where-Object PNPDeviceID -like '*VID_10C4&PID_EA60*' | Select DeviceID" 2>/dev/null | awk '/^COM/{print $1}'); do
|
||||
for DEV in $(wmic /locale:ms_409 path Win32_SerialPort Where "PNPDeviceID LIKE '%VID_10C4&PID_EA60%'" Get DeviceID 2>/dev/null | awk -b '/^COM/{print $1}'); do
|
||||
DEV=${DEV/ */}
|
||||
PM3LIST+=("$DEV")
|
||||
if [ ${#PM3LIST[*]} -ge "$N" ]; then
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue