mirror of
https://github.com/Proxmark/proxmark3.git
synced 2025-07-07 13:41:18 -07:00
lf improvements
fix noralsy demod bug (st should be true) fix sprint_bin_break bug (didn't print last bit) add a function to save/restore demodbuffer remove redundant countFC call in PSKDemod clean up pskclockdetect functions fix indala26decode bug (end of data sometimes not correct) improve PSK detection / demodulation improve NRZ detection improve t55xx commands & fix a few bugs add t55xx page1 detection - added it to lf search added experimental t55xx testmode write
This commit is contained in:
parent
6a772a1273
commit
b97311b1bd
13 changed files with 466 additions and 238 deletions
|
@ -54,6 +54,7 @@ This project uses the changelog in accordance with [keepchangelog](http://keepac
|
|||
- Added option c to 'hf list' (mark CRC bytes) (piwi)
|
||||
|
||||
### Changed
|
||||
- `lf t5 wakeup` has been adjusted to not need the p in front of the pwd arg.
|
||||
- `data psknexwatchdemod` has been moved to `lf nexwatch demod` (reads from graphbuffer)
|
||||
- `data fskparadoxdemod` has been moved to `lf paradox demod` (reads from graphbuffer)
|
||||
- `data fdxdemod` has been moved to `lf fdx demod` (reads from graphbuffer)
|
||||
|
|
|
@ -1096,7 +1096,7 @@ void CmdIOdemodFSK(int findone, int *high, int *low, int ledcontrol)
|
|||
void TurnReadLFOn(int delay) {
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_LF_ADC | FPGA_LF_ADC_READER_FIELD);
|
||||
// Give it a bit of time for the resonant antenna to settle.
|
||||
SpinDelayUs(delay); //155*8 //50*8
|
||||
WaitUS(delay); //155*8 //50*8
|
||||
}
|
||||
|
||||
// Write one bit to card
|
||||
|
@ -1106,7 +1106,7 @@ void T55xxWriteBit(int bit) {
|
|||
else
|
||||
TurnReadLFOn(WRITE_1);
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(WRITE_GAP);
|
||||
WaitUS(WRITE_GAP);
|
||||
}
|
||||
|
||||
// Send T5577 reset command then read stream (see if we can identify the start of the stream)
|
||||
|
@ -1117,16 +1117,18 @@ void T55xxResetRead(void) {
|
|||
|
||||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
StartTicks();
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(5);
|
||||
|
||||
// Trigger T55x7 in mode.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
WaitUS(START_GAP);
|
||||
|
||||
// reset tag - op code 00
|
||||
T55xxWriteBit(0);
|
||||
T55xxWriteBit(0);
|
||||
|
||||
// Turn field on to read the response
|
||||
TurnReadLFOn(READ_GAP);
|
||||
|
||||
// Acquisition
|
||||
|
@ -1143,18 +1145,22 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg
|
|||
LED_A_ON();
|
||||
bool PwdMode = arg & 0x1;
|
||||
uint8_t Page = (arg & 0x2)>>1;
|
||||
bool testMode = arg & 0x4;
|
||||
uint32_t i = 0;
|
||||
|
||||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
StartTicks();
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(5);
|
||||
// Trigger T55x7 in mode.
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
WaitUS(START_GAP);
|
||||
|
||||
// Opcode 10
|
||||
T55xxWriteBit(1);
|
||||
T55xxWriteBit(Page); //Page 0
|
||||
if (testMode) Dbprintf("TestMODE");
|
||||
// Std Opcode 10
|
||||
T55xxWriteBit(testMode ? 0 : 1);
|
||||
T55xxWriteBit(testMode ? 1 : Page); //Page 0
|
||||
if (PwdMode){
|
||||
// Send Pwd
|
||||
for (i = 0x80000000; i != 0; i >>= 1)
|
||||
|
@ -1173,11 +1179,31 @@ void T55xxWriteBlockExt(uint32_t Data, uint32_t Block, uint32_t Pwd, uint8_t arg
|
|||
|
||||
// Perform write (nominal is 5.6 ms for T55x7 and 18ms for E5550,
|
||||
// so wait a little more)
|
||||
|
||||
// "there is a clock delay before programming"
|
||||
// - programming takes ~5.6ms for t5577 ~18ms for E5550
|
||||
// so we should wait 1 clock + 5.6ms then read response?
|
||||
// but we need to know we are dealing with t55x7 vs e5550 (or q5) marshmellow...
|
||||
if (testMode) {
|
||||
// Turn field on to read the response
|
||||
TurnReadLFOn(READ_GAP);
|
||||
|
||||
// Acquisition
|
||||
// Now do the acquisition
|
||||
// Now do the acquisition
|
||||
DoPartialAcquisition(20, true, 12000);
|
||||
|
||||
//doT55x7Acquisition(12000);
|
||||
} else {
|
||||
TurnReadLFOn(20 * 1000);
|
||||
}
|
||||
//could attempt to do a read to confirm write took
|
||||
// as the tag should repeat back the new block
|
||||
// until it is reset, but to confirm it we would
|
||||
// need to know the current block 0 config mode
|
||||
// need to know the current block 0 config mode for
|
||||
// modulation clock an other details to demod the response...
|
||||
// response should be (for t55x7) a 0 bit then (ST if on)
|
||||
// block data written in on repeat until reset.
|
||||
|
||||
// turn field off
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
|
@ -1206,10 +1232,12 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
|||
|
||||
// Set up FPGA, 125kHz to power up the tag
|
||||
LFSetupFPGAForADC(95, true);
|
||||
|
||||
StartTicks();
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(5);
|
||||
// Trigger T55x7 Direct Access Mode with start gap
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
WaitUS(START_GAP);
|
||||
|
||||
// Opcode 1[page]
|
||||
T55xxWriteBit(1);
|
||||
|
@ -1229,10 +1257,13 @@ void T55xxReadBlock(uint16_t arg0, uint8_t Block, uint32_t Pwd) {
|
|||
T55xxWriteBit(Block & i);
|
||||
|
||||
// Turn field on to read the response
|
||||
TurnReadLFOn(READ_GAP);
|
||||
TurnReadLFOn(135*8);
|
||||
|
||||
// Acquisition
|
||||
doT55x7Acquisition(12000);
|
||||
// Now do the acquisition
|
||||
DoPartialAcquisition(0, true, 12000);
|
||||
|
||||
// doT55x7Acquisition(12000);
|
||||
|
||||
// Turn the field off
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF); // field off
|
||||
|
@ -1246,10 +1277,13 @@ void T55xxWakeUp(uint32_t Pwd){
|
|||
|
||||
// Set up FPGA, 125kHz
|
||||
LFSetupFPGAForADC(95, true);
|
||||
StartTicks();
|
||||
// make sure tag is fully powered up...
|
||||
WaitMS(5);
|
||||
|
||||
// Trigger T55x7 Direct Access Mode
|
||||
FpgaWriteConfWord(FPGA_MAJOR_MODE_OFF);
|
||||
SpinDelayUs(START_GAP);
|
||||
WaitUS(START_GAP);
|
||||
|
||||
// Opcode 10
|
||||
T55xxWriteBit(1);
|
||||
|
@ -1367,7 +1401,7 @@ void CopyIndala224toT55x7(uint32_t uid1, uint32_t uid2, uint32_t uid3, uint32_t
|
|||
// clone viking tag to T55xx
|
||||
void CopyVikingtoT55xx(uint32_t block1, uint32_t block2, uint8_t Q5) {
|
||||
uint32_t data[] = {T55x7_BITRATE_RF_32 | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT), block1, block2};
|
||||
if (Q5) data[0] = ( ((32-2)>>1) << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
if (Q5) data[0] = T5555_SET_BITRATE(32) | T5555_MODULATION_MANCHESTER | 2 << T5555_MAXBLOCK_SHIFT;
|
||||
// Program the data blocks for supplied ID and the block 0 config
|
||||
WriteT55xx(data, 0, 3);
|
||||
LED_D_OFF();
|
||||
|
@ -1451,8 +1485,7 @@ void WriteEM410x(uint32_t card, uint32_t id_hi, uint32_t id_lo) {
|
|||
}
|
||||
data[0] = clock | T55x7_MODULATION_MANCHESTER | (2 << T55x7_MAXBLOCK_SHIFT);
|
||||
} else { //t5555 (Q5)
|
||||
clock = (clock-2)>>1; //n = (RF-2)/2
|
||||
data[0] = (clock << T5555_BITRATE_SHIFT) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
|
||||
data[0] = T5555_SET_BITRATE(clock) | T5555_MODULATION_MANCHESTER | (2 << T5555_MAXBLOCK_SHIFT);
|
||||
}
|
||||
|
||||
WriteT55xx(data, 0, 3);
|
||||
|
|
|
@ -51,6 +51,24 @@ void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx)
|
|||
return;
|
||||
}
|
||||
|
||||
// option '1' to save DemodBuffer any other to restore
|
||||
void save_restoreDB(uint8_t saveOpt)
|
||||
{
|
||||
static uint8_t SavedDB[MAX_GRAPH_TRACE_LEN];
|
||||
static size_t SavedDBlen;
|
||||
static bool DB_Saved = false;
|
||||
|
||||
if (saveOpt==1) { //save
|
||||
memcpy(SavedDB, DemodBuffer, sizeof(DemodBuffer));
|
||||
SavedDBlen = DemodBufferLen;
|
||||
DB_Saved=true;
|
||||
} else if (DB_Saved){ //restore
|
||||
memcpy(DemodBuffer, SavedDB, sizeof(DemodBuffer));
|
||||
DemodBufferLen = SavedDBlen;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
int CmdSetDebugMode(const char *Cmd)
|
||||
{
|
||||
int demod=0;
|
||||
|
@ -200,6 +218,11 @@ int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType,
|
|||
CursorCPos = ststart;
|
||||
CursorDPos = stend;
|
||||
if (verbose || g_debugMode) PrintAndLog("\nFound Sequence Terminator - First one is shown by orange and blue graph markers");
|
||||
//Graph ST trim (for testing)
|
||||
//for (int i = 0; i < BitLen; i++) {
|
||||
// GraphBuffer[i] = BitStream[i]-128;
|
||||
//}
|
||||
//RepaintGraphWindow();
|
||||
}
|
||||
int errCnt = askdemod(BitStream, &BitLen, &clk, &invert, maxErr, askamp, askType);
|
||||
if (errCnt<0 || BitLen<16){ //if fatal error (or -1)
|
||||
|
@ -818,14 +841,6 @@ int PSKDemod(const char *Cmd, bool verbose)
|
|||
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
|
||||
size_t BitLen = getFromGraphBuf(BitStream);
|
||||
if (BitLen==0) return 0;
|
||||
uint8_t carrier=countFC(BitStream, BitLen, 0);
|
||||
if (carrier!=2 && carrier!=4 && carrier!=8){
|
||||
//invalid carrier
|
||||
return 0;
|
||||
}
|
||||
if (g_debugMode){
|
||||
PrintAndLog("Carrier: rf/%d",carrier);
|
||||
}
|
||||
int errCnt=0;
|
||||
errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert);
|
||||
if (errCnt > maxErr){
|
||||
|
|
|
@ -22,6 +22,7 @@ command_t * CmdDataCommands();
|
|||
int CmdData(const char *Cmd);
|
||||
void printDemodBuff(void);
|
||||
void setDemodBuf(uint8_t *buff, size_t size, size_t startIdx);
|
||||
void save_restoreDB(uint8_t saveOpt);// option '1' to save DemodBuffer any other to restore
|
||||
int CmdPrintDemodBuff(const char *Cmd);
|
||||
int Cmdaskrawdemod(const char *Cmd);
|
||||
int Cmdaskmandemod(const char *Cmd);
|
||||
|
@ -68,6 +69,8 @@ int getSamples(const char *Cmd, bool silent);
|
|||
extern uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
|
||||
extern size_t DemodBufferLen;
|
||||
extern uint8_t g_debugMode;
|
||||
//extern size_t g_demodStartIdx;
|
||||
//extern uint8_t g_demodClock;
|
||||
#define BIGBUF_SIZE 40000
|
||||
|
||||
#endif
|
||||
|
|
|
@ -863,17 +863,26 @@ int CheckChipType(char cmdp) {
|
|||
|
||||
//check for em4x05/em4x69 chips first
|
||||
save_restoreGB(1);
|
||||
save_restoreDB(1);
|
||||
if ((!offline && (cmdp != '1')) && EM4x05Block0Test(&wordData)) {
|
||||
PrintAndLog("\nValid EM4x05/EM4x69 Chip Found\nTry lf em 4x05... commands\n");
|
||||
save_restoreGB(0);
|
||||
save_restoreDB(0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
//TODO check for t55xx chip...
|
||||
|
||||
if ((!offline && (cmdp != '1')) && tryDetectP1(true)) {
|
||||
PrintAndLog("\nValid T55xx Chip Found\nTry lf t55xx ... commands\n");
|
||||
save_restoreGB(0);
|
||||
save_restoreDB(0);
|
||||
return 1;
|
||||
}
|
||||
save_restoreGB(0);
|
||||
save_restoreDB(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
int CmdLFfind(const char *Cmd)
|
||||
|
@ -932,6 +941,8 @@ int CmdLFfind(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
// TODO test for modulation then only test formats that use that modulation
|
||||
|
||||
ans=CmdFSKdemodIO("");
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid IO Prox ID Found!");
|
||||
|
@ -980,13 +991,13 @@ int CmdLFfind(const char *Cmd)
|
|||
return CheckChipType(cmdp);
|
||||
}
|
||||
|
||||
ans=CmdFdxDemod("");
|
||||
ans=CmdFdxDemod(""); //biphase
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid FDX-B ID Found!");
|
||||
return CheckChipType(cmdp);
|
||||
}
|
||||
|
||||
ans=EM4x50Read("", false);
|
||||
ans=EM4x50Read("", false); //ask
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid EM4x50 ID Found!");
|
||||
return 1;
|
||||
|
@ -1016,7 +1027,7 @@ int CmdLFfind(const char *Cmd)
|
|||
return CheckChipType(cmdp);
|
||||
}
|
||||
|
||||
ans=CmdIndalaDecode("");
|
||||
ans=CmdIndalaDecode(""); //psk
|
||||
if (ans>0) {
|
||||
PrintAndLog("\nValid Indala ID Found!");
|
||||
return CheckChipType(cmdp);
|
||||
|
|
|
@ -111,7 +111,7 @@ int NoralsyDemod_AM(uint8_t *dest, size_t *size) {
|
|||
int CmdNoralsyDemod(const char *Cmd) {
|
||||
|
||||
//ASK / Manchester
|
||||
bool st = false;
|
||||
bool st = true;
|
||||
if (!ASKDemod_ext("32 0 0", false, false, 1, &st)) {
|
||||
if (g_debugMode) PrintAndLog("DEBUG: Error - Noralsy: ASK/Manchester Demod failed");
|
||||
return 0;
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "data.h"
|
||||
#include "lfdemod.h"
|
||||
#include "cmdhf14a.h" //for getTagInfo
|
||||
#include "protocols.h"
|
||||
|
||||
#define T55x7_CONFIGURATION_BLOCK 0x00
|
||||
#define T55x7_PAGE0 0x00
|
||||
|
@ -78,12 +79,13 @@ int usage_t55xx_read(){
|
|||
return 0;
|
||||
}
|
||||
int usage_t55xx_write(){
|
||||
PrintAndLog("Usage: lf t55xx write [b <block>] [d <data>] [p <password>] [1]");
|
||||
PrintAndLog("Usage: lf t55xx write [b <block>] [d <data>] [p <password>] [1] [t]");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" b <block> - block number to write. Between 0-7");
|
||||
PrintAndLog(" d <data> - 4 bytes of data to write (8 hex characters)");
|
||||
PrintAndLog(" p <password> - OPTIONAL password 4bytes (8 hex characters)");
|
||||
PrintAndLog(" 1 - OPTIONAL write Page 1 instead of Page 0");
|
||||
PrintAndLog(" t - OPTIONAL test mode write - ****DANGER****");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf t55xx write b 3 d 11223344 - write 11223344 to block 3");
|
||||
|
@ -138,15 +140,28 @@ int usage_t55xx_detect(){
|
|||
PrintAndLog("");
|
||||
return 0;
|
||||
}
|
||||
int usage_t55xx_detectP1(){
|
||||
PrintAndLog("Usage: lf t55xx page1detect [1] [p <password>]");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" 1 - if set, use Graphbuffer otherwise read data from tag.");
|
||||
PrintAndLog(" p <password> - OPTIONAL password (8 hex characters)");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf t55xx page1detect");
|
||||
PrintAndLog(" lf t55xx page1detect 1");
|
||||
PrintAndLog(" lf t55xx page1detect p 11223344");
|
||||
PrintAndLog("");
|
||||
return 0;
|
||||
}
|
||||
int usage_t55xx_wakup(){
|
||||
PrintAndLog("Usage: lf t55xx wakeup [h] p <password>");
|
||||
PrintAndLog("Usage: lf t55xx wakeup [h] <password>");
|
||||
PrintAndLog("This commands send the Answer-On-Request command and leaves the readerfield ON afterwards.");
|
||||
PrintAndLog("Options:");
|
||||
PrintAndLog(" h - this help");
|
||||
PrintAndLog(" p <password> - password 4bytes (8 hex symbols)");
|
||||
PrintAndLog(" <password> - [required] password 4bytes (8 hex symbols)");
|
||||
PrintAndLog("");
|
||||
PrintAndLog("Examples:");
|
||||
PrintAndLog(" lf t55xx wakeup p 11223344 - send wakeup password");
|
||||
PrintAndLog(" lf t55xx wakeup 11223344 - send wakeup password");
|
||||
return 0;
|
||||
}
|
||||
int usage_t55xx_bruteforce(){
|
||||
|
@ -490,9 +505,10 @@ bool tryDetectModulation(){
|
|||
uint8_t hits = 0;
|
||||
t55xx_conf_block_t tests[15];
|
||||
int bitRate=0;
|
||||
uint8_t fc1 = 0, fc2 = 0, clk=0;
|
||||
if (GetFskClock("", false, false)){
|
||||
fskClocks(&fc1, &fc2, &clk, false);
|
||||
uint8_t fc1 = 0, fc2 = 0, ans = 0;
|
||||
int clk=0;
|
||||
ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, false);
|
||||
if (ans && ((fc1==10 && fc2==8) || (fc1==8 && fc2==5))) {
|
||||
if ( FSKrawDemod("0 0", false) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
|
||||
tests[hits].modulation = DEMOD_FSK;
|
||||
if (fc1==8 && fc2 == 5)
|
||||
|
@ -553,8 +569,6 @@ bool tryDetectModulation(){
|
|||
++hits;
|
||||
}
|
||||
}
|
||||
//undo trim from ask
|
||||
//save_restoreGB(0);
|
||||
clk = GetNrzClock("", false, false);
|
||||
if (clk>0) {
|
||||
if ( NRZrawDemod("0 0 1", false) && test(DEMOD_NRZ, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
|
||||
|
@ -576,12 +590,12 @@ bool tryDetectModulation(){
|
|||
}
|
||||
}
|
||||
|
||||
// allow undo
|
||||
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
|
||||
save_restoreGB(1);
|
||||
CmdLtrim("160");
|
||||
clk = GetPskClock("", false, false);
|
||||
if (clk>0) {
|
||||
// allow undo
|
||||
save_restoreGB(1);
|
||||
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
|
||||
CmdLtrim("160");
|
||||
if ( PSKDemod("0 0 6", false) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
|
||||
tests[hits].modulation = DEMOD_PSK1;
|
||||
tests[hits].bitrate = bitRate;
|
||||
|
@ -622,10 +636,10 @@ bool tryDetectModulation(){
|
|||
++hits;
|
||||
}
|
||||
} // inverse waves does not affect this demod
|
||||
}
|
||||
//undo trim samples
|
||||
save_restoreGB(0);
|
||||
}
|
||||
}
|
||||
if ( hits == 1) {
|
||||
config.modulation = tests[0].modulation;
|
||||
config.bitrate = tests[0].bitrate;
|
||||
|
@ -780,9 +794,7 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
|
|||
// moved test to here, since this gets most faults first.
|
||||
if ( resv > 0x00) continue;
|
||||
|
||||
uint8_t xtRate = PackBits(si, 3, DemodBuffer); si += 3; //extended mode part of rate
|
||||
int bitRate = PackBits(si, 3, DemodBuffer); si += 3; //bit rate
|
||||
if (bitRate > 7) continue;
|
||||
int bitRate = PackBits(si, 6, DemodBuffer); si += 6; //bit rate (includes extended mode part of rate)
|
||||
uint8_t extend = PackBits(si, 1, DemodBuffer); si += 1; //bit 15 extended mode
|
||||
uint8_t modread = PackBits(si, 5, DemodBuffer); si += 5+2+1;
|
||||
//uint8_t pskcr = PackBits(si, 2, DemodBuffer); si += 2+1; //could check psk cr
|
||||
|
@ -793,11 +805,13 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
|
|||
bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? true : false;
|
||||
|
||||
if (!extMode) {
|
||||
if (xtRate) continue; //nml01 || nml02 || caused issues on noralys tags
|
||||
if (bitRate > 7) continue;
|
||||
if (!testBitRate(bitRate, clk)) continue;
|
||||
} else { //extended mode bitrate = same function to calc bitrate as em4x05
|
||||
if (EM4x05_GET_BITRATE(bitRate) != clk) continue;
|
||||
}
|
||||
//test modulation
|
||||
if (!testModulation(mode, modread)) continue;
|
||||
if (!testBitRate(bitRate, clk)) continue;
|
||||
*fndBitRate = bitRate;
|
||||
*offset = idx;
|
||||
*Q5 = false;
|
||||
|
@ -854,7 +868,7 @@ int special(const char *Cmd) {
|
|||
int printConfiguration( t55xx_conf_block_t b){
|
||||
PrintAndLog("Chip Type : %s", (b.Q5) ? "T5555(Q5)" : "T55x7");
|
||||
PrintAndLog("Modulation : %s", GetSelectedModulationStr(b.modulation) );
|
||||
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );
|
||||
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate, (b.block0 & T55x7_X_MODE)) );
|
||||
PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );
|
||||
PrintAndLog("Offset : %d", b.offset);
|
||||
PrintAndLog("Seq. Term. : %s", (b.ST) ? "Yes" : "No" );
|
||||
|
@ -865,26 +879,11 @@ int printConfiguration( t55xx_conf_block_t b){
|
|||
|
||||
int CmdT55xxWakeUp(const char *Cmd) {
|
||||
uint32_t password = 0;
|
||||
uint8_t cmdp = 0;
|
||||
bool errors = true;
|
||||
while(param_getchar(Cmd, cmdp) != 0x00) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_t55xx_wakup();
|
||||
case 'p':
|
||||
case 'P':
|
||||
password = param_get32ex(Cmd, cmdp+1, 0xFFFFFFFF, 16);
|
||||
cmdp += 2;
|
||||
errors = false;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (errors) return usage_t55xx_wakup();
|
||||
if ( strlen(Cmd) <= 0 ) return usage_t55xx_wakup();
|
||||
char cmdp = param_getchar(Cmd, 0);
|
||||
if ( cmdp == 'h' || cmdp == 'H') return usage_t55xx_wakup();
|
||||
|
||||
password = param_get32ex(Cmd, 0, 0, 16);
|
||||
|
||||
UsbCommand c = {CMD_T55XX_WAKEUP, {password, 0, 0}};
|
||||
clearCommandBuffer();
|
||||
|
@ -900,6 +899,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
|||
bool usepwd = false;
|
||||
bool page1 = false;
|
||||
bool gotdata = false;
|
||||
bool testMode = false;
|
||||
bool errors = false;
|
||||
uint8_t cmdp = 0;
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
|
@ -924,6 +924,11 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
|||
usepwd = true;
|
||||
cmdp += 2;
|
||||
break;
|
||||
case 't':
|
||||
case 'T':
|
||||
testMode = true;
|
||||
cmdp++;
|
||||
break;
|
||||
case '1':
|
||||
page1 = true;
|
||||
cmdp++;
|
||||
|
@ -944,6 +949,7 @@ int CmdT55xxWriteBlock(const char *Cmd) {
|
|||
UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {data, block, 0}};
|
||||
UsbCommand resp;
|
||||
c.d.asBytes[0] = (page1) ? 0x2 : 0;
|
||||
c.d.asBytes[0] |= (testMode) ? 0x4 : 0;
|
||||
|
||||
char pwdStr[16] = {0};
|
||||
snprintf(pwdStr, sizeof(pwdStr), "pwd: 0x%08X", password);
|
||||
|
@ -1168,7 +1174,7 @@ int CmdT55xxInfo(const char *Cmd){
|
|||
PrintAndLog("-------------------------------------------------------------");
|
||||
PrintAndLog(" Safer key : %s", GetSaferStr(safer));
|
||||
PrintAndLog(" reserved : %d", resv);
|
||||
PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr));
|
||||
PrintAndLog(" Data bit rate : %s", GetBitRateStr(dbr, extend));
|
||||
PrintAndLog(" eXtended mode : %s", (extend) ? "Yes - Warning":"No");
|
||||
PrintAndLog(" Modulation : %s", GetModulationStr(datamod));
|
||||
PrintAndLog(" PSK clock frequency : %d", pskcf);
|
||||
|
@ -1234,10 +1240,13 @@ int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password ){
|
|||
return 1;
|
||||
}
|
||||
|
||||
char * GetBitRateStr(uint32_t id) {
|
||||
char * GetBitRateStr(uint32_t id, bool xmode) {
|
||||
static char buf[25];
|
||||
|
||||
char *retStr = buf;
|
||||
if (xmode) { //xmode bitrate calc is same as em4x05 calc
|
||||
snprintf(retStr,sizeof(buf),"%d - RF/%d", id, EM4x05_GET_BITRATE(id));
|
||||
} else {
|
||||
switch (id) {
|
||||
case 0: snprintf(retStr,sizeof(buf),"%d - RF/8",id); break;
|
||||
case 1: snprintf(retStr,sizeof(buf),"%d - RF/16",id); break;
|
||||
|
@ -1249,6 +1258,7 @@ char * GetBitRateStr(uint32_t id) {
|
|||
case 7: snprintf(retStr,sizeof(buf),"%d - RF/128",id); break;
|
||||
default: snprintf(retStr,sizeof(buf),"%d - (Unknown)",id); break;
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
|
@ -1540,11 +1550,160 @@ int CmdT55xxBruteForce(const char *Cmd) {
|
|||
return 0;
|
||||
}
|
||||
|
||||
// note length of data returned is different for different chips.
|
||||
// some return all page 1 (64 bits) and others return just that block (32 bits)
|
||||
// unfortunately the 64 bits makes this more likely to get a false positive...
|
||||
bool tryDetectP1(bool getData) {
|
||||
uint8_t preamble[] = {1,1,1,0,0,0,0,0,0,0,0,1,0,1,0,1};
|
||||
size_t startIdx = 0;
|
||||
uint8_t fc1 = 0, fc2 = 0, ans = 0;
|
||||
int clk = 0;
|
||||
bool st = true;
|
||||
|
||||
if ( getData ) {
|
||||
if ( !AquireData(T55x7_PAGE1, 1, false, 0) )
|
||||
return false;
|
||||
}
|
||||
|
||||
// try fsk clock detect. if successful it cannot be any other type of modulation... (in theory...)
|
||||
ans = fskClocks(&fc1, &fc2, (uint8_t *)&clk, false);
|
||||
if (ans && ((fc1==10 && fc2==8) || (fc1==8 && fc2==5))) {
|
||||
if ( FSKrawDemod("0 0", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
if ( FSKrawDemod("0 1", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// try psk clock detect. if successful it cannot be any other type of modulation... (in theory...)
|
||||
clk = GetPskClock("", false, false);
|
||||
if (clk>0) {
|
||||
// allow undo
|
||||
// save_restoreGB(1);
|
||||
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
|
||||
//CmdLtrim("160");
|
||||
if ( PSKDemod("0 0 6", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
//save_restoreGB(0);
|
||||
return true;
|
||||
}
|
||||
if ( PSKDemod("0 1 6", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
//save_restoreGB(0);
|
||||
return true;
|
||||
}
|
||||
// PSK2 - needs a call to psk1TOpsk2.
|
||||
if ( PSKDemod("0 0 6", false)) {
|
||||
psk1TOpsk2(DemodBuffer, DemodBufferLen);
|
||||
if (preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
//save_restoreGB(0);
|
||||
return true;
|
||||
}
|
||||
} // inverse waves does not affect PSK2 demod
|
||||
//undo trim samples
|
||||
//save_restoreGB(0);
|
||||
// no other modulation clocks = 2 or 4 so quit searching
|
||||
if (fc1 != 8) return false;
|
||||
}
|
||||
|
||||
// try ask clock detect. it could be another type even if successful.
|
||||
clk = GetAskClock("", false, false);
|
||||
if (clk>0) {
|
||||
if ( ASKDemod_ext("0 0 1", false, false, 1, &st) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
st = true;
|
||||
if ( ASKDemod_ext("0 1 1", false, false, 1, &st) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
if ( ASKbiphaseDemod("0 0 0 2", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
if ( ASKbiphaseDemod("0 0 1 2", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// try NRZ clock detect. it could be another type even if successful.
|
||||
clk = GetNrzClock("", false, false); //has the most false positives :(
|
||||
if (clk>0) {
|
||||
if ( NRZrawDemod("0 0 1", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
if ( NRZrawDemod("0 1 1", false) &&
|
||||
preambleSearchEx(DemodBuffer,preamble,sizeof(preamble),&DemodBufferLen,&startIdx,false) &&
|
||||
(DemodBufferLen == 32 || DemodBufferLen == 64) ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
// does this need to be a callable command?
|
||||
int CmdT55xxDetectPage1(const char *Cmd){
|
||||
bool errors = false;
|
||||
bool useGB = false;
|
||||
bool usepwd = false;
|
||||
uint32_t password = 0;
|
||||
uint8_t cmdp = 0;
|
||||
|
||||
while(param_getchar(Cmd, cmdp) != 0x00 && !errors) {
|
||||
switch(param_getchar(Cmd, cmdp)) {
|
||||
case 'h':
|
||||
case 'H':
|
||||
return usage_t55xx_detectP1();
|
||||
case 'p':
|
||||
case 'P':
|
||||
password = param_get32ex(Cmd, cmdp+1, 0, 16);
|
||||
usepwd = true;
|
||||
cmdp += 2;
|
||||
break;
|
||||
case '1':
|
||||
// use Graphbuffer data
|
||||
useGB = true;
|
||||
cmdp++;
|
||||
break;
|
||||
default:
|
||||
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
|
||||
errors = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (errors) return usage_t55xx_detectP1();
|
||||
|
||||
if ( !useGB ) {
|
||||
if ( !AquireData(T55x7_PAGE1, 1, usepwd, password) )
|
||||
return false;
|
||||
}
|
||||
bool success = tryDetectP1(false);
|
||||
if (success) PrintAndLog("T55xx chip found!");
|
||||
return success;
|
||||
}
|
||||
|
||||
static command_t CommandTable[] = {
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"bruteforce",CmdT55xxBruteForce,0, "<start password> <end password> [i <*.dic>] Simple bruteforce attack to find password"},
|
||||
{"config", CmdT55xxSetConfig, 1, "Set/Get T55XX configuration (modulation, inverted, offset, rate)"},
|
||||
{"detect", CmdT55xxDetect, 1, "[1] Try detecting the tag modulation from reading the configuration block."},
|
||||
{"p1detect", CmdT55xxDetectPage1,1, "[1] Try detecting if this is a t55xx tag by reading page 1"},
|
||||
{"read", CmdT55xxReadBlock, 0, "b <block> p [password] [o] [1] -- Read T55xx block data. Optional [p password], [override], [page1]"},
|
||||
{"resetread", CmdResetRead, 0, "Send Reset Cmd then lf read the stream to attempt to identify the start of it (needs a demod and/or plot after)"},
|
||||
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
|
||||
|
|
|
@ -47,7 +47,7 @@ typedef struct {
|
|||
DEMOD_FSK = 0xF0, //generic FSK (auto detect FCs)
|
||||
DEMOD_ASK = 0x08,
|
||||
DEMOD_BI = 0x10,
|
||||
DEMOD_BIa = 0x18,
|
||||
DEMOD_BIa = 0x18
|
||||
} modulation;
|
||||
bool inverted;
|
||||
uint8_t offset;
|
||||
|
@ -60,27 +60,27 @@ typedef struct {
|
|||
RF_50 = 0x04,
|
||||
RF_64 = 0x05,
|
||||
RF_100 = 0x06,
|
||||
RF_128 = 0x07,
|
||||
RF_128 = 0x07
|
||||
} bitrate;
|
||||
bool Q5;
|
||||
bool ST;
|
||||
} t55xx_conf_block_t;
|
||||
t55xx_conf_block_t Get_t55xx_Config();
|
||||
|
||||
t55xx_conf_block_t Get_t55xx_Config(void);
|
||||
void Set_t55xx_Config(t55xx_conf_block_t conf);
|
||||
|
||||
extern int CmdLFT55XX(const char *Cmd);
|
||||
extern int CmdT55xxBruteForce(const char *Cmd);
|
||||
extern int CmdT55xxSetConfig(const char *Cmd);
|
||||
extern int CmdT55xxReadBlock(const char *Cmd);
|
||||
extern int CmdT55xxWriteBlock(const char *Cmd);
|
||||
extern int CmdT55xxReadTrace(const char *Cmd);
|
||||
extern int CmdT55xxInfo(const char *Cmd);
|
||||
extern int CmdT55xxDetect(const char *Cmd);
|
||||
extern int CmdResetRead(const char *Cmd);
|
||||
extern int CmdT55xxWipe(const char *Cmd);
|
||||
|
||||
int CmdLFT55XX(const char *Cmd);
|
||||
int CmdT55xxBruteForce(const char *Cmd);
|
||||
int CmdT55xxSetConfig(const char *Cmd);
|
||||
int CmdT55xxReadBlock(const char *Cmd);
|
||||
int CmdT55xxWriteBlock(const char *Cmd);
|
||||
int CmdT55xxReadTrace(const char *Cmd);
|
||||
int CmdT55xxInfo(const char *Cmd);
|
||||
int CmdT55xxDetect(const char *Cmd);
|
||||
int CmdResetRead(const char *Cmd);
|
||||
int CmdT55xxWipe(const char *Cmd);
|
||||
|
||||
char * GetBitRateStr(uint32_t id);
|
||||
char * GetBitRateStr(uint32_t id, bool xmode);
|
||||
char * GetSaferStr(uint32_t id);
|
||||
char * GetModulationStr( uint32_t id);
|
||||
char * GetModelStrFromCID(uint32_t cid);
|
||||
|
@ -90,8 +90,9 @@ void printT5xxHeader(uint8_t page);
|
|||
void printT55xxBlock(const char *demodStr);
|
||||
int printConfiguration( t55xx_conf_block_t b);
|
||||
|
||||
bool DecodeT55xxBlock();
|
||||
bool tryDetectModulation();
|
||||
bool DecodeT55xxBlock(void);
|
||||
bool tryDetectModulation(void);
|
||||
extern bool tryDetectP1(bool getData);
|
||||
bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5);
|
||||
int special(const char *Cmd);
|
||||
int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
|
||||
|
|
|
@ -166,9 +166,10 @@ uint8_t GetPskCarrier(const char str[], bool printAns, bool verbose)
|
|||
PrintAndLog("Failed to copy from graphbuffer");
|
||||
return 0;
|
||||
}
|
||||
//uint8_t countPSK_FC(uint8_t *BitStream, size_t size)
|
||||
|
||||
carrier = countFC(grph,size,0);
|
||||
uint16_t fc = countFC(grph,size,0);
|
||||
carrier = fc & 0xFF;
|
||||
if (carrier != 2 && carrier != 4 && carrier != 8) return 0;
|
||||
if ((fc>>8) == 10 && carrier == 8) return 0;
|
||||
// Only print this message if we're not looping something
|
||||
if (printAns) {
|
||||
PrintAndLog("Auto-detected PSK carrier rate: %d", carrier);
|
||||
|
@ -193,7 +194,9 @@ int GetPskClock(const char str[], bool printAns, bool verbose)
|
|||
PrintAndLog("Failed to copy from graphbuffer");
|
||||
return -1;
|
||||
}
|
||||
clock = DetectPSKClock(grph,size,0);
|
||||
size_t firstPhaseShiftLoc = 0;
|
||||
uint8_t curPhase = 0, fc = 0;
|
||||
clock = DetectPSKClock(grph, size, 0, &firstPhaseShiftLoc, &curPhase, &fc);
|
||||
// Only print this message if we're not looping something
|
||||
if (printAns){
|
||||
PrintAndLog("Auto-detected clock rate: %d", clock);
|
||||
|
|
|
@ -169,7 +169,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea
|
|||
|
||||
size_t in_index = 0;
|
||||
// loop through the out_index to make sure we don't go too far
|
||||
for (size_t out_index=0; out_index < max_len-1; out_index++) {
|
||||
for (size_t out_index=0; out_index < max_len; out_index++) {
|
||||
// set character - (should be binary but verify it isn't more than 1 digit)
|
||||
if (data[in_index]<10)
|
||||
sprintf(tmp++, "%u", (unsigned int) data[in_index]);
|
||||
|
|
184
common/lfdemod.c
184
common/lfdemod.c
|
@ -33,6 +33,7 @@
|
|||
//-----------------------------------------------------------------------------
|
||||
|
||||
#include <string.h> // for memset, memcmp and size_t
|
||||
#include "lfdemod.h"
|
||||
#include <stdint.h> // for uint_32+
|
||||
#include <stdbool.h> // for bool
|
||||
#include "parity.h" // for parity test
|
||||
|
@ -277,6 +278,33 @@ bool loadWaveCounters(uint8_t samples[], size_t size, int lowToLowWaveLen[], int
|
|||
return true;
|
||||
}
|
||||
|
||||
size_t pskFindFirstPhaseShift(uint8_t samples[], size_t size, uint8_t *curPhase, size_t waveStart, uint16_t fc, uint16_t *fullWaveLen) {
|
||||
uint16_t loopCnt = (size+3 < 4096) ? size : 4096; //don't need to loop through entire array...
|
||||
|
||||
uint16_t avgWaveVal=0, lastAvgWaveVal=0;
|
||||
size_t i = waveStart, waveEnd, waveLenCnt, firstFullWave;
|
||||
for (; i<loopCnt; i++) {
|
||||
// find peak // was "samples[i] + fc" but why? must have been used to weed out some wave error... removed..
|
||||
if (samples[i] < samples[i+1] && samples[i+1] >= samples[i+2]){
|
||||
waveEnd = i+1;
|
||||
if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %u, waveStart: %u", waveEnd, waveStart);
|
||||
waveLenCnt = waveEnd-waveStart;
|
||||
if (waveLenCnt > fc && waveStart > fc && !(waveLenCnt > fc+8)){ //not first peak and is a large wave but not out of whack
|
||||
lastAvgWaveVal = avgWaveVal/(waveLenCnt);
|
||||
firstFullWave = waveStart;
|
||||
*fullWaveLen = waveLenCnt;
|
||||
//if average wave value is > graph 0 then it is an up wave or a 1 (could cause inverting)
|
||||
if (lastAvgWaveVal > FSK_PSK_THRESHOLD) *curPhase ^= 1;
|
||||
return firstFullWave;
|
||||
}
|
||||
waveStart = i+1;
|
||||
avgWaveVal = 0;
|
||||
}
|
||||
avgWaveVal += samples[i+2];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//amplify based on ask edge detection - not accurate enough to use all the time
|
||||
void askAmp(uint8_t *BitStream, size_t size) {
|
||||
|
@ -520,7 +548,7 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
|
|||
|
||||
//get high and low peak
|
||||
int peak, low;
|
||||
if (getHiLo(dest, loopCnt, &peak, &low, 75, 75) < 1) return 0;
|
||||
if (getHiLo(dest, loopCnt, &peak, &low, 85, 85) < 1) return 0;
|
||||
|
||||
int lowestTransition = DetectStrongNRZClk(dest, size-20, peak, low);
|
||||
size_t ii;
|
||||
|
@ -529,26 +557,24 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
|
|||
uint16_t smplCnt = 0;
|
||||
int16_t peakcnt = 0;
|
||||
int16_t peaksdet[] = {0,0,0,0,0,0,0,0};
|
||||
uint16_t maxPeak = 255;
|
||||
bool firstpeak = false;
|
||||
//test for large clipped waves
|
||||
uint16_t minPeak = 255;
|
||||
bool firstpeak = true;
|
||||
//test for large clipped waves - ignore first peak
|
||||
for (i=0; i<loopCnt; i++) {
|
||||
if (dest[i] >= peak || dest[i] <= low) {
|
||||
if (!firstpeak) continue;
|
||||
if (firstpeak) continue;
|
||||
smplCnt++;
|
||||
} else {
|
||||
firstpeak=true;
|
||||
if (smplCnt > 6 ){
|
||||
if (maxPeak > smplCnt){
|
||||
maxPeak = smplCnt;
|
||||
//prnt("maxPk: %d",maxPeak);
|
||||
}
|
||||
firstpeak = false;
|
||||
if (smplCnt > 0) {
|
||||
if (minPeak > smplCnt && smplCnt > 7) minPeak = smplCnt;
|
||||
peakcnt++;
|
||||
//prnt("maxPk: %d, smplCnt: %d, peakcnt: %d",maxPeak,smplCnt,peakcnt);
|
||||
if (g_debugMode == 2) prnt("DEBUG NRZ: minPeak: %d, smplCnt: %d, peakcnt: %d",minPeak,smplCnt,peakcnt);
|
||||
smplCnt = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (minPeak < 8) return 0;
|
||||
bool errBitHigh = 0;
|
||||
bool bitHigh = 0;
|
||||
uint8_t ignoreCnt = 0;
|
||||
|
@ -560,7 +586,7 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
|
|||
//test each valid clock from smallest to greatest to see which lines up
|
||||
for(clkCnt=0; clkCnt < 8; ++clkCnt) {
|
||||
//ignore clocks smaller than smallest peak
|
||||
if (clk[clkCnt] < maxPeak - (clk[clkCnt]/4)) continue;
|
||||
if (clk[clkCnt] < minPeak - (clk[clkCnt]/4)) continue;
|
||||
//try lining up the peaks by moving starting point (try first 256)
|
||||
for (ii=20; ii < loopCnt; ++ii) {
|
||||
if ((dest[ii] >= peak) || (dest[ii] <= low)) {
|
||||
|
@ -618,7 +644,7 @@ int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx
|
|||
} else if (peaksdet[iii] > peaksdet[best]) {
|
||||
best = iii;
|
||||
}
|
||||
if (g_debugMode==2) prnt("DEBUG NRZ: Clk: %d, peaks: %d, maxPeak: %d, bestClk: %d, lowestTrs: %d",clk[iii],peaksdet[iii],maxPeak, clk[best], lowestTransition);
|
||||
if (g_debugMode==2) prnt("DEBUG NRZ: Clk: %d, peaks: %d, minPeak: %d, bestClk: %d, lowestTrs: %d",clk[iii],peaksdet[iii],minPeak, clk[best], lowestTransition);
|
||||
}
|
||||
*clockStartIdx = bestStart[best];
|
||||
return clk[best];
|
||||
|
@ -691,6 +717,7 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) {
|
|||
best3=i;
|
||||
}
|
||||
if (g_debugMode==2) prnt("DEBUG countfc: FC %u, Cnt %u, best fc: %u, best2 fc: %u",fcLens[i],fcCnts[i],fcLens[best1],fcLens[best2]);
|
||||
if (fcLens[i]==0) break;
|
||||
}
|
||||
if (fcLens[best1]==0) return 0;
|
||||
uint8_t fcH=0, fcL=0;
|
||||
|
@ -709,17 +736,23 @@ uint16_t countFC(uint8_t *BitStream, size_t size, uint8_t fskAdj) {
|
|||
|
||||
uint16_t fcs = (((uint16_t)fcH)<<8) | fcL;
|
||||
if (fskAdj) return fcs;
|
||||
return fcLens[best1];
|
||||
return (uint16_t)fcLens[best2] << 8 | fcLens[best1];
|
||||
}
|
||||
|
||||
//by marshmellow
|
||||
//detect psk clock by reading each phase shift
|
||||
// a phase shift is determined by measuring the sample length of each wave
|
||||
int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseShift) {
|
||||
int DetectPSKClock(uint8_t dest[], size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc) {
|
||||
uint8_t clk[]={255,16,32,40,50,64,100,128,255}; //255 is not a valid clock
|
||||
uint16_t loopCnt = 4096; //don't need to loop through entire array...
|
||||
if (size == 0) return 0;
|
||||
if (size<loopCnt) loopCnt = size-20;
|
||||
if (size+3<loopCnt) loopCnt = size-20;
|
||||
|
||||
uint16_t fcs = countFC(dest, size, 0);
|
||||
*fc = fcs & 0xFF;
|
||||
if (g_debugMode==2) prnt("DEBUG PSK: FC: %d, FC2: %d",*fc, fcs>>8);
|
||||
if ((fcs>>8) == 10 && *fc == 8) return -1;
|
||||
if (*fc!=2 && *fc!=4 && *fc!=8) return -1;
|
||||
|
||||
//if we already have a valid clock quit
|
||||
size_t i=1;
|
||||
|
@ -727,37 +760,28 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
|
|||
if (clk[i] == clock) return clock;
|
||||
|
||||
size_t waveStart=0, waveEnd=0, firstFullWave=0, lastClkBit=0;
|
||||
uint8_t clkCnt, fc=0, fullWaveLen=0, tol=1;
|
||||
uint16_t peakcnt=0, errCnt=0, waveLenCnt=0;
|
||||
|
||||
uint8_t clkCnt, tol=1;
|
||||
uint16_t peakcnt=0, errCnt=0, waveLenCnt=0, fullWaveLen=0;
|
||||
uint16_t bestErr[]={1000,1000,1000,1000,1000,1000,1000,1000,1000};
|
||||
uint16_t peaksdet[]={0,0,0,0,0,0,0,0,0};
|
||||
fc = countFC(dest, size, 0);
|
||||
if (fc!=2 && fc!=4 && fc!=8) return -1;
|
||||
if (g_debugMode==2) prnt("DEBUG PSK: FC: %d",fc);
|
||||
|
||||
//find first full wave
|
||||
for (i=160; i<loopCnt; i++){
|
||||
if (dest[i] < dest[i+1] && dest[i+1] >= dest[i+2]){
|
||||
if (waveStart == 0) {
|
||||
waveStart = i+1;
|
||||
//prnt("DEBUG: waveStart: %d",waveStart);
|
||||
} else {
|
||||
waveEnd = i+1;
|
||||
//prnt("DEBUG: waveEnd: %d",waveEnd);
|
||||
waveLenCnt = waveEnd-waveStart;
|
||||
if (waveLenCnt > fc){
|
||||
firstFullWave = waveStart;
|
||||
fullWaveLen=waveLenCnt;
|
||||
break;
|
||||
}
|
||||
waveStart=0;
|
||||
}
|
||||
}
|
||||
//find start of modulating data in trace
|
||||
i = findModStart(dest, size, *fc);
|
||||
|
||||
firstFullWave = pskFindFirstPhaseShift(dest, size, curPhase, i, *fc, &fullWaveLen);
|
||||
if (firstFullWave == 0) {
|
||||
// no phase shift detected - could be all 1's or 0's - doesn't matter where we start
|
||||
// so skip a little to ensure we are past any Start Signal
|
||||
firstFullWave = 160;
|
||||
fullWaveLen = 0;
|
||||
}
|
||||
|
||||
*firstPhaseShift = firstFullWave;
|
||||
if (g_debugMode ==2) prnt("DEBUG PSK: firstFullWave: %d, waveLen: %d",firstFullWave,fullWaveLen);
|
||||
//test each valid clock from greatest to smallest to see which lines up
|
||||
for(clkCnt=7; clkCnt >= 1 ; clkCnt--) {
|
||||
tol = *fc/2;
|
||||
lastClkBit = firstFullWave; //set end of wave as clock align
|
||||
waveStart = 0;
|
||||
errCnt=0;
|
||||
|
@ -773,9 +797,9 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
|
|||
} else { //waveEnd
|
||||
waveEnd = i+1;
|
||||
waveLenCnt = waveEnd-waveStart;
|
||||
if (waveLenCnt > fc){
|
||||
if (waveLenCnt > *fc){
|
||||
//if this wave is a phase shift
|
||||
if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,i+1,fc);
|
||||
if (g_debugMode == 2) prnt("DEBUG PSK: phase shift at: %d, len: %d, nextClk: %d, i: %d, fc: %d",waveStart,waveLenCnt,lastClkBit+clk[clkCnt]-tol,i+1,*fc);
|
||||
if (i+1 >= lastClkBit + clk[clkCnt] - tol){ //should be a clock bit
|
||||
peakcnt++;
|
||||
lastClkBit+=clk[clkCnt];
|
||||
|
@ -784,7 +808,7 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
|
|||
} else { //phase shift before supposed to based on clock
|
||||
errCnt++;
|
||||
}
|
||||
} else if (i+1 > lastClkBit + clk[clkCnt] + tol + fc){
|
||||
} else if (i+1 > lastClkBit + clk[clkCnt] + tol + *fc){
|
||||
lastClkBit+=clk[clkCnt]; //no phase shift but clock bit
|
||||
}
|
||||
waveStart=i+1;
|
||||
|
@ -809,10 +833,11 @@ int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseSh
|
|||
return clk[best];
|
||||
}
|
||||
|
||||
int DetectPSKClock(uint8_t dest[], size_t size, int clock) {
|
||||
int firstPhaseShift = 0;
|
||||
return DetectPSKClock_ext(dest, size, clock, &firstPhaseShift);
|
||||
}
|
||||
//int DetectPSKClock(uint8_t dest[], size_t size, int clock) {
|
||||
// size_t firstPhaseShift = 0;
|
||||
// uint8_t curPhase = 0;
|
||||
// return DetectPSKClock_ext(dest, size, clock, &firstPhaseShift, &curPhase);
|
||||
//}
|
||||
|
||||
//by marshmellow
|
||||
//detects the bit clock for FSK given the high and low Field Clocks
|
||||
|
@ -955,7 +980,7 @@ bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststa
|
|||
//need to loop through all samples and identify our clock, look for the ST pattern
|
||||
int clk = 0;
|
||||
int tol = 0;
|
||||
int j, high, low, skip, start, end, minClk=255;
|
||||
int j=0, high, low, skip=0, start=0, end=0, minClk=255;
|
||||
size_t i = 0;
|
||||
//probably should malloc... || test if memory is available ... handle device side? memory danger!!! [marshmellow]
|
||||
int tmpbuff[bufsize / LOWEST_DEFAULT_CLOCK]; // low to low wave count //guess rf/32 clock, if click is smaller we will only have room for a fraction of the samples captured
|
||||
|
@ -1023,9 +1048,9 @@ bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststa
|
|||
return false;
|
||||
}
|
||||
size_t dataloc = start;
|
||||
if (buffer[dataloc-(clk*4)-(clk/8)] <= low && buffer[dataloc] <= low && buffer[dataloc-(clk*4)] >= high) {
|
||||
if (buffer[dataloc-(clk*4)-(clk/4)] <= low && buffer[dataloc] <= low && buffer[dataloc-(clk*4)] >= high) {
|
||||
//we have low drift (and a low just before the ST and a low just after the ST) - compensate by backing up the start
|
||||
for ( i=0; i <= (clk/8); ++i ) {
|
||||
for ( i=0; i <= (clk/4); ++i ) {
|
||||
if ( buffer[dataloc - (clk*4) - i] <= low ) {
|
||||
dataloc -= i;
|
||||
break;
|
||||
|
@ -1040,14 +1065,15 @@ bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststa
|
|||
// warning - overwriting buffer given with raw wave data with ST removed...
|
||||
while ( dataloc < bufsize-(clk/2) ) {
|
||||
//compensate for long high at end of ST not being high due to signal loss... (and we cut out the start of wave high part)
|
||||
if (buffer[dataloc]<high && buffer[dataloc]>low && buffer[dataloc+3]<high && buffer[dataloc+3]>low) {
|
||||
if (buffer[dataloc]<high && buffer[dataloc]>low && buffer[dataloc+clk/4]<high && buffer[dataloc+clk/4]>low) {
|
||||
for(i=0; i < clk/2-tol; ++i) {
|
||||
buffer[dataloc+i] = high+5;
|
||||
}
|
||||
} //test for single sample outlier (high between two lows) in the case of very strong waves
|
||||
if (buffer[dataloc] >= high && buffer[dataloc+2] <= low) {
|
||||
buffer[dataloc] = buffer[dataloc+2];
|
||||
buffer[dataloc+1] = buffer[dataloc+2];
|
||||
} //test for small spike outlier (high between two lows) in the case of very strong waves
|
||||
if (buffer[dataloc] > low && buffer[dataloc+clk/4] <= low) {
|
||||
for(i=0; i < clk/4; ++i) {
|
||||
buffer[dataloc+i] = buffer[dataloc+clk/4];
|
||||
}
|
||||
}
|
||||
if (firstrun) {
|
||||
*stend = dataloc;
|
||||
|
@ -1521,53 +1547,24 @@ void psk2TOpsk1(uint8_t *BitStream, size_t size) {
|
|||
return;
|
||||
}
|
||||
|
||||
size_t pskFindFirstPhaseShift(uint8_t samples[], size_t size, uint8_t *curPhase, size_t waveStart, uint16_t fc, uint16_t *fullWaveLen) {
|
||||
uint16_t loopCnt = (size+3 < 4096) ? size : 4096; //don't need to loop through entire array...
|
||||
|
||||
uint16_t avgWaveVal=0, lastAvgWaveVal=0;
|
||||
size_t i = waveStart, waveEnd, waveLenCnt, firstFullWave;
|
||||
for (; i<loopCnt; i++) {
|
||||
// find peak
|
||||
if (samples[i]+fc < samples[i+1] && samples[i+1] >= samples[i+2]){
|
||||
waveEnd = i+1;
|
||||
if (g_debugMode == 2) prnt("DEBUG PSK: waveEnd: %u, waveStart: %u", waveEnd, waveStart);
|
||||
waveLenCnt = waveEnd-waveStart;
|
||||
if (waveLenCnt > fc && waveStart > fc && !(waveLenCnt > fc+8)){ //not first peak and is a large wave but not out of whack
|
||||
lastAvgWaveVal = avgWaveVal/(waveLenCnt);
|
||||
firstFullWave = waveStart;
|
||||
*fullWaveLen = waveLenCnt;
|
||||
//if average wave value is > graph 0 then it is an up wave or a 1 (could cause inverting)
|
||||
if (lastAvgWaveVal > FSK_PSK_THRESHOLD) *curPhase ^= 1;
|
||||
return firstFullWave;
|
||||
}
|
||||
waveStart = i+1;
|
||||
avgWaveVal = 0;
|
||||
}
|
||||
avgWaveVal += samples[i+2];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
//by marshmellow - demodulate PSK1 wave
|
||||
//uses wave lengths (# Samples)
|
||||
int pskRawDemod_ext(uint8_t dest[], size_t *size, int *clock, int *invert, int *startIdx) {
|
||||
if (*size < 170) return -1;
|
||||
|
||||
uint8_t curPhase = *invert;
|
||||
uint8_t fc=0;
|
||||
size_t i=0, numBits=0, waveStart=1, waveEnd=0, firstFullWave=0, lastClkBit=0;
|
||||
uint16_t fc=0, fullWaveLen=0, waveLenCnt=0, avgWaveVal, tol=1;
|
||||
uint16_t fullWaveLen=0, waveLenCnt=0, avgWaveVal;
|
||||
uint16_t errCnt=0, errCnt2=0;
|
||||
|
||||
fc = countFC(dest, *size, 1);
|
||||
if ((fc >> 8) == 10) return -1; //fsk found - quit
|
||||
fc = fc & 0xFF;
|
||||
if (fc!=2 && fc!=4 && fc!=8) return -1;
|
||||
*clock = DetectPSKClock(dest, *size, *clock);
|
||||
*clock = DetectPSKClock(dest, *size, *clock, &firstFullWave, &curPhase, &fc);
|
||||
if (*clock == 0) return -1;
|
||||
|
||||
//if clock detect found firstfullwave...
|
||||
uint16_t tol = fc/2;
|
||||
if (firstFullWave == 0) {
|
||||
//find start of modulating data in trace
|
||||
i = findModStart(dest, *size, fc);
|
||||
|
||||
//find first phase shift
|
||||
firstFullWave = pskFindFirstPhaseShift(dest, *size, &curPhase, i, fc, &fullWaveLen);
|
||||
if (firstFullWave == 0) {
|
||||
|
@ -1578,6 +1575,9 @@ int pskRawDemod_ext(uint8_t dest[], size_t *size, int *clock, int *invert, int *
|
|||
} else {
|
||||
memset(dest, curPhase^1, firstFullWave / *clock);
|
||||
}
|
||||
} else {
|
||||
memset(dest, curPhase^1, firstFullWave / *clock);
|
||||
}
|
||||
//advance bits
|
||||
numBits += (firstFullWave / *clock);
|
||||
*startIdx = firstFullWave - (*clock * numBits)+2;
|
||||
|
@ -1616,6 +1616,8 @@ int pskRawDemod_ext(uint8_t dest[], size_t *size, int *clock, int *invert, int *
|
|||
} else if (waveLenCnt < fc - 1) { //wave is smaller than field clock (shouldn't happen often)
|
||||
errCnt2++;
|
||||
if(errCnt2 > 101) return errCnt2;
|
||||
avgWaveVal += dest[i+1];
|
||||
continue;
|
||||
}
|
||||
avgWaveVal = 0;
|
||||
waveStart = i+1;
|
||||
|
@ -1800,7 +1802,7 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert) {
|
|||
}
|
||||
if (*size != 64 && *size != 224) return -2;
|
||||
if (*invert==1)
|
||||
for (size_t i = startidx; i < *size; i++)
|
||||
for (size_t i = startidx; i < *size + startidx; i++)
|
||||
bitStream[i] ^= 1;
|
||||
|
||||
return (int) startidx;
|
||||
|
|
|
@ -30,8 +30,7 @@ extern uint8_t DetectCleanAskWave(uint8_t dest[], size_t size, uint8_t high, ui
|
|||
extern uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow);
|
||||
extern uint8_t detectFSKClk_ext(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t fcLow, int *firstClockEdge);
|
||||
extern int DetectNRZClock(uint8_t dest[], size_t size, int clock, size_t *clockStartIdx);
|
||||
extern int DetectPSKClock(uint8_t dest[], size_t size, int clock);
|
||||
extern int DetectPSKClock_ext(uint8_t dest[], size_t size, int clock, int *firstPhaseShift);
|
||||
extern int DetectPSKClock(uint8_t dest[], size_t size, int clock, size_t *firstPhaseShift, uint8_t *curPhase, uint8_t *fc);
|
||||
extern int DetectStrongAskClock(uint8_t dest[], size_t size, int high, int low, int *clock);
|
||||
extern bool DetectST(uint8_t buffer[], size_t *size, int *foundclock);
|
||||
extern bool DetectST_ext(uint8_t buffer[], size_t *size, int *foundclock, size_t *ststart, size_t *stend);
|
||||
|
@ -42,7 +41,7 @@ extern uint32_t manchesterEncode2Bytes(uint16_t datain);
|
|||
extern int ManchesterEncode(uint8_t *BitStream, size_t size);
|
||||
extern int manrawdecode(uint8_t *BitStream, size_t *size, uint8_t invert, uint8_t *alignPos);
|
||||
extern int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert, int *startIdx);
|
||||
extern uint8_t parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||
extern bool parityTest(uint32_t bits, uint8_t bitLen, uint8_t pType);
|
||||
extern uint8_t preambleSearch(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx);
|
||||
extern bool preambleSearchEx(uint8_t *BitStream, uint8_t *preamble, size_t pLen, size_t *size, size_t *startIdx, bool findone);
|
||||
extern int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert);
|
||||
|
|
|
@ -238,6 +238,7 @@ void getMemConfig(uint8_t mem_cfg, uint8_t chip_cfg, uint8_t *max_blk, uint8_t *
|
|||
#define T55x7_MODULATION_MANCHESTER 0x00008000
|
||||
#define T55x7_MODULATION_BIPHASE 0x00010000
|
||||
#define T55x7_MODULATION_DIPHASE 0x00018000
|
||||
#define T55x7_X_MODE 0x00020000
|
||||
#define T55x7_BITRATE_RF_8 0
|
||||
#define T55x7_BITRATE_RF_16 0x00040000
|
||||
#define T55x7_BITRATE_RF_32 0x00080000
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue