ADD: Added @marshmellow42 's new ST (sequence terminator detection)

This commit is contained in:
iceman1001 2016-02-19 22:30:19 +01:00
commit 0516439959
9 changed files with 246 additions and 40 deletions

View file

@ -277,7 +277,8 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo )
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose)
{
if (!ASKDemod(Cmd, FALSE, FALSE, 1)) return 0;
bool st = TRUE;
if (!ASKDemod_ext(Cmd, FALSE, FALSE, 1, &st)) return 0;
return AskEm410xDecode(verbose, hi, lo);
}
@ -312,8 +313,7 @@ int CmdAskEM410xDemod(const char *Cmd)
//verbose will print results and demoding messages
//emSearch will auto search for EM410x format in bitstream
//askType switches decode: ask/raw = 0, ask/manchester = 1
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType)
{
int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck) {
int invert=0;
int clk=0;
int maxErr=100;
@ -336,7 +336,14 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType)
if (g_debugMode) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
if (BitLen<255) return 0;
if (maxLen<BitLen && maxLen != 0) BitLen = maxLen;
int foundclk = 0;
bool st = false;
if (*stCheck) st = DetectST(BitStream, &BitLen, &foundclk);
if (st) {
*stCheck = st;
clk = (clk == 0) ? foundclk : clk;
if (verbose || g_debugMode) PrintAndLog("\nFound Sequence Terminator");
}
int errCnt = askdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp, askType);
if (errCnt<0 || BitLen<16){ //if fatal error (or -1)
if (g_debugMode) PrintAndLog("DEBUG: no data found %d, errors:%d, bitlen:%d, clock:%d",errCnt,invert,BitLen,clk);
@ -365,6 +372,10 @@ int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType)
}
return 1;
}
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType) {
bool st = false;
return ASKDemod_ext(Cmd, verbose, emSearch, askType, &st);
}
//by marshmellow
//takes 5 arguments - clock, invert, maxErr, maxLen as integers and amplify as char == 'a'
@ -374,7 +385,8 @@ int Cmdaskmandemod(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod am [clock] <invert> [maxError] [maxLen] [amplify]");
PrintAndLog("Usage: data rawdemod am <s> [clock] <invert> [maxError] [maxLen] [amplify]");
PrintAndLog(" ['s'] optional, check for Sequence Terminator");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect");
PrintAndLog(" <invert>, 1 to invert output");
PrintAndLog(" [set maximum allowed errors], default = 100");
@ -388,6 +400,12 @@ int Cmdaskmandemod(const char *Cmd)
PrintAndLog(" : data rawdemod am 64 1 0 = demod an ask/manchester tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0;
}
bool st = TRUE;
if (Cmd[0]=='s')
return ASKDemod_ext(Cmd++, TRUE, TRUE, 1, &st);
else if (Cmd[1] == 's')
return ASKDemod_ext(Cmd+=2, TRUE, TRUE, 1, &st);
else
return ASKDemod(Cmd, TRUE, TRUE, 1);
}
@ -964,7 +982,6 @@ int FSKrawDemod(const char *Cmd, bool verbose)
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
if (BitLen==0) return 0;
if (g_debugMode==2) PrintAndLog("DEBUG: Got samples");
//get field clock lengths
uint16_t fcs=0;
if (!fchigh || !fclow) {

View file

@ -63,6 +63,7 @@ int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo );
int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose);
int ASKbiphaseDemod(const char *Cmd, bool verbose);
int ASKDemod(const char *Cmd, bool verbose, bool emSearch, uint8_t askType);
int ASKDemod_ext(const char *Cmd, bool verbose, bool emSearch, uint8_t askType, bool *stCheck);
int FSKrawDemod(const char *Cmd, bool verbose);
int PSKDemod(const char *Cmd, bool verbose);
int NRZrawDemod(const char *Cmd, bool verbose);

View file

