forked from RfidResearchGroup/proxmark3
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request RfidResearchGroup#2502 from evildaemond/master
Simple Trace Parsing LUA Library
- Loading branch information
Showing
1 changed file
with
98 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,98 @@ | ||
--[[ | ||
Simple Trace Parser library | ||
-- fair warning, this is best to just get trace data values, I didn't see any better implementation for this, so I just made one myself | ||
-- Example Usage | ||
-- Load the traceParser library | ||
local traceParser = require("trace_parse") | ||
-- Parse the trace file | ||
local trace_data = traceParser.parse_trace_file(filename) | ||
-- Print the parsed data | ||
for _, record in ipairs(trace_data) do | ||
-- Format the data bytes | ||
local data_bytes = {} | ||
for i = 1, #record.data do | ||
table.insert(data_bytes, string.format("%02X", record.data:byte(i))) | ||
end | ||
local data_str = table.concat(data_bytes, "") | ||
print("Data: " .. data_str) | ||
end | ||
]] | ||
|
||
local bit = require("bit") -- Requires Lua bitwise library (bit) | ||
local traceParser = {} | ||
|
||
-- Function to read a 4-byte unsigned integer (little-endian) | ||
local function read_u32_le(data, pos) | ||
if pos + 3 > #data then return nil, pos end | ||
local b1, b2, b3, b4 = data:byte(pos, pos + 3) | ||
return (b4 * 2^24) + (b3 * 2^16) + (b2 * 2^8) + b1, pos + 4 | ||
end | ||
|
||
-- Function to read a 2-byte unsigned integer (little-endian) | ||
local function read_u16_le(data, pos) | ||
if pos + 1 > #data then return nil, pos end | ||
local b1, b2 = data:byte(pos, pos + 1) | ||
return (b2 * 2^8) + b1, pos + 2 | ||
end | ||
|
||
-- Function to parse a single record from the trace file | ||
local function parse_record(trace, pos) | ||
local record = {} | ||
|
||
-- Read the 32-bit timestamp (4 bytes, little-endian) | ||
record.timestamp_start, pos = read_u32_le(trace, pos) | ||
|
||
-- Read the 16-bit duration (2 bytes, little-endian) | ||
record.duration, pos = read_u16_le(trace, pos) | ||
|
||
-- Read the 15-bit data length and 1-bit isResponse flag | ||
local data_len_and_flag, pos = read_u16_le(trace, pos) | ||
record.data_len = bit.band(data_len_and_flag, 0x7FFF) -- 15 bits for data length | ||
record.is_response = bit.rshift(data_len_and_flag, 15) == 1 -- 1 bit for isResponse | ||
|
||
-- Read the data bytes | ||
record.data, pos = trace:sub(pos, pos + record.data_len - 1), pos + record.data_len | ||
|
||
-- Read the parity bytes (parity length is ceil(data_len / 8)) | ||
local parity_len = math.ceil(record.data_len / 8) | ||
record.parity, pos = trace:sub(pos, pos + parity_len - 1), pos + parity_len | ||
|
||
return record, pos | ||
end | ||
|
||
-- Function to parse the entire trace file | ||
function traceParser.parse_trace_file(file_path) | ||
local trace_data = {} | ||
local trace_file = io.open(file_path, "rb") | ||
|
||
if not trace_file then | ||
error("Could not open file: " .. file_path) | ||
end | ||
|
||
-- Read the entire content of the file | ||
local content = trace_file:read("*all") | ||
trace_file:close() | ||
|
||
-- Parse records in the file | ||
local pos = 1 | ||
while pos <= #content do | ||
local record | ||
record, pos = parse_record(content, pos) | ||
if record then | ||
table.insert(trace_data, record) | ||
else | ||
break -- Stop if the record is invalid or incomplete | ||
end | ||
end | ||
|
||
return trace_data | ||
end | ||
|
||
|
||
return traceParser | ||
|