chg: iso15693 lua lib works.

This commit is contained in:
iceman1001 2018-11-30 20:58:47 +01:00
commit 0372cb8a04
2 changed files with 65 additions and 87 deletions

View file

@ -2,12 +2,12 @@
This is a library to read 15693 tags. It can be used something like this
local reader = require('read15')
result, err = reader.read15693()
if not result then
local info, err = reader.read()
if not info then
print(err)
return
end
print(result.name)
print(info.UID)
--]]
-- Loads the commands-library
@ -29,10 +29,10 @@ local function sendToDevice(command, ignoreresponse)
print(err)
return nil, err
end
if ignoreresponse then return nil,nil end
if ignoreresponse then return nil, nil end
local response = core.WaitForResponseTimeout(cmds.CMD_ACK, TIMEOUT)
return response,nil
return response, nil
end
local function errorString15693(number)
@ -52,47 +52,31 @@ end
local function parse15693(data)
-- From common/iso15693tools.h :
--[[
#define ISO15_CRC_CHECK ((uint16_t)(~0xF0B8 & 0xFFFF)) // use this for checking of a correct crc
--]]
-- But that is very strange. Basically what is says is:
local bytes = utils.ConvertAsciiToBytes(data)
local tmp = utils.ConvertAsciiToHex(data)
-- define ISO15_CRC_CHECK 0F47
-- So we can just use that directly...
-- The following code is based on cmdhf15.c around line 666 (NoTB!) and onwards
if core.iso15693_crc(data, string.len(data)) ~= 0xF47 then
local crcStr = utils.Crc15(tmp, #tmp)
if string.sub(crcStr, #crcStr - 3) ~= '470F' then
print("CRC", crc )
return nil, "CRC failed"
elseif data[1] % 2 == 1 then
end
if bytes[1] % 2 == 1 then
-- Above is a poor-mans bit check:
-- recv[0] & ISO15_RES_ERROR //(0x01)
local err = "Tag returned error %i: %s"
err = string.format(err, data[1], errorString15693(data[1]))
err = string.format(err, bytes[1], errorString15693(bytes[1]))
return nil, err
end
-- Finally, let the parsing begin...
-- the UID is just the data in reverse... almost:
-- 0FC481FF70000104E001001B0301
-- 8877665544332211
-- UID = E004010070FF81C4
-- 1122334455667788
-- So, cut out the relevant part and reverse it
-- byte wise reverse.. not string reverse..
local uid = data:sub(2,9):reverse()
local uidStr = bin.unpack("H8", uid)
local _, manufacturer_code = bin.unpack("s", uid:sub(2,2))
local _, tag_size = bin.unpack(">I", data:sub(12,13))
local _, micref_modelcode = bin.unpack("s", data:sub(14,14))
return {
uid = uidStr,
manufacturer_code = manufacturer_code,
tag_size = tag_size,
micref_modelcode = micref_modelcode,
local uid = utils.ConvertBytesToHex( bytes, true )
uid = uid:sub(5, #uid-4)
return { uid = uid, }micref_modelcode = micref_modelcode,
}
end
-- This function does a connect and retrieves som einfo
-- This function does a connect and retrieves som info
-- @param dont_disconnect - if true, does not disable the field
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
@ -100,53 +84,37 @@ local function read15693(slow, dont_readresponse)
--[[
We start by trying this command:
We start by trying this command:
MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
proxmark3> hf 15 cmd sysinfo -2 u
0F C4 81 FF 70 00 01 04 E0 01 00 1B 03 01
UID = E004010070FF81C4
Philips; IC SL2 ICS20
DSFID supported, set to 01
AFI supported, set to 000
Tag provides info on memory layout (vendor dependent)
4 (or 3) bytes/page x 28 pages
IC reference given: 01
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.
If the above command doesn't give an answer (see example below):
proxmark3> hf 15 cmd sysinfo -2 u
timeout: no
we must send the MANDATORY (present in ALL iso15693 tags) command (the example below is sent to a tag different from the above one):
proxmark3> hf 15 cmd inquiry
pm3> hf 15 info u
UID=E007C1A257394244
Tag Info: Texas Instrument; Tag-it HF-I Standard; 8x32bit
proxmark3>
pm3>
From which we obtain less information than the above one.
From which we obtain less information than the above one.
"260100" means
0x26
-- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
-- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
-- #define ISO15_REQ_NONINVENTORY 0x00
0x01
inventory
0x00
--]]
local command, result, info, err, data
data = "260100"
--add crc
local payload = utils.Crc15(data)
data = utils.Crc15("260100")
command = Command:new{cmd = cmds.CMD_ISO_15693_COMMAND,
arg1 = string.len(payload) / 2,
arg1 = #data / 2,
arg2 = 1,
arg3 = 1,
data = payload}
-- These are defined in common/iso15693tools.h
-- #define ISO15_REQ_SUBCARRIER_SINGLE 0x00 // Tag should respond using one subcarrier (ASK)
-- #define ISO15_REQ_DATARATE_HIGH 0x02 // Tag should respond using high data rate
-- #define ISO15_REQ_NONINVENTORY 0x00
data = data}
if slow then
command.arg2 = 0
end
@ -157,23 +125,25 @@ local function read15693(slow, dont_readresponse)
local result, err = sendToDevice(command, dont_readresponse)
if not result then
print(err)
return nil, "15693 sysinfo: no answer"
return nil, "15693 identify: no answer"
end
local count, cmd, recvlen, arg1, arg2 = bin.unpack('LLLL',result)
data = string.sub(result, recvlen)
info, err = parse15693(data)
if err then
print(err)
return nil, err
local count, cmd, len, arg2, arg3 = bin.unpack('LLLL', result)
if len > 0 then
data = string.sub(result, count, count+len-1)
info, err = parse15693(data)
if err then
print(err)
return nil, err
end
return info
else
return nil, "Failed to get response"
end
return info
end
---
-- Waits for a mifare card to be placed within the vicinity of the reader.
-- Waits for a ISO15693 card to be placed within the vicinity of the reader.
-- @return if successfull: an table containing card info
-- @return if unsuccessfull : nil, error
local function waitFor15693()

View file

@ -257,15 +257,23 @@ local Utils =
end,
---
-- Convert Byte array to string of hex
ConvertBytesToHex = function(bytes)
ConvertBytesToHex = function(bytes, reverse)
if bytes == nil then return '' end
if #bytes == 0 then return '' end
local s={}
for i = 1, #bytes do
s[i] = string.format("%02X",bytes[i])
if reverse then
local j=1
for i = #bytes, 1, -1 do
s[i] = string.format("%02X", bytes[j])
j = j + 1
end
else
for i = 1, #bytes do
s[i] = string.format("%02X", bytes[i])
end
end
return table.concat(s)
end,
end,
-- Convert byte array to string with ascii
ConvertBytesToAscii = function(bytes)
if bytes == nil then return '' end