OpenCyphal / nunavut

Generate code from DSDL using PyDSDL and Jinja2
https://nunavut.readthedocs.io/
Other
39 stars 24 forks source link

Add Lua codegen to deserialize #314

Open emrainey opened 1 year ago

emrainey commented 1 year ago

Generate Lua functions to deserialize (serialization is not needed yet) for the Wireshark plugins in https://github.com/OpenCyphal-Garage/wireshark_plugins.

These would need to be "importable" modules which would take in the buffer, pfino, tree so that they could directly modify the Wireshark tree view.

The generated code would need to: 1.) emit a list of those expected ProtoFields which would have to somehow be added into their own Proto or incorporated into the Cyphal/CAN or Cyphal/UDP Protos. (TDB) 2.) emit a 'dissector' function which takes the buffer, pinfo, tree and populates the Wireshark tree using those fields 3.) emit function which has a very long switch/if/else condition per message type would also have to be created and then called from both Cyphal/CAN and Cyphal/UDP Protocol Dissectors.

Here's similar code which breaks down the Heartbeat:

payload_tree:add_le(cyphal_heartbeat_uptime, payload(0, 4))
payload_tree:add(cyphal_heartbeat_health, payload(4, 1))
payload_tree:add(cyphal_heartbeat_mode, payload(5, 1))
payload_tree:add(cyphal_heartbeat_vssc, payload(6, 1))

And the GetInfo

local offset = 0
payload_tree:add(cyphal_getinfo_protocol_version_major, payload(offset, 1))
offset = offset + 1
payload_tree:add(cyphal_getinfo_protocol_version_minor, payload(offset, 1))
offset = offset + 1
payload_tree:add(cyphal_getinfo_hardware_version_major, payload(offset, 1))
offset = offset + 1
payload_tree:add(cyphal_getinfo_hardware_version_minor, payload(offset, 1))
offset = offset + 1
payload_tree:add(cyphal_getinfo_software_version_major, payload(offset, 1))
offset = offset + 1
payload_tree:add(cyphal_getinfo_software_version_minor, payload(offset, 1))
offset = offset + 1
payload_tree:add(cyphal_getinfo_software_vcs_revision_id, payload(offset, 8))
offset = offset + 8
payload_tree:add(cyphal_getinfo_unique_id, payload(offset, 16))
offset = offset + 16
local len = payload(offset, 1):uint()
offset = offset + 1
payload_tree:add(cyphal_getinfo_name, payload(offset, len))
offset = offset + len
len = payload(offset, 1):uint()
offset = offset + 1
if len > 0 then
    payload_tree:add(cyphal_getinfo_software_image_crc, payload(offset, len))
end
offset = offset + len
len = payload(offset, 1):uint()
offset = offset + 1
if len > 0 then
    payload_tree:add(cyphal_getinfo_certificate_of_authority, payload(offset, len))
end

In both of these cases the payload is a Tvb object which can be subscripted to form ranges, integers, floats, etc. The payload_tree is the Wireshark 'tree' object which will hold the decoded values and the various cyphal_getinfo_* are the various ProtoField declarations which inform Wireshark what fields could be expected.

The calling function:

function decode_message(payload, pinfo, payload_tree. subject_id)
  if subject_id == 7509 then -- Heartbeat
    decode_cyphal_heartbeat(payload, pinfo, payload_tree)
  ... etc
  end
end

function decode_service(payload, pinfo, payload_tree, service_id, request_not_response) 
  if service_id == 430 then 
    if request_not_response then
      decode_request_getinfo(payload, pinfo, payload_tree)
   else
     decode_response_getinfo(payload, pinfo, payload_tree)
   end
 end
end

These are just ideas and are not hard requirements.

pavel-kirienko commented 1 year ago

Or we could add a bus monitor to Yukon, similar to this:

image
emrainey commented 1 year ago

image

emrainey commented 1 year ago

I have a require case working: Screenshot 2023-07-06 at 9 35 48 PM