mirror of
https://github.com/RfidResearchGroup/proxmark3.git
synced 2025-08-21 13:53:55 -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 the uid pointer unless NULL
|
||||||
* fills resp_data 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) {
|
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 halt[] = { 0x50, 0x00, 0x57, 0xCD }; // HALT
|
||||||
uint8_t wupa[] = { 0x52 }; // WAKE-UP
|
uint8_t wupa[] = { 0x52 }; // WAKE-UP
|
||||||
//uint8_t reqa[] = { 0x26 }; // REQUEST A
|
//uint8_t reqa[] = { 0x26 }; // REQUEST A
|
||||||
|
@ -1731,7 +1735,7 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
||||||
int len;
|
int len;
|
||||||
|
|
||||||
// test for the SKYLANDERS TOY.
|
// test for the SKYLANDERS TOY.
|
||||||
//ReaderTransmit(halt,sizeof(halt), NULL);
|
// ReaderTransmit(deselect,sizeof(deselect), NULL);
|
||||||
// len = ReaderReceive(resp, resp_par);
|
// len = ReaderReceive(resp, resp_par);
|
||||||
|
|
||||||
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
// Broadcast for a card, WUPA (0x52) will force response from all cards in the field
|
||||||
|
@ -1845,8 +1849,13 @@ int iso14443a_select_card(byte_t* uid_ptr, iso14a_card_select_t* p_hi14a_card, u
|
||||||
AppendCrc14443a(rats, 2);
|
AppendCrc14443a(rats, 2);
|
||||||
ReaderTransmit(rats, sizeof(rats), NULL);
|
ReaderTransmit(rats, sizeof(rats), NULL);
|
||||||
|
|
||||||
|
|
||||||
len = ReaderReceive(resp, resp_par);
|
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) {
|
if(p_hi14a_card) {
|
||||||
memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
|
memcpy(p_hi14a_card->ats, resp, sizeof(p_hi14a_card->ats));
|
||||||
|
|
|
@ -181,6 +181,11 @@ int CmdHF14AReader(const char *Cmd)
|
||||||
|
|
||||||
if(select_status == 0) {
|
if(select_status == 0) {
|
||||||
PrintAndLog("iso14443a card select failed");
|
PrintAndLog("iso14443a card select failed");
|
||||||
|
// disconnect
|
||||||
|
c.arg[0] = 0;
|
||||||
|
c.arg[1] = 0;
|
||||||
|
c.arg[2] = 0;
|
||||||
|
SendCommand(&c);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -43,7 +43,6 @@ int xorbits_8(uint8_t val)
|
||||||
|
|
||||||
int CmdHFiClassList(const char *Cmd)
|
int CmdHFiClassList(const char *Cmd)
|
||||||
{
|
{
|
||||||
|
|
||||||
bool ShowWaitCycles = false;
|
bool ShowWaitCycles = false;
|
||||||
char param = param_getchar(Cmd, 0);
|
char param = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
|
@ -55,8 +54,11 @@ int CmdHFiClassList(const char *Cmd)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t got[TRACE_BUFFER_SIZE];
|
// for the time being. Need better Bigbuf handling.
|
||||||
GetFromBigBuf(got,sizeof(got),0);
|
#define TRACE_SIZE 3000
|
||||||
|
|
||||||
|
uint8_t trace[TRACE_SIZE];
|
||||||
|
GetFromBigBuf(trace, TRACE_SIZE, 0);
|
||||||
WaitForResponse(CMD_ACK,NULL);
|
WaitForResponse(CMD_ACK,NULL);
|
||||||
|
|
||||||
PrintAndLog("Recorded Activity");
|
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("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("All times are in carrier periods (1/13.56Mhz)");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog(" Start | End | Src | Data");
|
PrintAndLog(" Start | End | Src | Data (! denotes parity error) | CRC ");
|
||||||
PrintAndLog("-----------|-----------|-----|--------");
|
PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
|
||||||
|
|
||||||
int i;
|
uint16_t tracepos = 0;
|
||||||
uint32_t first_timestamp = 0;
|
uint16_t duration;
|
||||||
|
uint16_t data_len;
|
||||||
|
uint16_t parity_len;
|
||||||
|
bool isResponse;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
bool tagToReader;
|
uint32_t first_timestamp;
|
||||||
uint32_t parityBits;
|
uint32_t EndOfTransmissionTimestamp;
|
||||||
uint8_t len;
|
|
||||||
uint8_t *frame;
|
|
||||||
uint32_t EndOfTransmissionTimestamp = 0;
|
|
||||||
|
|
||||||
|
for (;;) {
|
||||||
|
|
||||||
for( i=0; i < TRACE_BUFFER_SIZE;)
|
if(tracepos >= TRACE_SIZE) {
|
||||||
{
|
break;
|
||||||
//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 = *((uint32_t *)(trace + tracepos));
|
||||||
timestamp &= 0x7fffffff;
|
if(tracepos == 0) {
|
||||||
|
|
||||||
if(i==0) {
|
|
||||||
first_timestamp = timestamp;
|
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
|
// 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] = "";
|
tracepos += 4;
|
||||||
int j;
|
duration = *((uint16_t *)(trace + tracepos));
|
||||||
for (j = 0; j < len; j++) {
|
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 oddparity = 0x01;
|
||||||
int k;
|
int k;
|
||||||
|
|
||||||
|
@ -220,79 +125,68 @@ int CmdHFiClassListOld(const char *Cmd)
|
||||||
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
|
oddparity ^= (((frame[j] & 0xFF) >> k) & 0x01);
|
||||||
}
|
}
|
||||||
|
|
||||||
//if((parityBits >> (len - j - 1)) & 0x01) {
|
uint8_t parityBits = parityBytes[j>>3];
|
||||||
if (isResponse && (oddparity != ((parityBits >> (len - j - 1)) & 0x01))) {
|
if (isResponse && (oddparity != ((parityBits >> (7-(j&0x0007))) & 0x01))) {
|
||||||
sprintf(line+(j*4), "%02x! ", frame[j]);
|
sprintf(line[j/16]+((j%16)*4), "%02x! ", frame[j]);
|
||||||
}
|
} else {
|
||||||
else {
|
sprintf(line[j/16]+((j%16)*4), "%02x ", frame[j]);
|
||||||
sprintf(line+(j*4), "%02x ", frame[j]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char *crc;
|
}
|
||||||
crc = "";
|
|
||||||
if (len > 2) {
|
char *crc = "";
|
||||||
|
if (data_len > 2) {
|
||||||
uint8_t b1, b2;
|
uint8_t b1, b2;
|
||||||
for (j = 0; j < (len - 1); j++) {
|
if(!isResponse && data_len == 4 ) {
|
||||||
// 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) {
|
|
||||||
// Rough guess that this is a command from the reader
|
// Rough guess that this is a command from the reader
|
||||||
// For iClass the command byte is not part of the CRC
|
// 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 {
|
else {
|
||||||
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
// For other data.. CRC might not be applicable (UPDATE commands etc.)
|
||||||
ComputeCrc14443(CRC_ICLASS, frame, len-2, &b1, &b2);
|
ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
|
||||||
}
|
if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
|
||||||
//printf("%1x %1x",(unsigned)b1,(unsigned)b2);
|
crc = "!crc";
|
||||||
if (b1 != frame[len-2] || b2 != frame[len-1]) {
|
|
||||||
crc = (isResponse & (len < 8)) ? "" : " !crc";
|
|
||||||
} else {
|
|
||||||
crc = "";
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
crc = ""; // SHORT
|
|
||||||
}
|
}
|
||||||
|
|
||||||
char metricString[100];
|
EndOfTransmissionTimestamp = timestamp + duration;
|
||||||
if (isResponse) {
|
|
||||||
sprintf(metricString, "%3d", metric);
|
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 {
|
} else {
|
||||||
strcpy(metricString, " ");
|
PrintAndLog(" | | | %-64s| %s",
|
||||||
|
line[j],
|
||||||
|
(j == num_lines-1)?crc:"");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
PrintAndLog(" +%7d: %s: %s %s %s",
|
bool next_isResponse = *((uint16_t *)(trace + tracepos + 6)) & 0x8000;
|
||||||
(prev < 0 ? 0 : (timestamp - prev)),
|
|
||||||
metricString,
|
|
||||||
(isResponse ? "TAG" : " "), line, crc);
|
|
||||||
|
|
||||||
prev = timestamp;
|
if (ShowWaitCycles && !isResponse && next_isResponse) {
|
||||||
i += (len + 9);
|
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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -581,7 +581,7 @@ static command_t CommandTable[] =
|
||||||
{"simman", CmdLFSimManchester, 0, "<Clock> <Bitstream> [GAP] Simulate arbitrary Manchester LF tag"},
|
{"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)"},
|
{"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 }"},
|
{"em4x", CmdLFEM4X, 1, "{ EM4X tags }"},
|
||||||
{"hid", CmdLFHID, 1, "{ HID tags }"},
|
{"hid", CmdLFHID, 1, "{ HID tags }"},
|
||||||
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders }"},
|
{"hitag", CmdLFHitag, 1, "{ Hitag tags and transponders }"},
|
||||||
|
|
|
@ -12,14 +12,14 @@
|
||||||
#include <inttypes.h>
|
#include <inttypes.h>
|
||||||
#include "proxmark3.h"
|
#include "proxmark3.h"
|
||||||
#include "ui.h"
|
#include "ui.h"
|
||||||
#include "graph.h"
|
//#include "graph.h"
|
||||||
#include "cmdmain.h"
|
#include "cmdmain.h"
|
||||||
#include "cmdparser.h"
|
#include "cmdparser.h"
|
||||||
#include "cmddata.h"
|
//#include "cmddata.h"
|
||||||
#include "cmdlf.h"
|
#include "cmdlf.h"
|
||||||
#include "cmdlfawid26.h"
|
#include "cmdlfawid26.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "data.h"
|
//#include "data.h"
|
||||||
|
|
||||||
|
|
||||||
static int CmdHelp(const char *Cmd);
|
static int CmdHelp(const char *Cmd);
|
||||||
|
@ -29,11 +29,10 @@ int CmdClone(const char *Cmd)
|
||||||
char cmdp = param_getchar(Cmd, 0);
|
char cmdp = param_getchar(Cmd, 0);
|
||||||
|
|
||||||
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
|
if (strlen(Cmd) < 1 || cmdp == 'h' || cmdp == 'H') {
|
||||||
PrintAndLog("Usage: lf awid26 write []");
|
PrintAndLog("Usage: lf awid26 clone <facility> <id>");
|
||||||
PrintAndLog(" [], ");
|
PrintAndLog(" [], ");
|
||||||
PrintAndLog("");
|
PrintAndLog("");
|
||||||
PrintAndLog(" sample: lf awid26 write 26 2233");
|
PrintAndLog(" sample: lf awid26 clone 15 2233");
|
||||||
PrintAndLog(" : lf awid26 write 26 15 2233");
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -50,6 +49,108 @@ int CmdClone(const char *Cmd)
|
||||||
return 0;
|
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)
|
// int CmdReadTrace(const char *Cmd)
|
||||||
// {
|
// {
|
||||||
|
|
||||||
|
@ -85,7 +186,7 @@ int CmdClone(const char *Cmd)
|
||||||
static command_t CommandTable[] =
|
static command_t CommandTable[] =
|
||||||
{
|
{
|
||||||
{"help", CmdHelp, 1, "This help"},
|
{"help", CmdHelp, 1, "This help"},
|
||||||
{"clone", CmdClone, 0, "<facility> <id> -- clone to a t55xx tag"},
|
{"clone", CmdClone, 1, "<facility> <id> -- clone AWID26 to t55xx tag"},
|
||||||
{NULL, NULL, 0, NULL}
|
{NULL, NULL, 0, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -13,4 +13,6 @@
|
||||||
int CmdLFAWID26(const char *Cmd);
|
int CmdLFAWID26(const char *Cmd);
|
||||||
|
|
||||||
int CmdClone(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
|
#endif
|
||||||
|
|
|
@ -468,6 +468,9 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
|
||||||
|
|
||||||
int i = start;
|
int i = start;
|
||||||
int j = len-1;
|
int j = len-1;
|
||||||
|
if (len > 32) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
uint32_t tmp = 0;
|
uint32_t tmp = 0;
|
||||||
for (; j >= 0; --j, ++i){
|
for (; j >= 0; --j, ++i){
|
||||||
tmp |= bits[i] << j;
|
tmp |= bits[i] << j;
|
||||||
|
|
|
@ -292,3 +292,102 @@ int param_getstr(const char *line, int paramnum, char * str)
|
||||||
|
|
||||||
return en - bg + 1;
|
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
|
#ifndef MAX
|
||||||
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
# define MAX(a, b) (((a) > (b)) ? (a) : (b))
|
||||||
#endif
|
#endif
|
||||||
|
#define TRUE 1
|
||||||
|
#define FALSE 0
|
||||||
|
#define EVEN 0
|
||||||
|
#define ODD 1
|
||||||
|
|
||||||
int ukbhit(void);
|
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_gethex(const char *line, int paramnum, uint8_t * data, int hexcnt);
|
||||||
int param_getstr(const char *line, int paramnum, char * str);
|
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