wireshark/epan/dissectors/packet-uavcan-dsdl.c

690 lines
30 KiB
C

/* packet-uavcan-dsdl.c
* Routines for dissection of DSDL used in UAVCAN
*
* Copyright 2020-2021 NXP
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <inttypes.h>
#include <epan/packet.h>
#include <epan/prefs.h>
#include <epan/address_types.h>
#include <epan/to_str.h>
#include <epan/proto_data.h>
#include "packet-uavcan-dsdl.h"
void proto_register_dsdl(void);
void proto_reg_handoff_dsdl(void);
static int proto_dsdl = -1;
static int hf_heartbeat_uptime = -1;
static int hf_heartbeat_health = -1;
static int hf_heartbeat_mode = -1;
static int hf_heartbeat_status_code = -1;
static int hf_list_index = -1;
static int hf_register_name = -1;
static int hf_register_access_mutable = -1;
static int hf_register_access_persistent = -1;
static int hf_register_value_tag = -1;
static int hf_register_value_size = -1;
static int hf_node_id = -1;
static int hf_pnp_unique_id = -1;
static int hf_pnp_unique_id_hash = -1;
static int hf_pnp_alloc = -1;
static int hf_uavcan_primitive_Empty = -1;
static int hf_uavcan_primitive_String = -1;
static int hf_uavcan_primitive_Unstructured = -1;
static int hf_uavcan_primitive_array_Integer64 = -1;
static int hf_uavcan_primitive_array_Integer32 = -1;
static int hf_uavcan_primitive_array_Integer16 = -1;
static int hf_uavcan_primitive_array_Integer8 = -1;
static int hf_uavcan_primitive_array_Natural64 = -1;
static int hf_uavcan_primitive_array_Natural32 = -1;
static int hf_uavcan_primitive_array_Natural16 = -1;
static int hf_uavcan_primitive_array_Natural8 = -1;
static int hf_uavcan_primitive_array_Real64 = -1;
static int hf_uavcan_primitive_array_Real32 = -1;
static int hf_uavcan_primitive_array_Real16 = -1;
static int hf_uavcan_getinfo_path = -1;
static int hf_uavcan_getinfo_error = -1;
static int hf_uavcan_getinfo_size = -1;
static int hf_uavcan_getinfo_timestamp = -1;
static int hf_uavcan_getinfo_is_file_not_directory = -1;
static int hf_uavcan_getinfo_is_link = -1;
static int hf_uavcan_getinfo_is_readable = -1;
static int hf_uavcan_getinfo_is_writeable = -1;
static int hf_uavcan_directory_path = -1;
static int hf_uavcan_entry_base_name = -1;
static int hf_uavcan_modify_error = -1;
static int hf_uavcan_modify_source_path = -1;
static int hf_uavcan_modify_destination_path = -1;
static int hf_uavcan_modify_preserve_source = -1;
static int hf_uavcan_modify_overwrite_destination = -1;
static int hf_uavcan_read_offset = -1;
static int hf_uavcan_read_path = -1;
static int hf_uavcan_read_error = -1;
static int hf_uavcan_write_offset = -1;
static int hf_uavcan_write_path = -1;
static int hf_uavcan_write_error = -1;
static int hf_uavcan_entry_index = -1;
static int hf_uavcan_time_syncronizedtimestamp = -1;
static int hf_uavcan_diagnostic_severity = -1;
static gint ett_dsdl = -1;
const range_string uavcan_subject_id_vals[] = {
{ 0, 6143, "Unregulated identifier" },
{ 6144, 7167, "Non-standard fixed regulated identifier"},
{ 7168, 7168, "Synchronization.1.0" },
{ 7509, 7509, "Heartbeat.1.0" },
{ 7510, 7510, "List.0.1" },
{ 8165, 8165, "NodeIDAllocationData.2.0" },
{ 8166, 8166, "NodeIDAllocationData.1.0" },
{ 8184, 8184, "Record.1.X" },
{ 0, 0, NULL }
};
const range_string uavcan_service_id_vals[] = {
{ 0, 255, "Unregulated identifier" },
{ 256, 383, "Non-standard fixed regulated identifier"},
{ 384, 384, "Access.1.0" },
{ 385, 385, "List.1.0" },
{ 405, 405, "GetInfo.0.X" },
{ 406, 406, "List.0.X" },
{ 407, 407, "Modify.1.X" },
{ 408, 408, "Read.1.X" },
{ 409, 409, "Write.1.X" },
{ 430, 430, "GetInfo.1.0" },
{ 434, 434, "GetTransportStatistics.1.0" },
{ 435, 435, "ExecuteCommand.1.X" },
{ 0, 0, NULL }
};
static const address anonymous_address = {
AT_NONE,
9,
"Anonymous",
NULL
};
static const value_string uavcan_file_error_vals[] = {
{ 0, "Ok" },
{ 2, "Not found" },
{ 5, "I/O error" },
{ 13, "Access denied" },
{ 21, "Is directory" },
{ 22, "Invalid value" },
{ 27, "File too large" },
{ 28, "Out of space" },
{ 38, "Not supported" },
{ 65535, "Unknown" },
{ 0, NULL }
};
static const value_string uavcan_diagnostic_severity_vals[] = {
{ 0, "Trace" },
{ 1, "Debug" },
{ 2, "Info" },
{ 3, "Notice" },
{ 4, "Warning" },
{ 5, "Error" },
{ 6, "Critical" },
{ 7, "Alert" },
{ 0, NULL }
};
static const value_string uavcan_heartbeat_mode_vals[] = {
{ 0, "Operational" },
{ 1, "Initialization" },
{ 2, "Maintenance" },
{ 3, "Software update" },
{ 0, NULL }
};
static const value_string uavcan_heartbeat_health_vals[] = {
{ 0, "Nominal" },
{ 1, "Advisory" },
{ 2, "Caution" },
{ 3, "Warning" },
{ 0, NULL }
};
static const value_string uavcan_value_tag_vals[] = {
{ 0, "Empty" },
{ 1, "String" },
{ 2, "Unstructured" },
{ 3, "Bit array" },
{ 4, "Integer 64 Array" },
{ 5, "Integer 32 Array" },
{ 6, "Integer 16 Array" },
{ 7, "Integer 8 Array" },
{ 8, "Natural 64 Array" },
{ 9, "Natural 32 Array" },
{ 10, "Natural 16 Array" },
{ 11, "Natural 8 Array" },
{ 12, "Real 64 Array" },
{ 13, "Real 32 Array" },
{ 14, "Real 16 Array" },
{ 0, NULL }
};
static const value_string uavcan_nodeid_alloc_vals[] = {
{ 0, "request message" },
{ 1, "response message" },
{ 0, NULL }
};
static void
dissect_list_service_data(tvbuff_t *tvb, int tvb_offset, proto_tree *tree, gboolean is_request)
{
if (is_request == TRUE) {
proto_tree_add_item(tree, hf_list_index, tvb, tvb_offset, 2, ENC_LITTLE_ENDIAN);
} else {
/* FT_UINT_STRING counted string, with count being the first byte */
proto_tree_add_item(tree, hf_register_name,
tvb, tvb_offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
}
}
static void
dissect_access_service_data(tvbuff_t *tvb, int tvb_offset, proto_tree *tree, gboolean is_request)
{
guint32 tag;
gint offset;
offset = tvb_offset;
if (is_request == TRUE) {
gint len;
/* FT_UINT_STRING counted string, with count being the first byte */
proto_tree_add_item_ret_length(tree, hf_register_name,
tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN, &len);
offset += len;
} else {
proto_tree_add_item(tree, hf_uavcan_time_syncronizedtimestamp,
tvb, offset, 7, ENC_LITTLE_ENDIAN);
offset += 7;
proto_tree_add_item(tree, hf_register_access_mutable,
tvb, offset, 1, ENC_NA);
proto_tree_add_item(tree, hf_register_access_persistent,
tvb, offset, 1, ENC_NA);
offset += 1;
}
proto_tree_add_item_ret_uint(tree, hf_register_value_tag,
tvb, offset, 1, ENC_NA, &tag);
offset += 1;
if (tag == 1) { /* String */
proto_tree_add_item(tree, hf_register_value_size,
tvb, offset, 1, ENC_NA);
/* FT_UINT_STRING counted string, with count being the first byte */
proto_tree_add_item(tree, hf_register_name,
tvb, offset, 1, ENC_ASCII|ENC_BIG_ENDIAN);
} else if (tag == 2 || tag == 3) {
return; // Raw data do nothing
} else {
guint8 array_len = tvb_get_guint8(tvb, offset);
if (array_len == 0 || tag == 0) {
proto_tree_add_item(tree, hf_uavcan_primitive_Empty,
tvb, 0, 0, ENC_NA);
} else {
proto_tree_add_item(tree, hf_register_value_size,
tvb, offset, 1, ENC_NA);
offset += 1;
for (guint8 i = 0; i < array_len; i++) {
switch (tag) {
case 4: /*Integer64*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Integer64,
tvb, offset, 8, ENC_LITTLE_ENDIAN);
offset += 8;
break;
case 5: /*Integer32*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Integer32,
tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
break;
case 6: /*Integer16*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Integer16,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
break;
case 7: /*Integer8*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Integer8,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
break;
case 8: /*Natural64*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Natural64,
tvb, offset, 8, ENC_LITTLE_ENDIAN);
offset += 8;
break;
case 9: /*Natural32*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Natural32,
tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
break;
case 10: /*Natural16*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Natural16,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
break;
case 11: /*Natural8*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Natural8,
tvb, offset, 1, ENC_LITTLE_ENDIAN);
offset += 1;
break;
case 12: /*Real64*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Real64,
tvb, offset, 8, ENC_LITTLE_ENDIAN);
offset += 8;
break;
case 13: /*Real32*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Real32,
tvb, offset, 4, ENC_LITTLE_ENDIAN);
offset += 4;
break;
case 14: /*Real16*/
proto_tree_add_item(tree, hf_uavcan_primitive_array_Real16,
tvb, offset, 2, ENC_LITTLE_ENDIAN);
offset += 2;
break;
default:
proto_tree_add_item(tree, hf_uavcan_primitive_Empty,
tvb, 0, 0, ENC_NA);
}
}
}
}
}
static int
dissect_dsdl_message(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
guint32 id = GPOINTER_TO_INT(data);
proto_item_append_text(tree, " DSDL (%s)",
rval_to_str_const(id, uavcan_subject_id_vals, "Reserved"));
if (id == 7509) {
/* Dissect Heartbeat1.0 frame */
proto_tree_add_item(tree, hf_heartbeat_uptime, tvb, 0, 4, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_heartbeat_health, tvb, 4, 1, ENC_NA);
proto_tree_add_item(tree, hf_heartbeat_mode, tvb, 5, 1, ENC_NA);
proto_tree_add_item(tree, hf_heartbeat_status_code, tvb, 6, 1, ENC_NA);
return tvb_captured_length(tvb);
} else if (id == 8166) {
/* Dissect NodeIDAllocationData1.0 allocation request */
proto_tree_add_item(tree, hf_pnp_unique_id_hash, tvb, 0, 6, ENC_NA);
proto_tree_add_item(tree, hf_pnp_alloc, tvb, 6, 1, ENC_NA);
if (tvb_captured_length(tvb) > 8) {
proto_tree_add_item(tree, hf_node_id, tvb, 7, 2, ENC_LITTLE_ENDIAN);
}
return tvb_captured_length(tvb);
} else if (id == 8165) {
/* Dissect NodeIDAllocationData2.0 allocation request/response */
proto_tree_add_item(tree, hf_node_id, tvb, 0, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_pnp_unique_id, tvb, 2, 16, ENC_NA);
proto_tree_add_uint(tree, hf_pnp_alloc, tvb, 0, 0,
(cmp_address(&anonymous_address, (const address *) &pinfo->src) != 0));
return tvb_captured_length(tvb);
} else if (id == 8184) {
/* Dissect Synchronization.1.0 frame */
proto_tree_add_item(tree, hf_uavcan_time_syncronizedtimestamp, tvb, 0, 7,
ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_diagnostic_severity, tvb, 7, 1, ENC_NA);
proto_tree_add_item(tree, hf_uavcan_primitive_String, tvb, 8, 1,
ENC_ASCII|ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
}
return 0;
}
static int
dissect_dsdl_service_request(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
guint32 id = GPOINTER_TO_INT(data);
(void) pinfo;
proto_item_append_text(tree, " DSDL (%s)",
rval_to_str_const(id, uavcan_service_id_vals, "Reserved"));
if (id == 384) { /* Dissect Access.1.0 frame */
dissect_access_service_data(tvb, 0, tree, TRUE);
return tvb_captured_length(tvb);
} else if (id == 385) { /* Dissect List.1.0 frame */
dissect_list_service_data(tvb, 0, tree, TRUE);
return tvb_captured_length(tvb);
} else if (id == 405) { /* Dissect GetInfo.0.X frame */
proto_tree_add_item(tree, hf_uavcan_getinfo_path,
tvb, 0, 1, ENC_ASCII|ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
} else if (id == 406) { /* Dissect List.0.X frame */
proto_tree_add_item(tree, hf_uavcan_entry_index,
tvb, 0, 4, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_directory_path,
tvb, 8, 1, ENC_ASCII|ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
} else if (id == 407) { /* Dissect Modify.1.X frame */
proto_tree_add_item(tree, hf_uavcan_modify_preserve_source,
tvb, 0, 1, ENC_NA);
proto_tree_add_item(tree, hf_uavcan_modify_overwrite_destination,
tvb, 0, 1, ENC_NA);
gint len;
proto_tree_add_item_ret_length(tree, hf_uavcan_modify_source_path,
tvb, 4, 1, ENC_ASCII|ENC_BIG_ENDIAN, &len);
proto_tree_add_item(tree, hf_uavcan_modify_destination_path,
tvb, 4 + len, 1, ENC_ASCII|ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
} else if (id == 408) { /* Dissect Read.1.X frame */
proto_tree_add_item(tree, hf_uavcan_read_offset,
tvb, 0, 5, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_read_path,
tvb, 5, 1, ENC_ASCII|ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
} else if (id == 409) { /* Dissect Write.1.X frame */
proto_tree_add_item(tree, hf_uavcan_write_offset,
tvb, 0, 5, ENC_LITTLE_ENDIAN);
gint len;
proto_tree_add_item_ret_length(tree, hf_uavcan_write_path,
tvb, 5, 1, ENC_ASCII|ENC_BIG_ENDIAN, &len);
guint16 data_len = tvb_get_guint16(tvb, 5 + len, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_primitive_Unstructured,
tvb, 7 + len, data_len, ENC_NA);
return tvb_captured_length(tvb);
}
return 0;
}
static int
dissect_dsdl_service_response(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
{
guint32 id = GPOINTER_TO_INT(data);
(void) pinfo;
proto_item_append_text(tree, " DSDL (%s)",
rval_to_str_const(id, uavcan_service_id_vals, "Reserved"));
if (id == 384) { /* Dissect Access.1.0 frame */
dissect_access_service_data(tvb, 0, tree, FALSE);
return tvb_captured_length(tvb);
} else if (id == 385) { /* Dissect List.1.0 frame */
dissect_list_service_data(tvb, 0, tree, FALSE);
return tvb_captured_length(tvb);
} else if (id == 405) { /* Dissect GetInfo.0.X frame */
proto_tree_add_item(tree, hf_uavcan_getinfo_error,
tvb, 0, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_getinfo_size,
tvb, 2, 5, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_getinfo_timestamp,
tvb, 7, 5, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_getinfo_is_file_not_directory,
tvb, 13, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_getinfo_is_link,
tvb, 13, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_getinfo_is_readable,
tvb, 13, 1, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_getinfo_is_writeable,
tvb, 13, 1, ENC_LITTLE_ENDIAN);
return tvb_captured_length(tvb);
} else if (id == 406) { /* Dissect List.0.X frame */
/* FT_UINT_STRING counted string, with count being the first byte */
proto_tree_add_item(tree, hf_uavcan_entry_base_name,
tvb, 4, 1, ENC_ASCII|ENC_BIG_ENDIAN);
return tvb_captured_length(tvb);
} else if (id == 407) { /* Dissect Modify.1.X frame */
proto_tree_add_item(tree, hf_uavcan_modify_error,
tvb, 0, 2, ENC_LITTLE_ENDIAN);
return tvb_captured_length(tvb);
} else if (id == 408) { /* Dissect Read.1.X frame */
proto_tree_add_item(tree, hf_uavcan_read_error,
tvb, 0, 2, ENC_LITTLE_ENDIAN);
guint16 data_len = tvb_get_guint16(tvb, 2, ENC_LITTLE_ENDIAN);
proto_tree_add_item(tree, hf_uavcan_primitive_Unstructured,
tvb, 4, data_len, ENC_NA);
return tvb_captured_length(tvb);
} else if (id == 409) { /* Dissect Write.1.X frame */
proto_tree_add_item(tree, hf_uavcan_write_error,
tvb, 0, 2, ENC_LITTLE_ENDIAN);
return tvb_captured_length(tvb);
}
return 0;
}
void
proto_register_dsdl(void)
{
static hf_register_info hf[] = {
{&hf_node_id,
{"Node ID", "uavcan_dsdl.node.id",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_pnp_unique_id,
{"Unique ID", "uavcan_dsdl.pnp.unique_id",
FT_BYTES, BASE_NONE | BASE_ALLOW_ZERO, NULL, 0x0, NULL, HFILL}},
{&hf_pnp_unique_id_hash,
{"Unique ID hash", "uavcan_dsdl.pnp.unique_id_hash",
FT_BYTES, BASE_NONE | BASE_ALLOW_ZERO, NULL, 0x0, NULL, HFILL}},
{&hf_pnp_alloc,
{"allocation type", "uavcan_dsdl.pnp.allocation",
FT_UINT8, BASE_DEC, VALS(uavcan_nodeid_alloc_vals), 0x0, NULL, HFILL}},
// Heartbeat 1.0
{&hf_heartbeat_uptime,
{"Uptime", "uavcan_dsdl.Heartbeat.uptime",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_heartbeat_health,
{"Health", "uavcan_dsdl.Heartbeat.health",
FT_UINT8, BASE_DEC, VALS(uavcan_heartbeat_health_vals), 0x0, NULL, HFILL}},
{&hf_heartbeat_mode,
{"Mode", "uavcan_dsdl.Heartbeat.mode",
FT_UINT8, BASE_DEC, VALS(uavcan_heartbeat_mode_vals), 0x0, NULL, HFILL}},
{&hf_heartbeat_status_code,
{"Vendor specific status code",
"uavcan_dsdl.Heartbeat.vendor_specific_status_code",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_time_syncronizedtimestamp,
{"Timestamp (usec)", "uavcan_dsdl.time.SynchronizedTimestamp",
FT_UINT56, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_diagnostic_severity,
{"Severity", "uavcan_dsdl.diagnostic.severity",
FT_UINT8, BASE_DEC, VALS(uavcan_diagnostic_severity_vals), 0x0, NULL, HFILL}},
// List1.0 Request
{&hf_list_index,
{"Index", "uavcan_dsdl.register.List.index",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_register_name,
{"Name", "uavcan_dsdl.register.Name",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
// Access1.0 Value1.0
{&hf_register_access_mutable,
{"Mutable", "uavcan_dsdl.register.Access.mutable",
FT_UINT8, BASE_DEC, NULL, 0x1, NULL, HFILL}},
{&hf_register_access_persistent,
{"Persistent", "uavcan_dsdl.register.Access.persistent",
FT_UINT8, BASE_DEC, NULL, 0x2, NULL, HFILL}},
{&hf_register_value_tag,
{"Tag", "uavcan_dsdl.register.Value.tag",
FT_UINT8, BASE_DEC, VALS(uavcan_value_tag_vals), 0x0, NULL, HFILL}},
{&hf_register_value_size,
{"Array size", "uavcan_dsdl.primitive.array.size",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_Empty,
{"Empty", "uavcan_dsdl.primitive.Empty",
FT_NONE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_String,
{"String", "uavcan_dsdl.primitive.String",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_Unstructured,
{"Unstructured", "uavcan_dsdl.primitive.array.Unstructured",
FT_BYTES, BASE_NONE | BASE_ALLOW_ZERO, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Integer64,
{"Integer64", "uavcan_dsdl.primitive.array.Integer64",
FT_INT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Integer32,
{"Integer32", "uavcan_dsdl.primitive.array.Integer32",
FT_INT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Integer16,
{"Integer16", "uavcan_dsdl.primitive.array.Integer16",
FT_INT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Integer8,
{"Integer8", "uavcan_dsdl.primitive.array.Integer8",
FT_INT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Natural64,
{"Natural64", "uavcan_dsdl.primitive.array.Natural64",
FT_UINT64, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Natural32,
{"Natural32", "uavcan_dsdl.primitive.array.Natural32",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Natural16,
{"Natural16", "uavcan_dsdl.primitive.array.Natural16",
FT_UINT16, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Natural8,
{"Natural8", "uavcan_dsdl.primitive.array.Natural8",
FT_UINT8, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Real64,
{"Real64", "uavcan_dsdl.primitive.array.Real64",
FT_DOUBLE, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Real32,
{"Real32", "uavcan_dsdl.primitive.array.Real32",
FT_FLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_primitive_array_Real16,
{"Real16", "uavcan_dsdl.primitive.array.Real16",
FT_IEEE_11073_SFLOAT, BASE_NONE, NULL, 0x0, NULL, HFILL} /* TODO not sure check */
},
{&hf_uavcan_getinfo_path,
{"Path", "uavcan_dsdl.file.GetInfo.path",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_getinfo_error,
{"Error", "uavcan_dsdl.file.GetInfo.error",
FT_UINT16, BASE_DEC, VALS(uavcan_file_error_vals), 0x0, NULL, HFILL}},
{&hf_uavcan_getinfo_size,
{"Size", "uavcan_dsdl.file.GetInfo.size",
FT_UINT40, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_getinfo_timestamp,
{"Path", "uavcan_dsdl.file.GetInfo.timestamp",
FT_UINT40, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_getinfo_is_file_not_directory,
{"Is file not directory",
"uavcan_dsdl.file.GetInfo.is_file_not_directory",
FT_UINT8, BASE_DEC, NULL, 0x1, NULL, HFILL}},
{&hf_uavcan_getinfo_is_link,
{"Is link", "uavcan_dsdl.file.GetInfo.is_link",
FT_UINT8, BASE_DEC, NULL, 0x2, NULL, HFILL}},
{&hf_uavcan_getinfo_is_readable,
{"Is readable", "uavcan_dsdl.file.GetInfo.is_readable",
FT_UINT8, BASE_DEC, NULL, 0x4, NULL, HFILL}},
{&hf_uavcan_getinfo_is_writeable,
{"Is writeable", "uavcan_dsdl.file.GetInfo.is_writeable",
FT_UINT8, BASE_DEC, NULL, 0x8, NULL, HFILL}},
{&hf_uavcan_read_path,
{"Path", "uavcan_dsdl.file.Read.path",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_write_path,
{"Path", "uavcan_dsdl.file.Write.path",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_directory_path,
{"Directory path", "uavcan_dsdl.file.list.directory_path",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_entry_base_name,
{"Directory path", "uavcan_dsdl.file.list.entry_base_name",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_modify_source_path,
{"Source", "uavcan_dsdl.file.Modify.source",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_modify_destination_path,
{"Destination", "uavcan_dsdl.file.Modify.Destination",
FT_UINT_STRING, BASE_NONE, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_modify_preserve_source,
{"Preserve source", "uavcan_dsdl.Modify.preserve_source",
FT_UINT8, BASE_DEC, NULL, 0x1, NULL, HFILL}},
{&hf_uavcan_modify_overwrite_destination,
{"Overwrite destination", "uavcan_dsdl.Modify.overwrite_destination",
FT_UINT8, BASE_DEC, NULL, 0x2, NULL, HFILL}},
{&hf_uavcan_modify_error,
{"Error", "uavcan_dsdl.Modify.error",
FT_UINT16, BASE_DEC, VALS(uavcan_file_error_vals), 0x0, NULL, HFILL}},
{&hf_uavcan_read_offset,
{"Offset", "uavcan_dsdl.Read.offset",
FT_UINT40, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_read_error,
{"Error", "uavcan_dsdl.Read.error",
FT_UINT16, BASE_DEC, VALS(uavcan_file_error_vals), 0x0, NULL, HFILL}},
{&hf_uavcan_write_offset,
{"Offset", "uavcan_dsdl.Write.offset",
FT_UINT40, BASE_DEC, NULL, 0x0, NULL, HFILL}},
{&hf_uavcan_write_error,
{"Error", "uavcan_dsdl.Write.error",
FT_UINT16, BASE_DEC, VALS(uavcan_file_error_vals), 0x0, NULL, HFILL}},
{&hf_uavcan_entry_index,
{"Entry index", "uavcan_dsdl.file.list.entry_index",
FT_UINT32, BASE_DEC, NULL, 0x0, NULL, HFILL}},
};
static gint *ett[] = {
&ett_dsdl,
};
proto_dsdl = proto_register_protocol("UAVCAN DSDL", "DSDL", "uavcan_dsdl");
proto_register_field_array(proto_dsdl, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
register_dissector("uavcan_dsdl.message", dissect_dsdl_message, proto_dsdl);
register_dissector("uavcan_dsdl.request", dissect_dsdl_service_request, proto_dsdl);
register_dissector("uavcan_dsdl.response", dissect_dsdl_service_response, proto_dsdl);
}
void
proto_reg_handoff_dsdl(void)
{
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/