@ -38,7 +38,8 @@ int usage_lf_cmdread(void) {
PrintAndLog("Usage: lf cmdread d <delay period> z <zero period> o <one period> c <cmdbytes> [H]");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" H Freqency High (134 KHz), default is 'Low (125KHz)'");
PrintAndLog(" L Low frequency (125 KHz)");
PrintAndLog(" H High frequency (134 KHz)");
PrintAndLog(" d <delay> delay OFF period, (dec)");
PrintAndLog(" z <zero> time period ZERO, (dec)");
PrintAndLog(" o <one> time period ONE, (dec)");
@ -1186,8 +1187,8 @@ int CmdLFfind(const char *Cmd) {
return 1;
}
}
ans=ASKDemod("0 0 0",TRUE,FALSE,1);
bool st = TRUE;
ans=ASKDemod_ext("0 0 0",TRUE,FALSE,1,&st);
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'");
@ -1217,7 +1218,7 @@ static command_t CommandTable[] =
{"pcf7931", CmdLFPCF7931, 1, "{ PCF7931 RFIDs... }"},
{"presco", CmdLFPresco, 1, "{ Presco RFIDs... }"},
{"ti", CmdLFTI, 1, "{ TI RFIDs... }"},
{"t55xx", CmdLFT55XX, 1, "{ T55X7 RFIDs... }"},
{"t55xx", CmdLFT55XX, 1, "{ T55xx RFIDs... }"},
{"viking", CmdLFViking, 1, "{ Viking 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)"},
@ -1231,7 +1232,7 @@ static command_t CommandTable[] =
{"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, "Snoop LF"},
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
{"vchdemod", CmdVchDemod, 1, "['clone'] -- Demodulate samples for VeriChip"},
{NULL, NULL, 0, NULL}
};

View file

