Hoernchen has uploaded this change for review.
contrib: extend wireshark lua dissector
Still no reassembly, but enough to work with bug report pcaps
Change-Id: Ic78824d6122191c7d16152cea643a238c33f49b1
---
M contrib/simtrace.lua
1 file changed, 501 insertions(+), 140 deletions(-)
git pull ssh://gerrit.osmocom.org:29418/simtrace2 refs/changes/49/42749/1
diff --git a/contrib/simtrace.lua b/contrib/simtrace.lua
index 598a4e2..fd2277b 100644
--- a/contrib/simtrace.lua
+++ b/contrib/simtrace.lua
@@ -6,6 +6,9 @@
-- can be found in the Wireshark Help->About Wireshark->Folders tab
-- Windows: %APPDATA%\Wireshark\plugins.
-- Unix-like systems: ~/.local/lib/wireshark/plugins.
+--
+-- tshark works too:
+-- tshark -r capture.pcapng -X lua_script:/path/to/simtrace.lua
usb_simtrace_protocol = Proto("USB_simtrace", "USB simtrace protocol")
@@ -34,31 +37,105 @@
[0x0300] = "SNIFF_CHANGE",
[0x0301] = "SNIFF_FIDI",
[0x0302] = "SNIFF_ATR",
+[0x0303] = "SNIFF_PPS",
[0x0304] = "SNIFF_TPDU",
-[0x0303] = "SNIFF_PPS"
}
-local msgtype = ProtoField.uint16("usb_simtrace.msgtype", "Message Type", base.HEX_DEC, control_commands)
+local msg_class_names = {
+ [0] = "GENERIC",
+ [1] = "CARDEM",
+ [2] = "MODEM",
+ [3] = "SNIFF",
+}
+
+-- ISO 7816 / GSM SIM instruction
+local ins_names = {
+ [0x04] = "DEACTIVATE FILE",
+ [0x10] = "TERMINAL PROFILE",
+ [0x12] = "ENVELOPE",
+ [0x14] = "FETCH",
+ [0x20] = "VERIFY PIN",
+ [0x24] = "CHANGE PIN",
+ [0x26] = "DISABLE PIN",
+ [0x28] = "ENABLE PIN",
+ [0x2C] = "UNBLOCK PIN",
+ [0x32] = "INCREASE",
+ [0x44] = "ACTIVATE FILE",
+ [0x70] = "MANAGE CHANNEL",
+ [0x73] = "MANAGE SECURE CHANNEL",
+ [0x75] = "TRANSACT DATA",
+ [0x88] = "AUTHENTICATE",
+ [0x89] = "AUTHENTICATE",
+ [0xA4] = "SELECT",
+ [0xAA] = "TERMINAL CAPABILITY",
+ [0xB0] = "READ BINARY",
+ [0xB2] = "READ RECORD",
+ [0xC0] = "GET RESPONSE",
+ [0xC2] = "ENVELOPE",
+ [0xCB] = "RETRIEVE DATA",
+ [0xD6] = "UPDATE BINARY",
+ [0xDB] = "SET DATA",
+ [0xDC] = "UPDATE RECORD",
+ [0xF2] = "STATUS",
+ [0xFA] = "SLEEP",
+}
+
+-- ISO 7816 SW1
+local sw1_names = {
+ [0x90] = "OK",
+ [0x91] = "OK, proactive",
+ [0x9E] = "Response length",
+ [0x9F] = "Response length",
+ [0x61] = "Bytes available",
+ [0x62] = "Warning, unchanged",
+ [0x63] = "Warning, changed",
+ [0x64] = "Error, NV unchanged",
+ [0x65] = "Error, NV changed",
+ [0x67] = "Wrong length",
+ [0x68] = "CLA not supported",
+ [0x69] = "Command not allowed",
+ [0x6A] = "Wrong parameters",
+ [0x6B] = "Wrong P1/P2",
+ [0x6C] = "Wrong Le",
+ [0x6D] = "INS not supported",
+ [0x6E] = "CLA not supported",
+ [0x6F] = "Internal error",
+}
+
+local msgtype = ProtoField.uint16("usb_simtrace.msgtype", "Command", base.HEX_DEC, control_commands)
+local hf_msg_class = ProtoField.uint8("usb_simtrace.msg_class", "Message Class", base.HEX, msg_class_names)
+local hf_msg_type = ProtoField.uint8("usb_simtrace.msg_type", "Message Type", base.HEX)
+
local seqnr = ProtoField.uint8("usb_simtrace.seqnr", "Sequence Number", base.DEC)
local slotnr = ProtoField.uint8("usb_simtrace.slotnr", "Slot Number", base.DEC)
local reserved = ProtoField.uint16("usb_simtrace.reserved", "reserved", base.HEX_DEC)
-local payloadlen = ProtoField.uint16("usb_simtrace.length", "length", base.DEC)
+local payloadlen = ProtoField.uint16("usb_simtrace.length", "Message Length", base.DEC)
local payload = ProtoField.bytes("usb_simtrace.payload", "Data")
-local pb_and_rx = ProtoField.uint32("usb_simtrace.pb_and_rx", "pb_and_rx", base.HEX_DEC, NULL, 0x8)
-local pb_and_tx = ProtoField.uint32("usb_simtrace.pb_and_tx", "pb_and_tx", base.HEX_DEC, NULL, 0x4)
-local final = ProtoField.uint32("usb_simtrace.final", "final", base.HEX_DEC, NULL, 0x2)
-local tpdu_hdr = ProtoField.uint32("usb_simtrace.tpdu_hdr", "tpdu_hdr", base.HEX_DEC, NULL, 0x1)
-local rxtxdatalen = ProtoField.uint16("usb_simtrace.rxtxdatalen", "rx/tx data length", base.DEC)
-local rxtxdata = ProtoField.bytes("usb_simtrace.rxtxdata", "rx/tx (data)")
+local pb_and_rx = ProtoField.uint32("usb_simtrace.pb_and_rx", "pb_and_rx", base.HEX_DEC, NULL, 0x00000008)
+local pb_and_tx = ProtoField.uint32("usb_simtrace.pb_and_tx", "pb_and_tx", base.HEX_DEC, NULL, 0x00000004)
+local final = ProtoField.uint32("usb_simtrace.final", "Final", base.HEX_DEC, NULL, 0x00000002)
+local tpdu_hdr = ProtoField.uint32("usb_simtrace.tpdu_hdr", "TPDU Header", base.HEX_DEC, NULL, 0x00000001)
+local rxtxdatalen = ProtoField.uint16("usb_simtrace.rxtxdatalen", "Data Length", base.DEC)
+local rxtxdata = ProtoField.bytes("usb_simtrace.rxtxdata", "TPDU Data")
-local hf_pts_len = ProtoField.uint8("usb_simtrace.pts_len", "PTS length", base.DEC)
-local hf_pts_req = ProtoField.bytes("usb_simtrace.pts_req", "PTS request")
-local hf_pts_resp = ProtoField.bytes("usb_simtrace.pts_resp", "PTS response")
+local hf_tpdu_cla = ProtoField.uint8("usb_simtrace.tpdu.cla", "CLA", base.HEX)
+local hf_tpdu_ins = ProtoField.uint8("usb_simtrace.tpdu.ins", "INS", base.HEX, ins_names)
+local hf_tpdu_p1 = ProtoField.uint8("usb_simtrace.tpdu.p1", "P1", base.HEX)
+local hf_tpdu_p2 = ProtoField.uint8("usb_simtrace.tpdu.p2", "P2", base.HEX)
+local hf_tpdu_p3 = ProtoField.uint8("usb_simtrace.tpdu.p3", "P3", base.HEX)
+local hf_tpdu_pb = ProtoField.uint8("usb_simtrace.tpdu.pb", "Procedure Byte", base.HEX)
+local hf_tpdu_sw1 = ProtoField.uint8("usb_simtrace.tpdu.sw1", "SW1", base.HEX, sw1_names)
+local hf_tpdu_sw2 = ProtoField.uint8("usb_simtrace.tpdu.sw2", "SW2", base.HEX)
-local hf_cemu_cfg_features = ProtoField.uint32("usb_simtrace.cemu_cfg.features.status_irq", "CardEm Features", base.HEX)
-local hf_cemu_cfg_slot_mux_nr = ProtoField.uint32("usb_simtrace.cemu_cfg.features.slot_mux_nr", "CardEm Slot Mux Nr", base.DEC)
-local hf_cemu_cfg_presence_polarity = ProtoField.uint8("usb_simtrace.cemu_cfg.features.presence_polarity", "Sim presence polarity", base.DEC)
+local hf_pts_len = ProtoField.uint8("usb_simtrace.pts_len", "PTS Length", base.DEC)
+local hf_pts_req = ProtoField.bytes("usb_simtrace.pts_req", "PTS Request")
+local hf_pts_resp = ProtoField.bytes("usb_simtrace.pts_resp", "PTS Response")
+
+local hf_cemu_cfg_features = ProtoField.uint32("usb_simtrace.cemu_cfg.features", "CardEm Features", base.HEX)
+local hf_cemu_cfg_slot_mux_nr = ProtoField.uint8("usb_simtrace.cemu_cfg.slot_mux_nr", "CardEm Slot Mux Nr", base.DEC)
+local hf_cemu_cfg_presence_polarity = ProtoField.uint8("usb_simtrace.cemu_cfg.presence_polarity", "Sim Presence Polarity", base.HEX)
+local hf_cemu_cfg_feat_status_irq = ProtoField.uint32("usb_simtrace.cemu_cfg.features.status_irq", "Status IRQ", base.HEX_DEC, NULL, 0x00000001)
local card_insert_types = {
[0x00] = "not inserted",
@@ -72,16 +149,22 @@
local CEMU_STATUS_F_CARD_INSERT = ProtoField.uint32("usb_simtrace.CEMU_STATUS.F_CARD_INSERT", "CARD_INSERT", base.HEX_DEC, NULL, 0x00000008)
local CEMU_STATUS_F_RESET_ACTIVE = ProtoField.uint32("usb_simtrace.CEMU_STATUS.F_RESET_ACTIVE", "RESET_ACTIVE", base.HEX_DEC, NULL, 0x00000010)
-local CEMU_CONFIG_PRES_POL_PRES_H = ProtoField.uint32("usb_simtrace.CEMU_CONFIG.PRES_POL_PRES_H", "PRESENCE_HIGH", base.HEX_DEC, NULL, 0x00000001)
-local CEMU_CONFIG_PRES_POL_VALID = ProtoField.uint32("usb_simtrace.CEMU_CONFIG.PRES_POL_VALID", "PRESENCE_VALID", base.HEX_DEC, NULL, 0x00000002)
+local hf_status_voltage = ProtoField.uint16("usb_simtrace.status.voltage_mv", "Voltage (mV)", base.DEC)
+local hf_status_fi = ProtoField.uint8("usb_simtrace.status.fi", "F Index", base.DEC)
+local hf_status_di = ProtoField.uint8("usb_simtrace.status.di", "D Index", base.DEC)
+local hf_status_wi = ProtoField.uint8("usb_simtrace.status.wi", "Waiting Integer", base.DEC)
+local hf_status_wt = ProtoField.uint32("usb_simtrace.status.waiting_time", "Waiting Time (ETU)", base.DEC)
+
+local CEMU_CONFIG_PRES_POL_PRES_H = ProtoField.uint8("usb_simtrace.CEMU_CONFIG.PRES_POL_PRES_H", "PRESENCE_HIGH", base.HEX_DEC, NULL, 0x01)
+local CEMU_CONFIG_PRES_POL_VALID = ProtoField.uint8("usb_simtrace.CEMU_CONFIG.PRES_POL_VALID", "PRESENCE_VALID", base.HEX_DEC, NULL, 0x02)
local modem_reset_types = {
[0x00] = "de-assert",
[0x01] = "assert",
[0x02] = "pulse"
}
-local modem_reset_status = ProtoField.uint8("usb_simtrace.modem.reset_type", "modem reset type", base.HEX, modem_reset_types, 0xf)
-local modem_reset_len = ProtoField.uint8("usb_simtrace.modem.reset_len", "modem reset length (ms)", base.DEC)
+local modem_reset_status = ProtoField.uint8("usb_simtrace.modem.reset_type", "modem reset type", base.HEX, modem_reset_types, 0x0f)
+local modem_reset_len = ProtoField.uint16("usb_simtrace.modem.reset_len", "modem reset length (ms)", base.DEC)
local modem_sim_select_types = {
[0x00] = "local",
@@ -89,200 +172,478 @@
}
local hf_modem_sim_select = ProtoField.uint8("usb_simtrace.modem.sim_select", "SIM card selection", base.DEC, modem_sim_select_types, 0xff)
+local hf_modem_status_supported = ProtoField.uint8("usb_simtrace.modem.status.supported", "Supported Status Bits", base.HEX)
+local hf_modem_status_current = ProtoField.uint8("usb_simtrace.modem.status.current", "Current Status Bits", base.HEX)
+local hf_modem_status_changed = ProtoField.uint8("usb_simtrace.modem.status.changed", "Changed Status Bits", base.HEX)
+local hf_mdm_sts_wwan = ProtoField.uint8("usb_simtrace.modem.status.wwan_led", "WWAN LED", base.DEC, NULL, 0x01)
+local hf_mdm_sts_card = ProtoField.uint8("usb_simtrace.modem.status.card_inserted", "Card Inserted", base.DEC, NULL, 0x02)
+
+local hf_error_severity = ProtoField.uint8("usb_simtrace.error.severity", "Severity", base.DEC)
+local hf_error_subsystem = ProtoField.uint8("usb_simtrace.error.subsystem", "Subsystem", base.DEC)
+local hf_error_code = ProtoField.uint16("usb_simtrace.error.code", "Error Code", base.HEX)
+local hf_error_msg_len = ProtoField.uint8("usb_simtrace.error.msg_len", "Message Length", base.DEC)
+local hf_error_msg = ProtoField.string("usb_simtrace.error.msg", "Error Message")
+
+local hf_bi_hw_manufacturer = ProtoField.string("usb_simtrace.board_info.hw.manufacturer", "HW Manufacturer")
+local hf_bi_hw_model = ProtoField.string("usb_simtrace.board_info.hw.model", "HW Model")
+local hf_bi_hw_version = ProtoField.string("usb_simtrace.board_info.hw.version", "HW Version")
+local hf_bi_sw_provider = ProtoField.string("usb_simtrace.board_info.sw.provider", "SW Provider")
+local hf_bi_sw_name = ProtoField.string("usb_simtrace.board_info.sw.name", "SW Name")
+local hf_bi_sw_version = ProtoField.string("usb_simtrace.board_info.sw.version", "SW Version")
+local hf_bi_sw_buildhost = ProtoField.string("usb_simtrace.board_info.sw.buildhost", "Build Host")
+local hf_bi_sw_crc = ProtoField.uint32("usb_simtrace.board_info.sw.crc", "SW CRC", base.HEX)
+local hf_bi_max_baud = ProtoField.uint32("usb_simtrace.board_info.max_baud_rate", "Max Baud Rate", base.DEC)
+local hf_bi_cap_generic_bytes = ProtoField.uint8("usb_simtrace.board_info.cap_generic_bytes", "Generic Capability Bytes", base.DEC)
+local hf_bi_cap_vendor_bytes = ProtoField.uint8("usb_simtrace.board_info.cap_vendor_bytes", "Vendor Capability Bytes", base.DEC)
+local hf_bi_cap_data = ProtoField.bytes("usb_simtrace.board_info.cap_data", "Capability Data")
+
+local hf_atr_len = ProtoField.uint8("usb_simtrace.atr_len", "ATR Length", base.DEC)
+local hf_atr_data = ProtoField.bytes("usb_simtrace.atr_data", "ATR Data")
+
+local hf_sniff_change_flags = ProtoField.uint32("usb_simtrace.sniff.change_flags", "Change Flags", base.HEX)
+local hf_sniff_chg_card_insert = ProtoField.uint32("usb_simtrace.sniff.change.card_insert", "Card Insert", base.HEX_DEC, NULL, 0x00000001)
+local hf_sniff_chg_card_eject = ProtoField.uint32("usb_simtrace.sniff.change.card_eject", "Card Eject", base.HEX_DEC, NULL, 0x00000002)
+local hf_sniff_chg_reset_assert = ProtoField.uint32("usb_simtrace.sniff.change.reset_assert", "Reset Assert", base.HEX_DEC, NULL, 0x00000004)
+local hf_sniff_chg_reset_deassert = ProtoField.uint32("usb_simtrace.sniff.change.reset_deassert", "Reset Deassert", base.HEX_DEC, NULL, 0x00000008)
+local hf_sniff_chg_timeout_wt = ProtoField.uint32("usb_simtrace.sniff.change.timeout_wt", "Timeout WT", base.HEX_DEC, NULL, 0x00000010)
+
+local hf_sniff_fidi = ProtoField.uint8("usb_simtrace.sniff.fidi", "Fi/Di (TA1)", base.HEX)
+
+-- shared by SNIFF_ATR, SNIFF_PPS, SNIFF_TPDU
+local hf_sniff_data_flags = ProtoField.uint32("usb_simtrace.sniff.data.flags", "Data Flags", base.HEX)
+local hf_sniff_data_f_incomplete = ProtoField.uint32("usb_simtrace.sniff.data.flag.incomplete", "Incomplete", base.HEX_DEC, NULL, 0x00000020)
+local hf_sniff_data_f_malformed = ProtoField.uint32("usb_simtrace.sniff.data.flag.malformed", "Malformed", base.HEX_DEC, NULL, 0x00000040)
+local hf_sniff_data_f_checksum = ProtoField.uint32("usb_simtrace.sniff.data.flag.checksum_err", "Checksum Error", base.HEX_DEC, NULL, 0x00000080)
+local hf_sniff_data_f_overrun = ProtoField.uint32("usb_simtrace.sniff.data.flag.overrun", "Overrun", base.HEX_DEC, NULL, 0x00000100)
+local hf_sniff_data_f_framing = ProtoField.uint32("usb_simtrace.sniff.data.flag.framing_err", "Framing Error", base.HEX_DEC, NULL, 0x00000200)
+local hf_sniff_data_f_parity = ProtoField.uint32("usb_simtrace.sniff.data.flag.parity_err", "Parity Error", base.HEX_DEC, NULL, 0x00000400)
+local hf_sniff_data_len = ProtoField.uint16("usb_simtrace.sniff.data.length", "Data Length", base.DEC)
+local hf_sniff_data = ProtoField.bytes("usb_simtrace.sniff.data.data", "Data")
+
+
usb_simtrace_protocol.fields = {
- msgtype, seqnr, slotnr, reserved, payloadlen, payload,
+ hf_msg_class, hf_msg_type, msgtype, seqnr, slotnr, reserved, payloadlen, payload,
pb_and_rx, pb_and_tx, final, tpdu_hdr, rxtxdatalen, rxtxdata,
+ hf_tpdu_cla, hf_tpdu_ins, hf_tpdu_p1, hf_tpdu_p2, hf_tpdu_p3, hf_tpdu_pb, hf_tpdu_sw1, hf_tpdu_sw2,
CEMU_STATUS_F_VCC_PRESENT, CEMU_STATUS_F_CLK_ACTIVE, CEMU_STATUS_F_RCEMU_ACTIVE, CEMU_STATUS_F_CARD_INSERT, CEMU_STATUS_F_RESET_ACTIVE,
+ hf_status_voltage, hf_status_fi, hf_status_di, hf_status_wi, hf_status_wt,
CEMU_CONFIG_PRES_POL_PRES_H, CEMU_CONFIG_PRES_POL_VALID,
modem_reset_status, modem_reset_len,
hf_pts_len, hf_pts_req, hf_pts_resp,
- hf_cemu_cfg_features, hf_cemu_cfg_slot_mux_nr, hf_cemu_cfg_presence_polarity,
+ hf_cemu_cfg_features, hf_cemu_cfg_feat_status_irq, hf_cemu_cfg_slot_mux_nr, hf_cemu_cfg_presence_polarity,
hf_cemu_cardinsert, hf_modem_sim_select,
+ hf_modem_status_supported, hf_modem_status_current, hf_modem_status_changed,
+ hf_mdm_sts_wwan, hf_mdm_sts_card,
+ hf_error_severity, hf_error_subsystem, hf_error_code, hf_error_msg_len, hf_error_msg,
+ hf_bi_hw_manufacturer, hf_bi_hw_model, hf_bi_hw_version,
+ hf_bi_sw_provider, hf_bi_sw_name, hf_bi_sw_version, hf_bi_sw_buildhost, hf_bi_sw_crc,
+ hf_bi_max_baud, hf_bi_cap_generic_bytes, hf_bi_cap_vendor_bytes, hf_bi_cap_data,
+ hf_atr_len, hf_atr_data,
+ hf_sniff_change_flags, hf_sniff_chg_card_insert, hf_sniff_chg_card_eject,
+ hf_sniff_chg_reset_assert, hf_sniff_chg_reset_deassert, hf_sniff_chg_timeout_wt,
+ hf_sniff_fidi,
+ hf_sniff_data_flags, hf_sniff_data_f_incomplete, hf_sniff_data_f_malformed,
+ hf_sniff_data_f_checksum, hf_sniff_data_f_overrun, hf_sniff_data_f_framing,
+ hf_sniff_data_f_parity, hf_sniff_data_len, hf_sniff_data,
}
-local is_hdr = Field.new("usb_simtrace.tpdu_hdr")
-local is_pbrx = Field.new("usb_simtrace.pb_and_rx")
-local is_pbtx = Field.new("usb_simtrace.pb_and_tx")
-local is_final= Field.new("usb_simtrace.final")
+-- unfortunately no easy dissection due to mixed in procedure bytes
+-- that would need complicated reassembly of fragments, but this is enough to be useful
-function dissect_rxtx(payload_data,pinfo,tree)
+function dissect_rxtx(payload_data, pinfo, tree, command)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "rx/tx data")
+ local flags = payload_data(0,4):le_uint()
+ local len = payload_data(4,2):le_uint()
- local headerSubtree = tree:add(usb_simtrace_protocol, payload_data, "rx/tx data")
- local len = payload_data(4,2):le_uint();
- local cmd32 = payload_data(0,4):le_uint();
+ subtree:add_le(pb_and_rx, payload_data(0,4))
+ subtree:add_le(pb_and_tx, payload_data(0,4))
+ subtree:add_le(final, payload_data(0,4))
+ subtree:add_le(tpdu_hdr, payload_data(0,4))
- headerSubtree:add(pb_and_rx, cmd32)
- headerSubtree:add(pb_and_tx, cmd32)
- headerSubtree:add(final, cmd32)
- headerSubtree:add(tpdu_hdr, cmd32)
+ subtree:add_le(rxtxdatalen, payload_data(4,2))
+ subtree:add(rxtxdata, payload_data(6, len))
- headerSubtree:add(rxtxdatalen, len)
- headerSubtree:add_le(rxtxdata, payload_data(6,len))
+ local f_pbrx = bit.band(flags, 0x08) ~= 0
+ local f_pbtx = bit.band(flags, 0x04) ~= 0
+ local f_final = bit.band(flags, 0x02) ~= 0
+ local f_hdr = bit.band(flags, 0x01) ~= 0
- local flagstr = " "
- if is_pbrx().value == 1 then
- flagstr = flagstr .. "R"
- else
- flagstr = flagstr .. "."
+ local flagstr = " " .. (f_pbrx and "R" or ".") .. (f_pbtx and "T" or ".")
+ .. (f_final and "F" or ".") .. (f_hdr and "H" or ".")
+
+ local data_off = 6
+
+ if f_hdr and len >= 5 then
+ local hdr_tree = subtree:add(usb_simtrace_protocol, payload_data(data_off, 5), "TPDU Header")
+ hdr_tree:add(hf_tpdu_cla, payload_data(data_off, 1))
+ hdr_tree:add(hf_tpdu_ins, payload_data(data_off + 1, 1))
+ hdr_tree:add(hf_tpdu_p1, payload_data(data_off + 2, 1))
+ hdr_tree:add(hf_tpdu_p2, payload_data(data_off + 3, 1))
+ hdr_tree:add(hf_tpdu_p3, payload_data(data_off + 4, 1))
+
+ local ins = payload_data(data_off + 1, 1):uint()
+ local ins_name = ins_names[ins] or string.format("INS=%02X", ins)
+ pinfo.cols.info:append(string.format("%s %s P1=%02X P2=%02X P3=%02X",
+ flagstr, ins_name,
+ payload_data(data_off + 2, 1):uint(),
+ payload_data(data_off + 3, 1):uint(),
+ payload_data(data_off + 4, 1):uint()))
+ return
end
- if is_pbtx().value == 1 then
- flagstr = flagstr .. "T"
- else
- flagstr = flagstr .. "."
+
+ local pb_size = 0
+ if (f_pbrx or f_pbtx) and len >= 1 then
+ subtree:add(hf_tpdu_pb, payload_data(data_off, 1))
+ pb_size = 1
end
- if is_final().value == 1 then
- flagstr = flagstr .. "F"
+
+ if f_final and command == 0x0101 and len >= (pb_size + 2) then
+ local sw1_off = data_off + len - 2
+ subtree:add(hf_tpdu_sw1, payload_data(sw1_off, 1))
+ subtree:add(hf_tpdu_sw2, payload_data(sw1_off + 1, 1))
+
+ local sw1 = payload_data(sw1_off, 1):uint()
+ local sw2 = payload_data(sw1_off + 1, 1):uint()
+ local sw_text = string.format("SW=%02X%02X", sw1, sw2)
+ local sw_name = sw1_names[sw1]
+ if sw_name then sw_text = sw_text .. " (" .. sw_name .. ")" end
+
+ local resp_len = len - pb_size - 2
+ if pb_size > 0 then
+ pinfo.cols.info:append(string.format("%s PB=%02X", flagstr, payload_data(data_off, 1):uint()))
+ else
+ pinfo.cols.info:append(flagstr)
+ end
+ if resp_len > 0 then
+ pinfo.cols.info:append(string.format(" [%d bytes]", resp_len))
+ end
+ pinfo.cols.info:append(" " .. sw_text)
else
- flagstr = flagstr .. "."
+ if pb_size > 0 then
+ pinfo.cols.info:append(string.format("%s PB=%02X", flagstr, payload_data(data_off, 1):uint()))
+ else
+ pinfo.cols.info:append(flagstr)
+ end
+ local remaining = len - pb_size
+ if remaining > 0 then
+ pinfo.cols.info:append(" " .. payload_data(data_off + pb_size, remaining))
+ end
end
- if is_hdr().value == 1 then
- flagstr = flagstr .. "H"
- else
- flagstr = flagstr .. "."
- end
- flagstr = flagstr .. " "
- pinfo.cols.info:append(flagstr .. payload_data(6,len))
-
- -- ghetto dissection does not work due to mixed in procedure bytes
- --if pinfo.visited == false then
- -- Dissector.get("iso7816"):call(payload_data(6):tvb(), pinfo, tree)
-
--- local offs = 0
--- if (is_pbrx().value == 1 or is_pbtx().value == 1) and is_final().value == 0 then
--- offs = 1
--- else
--- offs = 0
--- end
---
--- if is_hdr().value == 1 then
--- Dissector.get("gsm_sim"):call(concatss:tvb(), pinfo, tree)
--- concatss = payload_data(6):bytes()
--- else
--- concatss = concatss .. payload_data(6+offs):bytes()
--- end
-
---end
-
end
-function dissect_status(payload_data,pinfo,tree)
+function dissect_status(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "status message")
- local headerSubtree = tree:add(usb_simtrace_protocol, payload_data, "status message")
- local cmd32 = payload_data(0,4):le_uint();
+ subtree:add_le(CEMU_STATUS_F_VCC_PRESENT, payload_data(0,4))
+ subtree:add_le(CEMU_STATUS_F_CLK_ACTIVE, payload_data(0,4))
+ subtree:add_le(CEMU_STATUS_F_RCEMU_ACTIVE, payload_data(0,4))
+ subtree:add_le(CEMU_STATUS_F_CARD_INSERT, payload_data(0,4))
+ subtree:add_le(CEMU_STATUS_F_RESET_ACTIVE, payload_data(0,4))
- headerSubtree:add(CEMU_STATUS_F_VCC_PRESENT, cmd32)
- headerSubtree:add(CEMU_STATUS_F_CLK_ACTIVE, cmd32)
- headerSubtree:add(CEMU_STATUS_F_RCEMU_ACTIVE, cmd32)
- headerSubtree:add(CEMU_STATUS_F_CARD_INSERT, cmd32)
- headerSubtree:add(CEMU_STATUS_F_RESET_ACTIVE, cmd32)
+ if payload_data:len() >= 6 then
+ subtree:add_le(hf_status_voltage, payload_data(4,2))
+ end
+ if payload_data:len() >= 7 then
+ subtree:add(hf_status_fi, payload_data(6,1))
+ end
+ if payload_data:len() >= 8 then
+ subtree:add(hf_status_di, payload_data(7,1))
+ end
+ if payload_data:len() >= 9 then
+ subtree:add(hf_status_wi, payload_data(8,1))
+ end
+ if payload_data:len() >= 13 then
+ subtree:add_le(hf_status_wt, payload_data(9,4))
+ end
pinfo.cols.info:append(" VCC:" .. payload_data(0,1):bitfield(7, 1) .. " CLK:" .. payload_data(0,1):bitfield(6, 1) .. " RESET:" .. payload_data(0,1):bitfield(3, 1))
-end
-function dissect_atr(payload_data,pinfo,tree)
-
- local len = payload_data(0,1):le_uint()
- Dissector.get("iso7816.atr"):call(payload_data(1):tvb(), pinfo, tree)
-end
-
-function dissect_modem_reset(payload_data,pinfo,tree)
-
- local headerSubtree = tree:add(usb_simtrace_protocol, payload_data, "modem reset")
- local cmd8 = payload_data(0,1):le_uint();
-
- headerSubtree:add(modem_reset_status, cmd8)
- pinfo.cols.info:append(" reset type:" .. modem_reset_types[cmd8]);
-
- if(cmd8 == 2) then
- local duration = payload_data(1,2):le_uint()
- headerSubtree:add(modem_reset_len, duration)
- pinfo.cols.info:append(" duration:" .. duration .. "ms")
+ if payload_data:len() >= 6 then
+ local voltage = payload_data(4,2):le_uint()
+ if voltage > 0 then
+ pinfo.cols.info:append(" " .. voltage .. "mV")
+ end
end
+ if payload_data:len() >= 9 then
+ pinfo.cols.info:append(" Fi=" .. payload_data(6,1):uint() .. " Di=" .. payload_data(7,1):uint() .. " Wi=" .. payload_data(8,1):uint())
+ end
+end
+function dissect_atr(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "Set ATR")
+ local len = payload_data(0,1):le_uint()
+ subtree:add(hf_atr_len, payload_data(0,1))
+
+ if len > 0 and payload_data:len() > 1 then
+ subtree:add(hf_atr_data, payload_data(1, len))
+ local ok, dissector = pcall(Dissector.get, "iso7816.atr")
+ if ok and dissector then
+ dissector:call(payload_data(1):tvb(), pinfo, tree)
+ end
+ pinfo.cols.info:append(" ATR:" .. payload_data(1, len))
+ end
+end
+
+function dissect_modem_reset(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "modem reset")
+ local cmd8 = payload_data(0,1):le_uint()
+
+ subtree:add(modem_reset_status, payload_data(0,1))
+ pinfo.cols.info:append(" reset type:" .. (modem_reset_types[cmd8] or "unknown"))
+
+ if cmd8 == 2 and payload_data:len() >= 3 then
+ subtree:add_le(modem_reset_len, payload_data(1,2))
+ local duration = payload_data(1,2):le_uint()
+ pinfo.cols.info:append(" duration:" .. duration .. "ms")
+ end
end
function dissect_pts(payload_data, pinfo, tree)
local subtree = tree:add(usb_simtrace_protocol, payload_data, "PTS")
local pts_len = payload_data(0,1):le_uint()
- local pts_req = payload_data(1, pts_len);
- local pts_resp = payload_data(7, pts_len);
+ local pts_req = payload_data(1, pts_len)
+ local pts_resp = payload_data(7, pts_len)
- subtree:add(hf_pts_len, pts_len);
- subtree:add(hf_pts_req, pts_req);
- subtree:add(hf_pts_resp, pts_resp);
+ subtree:add(hf_pts_len, payload_data(0,1))
+ subtree:add(hf_pts_req, pts_req)
+ subtree:add(hf_pts_resp, pts_resp)
- pinfo.cols.info:append(" Req: " .. pts_req .. ", Resp: " .. pts_resp);
+ pinfo.cols.info:append(" Req: " .. pts_req .. ", Resp: " .. pts_resp)
end
function dissect_cemu_config(payload_data, pinfo, tree)
local subtree = tree:add(usb_simtrace_protocol, payload_data, "Card Emu Config")
- subtree:add(hf_cemu_cfg_features, payload_data(0,4));
- if payload_data:len() >= 4 then
- subtree:add(hf_cemu_cfg_slot_mux_nr, payload_data(4,1));
- end
+ subtree:add_le(hf_cemu_cfg_features, payload_data(0,4))
+ subtree:add_le(hf_cemu_cfg_feat_status_irq, payload_data(0,4))
+
if payload_data:len() >= 5 then
- local pres = payload_data(5,1):le_uint();
- subtree:add(hf_cemu_cfg_presence_polarity, payload_data(5,1));
- headerSubtree:add(CEMU_CONFIG_PRES_POL_PRES_H, pres)
- headerSubtree:add(CEMU_CONFIG_PRES_POL_VALID, pres)
+ subtree:add(hf_cemu_cfg_slot_mux_nr, payload_data(4,1))
+ end
+ if payload_data:len() >= 6 then
+ subtree:add(hf_cemu_cfg_presence_polarity, payload_data(5,1))
+ subtree:add(CEMU_CONFIG_PRES_POL_PRES_H, payload_data(5,1))
+ subtree:add(CEMU_CONFIG_PRES_POL_VALID, payload_data(5,1))
end
end
function dissect_modem_sim_sel(payload_data, pinfo, tree)
local subtree = tree:add(usb_simtrace_protocol, payload_data, "Modem SIM Select")
- local sim_select = payload_data(0,1):le_uint();
+ local sim_select = payload_data(0,1):le_uint()
- subtree:add(hf_modem_sim_select, sim_select);
- pinfo.cols.info:append(" " .. modem_sim_select_types[sim_select]);
+ subtree:add(hf_modem_sim_select, payload_data(0,1))
+ pinfo.cols.info:append(" " .. (modem_sim_select_types[sim_select] or "unknown"))
end
function dissect_cemu_cardinsert(payload_data, pinfo, tree)
local subtree = tree:add(usb_simtrace_protocol, payload_data, "Card Insert")
local cins_type = payload_data(0,1):le_uint()
- subtree:add(hf_cemu_cardinsert, cins_type);
- pinfo.cols.info:append(" " .. card_insert_types[cins_type]);
+ subtree:add(hf_cemu_cardinsert, payload_data(0,1))
+ pinfo.cols.info:append(" " .. (card_insert_types[cins_type] or "unknown"))
end
+function dissect_error(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "Error")
+
+ subtree:add(hf_error_severity, payload_data(0,1))
+ subtree:add(hf_error_subsystem, payload_data(1,1))
+ subtree:add_le(hf_error_code, payload_data(2,2))
+
+ local severity = payload_data(0,1):uint()
+ local subsys = payload_data(1,1):uint()
+ local code = payload_data(2,2):le_uint()
+
+ if payload_data:len() >= 5 then
+ local msg_len = payload_data(4,1):uint()
+ subtree:add(hf_error_msg_len, payload_data(4,1))
+ if msg_len > 0 and payload_data:len() >= 5 + msg_len then
+ subtree:add(hf_error_msg, payload_data(5, msg_len))
+ end
+ end
+
+ pinfo.cols.info:append(string.format(" severity=%d subsys=%d code=0x%04X", severity, subsys, code))
+end
+
+function dissect_board_info(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "Board Info")
+
+ if payload_data:len() < 230 then
+ subtree:add(payload, payload_data)
+ return
+ end
+
+ subtree:add(hf_bi_hw_manufacturer, payload_data(0, 32))
+ subtree:add(hf_bi_hw_model, payload_data(32, 32))
+ subtree:add(hf_bi_hw_version, payload_data(64, 32))
+ subtree:add(hf_bi_sw_provider, payload_data(96, 32))
+ subtree:add(hf_bi_sw_name, payload_data(128, 32))
+ subtree:add(hf_bi_sw_version, payload_data(160, 32))
+ subtree:add(hf_bi_sw_buildhost, payload_data(192, 32))
+ subtree:add_le(hf_bi_sw_crc, payload_data(224, 4))
+ subtree:add_le(hf_bi_max_baud, payload_data(228, 4))
+ subtree:add(hf_bi_cap_generic_bytes, payload_data(232, 1))
+ subtree:add(hf_bi_cap_vendor_bytes, payload_data(233, 1))
+
+ local cap_generic = payload_data(232,1):uint()
+ local cap_vendor = payload_data(233,1):uint()
+ local cap_total = cap_generic + cap_vendor
+ if cap_total > 0 and payload_data:len() >= 234 + cap_total then
+ subtree:add(hf_bi_cap_data, payload_data(234, cap_total))
+ end
+
+ local model = payload_data(32, 32):string()
+ local version = payload_data(160, 32):string()
+ pinfo.cols.info:append(" " .. model .. " " .. version)
+end
+
+function dissect_modem_status(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "Modem Status")
+
+ subtree:add(hf_modem_status_supported, payload_data(0,1))
+ subtree:add(hf_mdm_sts_wwan, payload_data(0,1))
+ subtree:add(hf_mdm_sts_card, payload_data(0,1))
+
+ subtree:add(hf_modem_status_current, payload_data(1,1))
+ subtree:add(hf_mdm_sts_wwan, payload_data(1,1))
+ subtree:add(hf_mdm_sts_card, payload_data(1,1))
+
+ subtree:add(hf_modem_status_changed, payload_data(2,1))
+
+ local status = payload_data(1,1):uint()
+ local wwan = bit.band(status, 0x01)
+ local card = bit.rshift(bit.band(status, 0x02), 1)
+ pinfo.cols.info:append(string.format(" WWAN:%d CARD:%d", wwan, card))
+end
+
+function dissect_sniff_change(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "Sniff Change")
+ local flags = payload_data(0,4):le_uint()
+
+ subtree:add_le(hf_sniff_change_flags, payload_data(0,4))
+ subtree:add_le(hf_sniff_chg_card_insert, payload_data(0,4))
+ subtree:add_le(hf_sniff_chg_card_eject, payload_data(0,4))
+ subtree:add_le(hf_sniff_chg_reset_assert, payload_data(0,4))
+ subtree:add_le(hf_sniff_chg_reset_deassert, payload_data(0,4))
+ subtree:add_le(hf_sniff_chg_timeout_wt, payload_data(0,4))
+
+ local parts = {}
+ if bit.band(flags, 0x01) ~= 0 then parts[#parts+1] = "INSERT" end
+ if bit.band(flags, 0x02) ~= 0 then parts[#parts+1] = "EJECT" end
+ if bit.band(flags, 0x04) ~= 0 then parts[#parts+1] = "RST_ASSERT" end
+ if bit.band(flags, 0x08) ~= 0 then parts[#parts+1] = "RST_DEASSERT" end
+ if bit.band(flags, 0x10) ~= 0 then parts[#parts+1] = "TIMEOUT_WT" end
+ pinfo.cols.info:append(" " .. table.concat(parts, ","))
+end
+
+function dissect_sniff_fidi(payload_data, pinfo, tree)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "Sniff FiDi")
+
+ subtree:add(hf_sniff_fidi, payload_data(0,1))
+ pinfo.cols.info:append(string.format(" FiDi=0x%02X", payload_data(0,1):uint()))
+end
+
+function dissect_sniff_data(payload_data, pinfo, tree, label)
+ local subtree = tree:add(usb_simtrace_protocol, payload_data, "Sniff " .. label)
+ local flags = payload_data(0,4):le_uint()
+ local len = payload_data(4,2):le_uint()
+
+ subtree:add_le(hf_sniff_data_flags, payload_data(0,4))
+ subtree:add_le(hf_sniff_data_f_incomplete, payload_data(0,4))
+ subtree:add_le(hf_sniff_data_f_malformed, payload_data(0,4))
+ subtree:add_le(hf_sniff_data_f_checksum, payload_data(0,4))
+ subtree:add_le(hf_sniff_data_f_overrun, payload_data(0,4))
+ subtree:add_le(hf_sniff_data_f_framing, payload_data(0,4))
+ subtree:add_le(hf_sniff_data_f_parity, payload_data(0,4))
+ subtree:add_le(hf_sniff_data_len, payload_data(4,2))
+
+ if len > 0 and payload_data:len() >= 6 + len then
+ subtree:add(hf_sniff_data, payload_data(6, len))
+ pinfo.cols.info:append(" " .. payload_data(6, len))
+ end
+
+ if flags ~= 0 then
+ local parts = {}
+ if bit.band(flags, 0x020) ~= 0 then parts[#parts+1] = "INCOMPLETE" end
+ if bit.band(flags, 0x040) ~= 0 then parts[#parts+1] = "MALFORMED" end
+ if bit.band(flags, 0x080) ~= 0 then parts[#parts+1] = "CHECKSUM" end
+ if bit.band(flags, 0x100) ~= 0 then parts[#parts+1] = "OVERRUN" end
+ if bit.band(flags, 0x200) ~= 0 then parts[#parts+1] = "FRAMING" end
+ if bit.band(flags, 0x400) ~= 0 then parts[#parts+1] = "PARITY" end
+ if #parts > 0 then
+ pinfo.cols.info:append(" [" .. table.concat(parts, ",") .. "]")
+ end
+ end
+end
function usb_simtrace_protocol.dissector(buffer, pinfo, tree)
length = buffer:len()
if length == 0 then return end
+ if length < 8 then return 0 end
+
+ local msg_class = buffer(0,1):uint()
+ if msg_class > 3 then return 0 end
pinfo.cols.protocol = usb_simtrace_protocol.name
local subtree = tree:add(usb_simtrace_protocol, buffer(), "USB simtrace Data")
local command = buffer(0,2):uint()
+ subtree:add(hf_msg_class, buffer(0,1))
+ subtree:add(hf_msg_type, buffer(1,1))
subtree:add(msgtype, command):set_generated()
subtree:add(seqnr, buffer(2,1))
subtree:add(slotnr, buffer(3,1))
+ subtree:add_le(reserved, buffer(4,2))
subtree:add_le(payloadlen, buffer(6,2))
- pinfo.cols.info = string.format("Cmd 0x%04X : %s", command, control_commands[command])
- local payload_data = buffer(8,length-8)
- if(command == 0x0101 or command == 0x0106) then
- return dissect_rxtx(payload_data(),pinfo,subtree)
- elseif(command == 0x0104) then
- return dissect_status(payload_data(),pinfo,subtree)
- elseif(command == 0x0102) then
- return dissect_atr(payload_data(),pinfo,subtree)
- elseif(command == 0x0105) then
- return dissect_cemu_cardinsert(payload_data(),pinfo,subtree)
- elseif(command == 0x0107) then
- return dissect_pts(payload_data(),pinfo,subtree)
- elseif(command == 0x0108) then
- return dissect_cemu_config(payload_data(),pinfo,subtree)
- elseif(command == 0x0201) then
- return dissect_modem_reset(payload_data(),pinfo,subtree)
- elseif(command == 0x0202) then
- return dissect_modem_sim_sel(payload_data(),pinfo,subtree)
+
+ local cmd_name = control_commands[command]
+ if cmd_name then
+ pinfo.cols.info = cmd_name
+ else
+ pinfo.cols.info = string.format("Unknown (0x%04X)", command)
+ end
+
+ if length <= 8 then return end
+ local payload_data = buffer(8, length - 8)
+
+ if command == 0x0101 or command == 0x0106 then
+ return dissect_rxtx(payload_data(), pinfo, subtree, command)
+ elseif command == 0x0104 then
+ return dissect_status(payload_data(), pinfo, subtree)
+ elseif command == 0x0102 then
+ return dissect_atr(payload_data(), pinfo, subtree)
+ elseif command == 0x0105 then
+ return dissect_cemu_cardinsert(payload_data(), pinfo, subtree)
+ elseif command == 0x0107 then
+ return dissect_pts(payload_data(), pinfo, subtree)
+ elseif command == 0x0108 then
+ return dissect_cemu_config(payload_data(), pinfo, subtree)
+ elseif command == 0x0201 then
+ return dissect_modem_reset(payload_data(), pinfo, subtree)
+ elseif command == 0x0202 then
+ return dissect_modem_sim_sel(payload_data(), pinfo, subtree)
+ elseif command == 0x0203 then
+ return dissect_modem_status(payload_data(), pinfo, subtree)
+ elseif command == 0x0000 then
+ return dissect_error(payload_data(), pinfo, subtree)
+ elseif command == 0x0001 then
+ return dissect_board_info(payload_data(), pinfo, subtree)
+ elseif command == 0x0300 then
+ return dissect_sniff_change(payload_data(), pinfo, subtree)
+ elseif command == 0x0301 then
+ return dissect_sniff_fidi(payload_data(), pinfo, subtree)
+ elseif command == 0x0302 then
+ return dissect_sniff_data(payload_data(), pinfo, subtree, "ATR")
+ elseif command == 0x0303 then
+ return dissect_sniff_data(payload_data(), pinfo, subtree, "PPS")
+ elseif command == 0x0304 then
+ return dissect_sniff_data(payload_data(), pinfo, subtree, "TPDU")
else
subtree:add(payload, payload_data)
end
-
end
To view, visit change 42749. To unsubscribe, or for help writing mail filters, visit settings.