2 THIS IS WORK IN PROGREESS, very much not finished. 
 
   4 This library utilises other libraries under the hood, but can be used as a generic reader for 13.56MHz tags. 
 
   7 local reader14443A = require('read14a')
 
   8 local reader14443B = require('read14b')
 
   9 local cmds = require('commands')
 
  12 local function sendToDevice(command, ignoreresponse)
 
  13         core.clearCommandBuffer()
 
  14         local err = core.SendCommand(command:getBytes())
 
  19         if ignoreresponse then return nil,nil end
 
  20         local response = core.WaitForResponseTimeout(cmds.CMD_ACK,TIMEOUT)
 
  24 -------------------------------------------------------
 
  25 -- This will be moved to a separate 14443B library
 
  26 -------------------------------------------------------
 
  28 local reader14443B = {
 
  29         read = reader14443B.read14443b()
 
  31 -------------------------------------------------------
 
  32 -- This will be moved to a separate 1593 library
 
  33 -------------------------------------------------------
 
  35 local function errorString15693(number)
 
  37         errors[0x01] =  "The command is not supported"
 
  38         errors[0x02] =  "The command is not recognised"
 
  39         errors[0x03] =  "The option is not supported."
 
  40         errors[0x0f] =  "Unknown error."
 
  41         errors[0x10] =  "The specified block is not available (doesn’t exist)."
 
  42         errors[0x11] =  "The specified block is already -locked and thus cannot be locked again"
 
  43         errors[0x12] =  "The specified block is locked and its content cannot be changed."
 
  44         errors[0x13] =  "The specified block was not successfully programmed."
 
  45         errors[0x14] =  "The specified block was not successfully locked."
 
  47         return errors[number] or "Reserved for Future Use or Custom command error." 
 
  49 -------------------------------------------------------
 
  50 -- This will be moved to a separate 1593 library
 
  51 -------------------------------------------------------
 
  53 local function parse15693(data)
 
  54         -- From common/iso15693tools.h : 
 
  56         #define ISO15_CRC_CHECK  ((uint16_t)(~0xF0B8 & 0xFFFF))         // use this for checking of a correct crc
 
  58         -- But that is very strange. Basically what is says is:
 
  59         -- define ISO15_CRC_CHECK 0F47
 
  60         -- So we can just use that directly... 
 
  61         -- The following code is based on cmdhf15.c around line 666 (NoTB!) and onwards
 
  62         if core.iso15693_crc(data, string.len(data)) ~= 0xF47 then
 
  63                 return nil, "CRC failed"
 
  64         elseif data[1] % 2 == 1 then
 
  65                 -- Above is a poor-mans bit check:
 
  66                 -- recv[0] & ISO15_RES_ERROR //(0x01)
 
  67                 local err = "Tag returned error %i: %s"
 
  68                 err = string.format(err, data[1],errorString15693(data[1]))
 
  71         -- Finally, let the parsing begin... 
 
  72         -- the UID is just the data in reverse... almost:
 
  73         --      0FC481FF70000104E001001B0301
 
  75         --  UID = E004010070FF81C4
 
  77         -- So, cut out the relevant part and reverse it
 
  78         local uid = data:sub(2,9):reverse()
 
  79         local uidStr = bin.unpack("H8", uid)
 
  81         local _,manufacturer_code = bin.unpack("s",uid:sub(2,2))
 
  82         local _,tag_size = bin.unpack(">I",data:sub(12,13))
 
  83         local _,micref_modelcode = bin.unpack("s",data:sub(14,14))
 
  87                 manufacturer_code = manufacturer_code,
 
  89                 micref_modelcode = micref_modelcode,
 
  92 -------------------------------------------------------
 
  93 -- This will be moved to a separate 1593 library
 
  94 -------------------------------------------------------
 
  96 local function read15693()
 
  99         We start by trying this command:
 
 101                 proxmark3> hf 15 cmd sysinfo -2 u
 
 102                 0F C4 81 FF 70 00 01 04 E0 01 00 1B 03 01
 
 103                 UID = E004010070FF81C4
 
 104                 Philips; IC SL2 ICS20
 
 105                 DSFID supported, set to 01
 
 106                 AFI supported, set to 000
 
 107                 Tag provides info on memory layout (vendor dependent)
 
 108                  4 (or 3) bytes/page x 28 pages
 
 109                 IC reference given: 01
 
 111         This command is not always present in ISO15693 tags (it is an optional standard command) but if it is present usually the tags contain all the "colored" info above.
 
 113         If the above command doesn't give an answer (see example below):
 
 115                 proxmark3> hf 15 cmd sysinfo -2 u
 
 118         we must send the MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
 
 120                 proxmark3> hf 15 cmd inquiry
 
 122                 Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit         
 
 125         From which we obtain less information than the above one.
 
 128         local command, result, info, err, data
 
 130         local datalen = string.len(data) / 2
 
 133         command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND, 
 
 134                                                                 arg1 = datalen,arg2 = speed,arg3 =recv, data=data}
 
 135         -- These are defined in common/iso15693tools.h
 
 137         -- #define ISO15_REQ_SUBCARRIER_SINGLE  0x00    // Tag should respond using one subcarrier (ASK)
 
 138         -- #define ISO15_REQ_DATARATE_HIGH              0x02    // Tag should respond using high data rate
 
 139         -- #define ISO15_REQ_NONINVENTORY               0x00
 
 141         local result,err = sendToDevice(command)
 
 145                 return nil, "15693 sysinfo: no answer"
 
 148         local count,cmd,recvLen,arg1,arg2 = bin.unpack('LLLL',result)
 
 149         data = string.sub(result,recvlen)
 
 150         info, err = parse15693(data)
 
 159 local reader15693 = {
 
 165 -- This method library can be set waits or a 13.56 MHz tag, and when one is found, returns info about
 
 168 -- @return if successfull: an table containing card info
 
 169 -- @return if unsuccessfull : nil, error
 
 170 local function waitForTag()
 
 171         print("Waiting for card... press any key to quit")
 
 172         local readers = {reader14443A, reader14443B, reader15693}
 
 174         while not core.ukbhit() do
 
 177                 print("Reading with ",i)
 
 179                 if res then return res end
 
 181                         -- err means that there was no response from card
 
 183         return nil, "Aborted by user"
 
 187         waitForTag = waitForTag,