// Data and Graph commands
//-----------------------------------------------------------------------------
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <limits.h>
-#include "proxmark3.h"
-#include "data.h"
-#include "ui.h"
-#include "graph.h"
-#include "cmdparser.h"
+#include <stdio.h> // also included in util.h
+#include <string.h> // also included in util.h
+#include <inttypes.h>
+#include <limits.h> // for CmdNorm INT_MIN && INT_MAX
+#include "data.h" // also included in util.h
+#include "cmddata.h"
#include "util.h"
#include "cmdmain.h"
-#include "cmddata.h"
-#include "lfdemod.h"
-#include "usb_cmd.h"
-#include "crc.h"
-#include "crc16.h"
+#include "proxmark3.h"
+#include "ui.h" // for show graph controls
+#include "graph.h" // for graph data
+#include "cmdparser.h"// already included in cmdmain.h
+#include "usb_cmd.h" // already included in cmdmain.h and proxmark3.h
+#include "lfdemod.h" // for demod code
+#include "crc.h" // for pyramid checksum maxim
+#include "crc16.h" // for FDXB demod checksum
+#include "loclass/cipherutils.h" // for decimating samples in getsamples
+#include "cmdlfem4x.h"// for em410x demod
uint8_t DemodBuffer[MAX_DEMOD_BUF_LEN];
-uint8_t g_debugMode;
-size_t DemodBufferLen;
+uint8_t g_debugMode=0;
+size_t DemodBufferLen=0;
+//size_t g_demodStartIdx=0;
+//uint8_t g_demodClock=0;
+
static int CmdHelp(const char *Cmd);
//set the demod buffer with given array of binary (one bit per byte)
}
int usage_data_printdemodbuf(){
- PrintAndLog("Usage: data printdemodbuffer x o <offset>");
+ PrintAndLog("Usage: data printdemodbuffer x o <offset> l <length>");
PrintAndLog("Options: ");
PrintAndLog(" h This help");
PrintAndLog(" x output in hex (omit for binary output)");
PrintAndLog(" o <offset> enter offset in # of bits");
+ PrintAndLog(" l <length> enter length to print in # of bits or hex characters respectively");
return 0;
}
char hex[512]={0x00};
bool hexMode = false;
bool errors = false;
- uint8_t offset = 0;
+ uint32_t offset = 0; //could be size_t but no param_get16...
+ uint32_t length = 512;
char cmdp = 0;
while(param_getchar(Cmd, cmdp) != 0x00)
{
break;
case 'o':
case 'O':
- offset = param_get8(Cmd, cmdp+1);
+ offset = param_get32ex(Cmd, cmdp+1, 0, 10);
if (!offset) errors = true;
cmdp += 2;
break;
+ case 'l':
+ case 'L':
+ length = param_get32ex(Cmd, cmdp+1, 512, 10);
+ if (!length) errors = true;
+ cmdp += 2;
+ break;
default:
PrintAndLog("Unknown parameter '%c'", param_getchar(Cmd, cmdp));
errors = true;
}
//Validations
if(errors) return usage_data_printdemodbuf();
-
- int numBits = (DemodBufferLen-offset) & 0x7FC; //make sure we don't exceed our string
+ length = (length > (DemodBufferLen-offset)) ? DemodBufferLen-offset : length;
+ int numBits = (length) & 0x00FFC; //make sure we don't exceed our string
if (hexMode){
char *buf = (char *) (DemodBuffer + offset);
+ numBits = (numBits > sizeof(hex)) ? sizeof(hex) : numBits;
numBits = binarraytohex(hex, buf, numBits);
if (numBits==0) return 0;
PrintAndLog("DemodBuffer: %s",hex);
} else {
- //setDemodBuf(DemodBuffer, DemodBufferLen-offset, offset);
- char *bin = sprint_bin_break(DemodBuffer+offset,numBits,16);
- PrintAndLog("DemodBuffer:\n%s",bin);
+ PrintAndLog("DemodBuffer:\n%s", sprint_bin_break(DemodBuffer+offset,numBits,16));
}
return 1;
}
return 0;
}
-//by marshmellow
-//print 64 bit EM410x ID in multiple formats
-void printEM410x(uint32_t hi, uint64_t id)
-{
- if (id || hi){
- uint64_t iii=1;
- uint64_t id2lo=0;
- uint32_t ii=0;
- uint32_t i=0;
- for (ii=5; ii>0;ii--){
- for (i=0;i<8;i++){
- id2lo=(id2lo<<1LL) | ((id & (iii << (i+((ii-1)*8)))) >> (i+((ii-1)*8)));
- }
- }
- if (hi){
- //output 88 bit em id
- PrintAndLog("\nEM TAG ID : %06X%016llX", hi, id);
- } else{
- //output 40 bit em id
- PrintAndLog("\nEM TAG ID : %010llX", id);
- PrintAndLog("Unique TAG ID : %010llX", id2lo);
- PrintAndLog("\nPossible de-scramble patterns");
- PrintAndLog("HoneyWell IdentKey {");
- PrintAndLog("DEZ 8 : %08lld",id & 0xFFFFFF);
- PrintAndLog("DEZ 10 : %010lld",id & 0xFFFFFFFF);
- PrintAndLog("DEZ 5.5 : %05lld.%05lld",(id>>16LL) & 0xFFFF,(id & 0xFFFF));
- PrintAndLog("DEZ 3.5A : %03lld.%05lld",(id>>32ll),(id & 0xFFFF));
- PrintAndLog("DEZ 3.5B : %03lld.%05lld",(id & 0xFF000000) >> 24,(id & 0xFFFF));
- PrintAndLog("DEZ 3.5C : %03lld.%05lld",(id & 0xFF0000) >> 16,(id & 0xFFFF));
- PrintAndLog("DEZ 14/IK2 : %014lld",id);
- PrintAndLog("DEZ 15/IK3 : %015lld",id2lo);
- PrintAndLog("DEZ 20/ZK : %02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld%02lld",
- (id2lo & 0xf000000000) >> 36,
- (id2lo & 0x0f00000000) >> 32,
- (id2lo & 0x00f0000000) >> 28,
- (id2lo & 0x000f000000) >> 24,
- (id2lo & 0x0000f00000) >> 20,
- (id2lo & 0x00000f0000) >> 16,
- (id2lo & 0x000000f000) >> 12,
- (id2lo & 0x0000000f00) >> 8,
- (id2lo & 0x00000000f0) >> 4,
- (id2lo & 0x000000000f)
- );
- uint64_t paxton = (((id>>32) << 24) | (id & 0xffffff)) + 0x143e00;
- PrintAndLog("}\nOther : %05lld_%03lld_%08lld",(id&0xFFFF),((id>>16LL) & 0xFF),(id & 0xFFFFFF));
- PrintAndLog("Pattern Paxton : %lld [0x%llX]", paxton, paxton);
-
- uint32_t p1id = (id & 0xFFFFFF);
- uint8_t arr[32] = {0x00};
- int i =0;
- int j = 23;
- for (; i < 24; ++i, --j ){
- arr[i] = (p1id >> i) & 1;
- }
-
- uint32_t p1 = 0;
-
- p1 |= arr[23] << 21;
- p1 |= arr[22] << 23;
- p1 |= arr[21] << 20;
- p1 |= arr[20] << 22;
-
- p1 |= arr[19] << 18;
- p1 |= arr[18] << 16;
- p1 |= arr[17] << 19;
- p1 |= arr[16] << 17;
-
- p1 |= arr[15] << 13;
- p1 |= arr[14] << 15;
- p1 |= arr[13] << 12;
- p1 |= arr[12] << 14;
-
- p1 |= arr[11] << 6;
- p1 |= arr[10] << 2;
- p1 |= arr[9] << 7;
- p1 |= arr[8] << 1;
-
- p1 |= arr[7] << 0;
- p1 |= arr[6] << 8;
- p1 |= arr[5] << 11;
- p1 |= arr[4] << 3;
-
- p1 |= arr[3] << 10;
- p1 |= arr[2] << 4;
- p1 |= arr[1] << 5;
- p1 |= arr[0] << 9;
- PrintAndLog("Pattern 1 : %d [0x%X]", p1, p1);
-
- uint16_t sebury1 = id & 0xFFFF;
- uint8_t sebury2 = (id >> 16) & 0x7F;
- uint32_t sebury3 = id & 0x7FFFFF;
- PrintAndLog("Pattern Sebury : %d %d %d [0x%X 0x%X 0x%X]", sebury1, sebury2, sebury3, sebury1, sebury2, sebury3);
- }
- }
- return;
-}
-
-int AskEm410xDecode(bool verbose, uint32_t *hi, uint64_t *lo )
-{
- size_t idx = 0;
- size_t BitLen = DemodBufferLen;
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- memcpy(BitStream, DemodBuffer, BitLen);
- if (Em410xDecode(BitStream, &BitLen, &idx, hi, lo)){
- //set GraphBuffer for clone or sim command
- setDemodBuf(BitStream, BitLen, idx);
- if (g_debugMode){
- PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
- printDemodBuff();
- }
- if (verbose){
- PrintAndLog("EM410x pattern found: ");
- printEM410x(*hi, *lo);
- }
- return 1;
- }
- return 0;
-}
-
-int AskEm410xDemod(const char *Cmd, uint32_t *hi, uint64_t *lo, bool verbose)
-{
- if (!ASKDemod(Cmd, FALSE, FALSE, 1)) return 0;
- return AskEm410xDecode(verbose, hi, lo);
-}
-
-//by marshmellow
-//takes 3 arguments - clock, invert and maxErr as integers
-//attempts to demodulate ask while decoding manchester
-//prints binary found and saves in graphbuffer for further commands
-int CmdAskEM410xDemod(const char *Cmd)
-{
- char cmdp = param_getchar(Cmd, 0);
- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
- PrintAndLog("Usage: data askem410xdemod [clock] <0|1> [maxError]");
- PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
- PrintAndLog(" <invert>, 1 for invert output");
- PrintAndLog(" [set maximum allowed errors], default = 100.");
- PrintAndLog("");
- PrintAndLog(" sample: data askem410xdemod = demod an EM410x Tag ID from GraphBuffer");
- PrintAndLog(" : data askem410xdemod 32 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32");
- PrintAndLog(" : data askem410xdemod 32 1 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/32 and inverting data");
- PrintAndLog(" : data askem410xdemod 1 = demod an EM410x Tag ID from GraphBuffer while inverting data");
- PrintAndLog(" : data askem410xdemod 64 1 0 = demod an EM410x Tag ID from GraphBuffer using a clock of RF/64 and inverting data and allowing 0 demod errors");
- return 0;
- }
- uint64_t lo = 0;
- uint32_t hi = 0;
- return AskEm410xDemod(Cmd, &hi, &lo, true);
-}
-
//by marshmellow
//Cmd Args: Clock, invert, maxErr, maxLen as integers and amplify as char == 'a'
// (amp may not be needed anymore)
//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;
int maxLen=0;
- uint8_t askAmp = 0;
+ uint8_t askamp = 0;
char amp = param_getchar(Cmd, 0);
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
sscanf(Cmd, "%i %i %i %i %c", &clk, &invert, &maxErr, &maxLen, &);
- if (!maxLen) maxLen = 512*64;
+ if (!maxLen) maxLen = BIGBUF_SIZE;
if (invert != 0 && invert != 1) {
PrintAndLog("Invalid argument: %s", Cmd);
return 0;
invert=1;
clk=0;
}
- if (amp == 'a' || amp == 'A') askAmp=1;
size_t BitLen = getFromGraphBuf(BitStream);
if (g_debugMode) PrintAndLog("DEBUG: Bitlen from grphbuff: %d",BitLen);
- if (BitLen<255) return 0;
- if (maxLen<BitLen && maxLen != 0) BitLen = maxLen;
-
- int errCnt = askdemod(BitStream, &BitLen, &clk, &invert, maxErr, askAmp, askType);
+ if (BitLen < 255) return 0;
+ if (maxLen < BitLen && maxLen != 0) BitLen = maxLen;
+ int foundclk = 0;
+ //amp before ST check
+ if (amp == 'a' || amp == 'A') {
+ askAmp(BitStream, BitLen);
+ }
+ bool st = false;
+ size_t ststart = 0, stend = 0;
+ if (*stCheck) st = DetectST_ext(BitStream, &BitLen, &foundclk, &ststart, &stend);
+ if (st) {
+ *stCheck = st;
+ clk = (clk == 0) ? foundclk : clk;
+ CursorCPos = ststart;
+ CursorDPos = stend;
+ if (verbose || g_debugMode) PrintAndLog("\nFound Sequence Terminator - First one is shown by orange and blue graph markers");
+ }
+ 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);
return 0;
}
- if (errCnt>maxErr){
+ if (errCnt > maxErr){
if (g_debugMode) PrintAndLog("DEBUG: Too many errors found, errors:%d, bits:%d, clock:%d",errCnt, BitLen, clk);
return 0;
}
}
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'
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]");
+ if (strlen(Cmd) > 45 || cmdp == 'h' || cmdp == 'H') {
+ 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");
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;
}
- return ASKDemod(Cmd, TRUE, TRUE, 1);
+ 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);
}
//by marshmellow
sscanf(Cmd, "%i %i", &invert, &maxErr);
size=i;
- errCnt=manrawdecode(BitStream, &size, invert);
+ uint8_t alignPos = 0;
+ errCnt=manrawdecode(BitStream, &size, invert, &alignPos);
if (errCnt>=maxErr){
PrintAndLog("Too many errors: %d",errCnt);
return 0;
PrintAndLog(" : data rawdemod ab 0 64 1 0 0 a = demod an ask/biph tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0;
}
- return ASKbiphaseDemod(Cmd, TRUE);
-}
-
-//by marshmellow
-//attempts to demodulate and identify a G_Prox_II verex/chubb card
-//WARNING: if it fails during some points it will destroy the DemodBuffer data
-// but will leave the GraphBuffer intact.
-//if successful it will push askraw data back to demod buffer ready for emulation
-int CmdG_Prox_II_Demod(const char *Cmd)
-{
- if (!ASKbiphaseDemod(Cmd, FALSE)){
- if (g_debugMode) PrintAndLog("ASKbiphaseDemod failed 1st try");
- return 0;
- }
- size_t size = DemodBufferLen;
- //call lfdemod.c demod for gProxII
- int ans = gProxII_Demod(DemodBuffer, &size);
- if (ans < 0){
- if (g_debugMode) PrintAndLog("Error gProxII_Demod");
- return 0;
- }
- //got a good demod
- uint32_t ByteStream[65] = {0x00};
- uint8_t xorKey=0;
- uint8_t keyCnt=0;
- uint8_t bitCnt=0;
- uint8_t ByteCnt=0;
- size_t startIdx = ans + 6; //start after preamble
- for (size_t idx = 0; idx<size-6; idx++){
- if ((idx+1) % 5 == 0){
- //spacer bit - should be 0
- if (DemodBuffer[startIdx+idx] != 0) {
- if (g_debugMode) PrintAndLog("Error spacer not 0: %d, pos: %d",DemodBuffer[startIdx+idx],startIdx+idx);
- return 0;
- }
- continue;
- }
- if (keyCnt<8){ //lsb first
- xorKey = xorKey | (DemodBuffer[startIdx+idx]<<keyCnt);
- keyCnt++;
- if (keyCnt==8 && g_debugMode) PrintAndLog("xorKey Found: %02x", xorKey);
- continue;
- }
- //lsb first
- ByteStream[ByteCnt] = ByteStream[ByteCnt] | (DemodBuffer[startIdx+idx]<<bitCnt);
- bitCnt++;
- if (bitCnt % 8 == 0){
- if (g_debugMode) PrintAndLog("byte %d: %02x",ByteCnt,ByteStream[ByteCnt]);
- bitCnt=0;
- ByteCnt++;
- }
- }
- for (uint8_t i = 0; i < ByteCnt; i++){
- ByteStream[i] ^= xorKey; //xor
- if (g_debugMode) PrintAndLog("byte %d after xor: %02x", i, ByteStream[i]);
- }
- //now ByteStream contains 64 bytes of decrypted raw tag data
- //
- uint8_t fmtLen = ByteStream[0]>>2;
- uint32_t FC = 0;
- uint32_t Card = 0;
- uint32_t raw1 = bytebits_to_byte(DemodBuffer+ans,32);
- uint32_t raw2 = bytebits_to_byte(DemodBuffer+ans+32, 32);
- uint32_t raw3 = bytebits_to_byte(DemodBuffer+ans+64, 32);
-
- if (fmtLen==36){
- FC = ((ByteStream[3] & 0x7F)<<7) | (ByteStream[4]>>1);
- Card = ((ByteStream[4]&1)<<19) | (ByteStream[5]<<11) | (ByteStream[6]<<3) | (ByteStream[7]>>5);
- PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card);
- } else if(fmtLen==26){
- FC = ((ByteStream[3] & 0x7F)<<1) | (ByteStream[4]>>7);
- Card = ((ByteStream[4]&0x7F)<<9) | (ByteStream[5]<<1) | (ByteStream[6]>>7);
- PrintAndLog("G-Prox-II Found: FmtLen %d, FC %d, Card %d",fmtLen,FC,Card);
- } else {
- PrintAndLog("Unknown G-Prox-II Fmt Found: FmtLen %d",fmtLen);
- }
- PrintAndLog("Raw: %08x%08x%08x", raw1,raw2,raw3);
- setDemodBuf(DemodBuffer+ans, 96, 0);
- return 1;
+ return ASKbiphaseDemod(Cmd, true);
}
//by marshmellow - see ASKDemod
int Cmdaskrawdemod(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
- if (strlen(Cmd) > 25 || cmdp == 'h' || cmdp == 'H') {
+ if (strlen(Cmd) > 35 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod ar [clock] <invert> [maxError] [maxLen] [amplify]");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect");
PrintAndLog(" <invert>, 1 to invert output");
PrintAndLog(" : data rawdemod ar 64 1 0 0 a = demod an ask tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors, and amp");
return 0;
}
- return ASKDemod(Cmd, TRUE, FALSE, 0);
+ return ASKDemod(Cmd, true, false, 0);
}
int AutoCorrelate(int window, bool SaveGrph, bool verbose)
return usage_data_autocorr();
int window = 4000; //set default
char grph=0;
- bool updateGrph = FALSE;
+ bool updateGrph = false;
sscanf(Cmd, "%i %c", &window, &grph);
if (window >= GraphTraceLen) {
GraphTraceLen);
return 0;
}
- if (grph == 'g') updateGrph=TRUE;
- return AutoCorrelate(window, updateGrph, TRUE);
+ if (grph == 'g') updateGrph=true;
+ return AutoCorrelate(window, updateGrph, true);
}
int CmdBitsamples(const char *Cmd)
uint8_t factor = param_get8ex(Cmd, 0,2, 10);
//We have memory, don't we?
int swap[MAX_GRAPH_TRACE_LEN] = { 0 };
- uint32_t g_index = 0 ,s_index = 0;
- while(g_index < GraphTraceLen && s_index < MAX_GRAPH_TRACE_LEN)
+ uint32_t g_index = 0, s_index = 0;
+ while(g_index < GraphTraceLen && s_index + factor < MAX_GRAPH_TRACE_LEN)
{
int count = 0;
- for(count = 0; count < factor && s_index+count < MAX_GRAPH_TRACE_LEN; count ++)
+ for(count = 0; count < factor && s_index + count < MAX_GRAPH_TRACE_LEN; count++)
swap[s_index+count] = GraphBuffer[g_index];
- s_index+=count;
+
+ s_index += count;
+ g_index++;
}
- memcpy(GraphBuffer,swap, s_index * sizeof(int));
+ memcpy(GraphBuffer, swap, s_index * sizeof(int));
GraphTraceLen = s_index;
RepaintGraphWindow();
return 0;
int CmdAskEdgeDetect(const char *Cmd)
{
int thresLen = 25;
+ int Last = 0;
sscanf(Cmd, "%i", &thresLen);
for(int i = 1; i<GraphTraceLen; i++){
if (GraphBuffer[i]-GraphBuffer[i-1]>=thresLen) //large jump up
- GraphBuffer[i-1] = 127;
+ Last = 127;
else if(GraphBuffer[i]-GraphBuffer[i-1]<=-1*thresLen) //large jump down
- GraphBuffer[i-1] = -127;
+ Last = -127;
+ GraphBuffer[i-1] = Last;
}
RepaintGraphWindow();
return 0;
char *GetFSKType(uint8_t fchigh, uint8_t fclow, uint8_t invert)
{
- char *fskType;
+ static char fType[8];
+ memset(fType, 0x00, 8);
+ char *fskType = fType;
if (fchigh==10 && fclow==8){
if (invert) //fsk2a
- fskType = "FSK2a";
+ memcpy(fskType, "FSK2a", 5);
else //fsk2
- fskType = "FSK2";
+ memcpy(fskType, "FSK2", 4);
} else if (fchigh == 8 && fclow == 5) {
if (invert)
- fskType = "FSK1";
+ memcpy(fskType, "FSK1", 4);
else
- fskType = "FSK1a";
+ memcpy(fskType, "FSK1a", 5);
} else {
- fskType = "FSK??";
+ memcpy(fskType, "FSK??", 5);
}
return fskType;
}
int FSKrawDemod(const char *Cmd, bool verbose)
{
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
+ uint8_t rfLen, invert, fchigh, fclow;
//set defaults
- int rfLen = 0;
- int invert = 0;
- int fchigh = 0;
- int fclow = 0;
-
//set options from parameters entered with the command
- sscanf(Cmd, "%i %i %i %i", &rfLen, &invert, &fchigh, &fclow);
+ rfLen = param_get8(Cmd, 0);
+ invert = param_get8(Cmd, 1);
+ fchigh = param_get8(Cmd, 2);
+ fclow = param_get8(Cmd, 3);
if (strlen(Cmd)>0 && strlen(Cmd)<=2) {
- if (rfLen==1){
+ if (rfLen==1) {
invert = 1; //if invert option only is used
rfLen = 0;
- }
+ }
}
-
uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
size_t BitLen = getFromGraphBuf(BitStream);
if (BitLen==0) return 0;
//get field clock lengths
uint16_t fcs=0;
- if (fchigh==0 || fclow == 0){
+ if (!fchigh || !fclow) {
fcs = countFC(BitStream, BitLen, 1);
- if (fcs==0){
- fchigh=10;
- fclow=8;
- }else{
- fchigh = (fcs >> 8) & 0xFF;
- fclow = fcs & 0xFF;
+ if (!fcs) {
+ fchigh = 10;
+ fclow = 8;
+ } else {
+ fchigh = (fcs >> 8) & 0x00FF;
+ fclow = fcs & 0x00FF;
}
}
//get bit clock length
- if (rfLen==0){
+ if (!rfLen) {
rfLen = detectFSKClk(BitStream, BitLen, fchigh, fclow);
- if (rfLen == 0) rfLen = 50;
+ if (!rfLen) rfLen = 50;
}
- int size = fskdemod(BitStream,BitLen,(uint8_t)rfLen,(uint8_t)invert,(uint8_t)fchigh,(uint8_t)fclow);
- if (size>0){
+ int size = fskdemod(BitStream, BitLen, rfLen, invert, fchigh, fclow);
+ if (size > 0) {
setDemodBuf(BitStream,size,0);
// Now output the bitstream to the scrollback by line of 16 bits
if (verbose || g_debugMode) {
- PrintAndLog("\nUsing Clock:%d, invert:%d, fchigh:%d, fclow:%d", rfLen, invert, fchigh, fclow);
+ PrintAndLog("\nUsing Clock:%u, invert:%u, fchigh:%u, fclow:%u", (unsigned int)rfLen, (unsigned int)invert, (unsigned int)fchigh, (unsigned int)fclow);
PrintAndLog("%s decoded bitstream:",GetFSKType(fchigh,fclow,invert));
printDemodBuff();
}
return 1;
- } else{
+ } else {
if (g_debugMode) PrintAndLog("no FSK data found");
}
return 0;
int CmdFSKrawdemod(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ if (strlen(Cmd) > 20 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod fs [clock] <invert> [fchigh] [fclow]");
PrintAndLog(" [set clock as integer] optional, omit for autodetect.");
PrintAndLog(" <invert>, 1 for invert output, can be used even if the clock is omitted");
PrintAndLog(" : data rawdemod fs 50 1 10 8 = demod an fsk2a RF/50 tag from GraphBuffer");
return 0;
}
- return FSKrawDemod(Cmd, TRUE);
-}
-
-//by marshmellow (based on existing demod + holiman's refactor)
-//HID Prox demod - FSK RF/50 with preamble of 00011101 (then manchester encoded)
-//print full HID Prox ID and some bit format details if found
-int CmdFSKdemodHID(const char *Cmd)
-{
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- uint32_t hi2=0, hi=0, lo=0;
-
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- size_t BitLen = getFromGraphBuf(BitStream);
- if (BitLen==0) return 0;
- //get binary from fsk wave
- int idx = HIDdemodFSK(BitStream,&BitLen,&hi2,&hi,&lo);
- if (idx<0){
- if (g_debugMode){
- if (idx==-1){
- PrintAndLog("DEBUG: Just Noise Detected");
- } else if (idx == -2) {
- PrintAndLog("DEBUG: Error demoding fsk");
- } else if (idx == -3) {
- PrintAndLog("DEBUG: Preamble not found");
- } else if (idx == -4) {
- PrintAndLog("DEBUG: Error in Manchester data, SIZE: %d", BitLen);
- } else {
- PrintAndLog("DEBUG: Error demoding fsk %d", idx);
- }
- }
- return 0;
- }
- if (hi2==0 && hi==0 && lo==0) {
- if (g_debugMode) PrintAndLog("DEBUG: Error - no values found");
- return 0;
- }
- if (hi2 != 0){ //extra large HID tags
- PrintAndLog("HID Prox TAG ID: %x%08x%08x (%d)",
- (unsigned int) hi2, (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF);
- }
- else { //standard HID tags <38 bits
- uint8_t fmtLen = 0;
- uint32_t fc = 0;
- uint32_t cardnum = 0;
- if (((hi>>5)&1)==1){//if bit 38 is set then < 37 bit format is used
- uint32_t lo2=0;
- lo2=(((hi & 31) << 12) | (lo>>20)); //get bits 21-37 to check for format len bit
- uint8_t idx3 = 1;
- while(lo2>1){ //find last bit set to 1 (format len bit)
- lo2=lo2>>1;
- idx3++;
- }
- fmtLen =idx3+19;
- fc =0;
- cardnum=0;
- if(fmtLen==26){
- cardnum = (lo>>1)&0xFFFF;
- fc = (lo>>17)&0xFF;
- }
- if(fmtLen==34){
- cardnum = (lo>>1)&0xFFFF;
- fc= ((hi&1)<<15)|(lo>>17);
- }
- if(fmtLen==35){
- cardnum = (lo>>1)&0xFFFFF;
- fc = ((hi&1)<<11)|(lo>>21);
- }
- }
- else { //if bit 38 is not set then 37 bit format is used
- fmtLen = 37;
- fc = 0;
- cardnum = 0;
- if(fmtLen == 37){
- cardnum = (lo>>1)&0x7FFFF;
- fc = ((hi&0xF)<<12)|(lo>>20);
- }
- }
- PrintAndLog("HID Prox TAG ID: %x%08x (%d) - Format Len: %dbit - FC: %d - Card: %d",
- (unsigned int) hi, (unsigned int) lo, (unsigned int) (lo>>1) & 0xFFFF,
- (unsigned int) fmtLen, (unsigned int) fc, (unsigned int) cardnum);
- }
- setDemodBuf(BitStream,BitLen,idx);
- if (g_debugMode){
- PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, BitLen);
- printDemodBuff();
- }
- return 1;
+ return FSKrawDemod(Cmd, true);
}
//by marshmellow
return 1;
}
-//by marshmellow
-//IO-Prox demod - FSK RF/64 with preamble of 000000001
-//print ioprox ID and some format details
-int CmdFSKdemodIO(const char *Cmd)
-{
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- //set defaults
- int idx=0;
- //something in graphbuffer?
- if (GraphTraceLen < 65) {
- if (g_debugMode)PrintAndLog("DEBUG: not enough samples in GraphBuffer");
- return 0;
- }
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- size_t BitLen = getFromGraphBuf(BitStream);
- if (BitLen==0) return 0;
-
- //get binary from fsk wave
- idx = IOdemodFSK(BitStream,BitLen);
- if (idx<0){
- if (g_debugMode){
- if (idx==-1){
- PrintAndLog("DEBUG: Just Noise Detected");
- } else if (idx == -2) {
- PrintAndLog("DEBUG: not enough samples");
- } else if (idx == -3) {
- PrintAndLog("DEBUG: error during fskdemod");
- } else if (idx == -4) {
- PrintAndLog("DEBUG: Preamble not found");
- } else if (idx == -5) {
- PrintAndLog("DEBUG: Separator bits not found");
- } else {
- PrintAndLog("DEBUG: Error demoding fsk %d", idx);
- }
- }
- return 0;
- }
- if (idx==0){
- if (g_debugMode){
- PrintAndLog("DEBUG: IO Prox Data not found - FSK Bits: %d",BitLen);
- if (BitLen > 92) PrintAndLog("%s", sprint_bin_break(BitStream,92,16));
- }
- return 0;
- }
- //Index map
- //0 10 20 30 40 50 60
- //| | | | | | |
- //01234567 8 90123456 7 89012345 6 78901234 5 67890123 4 56789012 3 45678901 23
- //-----------------------------------------------------------------------------
- //00000000 0 11110000 1 facility 1 version* 1 code*one 1 code*two 1 ???????? 11
- //
- //XSF(version)facility:codeone+codetwo (raw)
- //Handle the data
- if (idx+64>BitLen) {
- if (g_debugMode) PrintAndLog("not enough bits found - bitlen: %d",BitLen);
- return 0;
- }
- PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx], BitStream[idx+1], BitStream[idx+2], BitStream[idx+3], BitStream[idx+4], BitStream[idx+5], BitStream[idx+6], BitStream[idx+7], BitStream[idx+8]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d",BitStream[idx+9], BitStream[idx+10], BitStream[idx+11],BitStream[idx+12],BitStream[idx+13],BitStream[idx+14],BitStream[idx+15],BitStream[idx+16],BitStream[idx+17]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d facility",BitStream[idx+18], BitStream[idx+19], BitStream[idx+20],BitStream[idx+21],BitStream[idx+22],BitStream[idx+23],BitStream[idx+24],BitStream[idx+25],BitStream[idx+26]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d version",BitStream[idx+27], BitStream[idx+28], BitStream[idx+29],BitStream[idx+30],BitStream[idx+31],BitStream[idx+32],BitStream[idx+33],BitStream[idx+34],BitStream[idx+35]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d code1",BitStream[idx+36], BitStream[idx+37], BitStream[idx+38],BitStream[idx+39],BitStream[idx+40],BitStream[idx+41],BitStream[idx+42],BitStream[idx+43],BitStream[idx+44]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d code2",BitStream[idx+45], BitStream[idx+46], BitStream[idx+47],BitStream[idx+48],BitStream[idx+49],BitStream[idx+50],BitStream[idx+51],BitStream[idx+52],BitStream[idx+53]);
- PrintAndLog("%d%d%d%d%d%d%d%d %d%d checksum",BitStream[idx+54],BitStream[idx+55],BitStream[idx+56],BitStream[idx+57],BitStream[idx+58],BitStream[idx+59],BitStream[idx+60],BitStream[idx+61],BitStream[idx+62],BitStream[idx+63]);
-
- uint32_t code = bytebits_to_byte(BitStream+idx,32);
- uint32_t code2 = bytebits_to_byte(BitStream+idx+32,32);
- uint8_t version = bytebits_to_byte(BitStream+idx+27,8); //14,4
- uint8_t facilitycode = bytebits_to_byte(BitStream+idx+18,8) ;
- uint16_t number = (bytebits_to_byte(BitStream+idx+36,8)<<8)|(bytebits_to_byte(BitStream+idx+45,8)); //36,9
- uint8_t crc = bytebits_to_byte(BitStream+idx+54,8);
- uint16_t calccrc = 0;
-
- for (uint8_t i=1; i<6; ++i){
- calccrc += bytebits_to_byte(BitStream+idx+9*i,8);
- }
- calccrc &= 0xff;
- calccrc = 0xff - calccrc;
-
- char *crcStr = (crc == calccrc) ? "crc ok": "!crc";
-
- PrintAndLog("IO Prox XSF(%02d)%02x:%05d (%08x%08x) [%02x %s]",version,facilitycode,number,code,code2, crc, crcStr);
- setDemodBuf(BitStream,64,idx);
- if (g_debugMode){
- PrintAndLog("DEBUG: idx: %d, Len: %d, Printing demod buffer:",idx,64);
- printDemodBuff();
- }
- return 1;
-}
-
-//by marshmellow
-//AWID Prox demod - FSK RF/50 with preamble of 00000001 (always a 96 bit data stream)
-//print full AWID Prox ID and some bit format details if found
-int CmdFSKdemodAWID(const char *Cmd)
-{
-
- //int verbose=1;
- //sscanf(Cmd, "%i", &verbose);
-
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- size_t size = getFromGraphBuf(BitStream);
- if (size==0) return 0;
-
- //get binary from fsk wave
- int idx = AWIDdemodFSK(BitStream, &size);
- if (idx<=0){
- if (g_debugMode==1){
- if (idx == -1)
- PrintAndLog("DEBUG: Error - not enough samples");
- else if (idx == -2)
- PrintAndLog("DEBUG: Error - only noise found");
- else if (idx == -3)
- PrintAndLog("DEBUG: Error - problem during FSK demod");
- else if (idx == -4)
- PrintAndLog("DEBUG: Error - AWID preamble not found");
- else if (idx == -5)
- PrintAndLog("DEBUG: Error - Size not correct: %d", size);
- else
- PrintAndLog("DEBUG: Error %d",idx);
- }
- return 0;
- }
-
- // Index map
- // 0 10 20 30 40 50 60
- // | | | | | | |
- // 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 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
- // f = facility code, c = card number
- // w = wiegand parity
- // (26 bit format shown)
-
- //get raw ID before removing parities
- uint32_t rawLo = bytebits_to_byte(BitStream+idx+64,32);
- uint32_t rawHi = bytebits_to_byte(BitStream+idx+32,32);
- uint32_t rawHi2 = bytebits_to_byte(BitStream+idx,32);
- setDemodBuf(BitStream,96,idx);
-
- size = removeParity(BitStream, idx+8, 4, 1, 88);
- if (size != 66){
- if (g_debugMode==1) PrintAndLog("DEBUG: Error - at parity check-tag size does not match AWID format");
- return 0;
- }
- // ok valid card found!
-
- // Index map
- // 0 10 20 30 40 50 60
- // | | | | | | |
- // 01234567 8 90123456 7890123456789012 3 456789012345678901234567890123456
- // -----------------------------------------------------------------------------
- // 00011010 1 01110101 0000000010001110 1 000000000000000000000000000000000
- // bbbbbbbb w ffffffff cccccccccccccccc w xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
- // |26 bit| |-117--| |-----142------|
- // b = format bit len, o = odd parity of last 3 bits
- // f = facility code, c = card number
- // w = wiegand parity
- // (26 bit format shown)
-
- uint32_t fc = 0;
- uint32_t cardnum = 0;
- uint32_t code1 = 0;
- uint32_t code2 = 0;
- uint8_t fmtLen = bytebits_to_byte(BitStream,8);
- if (fmtLen==26){
- fc = bytebits_to_byte(BitStream+9, 8);
- cardnum = bytebits_to_byte(BitStream+17, 16);
- code1 = bytebits_to_byte(BitStream+8,fmtLen);
- PrintAndLog("AWID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi2, rawHi, rawLo);
- } else {
- cardnum = bytebits_to_byte(BitStream+8+(fmtLen-17), 16);
- if (fmtLen>32){
- code1 = bytebits_to_byte(BitStream+8,fmtLen-32);
- code2 = bytebits_to_byte(BitStream+8+(fmtLen-32),32);
- PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x%08x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, code2, rawHi2, rawHi, rawLo);
- } else{
- code1 = bytebits_to_byte(BitStream+8,fmtLen);
- PrintAndLog("AWID Found - BitLength: %d -unknown BitLength- (%d) - Wiegand: %x, Raw: %08x%08x%08x", fmtLen, cardnum, code1, rawHi2, rawHi, rawLo);
- }
- }
- if (g_debugMode){
- PrintAndLog("DEBUG: idx: %d, Len: %d Printing Demod Buffer:", idx, 96);
- printDemodBuff();
- }
- //todo - convert hi2, hi, lo to demodbuffer for future sim/clone commands
- return 1;
-}
-
-//by marshmellow
-//Pyramid Prox demod - FSK RF/50 with preamble of 0000000000000001 (always a 128 bit data stream)
-//print full Farpointe Data/Pyramid Prox ID and some bit format details if found
-int CmdFSKdemodPyramid(const char *Cmd)
-{
- //raw fsk demod no manchester decoding no start bit finding just get binary from wave
- uint8_t BitStream[MAX_GRAPH_TRACE_LEN]={0};
- size_t size = getFromGraphBuf(BitStream);
- if (size==0) return 0;
-
- //get binary from fsk wave
- int idx = PyramiddemodFSK(BitStream, &size);
- if (idx < 0){
- if (g_debugMode==1){
- if (idx == -5)
- PrintAndLog("DEBUG: Error - not enough samples");
- else if (idx == -1)
- PrintAndLog("DEBUG: Error - only noise found");
- else if (idx == -2)
- PrintAndLog("DEBUG: Error - problem during FSK demod");
- else if (idx == -3)
- PrintAndLog("DEBUG: Error - Size not correct: %d", size);
- else if (idx == -4)
- PrintAndLog("DEBUG: Error - Pyramid preamble not found");
- else
- PrintAndLog("DEBUG: Error - idx: %d",idx);
- }
- return 0;
- }
- // Index map
- // 0 10 20 30 40 50 60
- // | | | | | | |
- // 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3
- // -----------------------------------------------------------------------------
- // 0000000 0 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1 0000000 1
- // premable xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o xxxxxxx o
-
- // 64 70 80 90 100 110 120
- // | | | | | | |
- // 4567890 1 2345678 9 0123456 7 8901234 5 6789012 3 4567890 1 2345678 9 0123456 7
- // -----------------------------------------------------------------------------
- // 0000000 1 0000000 1 0000000 1 0110111 0 0011000 1 0000001 0 0001100 1 1001010 0
- // xxxxxxx o xxxxxxx o xxxxxxx o xswffff o ffffccc o ccccccc o ccccccw o ppppppp o
- // |---115---||---------71---------|
- // s = format start bit, o = odd parity of last 7 bits
- // f = facility code, c = card number
- // w = wiegand parity, x = extra space for other formats
- // p = unknown checksum
- // (26 bit format shown)
-
- //get bytes for checksum calc
- uint8_t checksum = bytebits_to_byte(BitStream + idx + 120, 8);
- uint8_t csBuff[14] = {0x00};
- for (uint8_t i = 0; i < 13; i++){
- csBuff[i] = bytebits_to_byte(BitStream + idx + 16 + (i*8), 8);
- }
- //check checksum calc
- //checksum calc thanks to ICEMAN!!
- uint32_t checkCS = CRC8Maxim(csBuff,13);
-
- //get raw ID before removing parities
- uint32_t rawLo = bytebits_to_byte(BitStream+idx+96,32);
- uint32_t rawHi = bytebits_to_byte(BitStream+idx+64,32);
- uint32_t rawHi2 = bytebits_to_byte(BitStream+idx+32,32);
- uint32_t rawHi3 = bytebits_to_byte(BitStream+idx,32);
- setDemodBuf(BitStream,128,idx);
-
- size = removeParity(BitStream, idx+8, 8, 1, 120);
- if (size != 105){
- if (g_debugMode==1)
- PrintAndLog("DEBUG: Error at parity check - tag size does not match Pyramid format, SIZE: %d, IDX: %d, hi3: %x",size, idx, rawHi3);
- return 0;
- }
-
- // ok valid card found!
-
- // Index map
- // 0 10 20 30 40 50 60 70
- // | | | | | | | |
- // 01234567890123456789012345678901234567890123456789012345678901234567890
- // -----------------------------------------------------------------------
- // 00000000000000000000000000000000000000000000000000000000000000000000000
- // xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
-
- // 71 80 90 100
- // | | | |
- // 1 2 34567890 1234567890123456 7 8901234
- // ---------------------------------------
- // 1 1 01110011 0000000001000110 0 1001010
- // s w ffffffff cccccccccccccccc w ppppppp
- // |--115-| |------71------|
- // s = format start bit, o = odd parity of last 7 bits
- // f = facility code, c = card number
- // w = wiegand parity, x = extra space for other formats
- // p = unknown checksum
- // (26 bit format shown)
-
- //find start bit to get fmtLen
- int j;
- for (j=0; j<size; j++){
- if(BitStream[j]) break;
- }
- uint8_t fmtLen = size-j-8;
- 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);
- code1 = bytebits_to_byte(BitStream+72,fmtLen);
- PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Wiegand: %x, Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, code1, rawHi3, rawHi2, rawHi, rawLo);
- } else if (fmtLen==45){
- fmtLen=42; //end = 10 bits not 7 like 26 bit fmt
- fc = bytebits_to_byte(BitStream+53, 10);
- cardnum = bytebits_to_byte(BitStream+63, 32);
- PrintAndLog("Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x", fmtLen, fc, cardnum, rawHi3, rawHi2, rawHi, rawLo);
- } else {
- cardnum = bytebits_to_byte(BitStream+81, 16);
- if (fmtLen>32){
- //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen-32);
- //code2 = bytebits_to_byte(BitStream+(size-32),32);
- PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
- } else{
- //code1 = bytebits_to_byte(BitStream+(size-fmtLen),fmtLen);
- PrintAndLog("Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x", fmtLen, cardnum, rawHi3, rawHi2, rawHi, rawLo);
- }
- }
- if (checksum == checkCS)
- PrintAndLog("Checksum %02x passed", checksum);
- else
- PrintAndLog("Checksum %02x failed - should have been %02x", checksum, checkCS);
-
- if (g_debugMode){
- PrintAndLog("DEBUG: idx: %d, Len: %d, Printing Demod Buffer:", idx, 128);
- printDemodBuff();
- }
- return 1;
-}
-
// FDX-B ISO11784/85 demod (aka animal tag) BIPHASE, inverted, rf/32, with preamble of 00000000001 (128bits)
// 8 databits + 1 parity (1)
// CIITT 16 chksum
// NATIONAL CODE, ICAR database
// COUNTRY CODE (ISO3166) or http://cms.abvma.ca/uploads/ManufacturersISOsandCountryCodes.pdf
// FLAG (animal/non-animal)
+/*
+38 IDbits
+10 country code
+1 extra app bit
+14 reserved bits
+1 animal bit
+16 ccitt CRC chksum over 64bit ID CODE.
+24 appli bits.
+
+-- sample: 985121004515220 [ 37FF65B88EF94 ]
+*/
int CmdFDXBdemodBI(const char *Cmd){
int invert = 1;
if (g_debugMode) PrintAndLog("Error FDXBDemod , no startmarker found :: %d",preambleIndex);
return 0;
}
+ if (size != 128) {
+ if (g_debugMode) PrintAndLog("Error incorrect data length found");
+ return 0;
+ }
setDemodBuf(BitStream, 128, preambleIndex);
if (g_debugMode) PrintAndLog("Raw ID Hex: %s", sprint_hex(raw,8));
uint16_t calcCrc = crc16_ccitt_kermit(raw, 8);
- PrintAndLog("Animal ID: %04u-%012llu", countryCode, NationalCode);
- PrintAndLog("National Code: %012llu", NationalCode);
+ PrintAndLog("Animal ID: %04u-%012" PRIu64, countryCode, NationalCode);
+ PrintAndLog("National Code: %012" PRIu64, NationalCode);
PrintAndLog("CountryCode: %04u", countryCode);
PrintAndLog("Extended Data: %s", dataBlockBit ? "True" : "False");
PrintAndLog("reserved Code: %u", reservedCode);
//invalid carrier
return 0;
}
+ if (g_debugMode){
+ PrintAndLog("Carrier: rf/%d",carrier);
+ }
int errCnt=0;
errCnt = pskRawDemod(BitStream, &BitLen, &clk, &invert);
if (errCnt > maxErr){
return 1;
}
-// Indala 26 bit decode
-// by marshmellow
-// optional arguments - same as CmdpskNRZrawDemod (clock & invert)
-int CmdIndalaDecode(const char *Cmd)
-{
- int ans;
- if (strlen(Cmd)>0){
- ans = PSKDemod(Cmd, 0);
- } else{ //default to RF/32
- ans = PSKDemod("32", 0);
- }
-
- if (!ans){
- if (g_debugMode==1)
- PrintAndLog("Error1: %d",ans);
- return 0;
- }
- uint8_t invert=0;
- ans = indala26decode(DemodBuffer, &DemodBufferLen, &invert);
- if (ans < 1) {
- if (g_debugMode==1)
- PrintAndLog("Error2: %d",ans);
- return -1;
- }
- char showbits[251]={0x00};
- if (invert)
- if (g_debugMode==1)
- PrintAndLog("Had to invert bits");
-
- //convert UID to HEX
- uint32_t uid1, uid2, uid3, uid4, uid5, uid6, uid7;
- int idx;
- uid1=0;
- uid2=0;
- PrintAndLog("BitLen: %d",DemodBufferLen);
- if (DemodBufferLen==64){
- for( idx=0; idx<64; idx++) {
- uid1=(uid1<<1)|(uid2>>31);
- if (DemodBuffer[idx] == 0) {
- uid2=(uid2<<1)|0;
- showbits[idx]='0';
- } else {
- uid2=(uid2<<1)|1;
- showbits[idx]='1';
- }
- }
- showbits[idx]='\0';
- PrintAndLog("Indala UID=%s (%x%08x)", showbits, uid1, uid2);
- }
- else {
- uid3=0;
- uid4=0;
- uid5=0;
- uid6=0;
- uid7=0;
- for( idx=0; idx<DemodBufferLen; 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 (DemodBuffer[idx] == 0) {
- uid7=(uid7<<1)|0;
- showbits[idx]='0';
- }
- else {
- uid7=(uid7<<1)|1;
- showbits[idx]='1';
- }
- }
- showbits[idx]='\0';
- PrintAndLog("Indala UID=%s (%x%08x%08x%08x%08x%08x%08x)", showbits, uid1, uid2, uid3, uid4, uid5, uid6, uid7);
- }
- if (g_debugMode){
- PrintAndLog("DEBUG: printing demodbuffer:");
- printDemodBuff();
- }
- return 1;
-}
-
int CmdPSKNexWatch(const char *Cmd)
{
if (!PSKDemod("", false)) return 0;
size_t BitLen = getFromGraphBuf(BitStream);
if (BitLen==0) return 0;
int errCnt=0;
- errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, maxErr);
+ int clkStartIdx = 0;
+ errCnt = nrzRawDemod(BitStream, &BitLen, &clk, &invert, &clkStartIdx);
if (errCnt > maxErr){
if (g_debugMode) PrintAndLog("Too many errors found, clk: %d, invert: %d, numbits: %d, errCnt: %d",clk,invert,BitLen,errCnt);
return 0;
int CmdNRZrawDemod(const char *Cmd)
{
char cmdp = param_getchar(Cmd, 0);
- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ if (strlen(Cmd) > 16 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod nr [clock] <0|1> [maxError]");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
PrintAndLog(" <invert>, 1 for invert output");
PrintAndLog(" : data rawdemod nr 64 1 0 = demod a nrz/direct tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0;
}
- return NRZrawDemod(Cmd, TRUE);
+ return NRZrawDemod(Cmd, true);
}
// by marshmellow
{
int ans;
char cmdp = param_getchar(Cmd, 0);
- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ if (strlen(Cmd) > 16 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod p1 [clock] <0|1> [maxError]");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
PrintAndLog(" <invert>, 1 for invert output");
PrintAndLog(" : data rawdemod p1 64 1 0 = demod a psk1 tag from GraphBuffer using a clock of RF/64, inverting data and allowing 0 demod errors");
return 0;
}
- ans = PSKDemod(Cmd, TRUE);
+ ans = PSKDemod(Cmd, true);
//output
if (!ans){
if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
{
int ans=0;
char cmdp = param_getchar(Cmd, 0);
- if (strlen(Cmd) > 10 || cmdp == 'h' || cmdp == 'H') {
+ if (strlen(Cmd) > 16 || cmdp == 'h' || cmdp == 'H') {
PrintAndLog("Usage: data rawdemod p2 [clock] <0|1> [maxError]");
PrintAndLog(" [set clock as integer] optional, if not set, autodetect.");
PrintAndLog(" <invert>, 1 for invert output");
PrintAndLog(" : data rawdemod p2 64 1 0 = demod a psk2 tag from GraphBuffer using a clock of RF/64, inverting output and allowing 0 demod errors");
return 0;
}
- ans=PSKDemod(Cmd, TRUE);
+ ans=PSKDemod(Cmd, true);
if (!ans){
if (g_debugMode) PrintAndLog("Error demoding: %d",ans);
return 0;
{
char cmdp = Cmd[0]; //param_getchar(Cmd, 0);
- if (strlen(Cmd) > 20 || cmdp == 'h' || cmdp == 'H' || strlen(Cmd)<2) {
+ if (strlen(Cmd) > 35 || cmdp == 'h' || cmdp == 'H' || strlen(Cmd)<2) {
PrintAndLog("Usage: data rawdemod [modulation] <help>|<options>");
PrintAndLog(" [modulation] as 2 char, 'ab' for ask/biphase, 'am' for ask/manchester, 'ar' for ask/raw, 'fs' for fsk, ...");
PrintAndLog(" 'nr' for nrz/direct, 'p1' for psk1, 'p2' for psk2");
return 0;
}
+int CmdSetGraphMarkers(const char *Cmd) {
+ sscanf(Cmd, "%i %i", &CursorCPos, &CursorDPos);
+ RepaintGraphWindow();
+ return 0;
+}
+
int CmdHexsamples(const char *Cmd)
{
int i, j;
RepaintGraphWindow();
return 0;
}
-typedef struct {
- uint8_t * buffer;
- uint32_t numbits;
- uint32_t position;
-}BitstreamOut;
-bool _headBit( BitstreamOut *stream)
-{
- int bytepos = stream->position >> 3; // divide by 8
- int bitpos = (stream->position++) & 7; // mask out 00000111
- return (*(stream->buffer + bytepos) >> (7-bitpos)) & 1;
-}
-
-uint8_t getByte(uint8_t bits_per_sample, BitstreamOut* b)
+uint8_t getByte(uint8_t bits_per_sample, BitstreamIn* b)
{
int i;
uint8_t val = 0;
for(i =0 ; i < bits_per_sample; i++)
{
- val |= (_headBit(b) << (7-i));
+ val |= (headBit(b) << (7-i));
}
return val;
}
int n = strtol(Cmd, NULL, 0);
- if (n == 0)
- n = sizeof(got);
-
- if (n > sizeof(got))
+ if (n == 0 || n > sizeof(got))
n = sizeof(got);
PrintAndLog("Reading %d bytes from device memory\n", n);
if(bits_per_sample < 8)
{
PrintAndLog("Unpacking...");
- BitstreamOut bout = { got, bits_per_sample * n, 0};
+ BitstreamIn bout = { got, bits_per_sample * n, 0};
int j =0;
for (j = 0; j * bits_per_sample < n * 8 && j < n; j++) {
uint8_t sample = getByte(bits_per_sample, &bout);
int CmdTuneSamples(const char *Cmd)
{
- int timeout = 0;
+ int timeout = 0, arg = FLAG_TUNE_ALL;
+
+ if(*Cmd == 'l') {
+ arg = FLAG_TUNE_LF;
+ } else if (*Cmd == 'h') {
+ arg = FLAG_TUNE_HF;
+ } else if (*Cmd != '\0') {
+ PrintAndLog("use 'tune' or 'tune l' or 'tune h'");
+ return 0;
+ }
+
printf("\nMeasuring antenna characteristics, please wait...");
- UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING};
+ UsbCommand c = {CMD_MEASURE_ANTENNA_TUNING, {arg, 0, 0}};
SendCommand(&c);
UsbCommand resp;
return 0;
}
+// trim graph (middle) piece
+int CmdMtrim(const char *Cmd) {
+ int start = 0, stop = 0;
+ sscanf(Cmd, "%i %i", &start, &stop);
+
+ if (start > GraphTraceLen || stop > GraphTraceLen || start > stop) return 0;
+ start++; //leave start position sample
+
+ GraphTraceLen -= stop - start;
+ for (int i = 0; i < GraphTraceLen; i++) {
+ GraphBuffer[start+i] = GraphBuffer[stop+i];
+ }
+ return 0;
+}
+
+
int CmdNorm(const char *Cmd)
{
int i;
if (GraphBuffer[i] >= upThres && GraphBuffer[i] > lastValue)
{
lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
- GraphBuffer[i] = 1;
+ GraphBuffer[i] = 127;
}
// Apply second threshold to samples heading down
else if (GraphBuffer[i] <= downThres && GraphBuffer[i] < lastValue)
{
lastValue = GraphBuffer[i]; // Buffer last value as we overwrite it.
- GraphBuffer[i] = -1;
+ GraphBuffer[i] = -127;
}
else
{
return 0;
}
+int usage_data_bin2hex(){
+ PrintAndLog("Usage: data bin2hex <binary_digits>");
+ PrintAndLog(" This function will ignore all characters not 1 or 0 (but stop reading on whitespace)");
+ return 0;
+}
+
+/**
+ * @brief Utility for conversion via cmdline.
+ * @param Cmd
+ * @return
+ */
+int Cmdbin2hex(const char *Cmd)
+{
+ int bg =0, en =0;
+ if(param_getptr(Cmd, &bg, &en, 0))
+ {
+ return usage_data_bin2hex();
+ }
+ //Number of digits supplied as argument
+ size_t length = en - bg +1;
+ size_t bytelen = (length+7) / 8;
+ uint8_t* arr = (uint8_t *) malloc(bytelen);
+ memset(arr, 0, bytelen);
+ BitstreamOut bout = { arr, 0, 0 };
+
+ for(; bg <= en ;bg++)
+ {
+ char c = Cmd[bg];
+ if( c == '1') pushBit(&bout, 1);
+ else if( c == '0') pushBit(&bout, 0);
+ else PrintAndLog("Ignoring '%c'", c);
+ }
+
+ if(bout.numbits % 8 != 0)
+ {
+ printf("[padded with %d zeroes]\n", 8-(bout.numbits % 8));
+ }
+
+ //Uses printf instead of PrintAndLog since the latter
+ // adds linebreaks to each printout - this way was more convenient since we don't have to
+ // allocate a string and write to that first...
+ for(size_t x = 0; x < bytelen ; x++)
+ {
+ printf("%02X", arr[x]);
+ }
+ printf("\n");
+ free(arr);
+ return 0;
+}
+
+int usage_data_hex2bin() {
+ PrintAndLog("Usage: data hex2bin <hex_digits>");
+ PrintAndLog(" This function will ignore all non-hexadecimal characters (but stop reading on whitespace)");
+ return 0;
+
+}
+
+int Cmdhex2bin(const char *Cmd)
+{
+ int bg =0, en =0;
+ if(param_getptr(Cmd, &bg, &en, 0))
+ {
+ return usage_data_hex2bin();
+ }
+
+
+ while(bg <= en )
+ {
+ char x = Cmd[bg++];
+ // capitalize
+ if (x >= 'a' && x <= 'f')
+ x -= 32;
+ // convert to numeric value
+ if (x >= '0' && x <= '9')
+ x -= '0';
+ else if (x >= 'A' && x <= 'F')
+ x -= 'A' - 10;
+ else
+ continue;
+
+ //Uses printf instead of PrintAndLog since the latter
+ // adds linebreaks to each printout - this way was more convenient since we don't have to
+ // allocate a string and write to that first...
+
+ for(int i= 0 ; i < 4 ; ++i)
+ printf("%d",(x >> (3 - i)) & 1);
+ }
+ printf("\n");
+
+ return 0;
+}
+
static command_t CommandTable[] =
{
{"help", CmdHelp, 1, "This help"},
{"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"},
{"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"},
{"bitsamples", CmdBitsamples, 0, "Get raw samples as bitstring"},
{"buffclear", CmdBuffClear, 1, "Clear sample buffer and graph window"},
{"dec", CmdDec, 1, "Decimate samples"},
{"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"},
//{"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"},
- {"fskpyramiddemod", CmdFSKdemodPyramid, 1, "Demodulate a Pyramid FSK tag from GraphBuffer"},
{"fskparadoxdemod", CmdFSKdemodParadox, 1, "Demodulate a Paradox FSK tag from GraphBuffer"},
{"getbitstream", CmdGetBitStream, 1, "Convert GraphBuffer's >=1 values to 1 and <1 to 0"},
{"grid", CmdGrid, 1, "<x> <y> -- overlay grid on graph window, use zero value to turn off either"},
{"hexsamples", CmdHexsamples, 0, "<bytes> [<offset>] -- Dump big buffer as hex bytes"},
+ {"hex2bin", Cmdhex2bin, 1, "hex2bin <hexadecimal> -- Converts hexadecimal to binary"},
{"hide", CmdHide, 1, "Hide graph window"},
{"hpf", CmdHpf, 1, "Remove DC offset from trace"},
{"load", CmdLoad, 1, "<filename> -- Load trace (to graph window"},
{"ltrim", CmdLtrim, 1, "<samples> -- Trim samples from left of trace"},
{"rtrim", CmdRtrim, 1, "<location to end trace> -- Trim samples from right of trace"},
+ {"mtrim", CmdMtrim, 1, "<start> <stop> -- Trim out samples from the specified start to the specified stop"},
{"manrawdecode", Cmdmandecoderaw, 1, "[invert] [maxErr] -- Manchester decode binary stream in DemodBuffer"},
{"norm", CmdNorm, 1, "Normalize max/min to +/-128"},
{"plot", CmdPlot, 1, "Show graph window (hit 'h' in window for keystroke help)"},
- {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] [o] <offset> -- print the data in the DemodBuffer - 'x' for hex output"},
- {"pskindalademod", CmdIndalaDecode, 1, "[clock] [invert<0|1>] -- Demodulate an indala tag (PSK1) from GraphBuffer (args optional)"},
+ {"printdemodbuffer",CmdPrintDemodBuff, 1, "[x] [o] <offset> [l] <length> -- print the data in the DemodBuffer - 'x' for hex output"},
{"psknexwatchdemod",CmdPSKNexWatch, 1, "Demodulate a NexWatch tag (nexkey, quadrakey) (PSK1) from GraphBuffer"},
{"rawdemod", CmdRawDemod, 1, "[modulation] ... <options> -see help (h option) -- Demodulate the data in the GraphBuffer and output binary"},
{"samples", CmdSamples, 0, "[512 - 40000] -- Get raw samples for graph window (GraphBuffer)"},
{"save", CmdSave, 1, "<filename> -- Save trace (from graph window)"},
+ {"setgraphmarkers", CmdSetGraphMarkers, 1, "[orange_marker] [blue_marker] (in graph window)"},
{"scale", CmdScale, 1, "<int> -- Set cursor display scale"},
- {"setdebugmode", CmdSetDebugMode, 1, "<0|1> -- Turn on or off Debugging Mode for demods"},
+ {"setdebugmode", CmdSetDebugMode, 1, "<0|1|2> -- Turn on or off Debugging Level for lf demods"},
{"shiftgraphzero", CmdGraphShiftZero, 1, "<shift> -- Shift 0 for Graphed wave + or - shift value"},
{"dirthreshold", CmdDirectionalThreshold, 1, "<thres up> <thres down> -- Max rising higher up-thres/ Min falling lower down-thres, keep rest as prev."},
{"tune", CmdTuneSamples, 0, "Get hw tune samples for graph window"},