1 //----------------------------------------------------------------------------- 
   3 // This code is licensed to you under the terms of the GNU GPL, version 2 or, 
   4 // at your option, any later version. See the LICENSE.txt file for the text of 
   6 //----------------------------------------------------------------------------- 
   7 // Low frequency Presco tag commands 
   8 //----------------------------------------------------------------------------- 
  11 #include "cmdlfpresco.h" 
  12 static int CmdHelp(const char *Cmd
); 
  14 int usage_lf_presco_clone(void){ 
  15         PrintAndLog("clone a Presco tag to a T55x7 tag."); 
  16         PrintAndLog("Usage: lf presco clone <Card ID - 9 digits> <Q5>"); 
  17         PrintAndLog("Options :"); 
  18         PrintAndLog("  <Card Number>  : 9 digit presco card number"); 
  19         //PrintAndLog("  <Q5>           : specify write to Q5 (t5555 instead of t55x7)"); 
  21         PrintAndLog("Sample  : lf presco clone 123456789"); 
  25 int usage_lf_presco_sim(void) { 
  26         PrintAndLog("Enables simulation of presco card with specified card number."); 
  27         PrintAndLog("Simulation runs until the button is pressed or another USB command is issued."); 
  28         PrintAndLog("Per presco format, the card number is 9 digit number and can contain *# chars. Larger values are truncated."); 
  30         PrintAndLog("Usage:  lf presco sim <Card-Number>"); 
  31         PrintAndLog("Options :"); 
  32         PrintAndLog("  <Card Number>   : 9 digit presco card number"); 
  34         PrintAndLog("Sample  : lf presco sim 123456789"); 
  39 int GetWiegandFromPresco(const char *id
, uint32_t *sitecode
, uint32_t *usercode
) { 
  42         for (int index 
=0; index 
< strlen(id
); ++index
) { 
  44                 // Get value from number string. 
  45                 if ( id
[index
] == '*' ) val 
= 10; 
  46                 if ( id
[index
] == '#')  val 
= 11;                
  47                 if ( id
[index
] >= 0x30 && id
[index
] <= 0x39 ) 
  48                         val 
= id
[index
] - 0x30; 
  52                 // last digit is only added, not multipled. 
  53                 if ( index 
< strlen(id
)-1 )  
  56         *usercode 
= *sitecode 
% 65536; 
  57         *sitecode 
/= 16777216; 
  61 int GetPrescoBits(uint32_t sitecode
, uint32_t usercode
, uint8_t *prescoBits
) { 
  63         memset(pre
, 0, sizeof(pre
)); 
  65         num_to_bytebits(26, 8, pre
); 
  68         num_to_bytebits(sitecode
, 8, wiegand
); 
  69         num_to_bytebits(usercode
, 16, wiegand
+8); 
  71         wiegand_add_parity(pre
+8, wiegand
, 24); 
  72         size_t bitLen 
= addParity(pre
, prescoBits
+8, 66, 4, 1); 
  74         if (bitLen 
!= 88) return 0; 
  77 //see ASKDemod for what args are accepted 
  78 int CmdPrescoDemod(const char *Cmd
) { 
  79         if (!ASKDemod(Cmd
, false, false, 1)) { 
  80                 if (g_debugMode
) PrintAndLog("ASKDemod failed"); 
  83         size_t size 
= DemodBufferLen
; 
  84         //call lfdemod.c demod for Viking 
  85         int ans 
= PrescoDemod(DemodBuffer
, &size
); 
  87                 if (g_debugMode
) PrintAndLog("Error Presco_Demod %d", ans
); 
  91         uint32_t raw1 
= bytebits_to_byte(DemodBuffer
+ans
, 32); 
  92         uint32_t raw2 
= bytebits_to_byte(DemodBuffer
+ans
+32, 32); 
  93         uint32_t cardid 
= bytebits_to_byte(DemodBuffer
+ans
+24, 32); 
  94         PrintAndLog("Presco Tag Found: Card ID %08X", cardid
); 
  95         PrintAndLog("Raw: %08X%08X", raw1
,raw2
); 
  96         setDemodBuf(DemodBuffer
+ans
, 64, 0); 
  98         // uint32_t sitecode = 0, usercode = 0; 
  99         // GetWiegandFromPresco(id, &sitecode, &usercode); 
 100         // PrintAndLog8("SiteCode %d  |  UserCode %d", sitecode, usercode); 
 105 //see ASKDemod for what args are accepted 
 106 int CmdPrescoRead(const char *Cmd
) { 
 107         //      Presco Number: 123456789 --> Sitecode 30 | usercode 8665 
 111         // get samples silently 
 112         getSamples("30000",false); 
 113         // demod and output Presco ID    
 114         return CmdPrescoDemod(Cmd
); 
 117 int CmdPrescoClone(const char *Cmd
) { 
 119         char cmdp 
= param_getchar(Cmd
, 0); 
 120         if (strlen(Cmd
) == 0 || cmdp 
== 'h' || cmdp 
== 'H') return usage_lf_presco_clone(); 
 122         uint32_t sitecode
=0, usercode
=0; 
 125         memset(bs
,0,sizeof(bits
)); 
 126         uint32_t blocks
[5] = {T55x7_MODULATION_MANCHESTER 
| T55x7_BITRATE_RF_32 
| 4<<T55x7_MAXBLOCK_SHIFT 
| T55x7_ST_TERMINATOR
, 0, 0, 0, 5}; 
 128         if (param_getchar(Cmd
, 3) == 'Q' || param_getchar(Cmd
, 3) == 'q') 
 129                 blocks
[0] = T5555_MODULATION_MANCHESTER 
| 32<<T5555_BITRATE_SHIFT 
| 4<<T5555_MAXBLOCK_SHIFT 
| T5555_ST_TERMINATOR
; 
 131         // get wiegand from printed number. 
 132         GetWiegandFromPresco(Cmd
, &sitecode
, &usercode
); 
 134         if ((sitecode 
& 0xFF) != sitecode
) { 
 136                 PrintAndLog("Facility-Code Truncated to 8-bits (Presco): %u", sitecode
); 
 139         if ((usercode 
& 0xFFFF) != usercode
) { 
 141                 PrintAndLog("Card Number Truncated to 16-bits (Presco): %u", usercode
); 
 144         if ( !GetPrescoBits(sitecode
, usercode
, bs
)) { 
 145                 PrintAndLog("Error with tag bitstream generation."); 
 149         blocks
[1] = bytebits_to_byte(bs
,32); 
 150         blocks
[2] = bytebits_to_byte(bs
+32,32); 
 151         blocks
[3] = bytebits_to_byte(bs
+64,32); 
 152         blocks
[4] = bytebits_to_byte(bs
+96,32); 
 154         PrintAndLog("Preparing to clone Presco to T55x7 with SiteCode: %u, UserCode: %u", sitecode
, usercode
); 
 155         PrintAndLog("Blk | Data "); 
 156         PrintAndLog("----+------------"); 
 157         PrintAndLog(" 00 | 0x%08x", blocks
[0]); 
 158         PrintAndLog(" 01 | 0x%08x", blocks
[1]); 
 159         PrintAndLog(" 02 | 0x%08x", blocks
[2]); 
 160         PrintAndLog(" 03 | 0x%08x", blocks
[3]);  
 161         PrintAndLog(" 04 | 0x%08x", blocks
[4]);  
 164         // UsbCommand c = {CMD_T55XX_WRITE_BLOCK, {0,0,0}}; 
 166         // for (uint8_t i=0; i<5; i++) { 
 167                 // c.arg[0] = blocks[i]; 
 169                 // clearCommandBuffer(); 
 171                 // if (!WaitForResponseTimeout(CMD_ACK, &resp, 1000)){ 
 172                         // PrintAndLog("Error occurred, device did not respond during write operation."); 
 179 int CmdPrescoSim(const char *Cmd
) { 
 181         // uint64_t rawID = 0; 
 182         // uint8_t clk = 32, encoding = 1, separator = 0, invert = 0; 
 184         // char cmdp = param_getchar(Cmd, 0); 
 185         // if (strlen(Cmd) == 0 || cmdp == 'h' || cmdp == 'H') return usage_lf_presco_sim(); 
 187         // id = param_get32ex(Cmd, 0, 0, 16); 
 188         // if (id == 0) return usage_lf_presco_sim(); 
 190         //rawID = getVikingBits(id); 
 192         // uint16_t arg1, arg2; 
 194         // arg1 = clk << 8 | encoding; 
 195         // arg2 = invert << 8 | separator; 
 197         // PrintAndLog("Simulating - ID: %08X, Raw: %08X%08X",id,(uint32_t)(rawID >> 32),(uint32_t) (rawID & 0xFFFFFFFF)); 
 199         // UsbCommand c = {CMD_ASK_SIM_TAG, {arg1, arg2, size}}; 
 200         // num_to_bytebits(rawID, size, c.d.asBytes); 
 201         // clearCommandBuffer(); 
 206 static command_t CommandTable
[] = { 
 207     {"help",    CmdHelp
,                1, "This help"}, 
 208         {"read",        CmdPrescoRead
,  0, "Attempt to read and Extract tag data"}, 
 209         {"clone",       CmdPrescoClone
, 0, "<8 digit ID number> clone presco tag"}, 
 210 //      {"sim",         CmdPrescoSim,   0, "<8 digit ID number> simulate presco tag"}, 
 211     {NULL
, NULL
, 0, NULL
} 
 214 int CmdLFPresco(const char *Cmd
) { 
 215         clearCommandBuffer(); 
 216     CmdsParse(CommandTable
, Cmd
); 
 220 int CmdHelp(const char *Cmd
) { 
 221     CmdsHelp(CommandTable
);