// Low frequency commands
//-----------------------------------------------------------------------------
#include "cmdlf.h"
+
+bool g_lf_threshold_set = FALSE;
+
static int CmdHelp(const char *Cmd);
int usage_lf_cmdread(void) {
PrintAndLog("Options:");
PrintAndLog(" h This help");
PrintAndLog(" s silent run no printout");
- PrintAndLog("This function takes no arguments. ");
PrintAndLog("Use 'lf config' to set parameters.");
return 0;
}
int usage_lf_snoop(void) {
- PrintAndLog("Usage: lf snoop");
+ PrintAndLog("Snoop low frequence signal. Use 'lf config' to set parameters.");
+ PrintAndLog("Usage: lf snoop [h]");
PrintAndLog("Options:");
- PrintAndLog(" h This help");
- PrintAndLog("This function takes no arguments. ");
- PrintAndLog("Use 'lf config' to set parameters.");
+ PrintAndLog(" h This help");
return 0;
}
int usage_lf_config(void) {
int CmdIndalaDemod(const char *Cmd)
{
+ // PSK1, Bitrate 32,
+
// Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
-
int state = -1;
int count = 0;
int i, j;
count = 0;
}
}
+ if ( rawbit<1 ) return 0;
- if ( rawbit>0 ){
+ if (g_debugMode) {
PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
- } else {
- return 0;
}
// Finding the start of a UID
}
if (start == rawbit - uidlen + 1) {
- PrintAndLog("nothing to wait for");
+ if (g_debugMode) PrintAndLog("nothing to wait for");
return 0;
}
// Inverting signal if needed
if (first == 1) {
- for (i = start; i < rawbit; i++) {
+ for (i = start; i < rawbit; i++)
rawbits[i] = !rawbits[i];
- }
}
// Dumping UID
times += 1;
}
- PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
+ if (g_debugMode) PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
// Remodulating for tag cloning
// HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)
cmdp++;
break;
case 'q':
- errors |= param_getdec(Cmd,cmdp+1,&divisor);
+ errors |= param_getdec(Cmd, cmdp+1, &divisor);
cmdp+=2;
break;
case 't':
- errors |= param_getdec(Cmd,cmdp+1,&unsigned_trigg);
+ errors |= param_getdec(Cmd, cmdp+1, &unsigned_trigg);
cmdp+=2;
- if(!errors) trigger_threshold = unsigned_trigg;
+ if(!errors) {
+ trigger_threshold = unsigned_trigg;
+ g_lf_threshold_set = (trigger_threshold > 0);
+ }
break;
case 'b':
- errors |= param_getdec(Cmd,cmdp+1,&bps);
+ errors |= param_getdec(Cmd, cmdp+1, &bps);
cmdp+=2;
break;
case 'd':
- errors |= param_getdec(Cmd,cmdp+1,&decimation);
+ errors |= param_getdec(Cmd, cmdp+1, &decimation);
cmdp+=2;
break;
case 'a':
- averaging = param_getchar(Cmd,cmdp+1) == '1';
+ averaging = param_getchar(Cmd, cmdp+1) == '1';
cmdp+=2;
break;
default:
//Validations
if (errors) return usage_lf_config();
- //Bps is limited to 8, so fits in lower half of arg1
+ //Bps is limited to 8
if (bps >> 4) bps = 8;
sample_config config = { decimation, bps, averaging, divisor, trigger_threshold };
- //Averaging is a flag on high-bit of arg[1]
- UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG};
- memcpy(c.d.asBytes,&config,sizeof(sample_config));
+ UsbCommand c = {CMD_SET_LF_SAMPLING_CONFIG, {0,0,0} };
+ memcpy(c.d.asBytes, &config, sizeof(sample_config));
clearCommandBuffer();
SendCommand(&c);
return 0;
}
int CmdLFRead(const char *Cmd) {
- bool arg1 = false;
- uint8_t cmdp = param_getchar(Cmd, 0);
- if ( cmdp == 'h' || cmdp == 'H') return usage_lf_read();
+ if (offline) return 0;
- //suppress print
- if ( cmdp == 's' || cmdp == 'S') arg1 = true;
+ bool errors = FALSE;
+ bool arg1 = FALSE;
+ uint8_t cmdp = 0;
+ while(param_getchar(Cmd, cmdp) != 0x00) {
+ switch(param_getchar(Cmd, cmdp)) {
+ case 'h':
+ case 'H':
+ return usage_lf_read();
+ case 's':
+ case 'S':
+ arg1 = TRUE;
+ cmdp++;
+ break;
+ default:
+ PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
+ errors = TRUE;
+ break;
+ }
+ if(errors) break;
+ }
+
+ //Validations
+ if (errors) return usage_lf_read();
UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {arg1,0,0}};
clearCommandBuffer();
SendCommand(&c);
- if ( !WaitForResponseTimeout(CMD_ACK,NULL,2500) ) {
- PrintAndLog("command execution time out");
- return 1;
+ if ( g_lf_threshold_set ) {
+ WaitForResponse(CMD_ACK,NULL);
+ } else {
+ if ( !WaitForResponseTimeout(CMD_ACK, NULL ,2500) ) {
+ PrintAndLog("command execution time out");
+ return 1;
+ }
}
return 0;
}
uint8_t cmdp = param_getchar(Cmd, 0);
if(cmdp == 'h' || cmdp == 'H') return usage_lf_snoop();
- UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES};
+ UsbCommand c = {CMD_LF_SNOOP_RAW_ADC_SAMPLES,{0,0,0}};
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK,NULL);
+ getSamples("", false);
return 0;
}
for (i = 0; i < GraphTraceLen; i += USB_CMD_DATA_SIZE) {
UsbCommand c = {CMD_DOWNLOADED_SIM_SAMPLES_125K, {i, 0, 0}};
- for (j = 0; j < USB_CMD_DATA_SIZE; j++) {
+ for (j = 0; j < USB_CMD_DATA_SIZE; j++)
c.d.asBytes[j] = GraphBuffer[i+j];
- }
+
clearCommandBuffer();
SendCommand(&c);
WaitForResponse(CMD_ACK, NULL);
printf(".");
}
- PrintAndLog("Starting to simulate");
+ PrintAndLog("Simulating");
UsbCommand c = {CMD_SIMULATE_TAG_125K, {GraphTraceLen, gap, 0}};
clearCommandBuffer();
return 0;
}
+
+//by marshmellow
+int CheckChipset(bool getDeviceData) {
+
+ if (!getDeviceData) return 0;
+
+ uint32_t word = 0;
+ save_restoreGB(1);
+
+ //check for em4x05/em4x69 chips first
+ if (EM4x05IsBlock0(&word)) {
+ save_restoreGB(0);
+ PrintAndLog("\nValid EM4x05/EM4x69 Chipset found\nTry `lf em 4x05` commands\n");
+ return 1;
+ }
+
+ //TODO check for t55xx chip...
+ // if ( t55xxIsBlock0(() {
+ // save_restoreGB(0);
+ // PrintAndLog("\nValid T55xx Chipset found\nTry `lf t55xx` commands\n");
+ // return 1;
+ // }
+
+ save_restoreGB(0);
+ return 0;
+}
+
//by marshmellow
int CmdLFfind(const char *Cmd) {
int ans = 0;
+ size_t minLength = 1000;
char cmdp = param_getchar(Cmd, 0);
char testRaw = param_getchar(Cmd, 1);
if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') return usage_lf_find();
- if (!offline && (cmdp != '1')){
+ bool getDeviceData = (!offline && (cmdp != '1') );
+
+ if (getDeviceData) {
CmdLFRead("s");
- getSamples("30000",false);
- } else if (GraphTraceLen < 1000) {
+ getSamples("30000", false);
+ } else if (GraphTraceLen < minLength) {
PrintAndLog("Data in Graphbuffer was too small.");
return 0;
}
PrintAndLog("False Positives ARE possible\n");
PrintAndLog("\nChecking for known tags:\n");
+ size_t testLen = minLength;
+
+ // only run these tests if device is online
+ if (getDeviceData) {
+
+ // only run if graphbuffer is just noise as it should be for hitag/cotag
+ if (graphJustNoise(GraphBuffer, testLen)) {
+
+ if (CheckChipset(getDeviceData) )
+ return 1;
+
+ ans=CmdLFHitagReader("26");
+ if (ans==0)
+ return 1;
+
+ ans=CmdCOTAGRead("");
+ if (ans>0){
+ PrintAndLog("\nValid COTAG ID Found!");
+ return 1;
+ }
+ PrintAndLog("Signal looks just like noise. Quitting.");
+ return 0;
+ }
+ }
+
+ // identify chipset
+ CheckChipset(getDeviceData);
+
ans=CmdFSKdemodIO("");
if (ans>0) {
PrintAndLog("\nValid IO Prox ID Found!");
PrintAndLog("\nValid NexWatch ID Found!");
return 1;
}
+ ans=CmdPSKIdteck("");
+ if (ans>0) {
+ PrintAndLog("\nValid Idteck ID Found!");
+ return 1;
+ }
ans=CmdJablotronDemod("");
if (ans>0) {
PrintAndLog("\nValid Jablotron ID Found!");
PrintAndLog("\nValid NEDAP ID Found!");
return 1;
}
- // TIdemod?
-
+ ans=CmdVisa2kDemod("");
+ if (ans>0) {
+ PrintAndLog("\nValid Visa2000 ID Found!");
+ return 1;
+ }
+ ans=CmdNoralsyDemod("");
+ if (ans>0) {
+ PrintAndLog("\nValid Noralsy ID Found!");
+ return 1;
+ }
+ ans=CmdPrescoDemod("");
+ if (ans>0) {
+ PrintAndLog("\nValid Presco ID Found!");
+ return 1;
+ }
+ // TIdemod?
PrintAndLog("\nNo Known Tags Found!\n");
if (testRaw=='u' || testRaw=='U'){
//test unknown tag formats (raw mode)
return 0;
}
-static command_t CommandTable[] =
-{
+static command_t CommandTable[] = {
{"help", CmdHelp, 1, "This help"},
+ {"animal", CmdLFFdx, 1, "{ Animal RFIDs... }"},
{"awid", CmdLFAWID, 1, "{ AWID RFIDs... }"},
- {"em4x", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
+ {"cotag", CmdLFCOTAG, 1, "{ COTAG RFIDs... }"},
+ {"em", CmdLFEM4X, 1, "{ EM4X RFIDs... }"},
{"guard", CmdLFGuard, 1, "{ Guardall RFIDs... }"},
{"hid", CmdLFHID, 1, "{ HID RFIDs... }"},
{"hitag", CmdLFHitag, 1, "{ HITAG RFIDs... }"},
+// {"indala", CmdLFIndala, 1, "{ Indala RFIDs... }"},
{"io", CmdLFIO, 1, "{ IOPROX RFIDs... }"},
- {"jablotron", CmdLFJablotron, 1, "{ JABLOTRON RFIDs... }"},
- {"nedap", CmdLFNedap, 1, "{ NEDAP RFIDs... }"},
+ {"jablotron", CmdLFJablotron, 1, "{ Jablotron RFIDs... }"},
+ {"nedap", CmdLFNedap, 1, "{ Nedap RFIDs... }"},
+ {"noralsy", CmdLFNoralsy, 1, "{ Noralsy RFIDs... }"},
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
{"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"},
{"pyramid", CmdLFPyramid, 1, "{ Farpointe/Pyramid RFIDs... }"},
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
{"viking", CmdLFViking, 1, "{ Viking RFIDs... }"},
+ {"visa2000", CmdLFVisa2k, 1, "{ Visa2000 RFIDs... }"},
{"config", CmdLFSetConfig, 0, "Set config for LF sampling, bit/sample, decimation, frequency"},
{"cmdread", CmdLFCommandRead, 0, "<off period> <'0' period> <'1' period> <command> ['h' 134] \n\t\t-- Modulate LF reader field to send command before read (all periods in microseconds)"},
{"flexdemod", CmdFlexdemod, 1, "Demodulate samples for FlexPass"},
{"simfsk", CmdLFfskSim, 0, "[c <clock>] [i] [H <fcHigh>] [L <fcLow>] [d <hexdata>] \n\t\t-- Simulate LF FSK tag from demodbuffer or input"},
{"simpsk", CmdLFpskSim, 0, "[1|2|3] [c <clock>] [i] [r <carrier>] [d <raw hex to sim>] \n\t\t-- Simulate LF PSK tag from demodbuffer or input"},
{"simbidir", CmdLFSimBidir, 0, "Simulate LF tag (with bidirectional data transmission between reader and tag)"},
- {"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
+ {"snoop", CmdLFSnoop, 0, "Snoop LF"},
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
{NULL, NULL, 0, NULL}
};