@ -10,7 +10,6 @@
#include <stdio.h>
#include <string.h>
#include <inttypes.h>
//#include <time.h>
#include "proxmark3.h"
#include "ui.h"
#include "graph.h"
@ -22,7 +21,7 @@
#include "util.h"
#include "data.h"
#include "lfdemod.h"
#include "cmdhf14a.h"
#include "cmdhf14a.h" //for getTagInfo
#define T55x7_CONFIGURATION_BLOCK 0x00
#define T55x7_PAGE0 0x00
@ -49,6 +48,7 @@ int usage_t55xx_config(){
PrintAndLog(" i [1] Invert data signal, defaults to normal");
PrintAndLog(" o [offset] Set offset, where data should start decode in bitstream");
PrintAndLog(" Q5 Set as Q5(T5555) chip instead of T55x7");
PrintAndLog(" ST Set Sequence Terminator on");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx config d FSK - FSK demodulation");
@ -169,7 +169,7 @@ int usage_t55xx_wipe(){
PrintAndLog("This commands wipes a tag, fills blocks 1-7 with zeros and a default configuration block");
PrintAndLog("Options:");
PrintAndLog(" h - this help");
PrintAndLog(" Q5 - indicates to use the T555 (Q5) default configuration block");
PrintAndLog(" Q5 - indicates to use the T5555 (Q5) default configuration block");
PrintAndLog("");
PrintAndLog("Examples:");
PrintAndLog(" lf t55xx wipe - wipes a t55x7 tag, config block 0x000880E0");
@ -269,6 +269,11 @@ int CmdT55xxSetConfig(const char *Cmd) {
config.Q5 = TRUE;
cmdp++;
break;
case 'S':
case 's':
config.ST = TRUE;
cmdp++;
break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = TRUE;
@ -371,6 +376,7 @@ bool DecodeT55xxBlock(){
char buf[30] = {0x00};
char *cmdStr = buf;
int ans = 0;
bool ST = config.ST;
uint8_t bitRate[8] = {8,16,32,40,50,64,100,128};
DemodBufferLen = 0x00;
@ -391,7 +397,7 @@ bool DecodeT55xxBlock(){
break;
case DEMOD_ASK:
snprintf(cmdStr, sizeof(buf),"%d %d 1", bitRate[config.bitrate], config.inverted );
ans = ASKDemod(cmdStr, FALSE, FALSE, 1);
ans = ASKDemod_ext(cmdStr, FALSE, FALSE, 1, &ST);
break;
case DEMOD_PSK1:
// skip first 160 samples to allow antenna to settle in (psk gets inverted occasionally otherwise)
@ -496,6 +502,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = FALSE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
if ( FSKrawDemod("0 1", FALSE) && test(DEMOD_FSK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
@ -507,19 +514,22 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = TRUE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
} else {
clk = GetAskClock("", FALSE, FALSE);
if (clk>0) {
if ( ASKDemod("0 0 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].ST = TRUE;
if ( ASKDemod_ext("0 0 1", FALSE, FALSE, 1, &tests[hits].ST) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_ASK;
tests[hits].bitrate = bitRate;
tests[hits].inverted = FALSE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
++hits;
}
if ( ASKDemod("0 1 1", FALSE, FALSE, 1) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].ST = TRUE;
if ( ASKDemod_ext("0 1 1", FALSE, FALSE, 1, &tests[hits].ST) && test(DEMOD_ASK, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
tests[hits].modulation = DEMOD_ASK;
tests[hits].bitrate = bitRate;
tests[hits].inverted = TRUE;
@ -531,6 +541,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = FALSE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
if ( ASKbiphaseDemod("0 0 1 2", FALSE) && test(DEMOD_BIa, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5) ) {
@ -538,6 +549,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = TRUE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
}
@ -550,6 +562,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = FALSE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
@ -558,6 +571,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = TRUE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
}
@ -573,6 +587,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = FALSE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
if ( PSKDemod("0 1 6", FALSE) && test(DEMOD_PSK1, &tests[hits].offset, &bitRate, clk, &tests[hits].Q5)) {
@ -580,6 +595,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = TRUE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
// PSK2 - needs a call to psk1TOpsk2.
@ -590,6 +606,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = FALSE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
} // inverse waves does not affect this demod
@ -601,6 +618,7 @@ bool tryDetectModulation(){
tests[hits].bitrate = bitRate;
tests[hits].inverted = FALSE;
tests[hits].block0 = PackBits(tests[hits].offset, 32, DemodBuffer);
tests[hits].ST = FALSE;
++hits;
}
} // inverse waves does not affect this demod
@ -615,6 +633,7 @@ bool tryDetectModulation(){
config.offset = tests[0].offset;
config.block0 = tests[0].block0;
config.Q5 = tests[0].Q5;
config.ST = tests[0].ST;
printConfiguration( config );
return TRUE;
}
@ -767,14 +786,14 @@ bool test(uint8_t mode, uint8_t *offset, int *fndBitRate, uint8_t clk, bool *Q5)
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
uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode
uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2;
//uint8_t nml01 = PackBits(si, 1, DemodBuffer); si += 1+5; //bit 24, 30, 31 could be tested for 0 if not extended mode
//uint8_t nml02 = PackBits(si, 2, DemodBuffer); si += 2;
//if extended mode
bool extMode =( (safer == 0x6 || safer == 0x9) && extend) ? TRUE : FALSE;
if (!extMode){
if (nml01 || nml02 || xtRate) continue;
if (xtRate) continue; //nml01 || nml02 || caused issues on noralys tags
}
//test modulation
if (!testModulation(mode, modread)) continue;
@ -838,6 +857,7 @@ int printConfiguration( t55xx_conf_block_t b){
PrintAndLog("Bit Rate : %s", GetBitRateStr(b.bitrate) );
PrintAndLog("Inverted : %s", (b.inverted) ? "Yes" : "No" );
PrintAndLog("Offset : %d", b.offset);
PrintAndLog("Seq. Term. : %s", (b.ST) ? "Yes" : "No" );
PrintAndLog("Block0 : 0x%08X", b.block0);
PrintAndLog("");
return 0;
@ -956,8 +976,7 @@ int CmdT55xxReadTrace(const char *Cmd) {
if ( config.Q5 ){
if (!DecodeT5555TraceBlock()) return 0;
}
else {
} else {
if (!DecodeT55xxBlock()) return 0;
}
@ -1009,7 +1028,7 @@ int CmdT55xxReadTrace(const char *Cmd) {
} else {
t55xx_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .acl = 0, .mfc = 0, .cid = 0, .year = 0, .quarter = 0, .icr = 0, .lotid = 0, .wafer = 0, .dw = 0};
t55x7_tracedata_t data = {.bl1 = bl1, .bl2 = bl2, .acl = 0, .mfc = 0, .cid = 0, .year = 0, .quarter = 0, .icr = 0, .lotid = 0, .wafer = 0, .dw = 0};
data.acl = PackBits(si, 8, DemodBuffer); si += 8;
if ( data.acl != 0xE0 ) {
@ -1033,14 +1052,13 @@ int CmdT55xxReadTrace(const char *Cmd) {
else
data.year += 2010;
printT55xxTrace(data, repeat);
printT55x7Trace(data, repeat);
}
return 0;
}
void printT55xxTrace( t55xx_tracedata_t data, uint8_t repeat ){
PrintAndLog("-- T55xx Trace Information ----------------------------------");
void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat ){
PrintAndLog("-- T55x7 Trace Information ----------------------------------");
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" ACL Allocation class (ISO/IEC 15963-1) : 0x%02X (%d)", data.acl, data.acl);
PrintAndLog(" MFC Manufacturer ID (ISO/IEC 7816-6) : 0x%02X (%d) - %s", data.mfc, data.mfc, getTagInfo(data.mfc));
@ -1074,6 +1092,7 @@ void printT55xxTrace( t55xx_tracedata_t data, uint8_t repeat ){
18-32 DW, die number sequential
*/
}
void printT5555Trace( t5555_tracedata_t data, uint8_t repeat ){
PrintAndLog("-- T5555 (Q5) Trace Information -----------------------------");
PrintAndLog("-------------------------------------------------------------");
@ -1101,6 +1120,7 @@ void printT5555Trace( t5555_tracedata_t data, uint8_t repeat ){
*/
}
//need to add Q5 info...
int CmdT55xxInfo(const char *Cmd){
/*
Page 0 Block 0 Configuration data.
@ -1144,7 +1164,7 @@ int CmdT55xxInfo(const char *Cmd){
if (config.Q5) PrintAndLog("*** Warning *** Config Info read off a Q5 will not display as expected");
PrintAndLog("");
PrintAndLog("-- T55xx Configuration & Tag Information --------------------");
PrintAndLog("-- T55x7 Configuration & Tag Information --------------------");
PrintAndLog("-------------------------------------------------------------");
PrintAndLog(" Safer key : %s", GetSaferStr(safer));
PrintAndLog(" reserved : %d", resv);
@ -1544,7 +1564,7 @@ static command_t CommandTable[] = {
{"special", special, 0, "Show block changes with 64 different offsets"},
{"trace", CmdT55xxReadTrace, 1, "[1] Show T55x7 traceability data (page 1/ blk 0-1)"},
{"wakeup", CmdT55xxWakeUp, 0, "Send AOR wakeup command"},
{"wipe", CmdT55xxWipe, 0, "Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
{"wipe", CmdT55xxWipe, 0, "[q] Wipe a T55xx tag and set defaults (will destroy any data on tag)"},
{"write", CmdT55xxWriteBlock,0, "b <block> d <data> p [password] [1] -- Write T55xx block data. Optional [p password], [page1]"},
{NULL, NULL, 0, NULL}
};

View file

@ -61,7 +61,7 @@ typedef struct {
uint32_t lotid;
uint32_t wafer;
uint32_t dw;
} t55xx_tracedata_t;
} t55x7_tracedata_t;
typedef struct {
uint32_t bl1;
@ -102,6 +102,7 @@ typedef struct {
RF_128 = 0x07,
} bitrate;
bool Q5;
bool ST;
} t55xx_conf_block_t;
t55xx_conf_block_t Get_t55xx_Config();
void Set_t55xx_Config(t55xx_conf_block_t conf);
@ -136,7 +137,7 @@ int AquireData( uint8_t page, uint8_t block, bool pwdmode, uint32_t password );
bool detectPassword(int password);
void printT55xxTrace( t55xx_tracedata_t data, uint8_t repeat );
void printT55x7Trace( t55x7_tracedata_t data, uint8_t repeat );
void printT5555Trace( t5555_tracedata_t data, uint8_t repeat );
#endif

View file

@ -152,7 +152,7 @@ bool WaitForResponseTimeout(uint32_t cmd, UsbCommand* response, size_t ms_timeou
}
msleep(10); // XXX ugh
if (dm_seconds == 200) { // Two seconds elapsed
if (dm_seconds == 250) { // 2.5 seconds elapsed
PrintAndLog("Waiting for a response from the proxmark...");
PrintAndLog("Don't forget to cancel its operation first by pressing on the button");
}

View file

@ -151,7 +151,7 @@ char *sprint_bin_break(const uint8_t *data, const size_t len, const uint8_t brea
// loop through the out_index to make sure we don't go too far
for (size_t out_index=0; out_index < max_len-2; out_index++) {
// set character
sprintf(tmp++, "%u", data[in_index]);
sprintf(tmp++, "%u", (unsigned int) data[in_index]);
// check if a line break is needed and we have room to print it in our array
if ( (breaks > 0) && !((in_index+1) % breaks) && (out_index+1 != max_len) ) {
// increment and print line break

View file

@ -9,9 +9,8 @@
//-----------------------------------------------------------------------------
#include <stdlib.h>
#include <string.h>
#include "lfdemod.h"
#include "common.h"
#include <string.h>
//un_comment to allow debug print calls when used not on device
void dummy(char *fmt, ...){}
@ -217,6 +216,7 @@ int cleanAskRawDemod(uint8_t *BinStream, size_t *size, int clk, int invert, int
if (smplCnt > clk-(clk/4)-1) { //full clock
if (smplCnt > clk + (clk/4)+1) { //too many samples
errCnt++;
if (g_debugMode==2) prnt("DEBUG ASK: Modulation Error at: %u", i);
BinStream[bitCnt++]=7;
} else if (waveHigh) {
BinStream[bitCnt++] = invert;
@ -273,7 +273,7 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr
if (*clk==0 || start < 0) return -3;
if (*invert != 1) *invert = 0;
if (amp==1) askAmp(BinStream, *size);
if (g_debugMode==2) prnt("DEBUG: clk %d, beststart %d", *clk, start);
if (g_debugMode==2) prnt("DEBUG ASK: clk %d, beststart %d", *clk, start);
uint8_t initLoopMax = 255;
if (initLoopMax > *size) initLoopMax = *size;
@ -286,20 +286,21 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr
size_t errCnt = 0;
// if clean clipped waves detected run alternate demod
if (DetectCleanAskWave(BinStream, *size, high, low)) {
if (g_debugMode==2) prnt("DEBUG: Clean Wave Detected");
if (g_debugMode==2) prnt("DEBUG ASK: Clean Wave Detected - using clean wave demod");
errCnt = cleanAskRawDemod(BinStream, size, *clk, *invert, high, low);
if (askType) //askman
return manrawdecode(BinStream, size, 0);
else //askraw
return errCnt;
}
if (g_debugMode==2) prnt("DEBUG ASK: Weak Wave Detected - using weak wave demod");
int lastBit; //set first clock check - can go negative
size_t i, bitnum = 0; //output counter
uint8_t midBit = 0;
uint8_t tol = 0; //clock tolerance adjust - waves will be accepted as within the clock if they fall + or - this value + clock from last valid wave
if (*clk <= 32) tol = 1; //clock tolerance may not be needed anymore currently set to + or - 1 but could be increased for poor waves or removed entirely
size_t MaxBits = 3072;
size_t MaxBits = 3072; //max bits to collect
lastBit = start - *clk;
for (i = start; i < *size; ++i) {
@ -310,6 +311,7 @@ int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr
BinStream[bitnum++] = *invert ^ 1;
} else if (i-lastBit >= *clk+tol) {
if (bitnum > 0) {
if (g_debugMode==2) prnt("DEBUG ASK: Modulation Error at: %u", i);
BinStream[bitnum++]=7;
errCnt++;
}
@ -1212,7 +1214,7 @@ int indala26decode(uint8_t *bitStream, size_t *size, uint8_t *invert)
return (int) startidx;
}
// by marshmellow - demodulate NRZ wave
// by marshmellow - demodulate NRZ wave - requires a read with strong signal
// peaks invert bit (high=1 low=0) each clock cycle = 1 bit determined by last peak
int nrzRawDemod(uint8_t *dest, size_t *size, int *clk, int *invert){
if (justNoise(dest, *size)) return -1;
@ -1531,3 +1533,166 @@ int pskRawDemod(uint8_t dest[], size_t *size, int *clock, int *invert)
*size = numBits;
return errCnt;
}
//by marshmellow
//attempt to identify a Sequence Terminator in ASK modulated raw wave
bool DetectST(uint8_t buffer[], size_t *size, int *foundclock) {
size_t bufsize = *size;
//need to loop through all samples and identify our clock, look for the ST pattern
uint8_t fndClk[] = {8,16,32,40,50,64,128};
int clk = 0;
int tol = 0;
int i, j, skip, start, end, low, high, minClk, waveStart;
bool complete = false;
int tmpbuff[bufsize / 64];
int waveLen[bufsize / 64];
size_t testsize = (bufsize < 512) ? bufsize : 512;
int phaseoff = 0;
high = low = 128;
memset(tmpbuff, 0, sizeof(tmpbuff));
if ( getHiLo(buffer, testsize, &high, &low, 80, 80) == -1 ) {
if (g_debugMode==2) prnt("DEBUG STT: just noise detected - quitting");
return false; //just noise
}
i = 0;
j = 0;
minClk = 255;
// get to first full low to prime loop and skip incomplete first pulse
while ((buffer[i] < high) && (i < bufsize))
++i;
while ((buffer[i] > low) && (i < bufsize))
++i;
skip = i;
// populate tmpbuff buffer with pulse lengths
while (i < bufsize) {
// measure from low to low
while ((buffer[i] > low) && (i < bufsize))
++i;
start= i;
while ((buffer[i] < high) && (i < bufsize))
++i;
//first high point for this wave
waveStart = i;
while ((buffer[i] > low) && (i < bufsize))
++i;
if (j >= (bufsize/64)) {
break;
}
waveLen[j] = i - waveStart; //first high to first low
tmpbuff[j++] = i - start;
if (i-start < minClk && i < bufsize) {
minClk = i - start;
}
}
// set clock - might be able to get this externally and remove this work...
if (!clk) {
for (uint8_t clkCnt = 0; clkCnt<7; clkCnt++) {
tol = fndClk[clkCnt]/8;
if (minClk >= fndClk[clkCnt]-tol && minClk <= fndClk[clkCnt]+1) {
clk=fndClk[clkCnt];
break;
}
}
// clock not found - ERROR
if (!clk) {
if (g_debugMode==2) prnt("DEBUG STT: clock not found - quitting");
return false;
}
} else tol = clk/8;
*foundclock = clk;
// look for Sequence Terminator - should be pulses of clk*(1 or 1.5), clk*2, clk*(1.5 or 2)
start = -1;
for (i = 0; i < j - 4; ++i) {
skip += tmpbuff[i];
if (tmpbuff[i] >= clk*1-tol && tmpbuff[i] <= (clk*2)+tol && waveLen[i] < clk+tol) { //1 to 2 clocks depending on 2 bits prior
if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol && waveLen[i+1] > clk*3/2-tol) { //2 clocks and wave size is 1 1/2
if (tmpbuff[i+2] >= (clk*3)/2-tol && tmpbuff[i+2] <= clk*2+tol && waveLen[i+2] > clk-tol) { //1 1/2 to 2 clocks and at least one full clock wave
if (tmpbuff[i+3] >= clk*1-tol && tmpbuff[i+3] <= clk*2+tol) { //1 to 2 clocks for end of ST + first bit
start = i + 3;
break;
}
}
}
}
}
// first ST not found - ERROR
if (start < 0) {
if (g_debugMode==2) prnt("DEBUG STT: first STT not found - quitting");
return false;
}
if (waveLen[i+2] > clk*1+tol)
phaseoff = 0;
else
phaseoff = clk/2;
// skip over the remainder of ST
skip += clk*7/2; //3.5 clocks from tmpbuff[i] = end of st - also aligns for ending point
// now do it again to find the end
end = skip;
for (i += 3; i < j - 4; ++i) {
end += tmpbuff[i];
if (tmpbuff[i] >= clk*1-tol && tmpbuff[i] <= (clk*2)+tol) { //1 to 2 clocks depending on 2 bits prior
if (tmpbuff[i+1] >= clk*2-tol && tmpbuff[i+1] <= clk*2+tol && waveLen[i+1] > clk*3/2-tol) { //2 clocks and wave size is 1 1/2
if (tmpbuff[i+2] >= (clk*3)/2-tol && tmpbuff[i+2] <= clk*2+tol && waveLen[i+2] > clk-tol) { //1 1/2 to 2 clocks and at least one full clock wave
if (tmpbuff[i+3] >= clk*1-tol && tmpbuff[i+3] <= clk*2+tol) { //1 to 2 clocks for end of ST + first bit
complete = true;
break;
}
}
}
}
}
end -= phaseoff;
//didn't find second ST - ERROR
if (!complete) {
if (g_debugMode==2) prnt("DEBUG STT: second STT not found - quitting");
return false;
}
if (g_debugMode==2) prnt("DEBUG STT: start of data: %d end of data: %d, datalen: %d, clk: %d, bits: %d, phaseoff: %d", skip, end, end-skip, clk, (end-skip)/clk, phaseoff);
//now begin to trim out ST so we can use normal demod cmds
start = skip;
size_t datalen = end - start;
// check validity of datalen (should be even clock increments) - use a tolerance of up to 1/8th a clock
if (datalen % clk > clk/8) {
if (g_debugMode==2) prnt("DEBUG STT: datalen not divisible by clk: %u %% %d = %d - quitting", datalen, clk, datalen % clk);
return false;
} else {
// padd the amount off - could be problematic... but shouldn't happen often
datalen += datalen % clk;
}
// if datalen is less than one t55xx block - ERROR
if (datalen/clk < 8*4) {
if (g_debugMode==2) prnt("DEBUG STT: datalen is less than 1 full t55xx block - quitting");
return false;
}
size_t dataloc = start;
size_t newloc = 0;
i=0;
// 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... (we cut out the high part)
if (buffer[dataloc]<high && buffer[dataloc]>low && buffer[dataloc+3]<high && buffer[dataloc+3]>low) {
for(i=0; i < clk/2-tol; ++i) {
buffer[dataloc+i] = high+5;
}
}
for (i=0; i<datalen; ++i) {
if (i+newloc < bufsize) {
if (i+newloc < dataloc)
buffer[i+newloc] = buffer[dataloc];
dataloc++;
}
}
newloc += i;
//skip next ST
dataloc += clk*4;
}
*size = newloc;
return true;
}

View file

@ -14,9 +14,9 @@
#ifndef LFDEMOD_H__
#define LFDEMOD_H__
#include <stdint.h>
#include "common.h" //for bool
//generic
uint8_t justNoise(uint8_t *BitStream, size_t size);
size_t addParity(uint8_t *BitSource, uint8_t *dest, uint8_t sourceLen, uint8_t pLen, uint8_t pType);
int askdemod(uint8_t *BinStream, size_t *size, int *clk, int *invert, int maxErr, uint8_t amp, uint8_t askType);
int BiphaseRawDecode(uint8_t * BitStream, size_t *size, int offset, int invert);
@ -29,6 +29,7 @@ uint8_t detectFSKClk(uint8_t *BitStream, size_t size, uint8_t fcHigh, uint8_t f
int DetectNRZClock(uint8_t dest[], size_t size, int clock);
int DetectPSKClock(uint8_t dest[], size_t size, int clock);
int DetectStrongAskClock(uint8_t dest[], size_t size, uint8_t high, uint8_t low);
bool DetectST(uint8_t buffer[], size_t *size, int *foundclock);
int fskdemod(uint8_t *dest, size_t size, uint8_t rfLen, uint8_t invert, uint8_t fchigh, uint8_t fclow);
int getHiLo(uint8_t *BitStream, size_t size, int *high, int *low, uint8_t fuzzHi, uint8_t fuzzLo);
uint32_t manchesterEncode2Bytes(uint16_t datain);