2016-02-26 00:49:48 +08:00
//-----------------------------------------------------------------------------
//
// This code is licensed to you under the terms of the GNU GPL, version 2 or,
// at your option, any later version. See the LICENSE.txt file for the text of
// the license.
//-----------------------------------------------------------------------------
// Low frequency Farpoint / Pyramid tag commands
2017-07-15 03:22:03 +08:00
// FSK2a, rf/50, 128 bits (complete)
2016-02-26 00:49:48 +08:00
//-----------------------------------------------------------------------------
# include "cmdlfpyramid.h"
2019-09-27 02:32:33 +08:00
# include "common.h"
# include <string.h>
# include <stdlib.h>
# include <stdio.h>
# include <ctype.h>
# include "commonutil.h" // ARRAYLEN
# include "cmdparser.h" // command_t
# include "comms.h"
# include "ui.h"
# include "graph.h"
# include "cmddata.h"
# include "cmdlf.h"
# include "protocols.h" // for T55xx config register definitions
# include "lfdemod.h" // parityTest
# include "crc.h"
# include "cmdlft55xx.h" // verifywrite
2017-07-30 15:17:48 +08:00
2016-02-26 00:49:48 +08:00
static int CmdHelp ( const char * Cmd ) ;
2019-04-10 19:06:05 +08:00
static int usage_lf_pyramid_clone ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " clone a Farpointe/Pyramid tag to a T55x7 tag. " ) ;
PrintAndLogEx ( NORMAL , " The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. " ) ;
PrintAndLogEx ( NORMAL , " Currently only works on 26bit " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf pyramid clone [h] <Facility-Code> <Card-Number> [Q5] " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h : this help " ) ;
PrintAndLogEx ( NORMAL , " <Facility-Code> : 8-bit value facility code " ) ;
PrintAndLogEx ( NORMAL , " <Card Number> : 16-bit value card number " ) ;
PrintAndLogEx ( NORMAL , " Q5 : optional - clone to Q5 (T5555) instead of T55x7 chip " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf pyramid clone 123 11223 " ) ;
2019-05-22 21:46:40 +08:00
return PM3_SUCCESS ;
2016-02-26 00:49:48 +08:00
}
2019-04-10 19:06:05 +08:00
static int usage_lf_pyramid_sim ( void ) {
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( NORMAL , " Enables simulation of Farpointe/Pyramid card with specified card number. " ) ;
PrintAndLogEx ( NORMAL , " Simulation runs until the button is pressed or another USB command is issued. " ) ;
PrintAndLogEx ( NORMAL , " The facility-code is 8-bit and the card number is 16-bit. Larger values are truncated. " ) ;
PrintAndLogEx ( NORMAL , " Currently work only on 26bit " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Usage: lf pyramid sim [h] <Facility-Code> <Card-Number> " ) ;
PrintAndLogEx ( NORMAL , " Options: " ) ;
PrintAndLogEx ( NORMAL , " h : this help " ) ;
PrintAndLogEx ( NORMAL , " <Facility-Code> : 8-bit value facility code " ) ;
PrintAndLogEx ( NORMAL , " <Card Number> : 16-bit value card number " ) ;
PrintAndLogEx ( NORMAL , " " ) ;
PrintAndLogEx ( NORMAL , " Examples: " ) ;
PrintAndLogEx ( NORMAL , " lf pyramid sim 123 11223 " ) ;
2019-05-22 21:46:40 +08:00
return PM3_SUCCESS ;
2016-02-26 00:49:48 +08:00
}
2017-07-30 15:17:48 +08:00
//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
2019-04-12 08:07:11 +08:00
static int CmdPyramidDemod ( const char * Cmd ) {
2019-04-10 18:23:40 +08:00
( void ) Cmd ; // Cmd is not used so far
2019-03-10 06:35:06 +08:00
//raw fsk demod no manchester decoding no start bit finding just get binary from wave
2019-03-10 07:00:59 +08:00
uint8_t bits [ MAX_GRAPH_TRACE_LEN ] = { 0 } ;
2019-03-10 06:35:06 +08:00
size_t size = getFromGraphBuf ( bits ) ;
if ( size = = 0 ) {
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid not enough samples " ) ;
2019-05-22 21:46:40 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
//get binary from fsk wave
2019-03-10 07:00:59 +08:00
int waveIdx = 0 ;
2019-03-10 06:35:06 +08:00
int idx = detectPyramid ( bits , & size , & waveIdx ) ;
2019-03-10 07:00:59 +08:00
if ( idx < 0 ) {
if ( idx = = - 1 )
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: not enough samples " ) ;
else if ( idx = = - 2 )
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: only noise found " ) ;
else if ( idx = = - 3 )
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: problem during FSK demod " ) ;
else if ( idx = = - 4 )
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: preamble not found " ) ;
else if ( idx = = - 5 )
2019-10-06 05:56:19 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: size not correct: %zu " , size ) ;
2019-03-10 06:35:06 +08:00
else
2019-03-10 07:00:59 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: error demoding fsk idx: %d " , idx ) ;
2019-05-22 21:46:40 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2019-04-07 03:46:00 +08:00
setDemodBuff ( bits , size , idx ) ;
2019-03-10 07:00:59 +08:00
setClockGrid ( 50 , waveIdx + ( idx * 50 ) ) ;
2019-03-10 06:35:06 +08:00
// 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 = CRC8maxim checksum
// (26 bit format shown)
//get bytes for checksum calc
uint8_t checksum = bytebits_to_byte ( bits + idx + 120 , 8 ) ;
uint8_t csBuff [ 14 ] = { 0x00 } ;
2019-03-10 07:00:59 +08:00
for ( uint8_t i = 0 ; i < 13 ; i + + ) {
csBuff [ i ] = bytebits_to_byte ( bits + idx + 16 + ( i * 8 ) , 8 ) ;
2019-03-10 06:35:06 +08:00
}
//check checksum calc
//checksum calc thanks to ICEMAN!!
uint32_t checkCS = CRC8Maxim ( csBuff , 13 ) ;
//get raw ID before removing parities
2019-03-10 07:00:59 +08:00
uint32_t rawLo = bytebits_to_byte ( bits + idx + 96 , 32 ) ;
uint32_t rawHi = bytebits_to_byte ( bits + idx + 64 , 32 ) ;
uint32_t rawHi2 = bytebits_to_byte ( bits + idx + 32 , 32 ) ;
uint32_t rawHi3 = bytebits_to_byte ( bits + idx , 32 ) ;
size = removeParity ( bits , idx + 8 , 8 , 1 , 120 ) ;
if ( size ! = 105 ) {
if ( size = = 0 )
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: parity check failed - IDX: %d, hi3: %08X " , idx , rawHi3 ) ;
else
2019-10-06 05:56:19 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Error - Pyramid: at parity check - tag size does not match Pyramid format, SIZE: %zu, IDX: %d, hi3: %08X " , size , idx , rawHi3 ) ;
2019-05-22 21:46:40 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
// 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 = CRC8-Maxim checksum
// (26 bit format shown)
//find start bit to get fmtLen
int j ;
2019-03-10 07:00:59 +08:00
for ( j = 0 ; j < size ; + + j ) {
if ( bits [ j ] ) break ;
2019-03-10 06:35:06 +08:00
}
2019-03-10 07:00:59 +08:00
uint8_t fmtLen = size - j - 8 ;
2019-03-10 06:35:06 +08:00
2019-03-10 07:00:59 +08:00
if ( fmtLen = = 26 ) {
2019-06-08 00:41:39 +08:00
uint32_t fc = bytebits_to_byte ( bits + 73 , 8 ) ;
uint32_t cardnum = bytebits_to_byte ( bits + 81 , 16 ) ;
uint32_t code1 = bytebits_to_byte ( bits + 72 , fmtLen ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( SUCCESS , " 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
2019-06-08 00:41:39 +08:00
uint32_t fc = bytebits_to_byte ( bits + 53 , 10 ) ;
uint32_t cardnum = bytebits_to_byte ( bits + 63 , 32 ) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( SUCCESS , " Pyramid ID Found - BitLength: %d, FC: %d, Card: %d - Raw: %08x%08x%08x%08x " , fmtLen , fc , cardnum , rawHi3 , rawHi2 , rawHi , rawLo ) ;
2019-04-10 15:38:33 +08:00
/*
} else if ( fmtLen > 32 ) {
2019-06-08 00:41:39 +08:00
uint32_t cardnum = bytebits_to_byte ( bits + 81 , 16 ) ;
//uint32_t code1 = bytebits_to_byte(bits+(size-fmtLen),fmtLen-32);
2019-04-10 15:38:33 +08:00
//code2 = bytebits_to_byte(bits+(size-32),32);
PrintAndLogEx ( SUCCESS , " Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x " , fmtLen , cardnum , rawHi3 , rawHi2 , rawHi , rawLo ) ;
*/
2019-03-10 06:35:06 +08:00
} else {
2019-06-08 00:41:39 +08:00
uint32_t cardnum = bytebits_to_byte ( bits + 81 , 16 ) ;
//uint32_t code1 = bytebits_to_byte(bits+(size-fmtLen),fmtLen);
2019-04-08 14:11:18 +08:00
PrintAndLogEx ( SUCCESS , " Pyramid ID Found - BitLength: %d -unknown BitLength- (%d), Raw: %08x%08x%08x%08x " , fmtLen , cardnum , rawHi3 , rawHi2 , rawHi , rawLo ) ;
2019-03-10 06:35:06 +08:00
}
2019-03-24 02:09:37 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Pyramid: checksum : 0x%02X - %02X - %s "
2019-03-28 21:19:41 +08:00
, checksum
, checkCS
2019-04-12 16:55:09 +08:00
, ( checksum = = checkCS ) ? _GREEN_ ( " Passed " ) : _RED_ ( " Fail " )
2019-03-28 21:19:41 +08:00
) ;
2019-03-10 06:35:06 +08:00
PrintAndLogEx ( DEBUG , " DEBUG: Pyramid: idx: %d, Len: %d, Printing Demod Buffer: " , idx , 128 ) ;
if ( g_debugMode )
printDemodBuff ( ) ;
2019-05-22 21:46:40 +08:00
return PM3_SUCCESS ;
2017-07-30 15:17:48 +08:00
}
2019-04-12 08:07:11 +08:00
static int CmdPyramidRead ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
lf_read ( true , 15000 ) ;
return CmdPyramidDemod ( Cmd ) ;
2016-02-26 00:49:48 +08:00
}
2019-04-12 08:07:11 +08:00
static int CmdPyramidClone ( const char * Cmd ) {
2016-02-26 00:49:48 +08:00
2019-05-24 19:22:50 +08:00
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
if ( strlen ( Cmd ) = = 0 | | cmdp = = ' h ' ) return usage_lf_pyramid_clone ( ) ;
2019-03-10 07:00:59 +08:00
uint32_t facilitycode = 0 , cardnumber = 0 , fc = 0 , cn = 0 ;
2019-10-06 07:18:04 +08:00
if ( sscanf ( Cmd , " %u %u " , & fc , & cn ) ! = 2 ) return usage_lf_pyramid_clone ( ) ;
2019-03-10 06:35:06 +08:00
uint32_t blocks [ 5 ] ;
2019-09-27 02:32:33 +08:00
uint8_t * bs = calloc ( 128 , sizeof ( uint8_t ) ) ;
if ( bs = = NULL ) {
return PM3_EMALLOC ;
}
2016-02-26 00:49:48 +08:00
2019-03-10 06:35:06 +08:00
facilitycode = ( fc & 0x000000FF ) ;
cardnumber = ( cn & 0x0000FFFF ) ;
2019-03-09 15:59:13 +08:00
2019-05-24 05:07:12 +08:00
if ( getPyramidBits ( facilitycode , cardnumber , bs ) ! = PM3_SUCCESS ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error with tag bitstream generation. " ) ;
2019-05-22 21:46:40 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2016-02-26 00:49:48 +08:00
2019-03-10 06:35:06 +08:00
//Pyramid - compat mode, FSK2a, data rate 50, 4 data blocks
blocks [ 0 ] = T55x7_MODULATION_FSK2a | T55x7_BITRATE_RF_50 | 4 < < T55x7_MAXBLOCK_SHIFT ;
2016-03-08 01:53:02 +08:00
2019-03-10 06:35:06 +08:00
// Q5
if ( param_getchar ( Cmd , 2 ) = = ' Q ' | | param_getchar ( Cmd , 2 ) = = ' q ' )
blocks [ 0 ] = T5555_MODULATION_FSK2 | T5555_INVERT_OUTPUT | T5555_SET_BITRATE ( 50 ) | 4 < < T5555_MAXBLOCK_SHIFT ;
2016-03-08 01:53:02 +08:00
2019-03-10 06:35:06 +08:00
blocks [ 1 ] = bytebits_to_byte ( bs , 32 ) ;
blocks [ 2 ] = bytebits_to_byte ( bs + 32 , 32 ) ;
blocks [ 3 ] = bytebits_to_byte ( bs + 64 , 32 ) ;
blocks [ 4 ] = bytebits_to_byte ( bs + 96 , 32 ) ;
2016-02-26 00:49:48 +08:00
2019-09-27 02:32:33 +08:00
free ( bs ) ;
2019-09-15 07:33:54 +08:00
2019-09-27 02:32:33 +08:00
PrintAndLogEx ( INFO , " Preparing to clone Farpointe/Pyramid to T55x7 with Facility Code: %u, Card Number: %u " , facilitycode , cardnumber ) ;
print_blocks ( blocks , ARRAYLEN ( blocks ) ) ;
2019-09-19 16:47:12 +08:00
2019-09-27 02:32:33 +08:00
return clone_t55xx_tag ( blocks , ARRAYLEN ( blocks ) ) ;
2016-02-26 00:49:48 +08:00
}
2019-04-12 08:07:11 +08:00
static int CmdPyramidSim ( const char * Cmd ) {
2016-02-26 00:49:48 +08:00
2019-05-24 19:22:50 +08:00
char cmdp = tolower ( param_getchar ( Cmd , 0 ) ) ;
if ( strlen ( Cmd ) = = 0 | | cmdp = = ' h ' ) return usage_lf_pyramid_sim ( ) ;
2016-02-26 00:49:48 +08:00
2019-03-10 06:35:06 +08:00
uint32_t facilitycode = 0 , cardnumber = 0 , fc = 0 , cn = 0 ;
2019-03-09 15:59:13 +08:00
2019-03-10 06:35:06 +08:00
uint8_t bs [ 128 ] ;
2019-04-19 23:03:39 +08:00
memset ( bs , 0x00 , sizeof ( bs ) ) ;
2019-06-08 03:40:33 +08:00
2019-03-10 07:00:59 +08:00
if ( sscanf ( Cmd , " %u %u " , & fc , & cn ) ! = 2 ) return usage_lf_pyramid_sim ( ) ;
2016-02-26 00:49:48 +08:00
2019-03-10 06:35:06 +08:00
facilitycode = ( fc & 0x000000FF ) ;
cardnumber = ( cn & 0x0000FFFF ) ;
2019-03-09 15:59:13 +08:00
2019-05-24 05:07:12 +08:00
if ( getPyramidBits ( facilitycode , cardnumber , bs ) ! = PM3_SUCCESS ) {
2019-07-14 06:35:18 +08:00
PrintAndLogEx ( ERR , " Error with tag bitstream generation. " ) ;
2019-05-22 21:47:03 +08:00
return PM3_ESOFT ;
2019-03-10 06:35:06 +08:00
}
2016-02-26 00:49:48 +08:00
2019-03-10 07:00:59 +08:00
PrintAndLogEx ( SUCCESS , " Simulating Farpointe/Pyramid - Facility Code: %u, CardNumber: %u " , facilitycode , cardnumber ) ;
2019-03-09 15:59:13 +08:00
2019-05-24 19:22:50 +08:00
// Pyramid uses: fcHigh: 10, fcLow: 8, clk: 50, invert: 0
2019-05-24 05:07:12 +08:00
lf_fsksim_t * payload = calloc ( 1 , sizeof ( lf_fsksim_t ) + sizeof ( bs ) ) ;
2019-05-24 19:22:50 +08:00
payload - > fchigh = 10 ;
payload - > fclow = 8 ;
payload - > separator = 0 ;
payload - > clock = 50 ;
2019-05-24 05:07:12 +08:00
memcpy ( payload - > data , bs , sizeof ( bs ) ) ;
2019-03-10 06:35:06 +08:00
clearCommandBuffer ( ) ;
2019-08-04 01:17:00 +08:00
SendCommandNG ( CMD_LF_FSK_SIMULATE , ( uint8_t * ) payload , sizeof ( lf_fsksim_t ) + sizeof ( bs ) ) ;
2019-05-24 19:22:50 +08:00
free ( payload ) ;
2019-05-24 05:07:12 +08:00
2019-05-09 06:08:59 +08:00
PacketResponseNG resp ;
2019-08-04 01:17:00 +08:00
WaitForResponse ( CMD_LF_FSK_SIMULATE , & resp ) ;
2019-05-24 05:07:12 +08:00
PrintAndLogEx ( INFO , " Done " ) ;
2019-05-10 02:20:54 +08:00
if ( resp . status ! = PM3_EOPABORTED )
2019-05-09 06:08:59 +08:00
return resp . status ;
return PM3_SUCCESS ;
2016-02-26 00:49:48 +08:00
}
static command_t CommandTable [ ] = {
2019-05-02 06:02:38 +08:00
{ " help " , CmdHelp , AlwaysAvailable , " this help " } ,
{ " demod " , CmdPyramidDemod , AlwaysAvailable , " demodulate a Pyramid FSK tag from the GraphBuffer " } ,
{ " read " , CmdPyramidRead , IfPm3Lf , " attempt to read and extract tag data " } ,
{ " clone " , CmdPyramidClone , IfPm3Lf , " clone pyramid tag " } ,
{ " sim " , CmdPyramidSim , IfPm3Lf , " simulate pyramid tag " } ,
2019-05-02 02:48:15 +08:00
{ NULL , NULL , NULL , NULL }
2016-02-26 00:49:48 +08:00
} ;
2019-03-10 18:20:22 +08:00
int CmdLFPyramid ( const char * Cmd ) {
2019-03-10 06:35:06 +08:00
clearCommandBuffer ( ) ;
2019-04-19 06:47:51 +08:00
return CmdsParse ( CommandTable , Cmd ) ;
2016-02-26 00:49:48 +08:00
}
2019-03-10 18:20:22 +08:00
int CmdHelp ( const char * Cmd ) {
2019-04-10 18:23:40 +08:00
( void ) Cmd ; // Cmd is not used so far
2016-02-26 00:49:48 +08:00
CmdsHelp ( CommandTable ) ;
2019-05-22 21:46:40 +08:00
return PM3_SUCCESS ;
2016-02-26 00:49:48 +08:00
}
2019-04-12 06:38:54 +08:00
// Works for 26bits.
int getPyramidBits ( uint32_t fc , uint32_t cn , uint8_t * pyramidBits ) {
uint8_t pre [ 128 ] ;
memset ( pre , 0x00 , sizeof ( pre ) ) ;
// format start bit
pre [ 79 ] = 1 ;
// Get 26 wiegand from FacilityCode, CardNumber
uint8_t wiegand [ 24 ] ;
memset ( wiegand , 0x00 , sizeof ( wiegand ) ) ;
2019-06-08 03:40:33 +08:00
num_to_bytebits ( fc , 8 , wiegand ) ;
num_to_bytebits ( cn , 16 , wiegand + 8 ) ;
2019-04-12 06:38:54 +08:00
// add wiegand parity bits (dest, source, len)
wiegand_add_parity ( pre + 80 , wiegand , 24 ) ;
// add paritybits (bitsource, dest, sourcelen, paritylen, parityType (odd, even,)
addParity ( pre + 8 , pyramidBits + 8 , 102 , 8 , 1 ) ;
// add checksum
uint8_t csBuff [ 13 ] ;
for ( uint8_t i = 0 ; i < 13 ; i + + )
csBuff [ i ] = bytebits_to_byte ( pyramidBits + 16 + ( i * 8 ) , 8 ) ;
uint32_t crc = CRC8Maxim ( csBuff , 13 ) ;
num_to_bytebits ( crc , 8 , pyramidBits + 120 ) ;
2019-05-22 21:46:40 +08:00
return PM3_SUCCESS ;
2019-04-12 06:38:54 +08:00
}
int demodPyramid ( void ) {
return CmdPyramidDemod ( " " ) ;
}
// by marshmellow
// FSK Demod then try to locate a Farpointe Data (pyramid) ID
int detectPyramid ( uint8_t * dest , size_t * size , int * waveStartIdx ) {
//make sure buffer has data
if ( * size < 128 * 50 ) return - 1 ;
//test samples are not just noise
if ( getSignalProperties ( ) - > isnoise ) return - 2 ;
// FSK demodulator RF/50 FSK 10,8
* size = fskdemod ( dest , * size , 50 , 1 , 10 , 8 , waveStartIdx ) ; // pyramid fsk2
//did we get a good demod?
if ( * size < 128 ) return - 3 ;
size_t startIdx = 0 ;
uint8_t preamble [ ] = { 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 1 } ;
if ( ! preambleSearch ( dest , preamble , sizeof ( preamble ) , size , & startIdx ) )
return - 4 ; //preamble not found
// wrong size? (between to preambles)
if ( * size ! = 128 ) return - 5 ;
return ( int ) startIdx ;
}