Hoernchen has uploaded this change for review. ( 
https://gerrit.osmocom.org/c/simtrace2/+/42749?usp=email )


Change subject: contrib: extend wireshark lua dissector
......................................................................

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 https://gerrit.osmocom.org/c/simtrace2/+/42749?usp=email
To unsubscribe, or for help writing mail filters, visit 
https://gerrit.osmocom.org/settings?usp=email

Gerrit-MessageType: newchange
Gerrit-Project: simtrace2
Gerrit-Branch: master
Gerrit-Change-Id: Ic78824d6122191c7d16152cea643a238c33f49b1
Gerrit-Change-Number: 42749
Gerrit-PatchSet: 1
Gerrit-Owner: Hoernchen <[email protected]>

Reply via email to