mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 05:43:48 -07:00
added the changes from PM3 master.
added some code for the AWID26
This commit is contained in:
parent
f5ed4d12de
commit
3bc3598e88
9 changed files with 343 additions and 220 deletions
|
@ -1715,6 +1715,10 @@ int ReaderReceive(uint8_t *receivedAnswer, uint8_t *parity)
|
|||
* fills the uid pointer unless NULL
|
||||
* fills resp_data unless NULL */
|
||||
int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, uint32_t* cuid_ptr) {
|
||||
|
||||
iso14a_set_timeout(10500); // 10ms default 10*105 =
|
||||
|
||||
//uint8_t deselect[] = {0xc2}; //DESELECT
|
||||
//uint8_t halt[] = { 0x50, 0x00, 0x57, 0xCD }; // HALT
|
||||
uint8_t wupa[] = { 0x52 }; // WAKE-UP
|
||||
//uint8_t reqa[] = { 0x26 }; // REQUEST A
|
||||
|
@ -1731,8 +1735,8 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
|||
int len;
|
||||
|
||||
// test for the SKYLANDERS TOY.
|
||||
//ReaderTransmit(halt,sizeof(halt), NULL);
|
||||
//len = ReaderReceive(resp, resp_par);
|
||||
// ReaderTransmit(deselect,sizeof(deselect), NULL);
|
||||
// len = ReaderReceive(resp, resp_par);
|
||||
|
||||
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
||||
ReaderTransmitBitsPar(wupa,7,0, NULL);
|
||||
|
@ -1836,7 +1840,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
|||
p_hi14a_card->sak = sak;
|
||||
p_hi14a_card->ats_len = 0;
|
||||
}
|
||||
|
||||
|
||||
if( (sak & 0x20) == 0) {
|
||||
return 2; // non iso14443a compliant tag
|
||||
}
|
||||
|
@ -1845,8 +1849,13 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
|||
AppendCrc14443a(rats, 2);
|
||||
ReaderTransmit(rats, sizeof(rats), NULL);
|
||||
|
||||
|
||||
len = ReaderReceive(resp, resp_par);
|
||||
if(!len) return 0;
|
||||
Dbprintf("RATS Reponse: %d", len);
|
||||
if(!len) {
|
||||
Dbprintf("RATS: %02x %02x %02x", resp[0], resp[1], resp[2]);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(p_hi14a_card) {
|
||||
memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
|
||||
|
|
|
@ -181,6 +181,11 @@ int CmdHF14AReader(const char *Cmd)
|
|||
|
||||
if(select_status == 0) {
|
||||
PrintAndLog("iso14443a card select failed");
|
||||
// disconnect
|
||||
c.arg[0] = 0;
|
||||
c.arg[1] = 0;
|
||||
c.arg[2] = 0;
|
||||
SendCommand(&c);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,6 @@ int xorbits_8(uint8_t val)
|
|||
|
||||
int CmdHFiClassList(const char *Cmd)
|
||||
{
|
||||
|
||||
bool ShowWaitCycles = false;
|
||||
char param = param_getchar(Cmd, 0);
|
||||
|
||||
|
@ -55,8 +54,11 @@ int CmdHFiClassList(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
uint8_t got[TRACE_BUFFER_SIZE];
|
||||
GetFromBigBuf(got,sizeof(got),0);
|
||||
// for the time being. Need better Bigbuf handling.
|
||||
#define TRACE_SIZE 3000
|
||||
|
||||
uint8_t trace[TRACE_SIZE];
|
||||
GetFromBigBuf(trace, TRACE_SIZE, 0);
|
||||
WaitForResponse(CMD_ACK,NULL);
|
||||
|
||||
PrintAndLog("Recorded Activity");
|
||||
|
@ -64,155 +66,58 @@ int CmdHFiClassList(const char *Cmd)
|
|||
PrintAndLog("Start = Start of Start Bit, End = End of last modulation. Src = Source of Transfer");
|
||||
PrintAndLog("All times are in carrier periods (1/13.56Mhz)");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" Start | End | Src | Data");
|
||||
PrintAndLog("-----------|-----------|-----|--------");
|
||||
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC ");
|
||||
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
|
||||
|
||||
int i;
|
||||
uint32_t first_timestamp = 0;
|
||||
uint16_t tracepos = 0;
|
||||
uint16_t duration;
|
||||
uint16_t data_len;
|
||||
uint16_t parity_len;
|
||||
bool isResponse;
|
||||
uint32_t timestamp;
|
||||
bool tagToReader;
|
||||
uint32_t parityBits;
|
||||
uint8_t len;
|
||||
uint8_t *frame;
|
||||
uint32_t EndOfTransmissionTimestamp = 0;
|
||||
uint32_t first_timestamp;
|
||||
uint32_t EndOfTransmissionTimestamp;
|
||||
|
||||
for (;;) {
|
||||
|
||||
if(tracepos >= TRACE_SIZE) {
|
||||
break;
|
||||
}
|
||||
|
||||
for( i=0; i < TRACE_BUFFER_SIZE;)
|
||||
{
|
||||
//First 32 bits contain
|
||||
// isResponse (1 bit)
|
||||
// timestamp (remaining)
|
||||
//Then paritybits
|
||||
//Then length
|
||||
timestamp = *((uint32_t *)(got+i));
|
||||
parityBits = *((uint32_t *)(got+i+4));
|
||||
len = got[i+8];
|
||||
frame = (got+i+9);
|
||||
uint32_t next_timestamp = (*((uint32_t *)(got+i+9))) & 0x7fffffff;
|
||||
|
||||
tagToReader = timestamp & 0x80000000;
|
||||
timestamp &= 0x7fffffff;
|
||||
|
||||
if(i==0) {
|
||||
timestamp = *((uint32_t *)(trace + tracepos));
|
||||
if(tracepos == 0) {
|
||||
first_timestamp = timestamp;
|
||||
}
|
||||
|
||||
// Break and stick with current result idf buffer was not completely full
|
||||
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[2] == 0x44 && frame[3] == 0x44) break;
|
||||
|
||||
char line[1000] = "";
|
||||
|
||||
if(len)//We have some data to display
|
||||
{
|
||||
int j,oddparity;
|
||||
|
||||
for(j = 0; j < len ; j++)
|
||||
{
|
||||
oddparity = 0x01 ^ xorbits_8(frame[j] & 0xFF);
|
||||
|
||||
if (tagToReader && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
|
||||
sprintf(line+(j*4), "%02x! ", frame[j]);
|
||||
} else {
|
||||
sprintf(line+(j*4), "%02x ", frame[j]);
|
||||
}
|
||||
}
|
||||
}else
|
||||
{
|
||||
if (ShowWaitCycles) {
|
||||
sprintf(line, "fdt (Frame Delay Time): %d", (next_timestamp - timestamp));
|
||||
}
|
||||
}
|
||||
|
||||
char *crc = "";
|
||||
|
||||
if(len > 2)
|
||||
{
|
||||
uint8_t b1, b2;
|
||||
if(!tagToReader && len == 4) {
|
||||
// Rough guess that this is a command from the reader
|
||||
// For iClass the command byte is not part of the CRC
|
||||
ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
|
||||
}
|
||||
else {
|
||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
||||
ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
|
||||
}
|
||||
|
||||
if (b1 != frame[len-2] || b2 != frame[len-1]) {
|
||||
crc = (tagToReader & (len < 8)) ? "" : " !crc";
|
||||
}
|
||||
}
|
||||
|
||||
i += (len + 9);
|
||||
EndOfTransmissionTimestamp = (*((uint32_t *)(got+i))) & 0x7fffffff;
|
||||
|
||||
// Not implemented for iclass on the ARM-side
|
||||
//if (!ShowWaitCycles) i += 9;
|
||||
|
||||
PrintAndLog(" %9d | %9d | %s | %s %s",
|
||||
(timestamp - first_timestamp),
|
||||
(EndOfTransmissionTimestamp - first_timestamp),
|
||||
(len?(tagToReader ? "Tag" : "Rdr"):" "),
|
||||
line, crc);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int CmdHFiClassListOld(const char *Cmd)
|
||||
{
|
||||
uint8_t got[1920];
|
||||
GetFromBigBuf(got,sizeof(got),0);
|
||||
|
||||
PrintAndLog("recorded activity:");
|
||||
PrintAndLog(" ETU :rssi: who bytes");
|
||||
PrintAndLog("---------+----+----+-----------");
|
||||
|
||||
int i = 0;
|
||||
int prev = -1;
|
||||
|
||||
for (;;) {
|
||||
if(i >= 1900) {
|
||||
break;
|
||||
}
|
||||
|
||||
bool isResponse;
|
||||
int timestamp = *((uint32_t *)(got+i));
|
||||
if (timestamp & 0x80000000) {
|
||||
timestamp &= 0x7fffffff;
|
||||
isResponse = 1;
|
||||
} else {
|
||||
isResponse = 0;
|
||||
}
|
||||
|
||||
|
||||
int metric = 0;
|
||||
|
||||
int parityBits = *((uint32_t *)(got+i+4));
|
||||
// 4 bytes of additional information...
|
||||
// maximum of 32 additional parity bit information
|
||||
//
|
||||
// TODO:
|
||||
// at each quarter bit period we can send power level (16 levels)
|
||||
// or each half bit period in 256 levels.
|
||||
|
||||
|
||||
int len = got[i+8];
|
||||
|
||||
if (len > 100) {
|
||||
break;
|
||||
}
|
||||
if (i + len >= 1900) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *frame = (got+i+9);
|
||||
|
||||
// Break and stick with current result if buffer was not completely full
|
||||
if (frame[0] == 0x44 && frame[1] == 0x44 && frame[3] == 0x44) { break; }
|
||||
if (timestamp == 0x44444444) break;
|
||||
|
||||
char line[1000] = "";
|
||||
int j;
|
||||
for (j = 0; j < len; j++) {
|
||||
tracepos += 4;
|
||||
duration = *((uint16_t *)(trace + tracepos));
|
||||
tracepos += 2;
|
||||
data_len = *((uint16_t *)(trace + tracepos));
|
||||
tracepos += 2;
|
||||
|
||||
if (data_len & 0x8000) {
|
||||
data_len &= 0x7fff;
|
||||
isResponse = true;
|
||||
} else {
|
||||
isResponse = false;
|
||||
}
|
||||
|
||||
parity_len = (data_len-1)/8 + 1;
|
||||
|
||||
if (tracepos + data_len + parity_len >= TRACE_SIZE) {
|
||||
break;
|
||||
}
|
||||
|
||||
uint8_t *frame = trace + tracepos;
|
||||
tracepos += data_len;
|
||||
uint8_t *parityBytes = trace + tracepos;
|
||||
tracepos += parity_len;
|
||||
|
||||
char line[16][110];
|
||||
for (int j = 0; j < data_len; j++) {
|
||||
int oddparity = 0x01;
|
||||
int k;
|
||||
|
||||
|
@ -220,79 +125,68 @@ int CmdHFiClassListOld(const char *Cmd)
|
|||
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
|
||||
}
|
||||
|
||||
//if((parityBits >> (len - j - 1)) & 0x01) {
|
||||
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
|
||||
sprintf(line+(j*4), "%02x! ", frame[j]);
|
||||
}
|
||||
else {
|
||||
sprintf(line+(j*4), "%02x ", frame[j]);
|
||||
}
|
||||
}
|
||||
uint8_t parityBits = parityBytes[j>>3];
|
||||
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
|
||||
} else {
|
||||
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
|
||||
}
|
||||
|
||||
char *crc;
|
||||
crc = "";
|
||||
if (len > 2) {
|
||||
}
|
||||
|
||||
char *crc = "";
|
||||
if (data_len > 2) {
|
||||
uint8_t b1, b2;
|
||||
for (j = 0; j < (len - 1); j++) {
|
||||
// gives problems... search for the reason..
|
||||
/*if(frame[j] == 0xAA) {
|
||||
switch(frame[j+1]) {
|
||||
case 0x01:
|
||||
crc = "[1] Two drops close after each other";
|
||||
break;
|
||||
case 0x02:
|
||||
crc = "[2] Potential SOC with a drop in second half of bitperiod";
|
||||
break;
|
||||
case 0x03:
|
||||
crc = "[3] Segment Z after segment X is not possible";
|
||||
break;
|
||||
case 0x04:
|
||||
crc = "[4] Parity bit of a fully received byte was wrong";
|
||||
break;
|
||||
default:
|
||||
crc = "[?] Unknown error";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}*/
|
||||
}
|
||||
|
||||
if (strlen(crc)==0) {
|
||||
if(!isResponse && len == 4) {
|
||||
if(!isResponse && data_len == 4 ) {
|
||||
// Rough guess that this is a command from the reader
|
||||
// For iClass the command byte is not part of the CRC
|
||||
ComputeCrc14443(CRC_ICLASS, &frame[1], len-3, &b1, &b2);
|
||||
ComputeCrc14443(CRC_ICLASS, &frame[1], data_len-3, &b1, &b2);
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
crc = "!crc";
|
||||
}
|
||||
}
|
||||
else {
|
||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
||||
ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
|
||||
}
|
||||
//printf("%1x %1x",(unsigned)b1,(unsigned)b2);
|
||||
if (b1 != frame[len-2] || b2 != frame[len-1]) {
|
||||
crc = (isResponse & (len < 8)) ? "" : " !crc";
|
||||
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
|
||||
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||
crc = "!crc";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
EndOfTransmissionTimestamp = timestamp + duration;
|
||||
|
||||
int num_lines = (data_len - 1)/16 + 1;
|
||||
for (int j = 0; j < num_lines; j++) {
|
||||
if (j == 0) {
|
||||
PrintAndLog(" %9d | %9d | %s | %-64s| %s",
|
||||
(timestamp - first_timestamp),
|
||||
(EndOfTransmissionTimestamp - first_timestamp),
|
||||
(isResponse ? "Tag" : "Rdr"),
|
||||
line[j],
|
||||
(j == num_lines-1)?crc:"");
|
||||
} else {
|
||||
crc = "";
|
||||
}
|
||||
}
|
||||
} else {
|
||||
crc = ""; // SHORT
|
||||
}
|
||||
PrintAndLog(" | | | %-64s| %s",
|
||||
line[j],
|
||||
(j == num_lines-1)?crc:"");
|
||||
}
|
||||
}
|
||||
|
||||
char metricString[100];
|
||||
if (isResponse) {
|
||||
sprintf(metricString, "%3d", metric);
|
||||
} else {
|
||||
strcpy(metricString, " ");
|
||||
}
|
||||
|
||||
PrintAndLog(" +%7d: %s: %s %s %s",
|
||||
(prev < 0 ? 0 : (timestamp - prev)),
|
||||
metricString,
|
||||
(isResponse ? "TAG" : " "), line, crc);
|
||||
|
||||
prev = timestamp;
|
||||
i += (len + 9);
|
||||
}
|
||||
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
||||
|
||||
if (ShowWaitCycles && !isResponse && next_isResponse) {
|
||||
uint32_t next_timestamp = *((uint32_t *)(trace + tracepos));
|
||||
if (next_timestamp != 0x44444444) {
|
||||
PrintAndLog(" %9d | %9d | %s | fdt (Frame Delay Time): %d",
|
||||
(EndOfTransmissionTimestamp - first_timestamp),
|
||||
(next_timestamp - first_timestamp),
|
||||
" ",
|
||||
(next_timestamp - EndOfTransmissionTimestamp));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -581,7 +581,7 @@ static command_t CommandTable[] =
|
|||
{"simman", CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
|
||||
{"snoop", CmdLFSnoop, 0, "['l'|'h'|<divisor>] [trigger threshold]-- Snoop LF (l:125khz, h:134khz)"},
|
||||
|
||||
{"avid", CmdLFAWID26, 1, "{ AWID26 tags }"},
|
||||
{"awid26", CmdLFAWID26, 1, "{ AWID26 tags }"},
|
||||
{"em4x", CmdLFEM4X, 1, "{ EM4X tags }"},
|
||||
{"hid", CmdLFHID, 1, "{ HID tags }"},
|
||||
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders }"},
|
||||
|
|
|
@ -12,14 +12,14 @@
|
|||
#include <inttypes.h>
|
||||
#include "proxmark3.h"
|
||||
#include "ui.h"
|
||||
#include "graph.h"
|
||||
//#include "graph.h"
|
||||
#include "cmdmain.h"
|
||||
#include "cmdparser.h"
|
||||
#include "cmddata.h"
|
||||
//#include "cmddata.h"
|
||||
#include "cmdlf.h"
|
||||
#include "cmdlfawid26.h"
|
||||
#include "util.h"
|
||||
#include "data.h"
|
||||
//#include "data.h"
|
||||
|
||||
|
||||
static int CmdHelp(const char *Cmd);
|
||||
|
@ -29,11 +29,10 @@ int CmdClone(const char *Cmd)
|
|||
char cmdp = param_getchar(Cmd, 0);
|
||||
|
||||
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
|
||||
PrintAndLog("Usage: lf awid26 write []");
|
||||
PrintAndLog("Usage: lf awid26 clone <facility> <id>");
|
||||
PrintAndLog(" [], ");
|
||||
PrintAndLog("");
|
||||
PrintAndLog(" sample: lf awid26 write 26 2233");
|
||||
PrintAndLog(" : lf awid26 write 26 15 2233");
|
||||
PrintAndLog(" sample: lf awid26 clone 15 2233");
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -50,6 +49,108 @@ int CmdClone(const char *Cmd)
|
|||
return 0;
|
||||
}
|
||||
|
||||
|
||||
// convert 96 bit AWID FSK data to 8 digit BCD UID
|
||||
bool awid26_hex_to_uid(unsigned char *response, unsigned char *awid26)
|
||||
{
|
||||
// uint8_t i, tmp[96], tmp1[7];
|
||||
// int site;
|
||||
// int id;
|
||||
|
||||
// if(!hextobinarray(tmp, awid26))
|
||||
// return false;
|
||||
|
||||
// // data is in blocks of 4 bits - every 4th bit is parity, except the first
|
||||
// // block which is all zeros
|
||||
// for(i= 0 ; i < 4 ; ++i)
|
||||
// if(tmp[i] != 0x00)
|
||||
// return false;
|
||||
|
||||
// // discard 1st block
|
||||
// memcpy(tmp, tmp + 4, 92);
|
||||
|
||||
// // check and strip parity on the rest
|
||||
// for(i= 1 ; i < 23 ; ++i)
|
||||
// if(tmp[(i * 4) - 1] != parity(tmp + (i - 1) * 4, ODD, 3))
|
||||
// return false;
|
||||
// else
|
||||
// memcpy((tmp + (i - 1) * 3), tmp + (i - 1) * 4, 3);
|
||||
|
||||
// // discard the rest of the header - 1 more 3 bit block
|
||||
// memcpy(tmp, tmp + 3, 66);
|
||||
|
||||
// // next 8 bits is data length - should be 26: 0x1A
|
||||
// binarraytohex(tmp1, tmp, 8);
|
||||
// if(strcmp(tmp1, "1A") != 0)
|
||||
// return false;
|
||||
// memcpy(tmp, tmp +8, 58);
|
||||
|
||||
// // standard wiegand parity check - even for 1st 12 bits, odd for 2nd 12
|
||||
// if(tmp[0] != parity(tmp + 1, EVEN, 12))
|
||||
// return false;
|
||||
// if(tmp[25] != parity(tmp + 13, ODD, 12))
|
||||
// return false;
|
||||
|
||||
// // convert to hex, ignoring parity bits
|
||||
// if(!binarraytohex(tmp1, tmp + 1, 24))
|
||||
// return false;
|
||||
|
||||
// // convert hex to site/id
|
||||
// sscanf(tmp1,"%2X%4X", &site, &id);
|
||||
|
||||
// // final output 8 byte BCD
|
||||
// sprintf(response,"%03d%05d", site, id);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// convert null-terminated BCD UID (8 digits) to 96 bit awid26 encoded binary array
|
||||
bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd)
|
||||
{
|
||||
// char i, p, tmp1[8], tmp2[26];
|
||||
// int tmpint;
|
||||
|
||||
// if(strlen(bcd) != 8)
|
||||
// return false;
|
||||
|
||||
// // convert BCD site code to HEX
|
||||
// sscanf(bcd, "%03d", &tmpint);
|
||||
// sprintf(tmp2, "%02x", tmpint);
|
||||
// memcpy(tmp1, tmp2, 2);
|
||||
|
||||
// // convert BCD ID to HEX
|
||||
// sscanf(bcd + 3, "%05d", &tmpint);;
|
||||
// sprintf(tmp2, "%04x", tmpint);
|
||||
|
||||
// // copy with trailing NULL
|
||||
// memcpy(tmp1 + 2, tmp2, 5);
|
||||
|
||||
// // convert full HEX to binary, leaving room for parity prefix
|
||||
// hextobinarray(tmp2 + 1, tmp1);
|
||||
|
||||
// wiegand_add_parity(tmp2, tmp2 + 1, 24);
|
||||
|
||||
// memset(awid26, '\x0', 96);
|
||||
|
||||
// // magic 18 bit awid26 header (we will overwrite the last two bits)
|
||||
// hextobinarray(awid26, "011D8");
|
||||
|
||||
// // copy to target leaving space for parity bits
|
||||
// for(i= 0, p= 18 ; i < 26 ; ++i, ++p)
|
||||
// {
|
||||
// // skip target bit if this is a parity location
|
||||
// if(!((p + 1) % 4))
|
||||
// p += 1;
|
||||
// awid26[p]= tmp2[i];
|
||||
// }
|
||||
|
||||
// // add parity bits
|
||||
// for(i= 1 ; i < 24 ; ++i)
|
||||
// awid26[((i + 1) * 4) - 1]= parity(&awid26[i * 4], ODD, 3);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
// int CmdReadTrace(const char *Cmd)
|
||||
// {
|
||||
|
||||
|
@ -84,8 +185,8 @@ int CmdClone(const char *Cmd)
|
|||
|
||||
static command_t CommandTable[] =
|
||||
{
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"clone", CmdClone, 0, "<facility> <id> -- clone to a t55xx tag"},
|
||||
{"help", CmdHelp, 1, "This help"},
|
||||
{"clone", CmdClone, 1, "<facility> <id> -- clone AWID26 to t55xx tag"},
|
||||
{NULL, NULL, 0, NULL}
|
||||
};
|
||||
|
||||
|
|
|
@ -13,4 +13,6 @@
|
|||
int CmdLFAWID26(const char *Cmd);
|
||||
|
||||
int CmdClone(const char *Cmd);
|
||||
bool awid26_hex_to_uid(unsigned char *response, unsigned char *awid26);
|
||||
bool bcd_to_awid26_bin(unsigned char *awid26, unsigned char *bcd);
|
||||
#endif
|
||||
|
|
|
@ -468,6 +468,9 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
|
|||
|
||||
int i = start;
|
||||
int j = len-1;
|
||||
if (len > 32) {
|
||||
return 0;
|
||||
}
|
||||
uint32_t tmp = 0;
|
||||
for (; j >= 0; --j, ++i){
|
||||
tmp |= bits[i] << j;
|
||||
|
|
|
@ -292,3 +292,102 @@ int param_getstr(const char *line, int paramnum, char * str)
|
|||
|
||||
return en - bg + 1;
|
||||
}
|
||||
|
||||
/*
|
||||
The following methods comes from Rfidler sourcecode.
|
||||
https://github.com/ApertureLabsLtd/RFIDler/blob/master/firmware/Pic32/RFIDler.X/src/
|
||||
*/
|
||||
|
||||
// convert hex to sequence of 0/1 bit values
|
||||
// returns number of bits converted
|
||||
int hextobinarray(char *target, char *source)
|
||||
{
|
||||
int length, i, count= 0;
|
||||
char x;
|
||||
|
||||
length = strlen(source);
|
||||
// process 4 bits (1 hex digit) at a time
|
||||
while(length--)
|
||||
{
|
||||
x= *(source++);
|
||||
// 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
|
||||
return 0;
|
||||
// output
|
||||
for(i= 0 ; i < 4 ; ++i, ++count)
|
||||
*(target++)= (x >> (3 - i)) & 1;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
// convert hex to human readable binary string
|
||||
int hextobinstring(char *target, char *source)
|
||||
{
|
||||
int length;
|
||||
|
||||
if(!(length= hextobinarray(target, source)))
|
||||
return 0;
|
||||
binarraytobinstring(target, target, length);
|
||||
return length;
|
||||
}
|
||||
|
||||
// convert binary array of 0x00/0x01 values to hex (safe to do in place as target will always be shorter than source)
|
||||
// return number of bits converted
|
||||
int binarraytohex(char *target, char *source, int length)
|
||||
{
|
||||
unsigned char i, x;
|
||||
int j = length;
|
||||
|
||||
if(j % 4)
|
||||
return 0;
|
||||
|
||||
while(j)
|
||||
{
|
||||
for(i= x= 0 ; i < 4 ; ++i)
|
||||
x += ( source[i] << (3 - i));
|
||||
sprintf(target,"%X", x);
|
||||
++target;
|
||||
source += 4;
|
||||
j -= 4;
|
||||
}
|
||||
return length;
|
||||
}
|
||||
|
||||
// convert binary array to human readable binary
|
||||
void binarraytobinstring(char *target, char *source, int length)
|
||||
{
|
||||
int i;
|
||||
|
||||
for(i= 0 ; i < length ; ++i)
|
||||
*(target++)= *(source++) + '0';
|
||||
*target= '\0';
|
||||
}
|
||||
|
||||
// return parity bit required to match type
|
||||
uint8_t parity( char *bits, uint8_t type, int length)
|
||||
{
|
||||
int x;
|
||||
|
||||
for(x= 0 ; length > 0 ; --length)
|
||||
x += bits[length - 1];
|
||||
x %= 2;
|
||||
|
||||
return x ^ type;
|
||||
}
|
||||
|
||||
// add HID parity to binary array: EVEN prefix for 1st half of ID, ODD suffix for 2nd half
|
||||
void wiegand_add_parity(char *target, char *source, char length)
|
||||
{
|
||||
*(target++)= parity(source, EVEN, length / 2);
|
||||
memcpy(target, source, length);
|
||||
target += length;
|
||||
*(target)= parity(source + length / 2, ODD, length / 2);
|
||||
}
|
||||
|
|
|
@ -23,6 +23,10 @@
|
|||
#ifndef MAX
|
||||
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||
#endif
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
#define EVEN 0
|
||||
#define ODD 1
|
||||
|
||||
int ukbhit(void);
|
||||
|
||||
|
@ -48,4 +52,10 @@ uint64_t param_get64ex(const char *line, int paramnum, int deflt, int base);
|
|||
int param_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
|
||||
int param_getstr(const char *line, int paramnum, char * str);
|
||||
|
||||
int hextobinarray( char *target, char *source);
|
||||
int hextobinstring( char *target, char *source);
|
||||
int binarraytohex( char *target, char *source, int length);
|
||||
void binarraytobinstring(char *target, char *source, int length);
|
||||
uint8_t parity( char *string, uint8_t type, int length);
|
||||
void wiegand_add_parity(char *target, char *source, char length);
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue