adjusted it to fit with the clone/demod that is under "lf viking" commands.
did some code clean up, 3spaces into tab.
--
### Added
+- Added viking demod to `lf search` (marshmellow)
+- `data askvikingdemod` demod viking id tag from graphbuffer (marshmellow)
- `lf t55xx resetread` added reset then read command - should allow determining start
of stream transmissions (marshmellow)
- `lf t55xx wakeup` added wake with password (AOR) to allow lf search or standard lf read after (iceman, marshmellow)
- Added 'hw status'. This command makes the ARM print out some runtime information. (holiman)
- Added 'hw ping'. This command just sends a usb packets and checks if the pm3 is responsive. Can be used to abort certain operations which supports abort over usb. (holiman)
- Added `data hex2bin` and `data bin2hex` for command line conversion between binary and hexadecimal (holiman)
+- Added 'hf snoop'. This command take digitalized signal from FPGA and put in BigBuffer. (pwpiwi + enio)
+- Added Topaz (NFC type 1) protocol support ('hf topaz reader', 'hf list topaz', 'hf 14a raw -T', 'hf topaz snoop'). (piwi)
+- Added option c to 'hf list' (mark CRC bytes) (piwi)
### Changed
+- Adjusted lf em410x em410xsim to accept a clock argument
- Adjusted lf t55xx dump to allow overriding the safety check and warning text (marshmellow)
- Adjusted lf t55xx write input variables (marshmellow)
- Adjusted lf t55xx read with password safety check and warning text and adjusted the input variables (marshmellow & iceman)
break;
case CMD_AWID_DEMOD_FSK: // Set realtime AWID demodulation
CmdAWIDdemodFSK(c->arg[0], 0, 0, 1);
- break;
+ break;
case CMD_VIKING_CLONE_TAG:
CopyViKingtoT55x7(c->arg[0],c->arg[1]);
break;
void CopyIndala64toT55x7(uint32_t hi, uint32_t lo); // Clone Indala 64-bit tag by UID to T55x7
void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t uid4, uint32_t uid5, uint32_t uid6, uint32_t uid7); // Clone Indala 224-bit tag by UID to T55x7
void T55xxResetRead(void);
-void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t PwdMode);
+void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg);
+void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg);
void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd);
void T55xxWakeUp(uint32_t Pwd);
void TurnReadLFOn();
}
// Write one card block in page 0, no lock
-void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
+void T55xxWriteBlockExt(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
LED_A_ON();
bool PwdMode = arg & 0x1;
uint8_t Page = (arg & 0x2)>>1;
}
// Write one card block in page 0, no lock
-void T55xxWriteBlock(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg) {
+void T55xxWriteBlock(uint32_t Data, uint8_t Block, uint32_t Pwd, uint8_t arg) {
T55xxWriteBlockExt(Data, Block, Pwd, arg);
cmd_send(CMD_ACK,0,0,0,0,0);
}
void WriteT55xx(uint32_t *blockdata, uint8_t startblock, uint8_t numblocks) {
// write last block first and config block last (if included)
- for (uint8_t i = numblocks+startblock; i > startblock; i--) {
- //Dbprintf("write- Blk: %d, d:%08X",i-1,blockdata[i-1]);
+ for (uint8_t i = numblocks+startblock; i > startblock; i--)
T55xxWriteBlockExt(blockdata[i-1],i-1,0,0);
- }
}
// Copy HID id to card and setup block 0 config
}
void CopyViKingtoT55x7(uint32_t block1, uint32_t block2) {
- LED_D_ON();
- T55xxWriteBlock(block1,1,0,0);
- T55xxWriteBlock(block2,2,0,0);
- T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T55x7_MAXBLOCK_SHIFT,0,0,0);
- // T55xxWriteBlock(T55x7_MODULATION_MANCHESTER | T55x7_BITRATE_RF_32 | 2 << T5555_MAXBLOCK_SHIFT,0,0,1);
- // ICEMAN NOTES:
- // Shouldn't this one be: T55x7_MAXBLOCK_SHIFT and 0 in password mode
- LED_D_OFF();
+
+ uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
+ // Program the data blocks for supplied ID and the block 0 config
+ WriteT55xx(data, 0, 3);
+ LED_D_OFF();
}
// | | | | | | |
// 01234567 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 456 7 890 1 234 5 678 9 012 3 - to 96
// -----------------------------------------------------------------------------
- // 00000001 000 1 110 1 101 1 011 1 1 d01 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
+ // 00000001 000 1 110 1 101 1 011 1 101 1 010 0 000 1 000 1 010 0 001 0 110 1 100 0 000 1 000 1
// premable bbb o bbb o bbw o fff o fff o ffc o ccc o ccc o ccc o ccc o ccc o wxx o xxx o xxx o - to 96
// |---26 bit---| |-----117----||-------------142-------------|
// b = format bit len, o = odd parity of last 3 bits
uint32_t fc = 0;
uint32_t cardnum = 0;
uint32_t code1 = 0;
- //uint32_t code2 = 0;
if (fmtLen==26){
fc = bytebits_to_byte(BitStream+73, 8);
cardnum = bytebits_to_byte(BitStream+81, 16);
return ans;
}
-int AmVikingDecode(const uint8_t *id){
- // searching the buffer for the id
- //uint8_t id_bits[32];
- // convert 4 bytes of id to 32 bits present in 32 bytes data;
- //bytes_to_bits(id,4,id_bits,sizeof(id_bits));
-
- //print_arraybinary(id_bits,sizeof(id_bits));
- PrintAndLog(" binary: %s", printBits(4, id) );
-
- //size_t idx = 0;
- size_t BitLen = DemodBufferLen;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- memcpy(BitStream, DemodBuffer, BitLen);
-
- // if (VikingDecode(BitStream,BitLen,&idx,id_bits,sizeof(id_bits)) == 1)
- // {
- // setDemodBuf(BitStream,64, idx);
- // PrintAndLog("Found Viking tag\n");
- // CmdPrintDemodBuff("x");
- // }
- // else
- // {
- // PrintAndLog("Not found Viking tag\n");
- // }
- return 0;
-}
-int AMVikingDemod(const uint8_t *id){
- // demod am clock 32 fail
- if (!ASKDemod("32",g_debugMode,false,1))
- return 0;
- // search for the card id from bitstream.
- return AmVikingDecode(id);
-}
-//by Gusto
-// takes 1 argument <8 bytes of Hex number on the card
-// print binary found and saves in grapbuffer for further commands
-int CmdAMVikingDemod(const char *Cmd){
- uint8_t id[4];
- if (param_gethex(Cmd,0,id,8) == 1)
- {
- PrintAndLog("Usage: data vikingdemod CardID 8 bytes of hex number");
- return 0;
- }
- PrintAndLog("Card ID : %02X%02X%02X%02X\n",id[0],id[1],id[2],id[3]);
- // try to demod AMViking
- return AMVikingDemod(id);
-}
-
int CmdGrid(const char *Cmd)
{
sscanf(Cmd, "%i %i", &PlotGridX, &PlotGridY);
{"askedgedetect", CmdAskEdgeDetect, 1, "[threshold] Adjust Graph for manual ask demod using the length of sample differences to detect the edge of a wave (use 20-45, def:25)"},
{"askem410xdemod", CmdAskEM410xDemod, 1, "[clock] [invert<0|1>] [maxErr] -- Demodulate an EM410x tag from GraphBuffer (args optional)"},
{"askgproxiidemod", CmdG_Prox_II_Demod, 1, "Demodulate a G Prox II tag from GraphBuffer"},
+ {"askvikingdemod", CmdVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"},
{"autocorr", CmdAutoCorr, 1, "[window length] [g] -- Autocorrelation over window - g to save back to GraphBuffer (overwrite)"},
{"biphaserawdecode",CmdBiphaseDecodeRaw,1, "[offset] [invert<0|1>] [maxErr] -- Biphase decode bin stream in DemodBuffer (offset = 0|1 bits to shift the decode start)"},
{"bin2hex", Cmdbin2hex, 1, "bin2hex <digits> -- Converts binary to hexadecimal"},
{"detectclock", CmdDetectClockRate, 1, "[modulation] Detect clock rate of wave in GraphBuffer (options: 'a','f','n','p' for ask, fsk, nrz, psk respectively)"},
{"fdxbdemod", CmdFDXBdemodBI , 1, "Demodulate a FDX-B ISO11784/85 Biphase tag from GraphBuffer"},
{"fskawiddemod", CmdFSKdemodAWID, 1, "Demodulate an AWID FSK tag from GraphBuffer"},
- {"vikingdemod", CmdAMVikingDemod, 1, "Demodulate a Viking AM tag from GraphBuffer"},
//{"fskfcdetect", CmdFSKfcDetect, 1, "Try to detect the Field Clock of an FSK wave"},
{"fskhiddemod", CmdFSKdemodHID, 1, "Demodulate a HID FSK tag from GraphBuffer"},
{"fskiodemod", CmdFSKdemodIO, 1, "Demodulate an IO Prox FSK tag from GraphBuffer"},
void printDemodBuff(void);
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
int CmdAskEM410xDemod(const char *Cmd);
+int CmdVikingDemod(const char *Cmd);
int CmdG_Prox_II_Demod(const char *Cmd);
int Cmdaskrawdemod(const char *Cmd);
int Cmdaskmandemod(const char *Cmd);
int NRZrawDemod(const char *Cmd, bool verbose);
void printEM410x(uint32_t hi, uint64_t id);
int getSamples(const char *Cmd, bool silent);
-int AMVikingDemod(const uint8_t *cardid);
-int CmdAMVikingDemod(const char *cmd);
+
#define MAX_DEMOD_BUF_LEN (1024*128)
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
PrintAndLog(" d <hexdata> Data to sim as hex - omit to sim from DemodBuffer");
return 0;
}
+int usage_lf_find(void){
+ PrintAndLog("Usage: lf search <0|1> [u]");
+ PrintAndLog(" <use data from Graphbuffer> , if not set, try reading data from tag.");
+ PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags.");
+ PrintAndLog("");
+ PrintAndLog(" sample: lf search = try reading data from tag & search for known tags");
+ PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags");
+ PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags");
+ PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags");
+ return 0;
+}
+
/* send a LF command before reading */
int CmdLFCommandRead(const char *Cmd)
int CmdIndalaDemod(const char *Cmd)
{
- // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
-
- int state = -1;
- int count = 0;
- int i, j;
-
- // worst case with GraphTraceLen=64000 is < 4096
- // under normal conditions it's < 2048
-
- uint8_t rawbits[4096];
- int rawbit = 0;
- int worst = 0, worstPos = 0;
- // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
- for (i = 0; i < GraphTraceLen-1; i += 2) {
- count += 1;
- if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
- if (state == 0) {
- for (j = 0; j < count - 8; j += 16) {
- rawbits[rawbit++] = 0;
- }
- if ((abs(count - j)) > worst) {
- worst = abs(count - j);
- worstPos = i;
- }
- }
- state = 1;
- count = 0;
- } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {
- if (state == 1) {
- for (j = 0; j < count - 8; j += 16) {
- rawbits[rawbit++] = 1;
- }
- if ((abs(count - j)) > worst) {
- worst = abs(count - j);
- worstPos = i;
- }
- }
- state = 0;
- count = 0;
- }
- }
-
- if (rawbit>0){
- PrintAndLog("Recovered %d raw bits, expected: %d", rawbit, GraphTraceLen/32);
- PrintAndLog("worst metric (0=best..7=worst): %d at pos %d", worst, worstPos);
+ // Usage: recover 64bit UID by default, specify "224" as arg to recover a 224bit UID
+
+ int state = -1;
+ int count = 0;
+ int i, j;
+
+ // worst case with GraphTraceLen=64000 is < 4096
+ // under normal conditions it's < 2048
+
+ uint8_t rawbits[4096];
+ int rawbit = 0;
+ int worst = 0, worstPos = 0;
+ // PrintAndLog("Expecting a bit less than %d raw bits", GraphTraceLen / 32);
+ for (i = 0; i < GraphTraceLen-1; i += 2) {
+ count += 1;
+ if ((GraphBuffer[i] > GraphBuffer[i + 1]) && (state != 1)) {
+ if (state == 0) {
+ for (j = 0; j < count - 8; j += 16) {
+ rawbits[rawbit++] = 0;
+ }
+ if ((abs(count - j)) > worst) {
+ worst = abs(count - j);
+ worstPos = i;
+ }
+ }
+ state = 1;
+ count = 0;
+ } else if ((GraphBuffer[i] < GraphBuffer[i + 1]) && (state != 0)) {
+ if (state == 1) {
+ for (j = 0; j < count - 8; j += 16) {
+ rawbits[rawbit++] = 1;
+ }
+ if ((abs(count - j)) > worst) {
+ worst = abs(count - j);
+ worstPos = i;
+ }
+ }
+ state = 0;
+ count = 0;
+ }
+ }
+
+ if ( rawbit>0 ){
+ 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
- int uidlen, long_wait;
- if (strcmp(Cmd, "224") == 0) {
- uidlen = 224;
- long_wait = 30;
- } else {
- uidlen = 64;
- long_wait = 29;
- }
+ // Finding the start of a UID
+ int uidlen, long_wait;
+ if (strcmp(Cmd, "224") == 0) {
+ uidlen = 224;
+ long_wait = 30;
+ } else {
+ uidlen = 64;
+ long_wait = 29;
+ }
- int start;
- int first = 0;
- for (start = 0; start <= rawbit - uidlen; start++) {
- first = rawbits[start];
- for (i = start; i < start + long_wait; i++) {
- if (rawbits[i] != first) {
- break;
- }
- }
- if (i == (start + long_wait)) {
- break;
- }
- }
+ int start;
+ int first = 0;
+ for (start = 0; start <= rawbit - uidlen; start++) {
+ first = rawbits[start];
+ for (i = start; i < start + long_wait; i++) {
+ if (rawbits[i] != first) {
+ break;
+ }
+ }
+ if (i == (start + long_wait)) {
+ break;
+ }
+ }
- if (start == rawbit - uidlen + 1) {
- PrintAndLog("nothing to wait for");
- return 0;
- }
+ if (start == rawbit - uidlen + 1) {
+ PrintAndLog("nothing to wait for");
+ return 0;
+ }
- // Inverting signal if needed
- if (first == 1) {
- for (i = start; i < rawbit; i++) {
- rawbits[i] = !rawbits[i];
- }
- }
+ // Inverting signal if needed
+ if (first == 1) {
+ for (i = start; i < rawbit; i++) {
+ rawbits[i] = !rawbits[i];
+ }
+ }
- // Dumping UID
+ // Dumping UID
uint8_t bits[224] = {0x00};
char showbits[225] = {0x00};
- int bit;
- i = start;
- int times = 0;
+ int bit;
+ i = start;
+ int times = 0;
- if (uidlen > rawbit) {
- PrintAndLog("Warning: not enough raw bits to get a full UID");
- for (bit = 0; bit < rawbit; bit++) {
- bits[bit] = rawbits[i++];
- // As we cannot know the parity, let's use "." and "/"
- showbits[bit] = '.' + bits[bit];
- }
- showbits[bit+1]='\0';
- PrintAndLog("Partial UID=%s", showbits);
- return 0;
- } else {
- for (bit = 0; bit < uidlen; bit++) {
- bits[bit] = rawbits[i++];
- showbits[bit] = '0' + bits[bit];
- }
- times = 1;
- }
+ if (uidlen > rawbit) {
+ PrintAndLog("Warning: not enough raw bits to get a full UID");
+ for (bit = 0; bit < rawbit; bit++) {
+ bits[bit] = rawbits[i++];
+ // As we cannot know the parity, let's use "." and "/"
+ showbits[bit] = '.' + bits[bit];
+ }
+ showbits[bit+1]='\0';
+ PrintAndLog("Partial UID=%s", showbits);
+ return 0;
+ } else {
+ for (bit = 0; bit < uidlen; bit++) {
+ bits[bit] = rawbits[i++];
+ showbits[bit] = '0' + bits[bit];
+ }
+ times = 1;
+ }
- //convert UID to HEX
- uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
- int idx;
+ //convert UID to HEX
+ uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
+ int idx;
uid1 = uid2 = 0;
- if (uidlen==64){
- for( idx=0; idx<64; idx++) {
- if (showbits[idx] == '0') {
- uid1=(uid1<<1)|(uid2>>31);
- uid2=(uid2<<1)|0;
- } else {
- uid1=(uid1<<1)|(uid2>>31);
- uid2=(uid2<<1)|1;
- }
- }
- PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
- }
- else {
+ if (uidlen==64){
+ for( idx=0; idx<64; idx++) {
+ if (showbits[idx] == '0') {
+ uid1 = (uid1<<1) | (uid2>>31);
+ uid2 = (uid2<<1) | 0;
+ } else {
+ uid1 = (uid1<<1) | (uid2>>31);
+ uid2 = (uid2<<1) | 1;
+ }
+ }
+ PrintAndLog("UID=%s (%x%08x)", showbits, uid1, uid2);
+ } else {
uid3 = uid4 = uid5 = uid6 = uid7 = 0;
- for( idx=0; idx<224; idx++) {
- uid1=(uid1<<1)|(uid2>>31);
- uid2=(uid2<<1)|(uid3>>31);
- uid3=(uid3<<1)|(uid4>>31);
- uid4=(uid4<<1)|(uid5>>31);
- uid5=(uid5<<1)|(uid6>>31);
- uid6=(uid6<<1)|(uid7>>31);
-
+ for( idx=0; idx<224; idx++) {
+ uid1 = (uid1<<1) | (uid2>>31);
+ uid2 = (uid2<<1) | (uid3>>31);
+ uid3 = (uid3<<1) | (uid4>>31);
+ uid4 = (uid4<<1) | (uid5>>31);
+ uid5 = (uid5<<1) | (uid6>>31);
+ uid6 = (uid6<<1) | (uid7>>31);
+
if (showbits[idx] == '0')
uid7 = (uid7<<1) | 0;
else
uid7 = (uid7<<1) | 1;
- }
- PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
- }
+ }
+ PrintAndLog("UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
+ }
- // Checking UID against next occurrences
- int failed = 0;
+ // Checking UID against next occurrences
+ int failed = 0;
for (; i + uidlen <= rawbit;) {
failed = 0;
- for (bit = 0; bit < uidlen; bit++) {
- if (bits[bit] != rawbits[i++]) {
- failed = 1;
- break;
- }
- }
- if (failed == 1) {
- break;
- }
- times += 1;
- }
+ for (bit = 0; bit < uidlen; bit++) {
+ if (bits[bit] != rawbits[i++]) {
+ failed = 1;
+ break;
+ }
+ }
+ if (failed == 1) {
+ break;
+ }
+ times += 1;
+ }
- PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
+ PrintAndLog("Occurrences: %d (expected %d)", times, (rawbit - start) / uidlen);
- // Remodulating for tag cloning
+ // Remodulating for tag cloning
// HACK: 2015-01-04 this will have an impact on our new way of seening lf commands (demod)
// since this changes graphbuffer data.
- GraphTraceLen = 32*uidlen;
- i = 0;
- int phase = 0;
- for (bit = 0; bit < uidlen; bit++) {
- if (bits[bit] == 0) {
- phase = 0;
- } else {
- phase = 1;
- }
- int j;
- for (j = 0; j < 32; j++) {
- GraphBuffer[i++] = phase;
- phase = !phase;
- }
- }
+ GraphTraceLen = 32 * uidlen;
+ i = 0;
+ int phase = 0;
+ for (bit = 0; bit < uidlen; bit++) {
+ phase = (bits[bit] == 0) ? 0 : 1;
+ int j;
+ for (j = 0; j < 32; j++) {
+ GraphBuffer[i++] = phase;
+ phase = !phase;
+ }
+ }
- RepaintGraphWindow();
- return 1;
+ RepaintGraphWindow();
+ return 1;
}
int CmdIndalaClone(const char *Cmd)
//by marshmellow
int CmdLFfind(const char *Cmd)
{
- int ans=0;
+ int ans = 0;
char cmdp = param_getchar(Cmd, 0);
char testRaw = param_getchar(Cmd, 1);
- if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') {
- PrintAndLog("Usage: lf search <0|1> [u]");
- PrintAndLog(" <use data from Graphbuffer> , if not set, try reading data from tag.");
- PrintAndLog(" [Search for Unknown tags] , if not set, reads only known tags.");
- PrintAndLog("");
- PrintAndLog(" sample: lf search = try reading data from tag & search for known tags");
- PrintAndLog(" : lf search 1 = use data from GraphBuffer & search for known tags");
- PrintAndLog(" : lf search u = try reading data from tag & search for known and unknown tags");
- PrintAndLog(" : lf search 1 u = use data from GraphBuffer & search for known and unknown tags");
-
- return 0;
- }
+ if (strlen(Cmd) > 3 || cmdp == 'h' || cmdp == 'H') return usage_lf_find();
if (!offline && (cmdp != '1')){
- CmdLFRead("s");
- getSamples("30000",false);
+ CmdLFRead("s");
+ getSamples("30000",false);
} else if (GraphTraceLen < 1000) {
PrintAndLog("Data in Graphbuffer was too small.");
return 0;
return 1;
}
+ ans=CmdVikingDemod("");
+ if (ans>0) {
+ PrintAndLog("\nValid Viking ID Found!");
+ return 1;
+ }
+
ans=CmdPSKNexWatch("");
if (ans>0) {
PrintAndLog("\nValid NexWatch ID Found!");
}
}
}
- ans=GetFskClock("",FALSE,FALSE);
+ ans=GetFskClock("",FALSE,FALSE);
if (ans != 0){ //fsk
- ans=FSKrawDemod("",TRUE);
- if (ans>0) {
- PrintAndLog("\nUnknown FSK Modulated Tag Found!");
- return 1;
- }
+ ans=FSKrawDemod("",TRUE);
+ if (ans>0) {
+ PrintAndLog("\nUnknown FSK Modulated Tag Found!");
+ return 1;
+ }
}
- ans=ASKDemod("0 0 0",TRUE,FALSE,1);
+ ans=ASKDemod("0 0 0",TRUE,FALSE,1);
if (ans>0) {
PrintAndLog("\nUnknown ASK Modulated and Manchester encoded Tag Found!");
PrintAndLog("\nif it does not look right it could instead be ASK/Biphase - try 'data rawdemod ab'");
}
ans=CmdPSK1rawDemod("");
if (ans>0) {
- PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
- PrintAndLog("\nCould also be PSK3 - [currently not supported]");
- PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
- return 1;
+ PrintAndLog("Possible unknown PSK1 Modulated Tag Found above!\n\nCould also be PSK2 - try 'data rawdemod p2'");
+ PrintAndLog("\nCould also be PSK3 - [currently not supported]");
+ PrintAndLog("\nCould also be NRZ - try 'data nrzrawdemod");
+ return 1;
}
PrintAndLog("\nNo Data Found!\n");
}
#include "cmdlfviking.h"
#include "lfdemod.h"
static int CmdHelp(const char *Cmd);
+
+int usage_lf_viking_clone(void){
+ PrintAndLog("clone a Viking AM tag to a T55x7 tag.");
+ PrintAndLog("Usage: lf viking clone <Card ID 16 bytes of hex number>");
+ return 0;
+}
+
+//by marshmellow
+//see ASKDemod for what args are accepted
int CmdVikingDemod(const char *Cmd)
{
- uint8_t id[4];
- if (param_gethex(Cmd,0,id,8) == 1)
- {
- PrintAndLog("Usage: lf viking demod <CardID 8 bytes of hex number>");
- return 0;
- }
- UsbCommand c = {CMD_ACQUIRE_RAW_ADC_SAMPLES_125K, {false,0,0}};
- SendCommand(&c);
- WaitForResponse(CMD_ACK,NULL);
- getSamples("40000",true);
- // try to demod AMViking
- return AMVikingDemod(id);
+ CmdLFRead("s");
+ getSamples("30000",false);
+
+ if (!ASKDemod(Cmd, false, false, 1)) {
+ if (g_debugMode) PrintAndLog("ASKDemod failed");
+ return 0;
+ }
+ size_t size = DemodBufferLen;
+
+ int ans = VikingDemod_AM(DemodBuffer, &size);
+ if (ans < 0) {
+ if (g_debugMode) PrintAndLog("Error Viking_Demod");
+ return 0;
+ }
+ //got a good demod
+ uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans, 32);
+ uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
+ uint32_t cardid = bytebits_to_byte(DemodBuffer+ans+24, 32);
+ uint8_t checksum = bytebits_to_byte(DemodBuffer+ans+32+24, 8);
+ PrintAndLog("Viking Tag Found: Card ID %08X, Checksum: %02X", cardid, checksum);
+ PrintAndLog("Raw: %08X%08X", raw1,raw2);
+ setDemodBuf(DemodBuffer+ans, 64, 0);
+ return 1;
}
+
int CmdVikingClone(const char *Cmd)
{
uint32_t b1,b2;
// get the tag number 64 bits (8 bytes) in hex
uint8_t id[8];
- if (param_gethex(Cmd,0,id,16) == 1)
- {
- PrintAndLog("Usage: lf viking clone <Card ID 16 bytes of hex number>");
- return 0;
- }
- b1 = bytes_to_num(id,sizeof(uint32_t));
- b2 = bytes_to_num(id + sizeof(uint32_t),sizeof(uint32_t));
+
+ char cmdp = param_getchar(Cmd, 0);
+ if (strlen(Cmd) < 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_viking_clone();
+
+ if (param_gethex(Cmd, 0, id, 16) == 1)
+ return usage_lf_viking_clone();
+
+ b1 = bytes_to_num(id, sizeof(uint32_t));
+ b2 = bytes_to_num(id + sizeof(uint32_t), sizeof(uint32_t));
UsbCommand c = {CMD_VIKING_CLONE_TAG,{b1,b2}};
- SendCommand(&c);
+ clearCommandBuffer();
+ SendCommand(&c);
+ //check for ACK?
return 0;
}
static command_t CommandTable[] =
{
- {"help", CmdHelp, 1, "This help"},
- {"demod",CmdVikingDemod ,1, "<8 digits tag id> -- Extract tag data"},
- {"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"},
+ {"help", CmdHelp, 1, "This help"},
+ {"demod", CmdVikingDemod, 1, "Extract tag data"},
+ {"clone", CmdVikingClone, 1, "<16 digits card data> clone viking tag"},
{NULL, NULL, 0, NULL}
};
return -5;
}
+// by marshmellow
+// find viking preamble 0xF200 in already demoded data
+int VikingDemod_AM(uint8_t *dest, size_t *size) {
+ if (justNoise(dest, *size)) return -1;
+ //make sure buffer has data
+ if (*size < 64*2) return -2;
+
+ size_t startIdx = 0;
+ uint8_t preamble[] = {1,1,1,1,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0};
+ uint8_t errChk = preambleSearch(dest, preamble, sizeof(preamble), size, &startIdx);
+ if (errChk == 0) return -4; //preamble not found
+ uint32_t checkCalc = bytebits_to_byte(dest+startIdx,8) ^ bytebits_to_byte(dest+startIdx+8,8) ^ bytebits_to_byte(dest+startIdx+16,8)
+ ^ bytebits_to_byte(dest+startIdx+24,8) ^ bytebits_to_byte(dest+startIdx+32,8) ^ bytebits_to_byte(dest+startIdx+40,8)
+ ^ bytebits_to_byte(dest+startIdx+48,8) ^ bytebits_to_byte(dest+startIdx+56,8);
+ if ( checkCalc != 0xA8 ) return -5;
+ if (*size != 64) return -5;
+ //return start position
+ return (int) startIdx;
+}
+
// by marshmellow
// takes a array of binary values, start position, length of bits per parity (includes parity bit),
// Parity Type (1 for odd; 0 for even; 2 Always 1's), and binary Length (length to run)
*size = numBits;
return errCnt;
}
-// on successful return 1 otherwise return 0
-int VikingDecode(uint8_t *BitStream,
- size_t size,
- size_t *startIdx,
- uint8_t *id_bits,
- size_t id_bits_size)
-{
- //no arguments needed - built this way in case we want this to be a direct call from "data " cmds in the future
- // otherwise could be a void with no arguments
- //set defaults
- uint32_t i = 0;
- uint32_t lastcheckindex = size - (id_bits_size * 2);
- int found = 0;
- while (i < lastcheckindex)
- {
- if (memcmp(BitStream + i,id_bits,id_bits_size) == 0)
- {
- *startIdx = i;
- found = 1;
- break;
- }
- i++;
- }
- return found;
-}
-
-
int HIDdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
int IOdemodFSK(uint8_t *dest, size_t size);
int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert);
-int PyramiddemodFSK(uint8_t *dest, size_t *size);
int ParadoxdemodFSK(uint8_t *dest, size_t *size, uint32_t *hi2, uint32_t *hi, uint32_t *lo);
-int VikingDecode(uint8_t *BitStream, size_t size, size_t *startIdx,uint8_t *id_bit,size_t id_bits_size);
+int PyramiddemodFSK(uint8_t *dest, size_t *size);
+int VikingDemod_AM(uint8_t *dest, size_t *size);
#endif