]> cvs.zerfleddert.de Git - proxmark3-svn/commitdiff
added the changes from PM3 master.
authoriceman1001 <iceman@iuse.se>
Mon, 22 Dec 2014 14:14:05 +0000 (15:14 +0100)
committericeman1001 <iceman@iuse.se>
Mon, 22 Dec 2014 14:14:05 +0000 (15:14 +0100)
added some code for the AWID26

armsrc/iso14443a.c
client/cmdhf14a.c
client/cmdhficlass.c
client/cmdlf.c
client/cmdlfawid26.c
client/cmdlfawid26.h
client/cmdlft55xx.c
client/util.c
client/util.h

index d8edc209803f017c15da7e7cf7ec6ddae9a8a75a..269a00c5437c96f784d4262d88379d7fb5999902 100644 (file)
@@ -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));
index 97d102be0938a129b82a6c2456d44f07866ac250..bfa7bfbfdc91ddf34099e588e351c66eaeb8edd9 100644 (file)
@@ -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;
        }
 
index e033422a0c1a7de5e81b01ba4ba799593b1da12b..75c6e2c975265a808ed05a1e018d45f3f07c5f0d 100644 (file)
@@ -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("-----------|-----------|-----|--------");
-
-       int i;
-       uint32_t first_timestamp = 0;
+       PrintAndLog("     Start |       End | Src | Data (! denotes parity error)                                   | CRC ");
+       PrintAndLog("-----------|-----------|-----|-----------------------------------------------------------------------");
+
+       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));
-                       }
+    // Break and stick with current result if buffer was not completely full
+               if (timestamp == 0x44444444) break; 
+
+               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;
                }
 
-               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);
-                       }
+               parity_len = (data_len-1)/8 + 1;
 
-                       if (b1 != frame[len-2] || b2 != frame[len-1]) {
-                               crc = (tagToReader & (len < 8)) ? "" : " !crc";
-                       }
+               if (tracepos + data_len + parity_len >= TRACE_SIZE) {
+                       break;
                }
-
-               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; }
-
-    char line[1000] = "";
-    int j;
-    for (j = 0; j < len; j++) {
+               
+               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) {
-      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) {
+               char *crc = ""; 
+               if (data_len > 2) {
+      uint8_t b1, b2;
+                       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";
-        } else {
-          crc = "";
-        }
-      }
-    } else {
-      crc = ""; // SHORT
-    }
-
-    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);
+                               ComputeCrc14443(CRC_ICLASS, frame, data_len-2, &b1, &b2);
+                               if (b1 != frame[data_len-2] || b2 != frame[data_len-1]) {
+                                       crc = "!crc";
+                               }
+                       }
+               }
 
-    prev = timestamp;
-    i += (len + 9);
-  }
+               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 {
+                               PrintAndLog("           |           |     | %-64s| %s",
+                                       line[j], 
+                                       (j == num_lines-1)?crc:"");
+                       }
+               }                               
+
+               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;
 }
 
index 2f55cd22caa5d972b4fd1e4890de002931e527c0..faf95ccdfe25b4054ffb1e43f5363ae3c1a4acd2 100644 (file)
@@ -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 }"},
index 63b35fdde6f82b92dfaa5ae38e5b53ef682dd9ea..0e1fca8ed44fe1384bb75d3fc7513dfa48d5d2a8 100644 (file)
 #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}
 };
 
index c0facf5177376c952e0a0903faaba915db30b872..cb1cd9e213017e04455d94407aa89ee65ff5b3e6 100644 (file)
@@ -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
index 78d90e7cda17ee9f80f25daa030ce0e8bff91d29..6ea9d2d3a575beff7868050ab5a298284abc01b6 100644 (file)
@@ -468,6 +468,9 @@ uint32_t PackBits(uint8_t start, uint8_t len, uint8_t* bits){
        \r
        int i = start;\r
        int j = len-1;\r
+       if (len > 32) {\r
+               return 0;\r
+       }\r
        uint32_t tmp = 0;\r
        for (; j >= 0; --j, ++i){\r
                tmp     |= bits[i] << j;\r
index 56c4998d8368c69103b5716d09eb5a62cee90fe8..0418dd98f9f6c4c35f7cc50962766e092011c6e2 100644 (file)
@@ -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);
+}
index 54562a07069f76d9e604320f7e1512cb84f20fbc..10bafba98b75878d339e3755de1a257a0f1fae69 100644 (file)
 #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);
 
Impressum, Datenschutz