summaryrefslogtreecommitdiff
path: root/epan/dissectors/packet-rtps.c
diff options
context:
space:
mode:
authorJuanjo Martin <juanjo@rti.com>2016-05-09 14:10:17 +0200
committerAnders Broman <a.broman58@gmail.com>2016-05-27 04:30:10 +0000
commita62c9631dac37da136040ea4af187150f26909b9 (patch)
tree65788236bed17f74098db10922c7eedc382747ac /epan/dissectors/packet-rtps.c
parenta8af8c84795fb9789b54aed4ec1ab2e81c2fbfe1 (diff)
downloadwireshark-a62c9631dac37da136040ea4af187150f26909b9.tar.gz
RTPS: Added support to parse the PID_TYPE_OBJECT
Bug:12415 Change-Id: I457bda34b089f95525192ed4cdce0d4fe8883fd7 Reviewed-on: https://code.wireshark.org/review/15305 Petri-Dish: Michael Mann <mmann78@netscape.net> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-rtps.c')
-rw-r--r--epan/dissectors/packet-rtps.c641
1 files changed, 639 insertions, 2 deletions
diff --git a/epan/dissectors/packet-rtps.c b/epan/dissectors/packet-rtps.c
index 7cb76b1cd8..dcfa312099 100644
--- a/epan/dissectors/packet-rtps.c
+++ b/epan/dissectors/packet-rtps.c
@@ -294,6 +294,23 @@ static int hf_rtps_heartbeat_count = -1;
static int hf_rtps_encapsulation_options = -1;
static int hf_rtps_serialized_key = -1;
static int hf_rtps_serialized_data = -1;
+static int hf_rtps_type_object_type_id_disc = -1;
+static int hf_rtps_type_object_type_id = -1;
+static int hf_rtps_type_object_primitive_type_id = -1;
+static int hf_rtps_type_object_base_type = -1;
+static int hf_rtps_type_object_base_primitive_type_id = -1;
+static int hf_rtps_type_object_element_raw = -1;
+static int hf_rtps_type_object_type_property_name = -1;
+static int hf_rtps_type_object_flags = -1;
+static int hf_rtps_type_object_member_id = -1;
+static int hf_rtps_type_object_annotation_value_d = -1;
+static int hf_rtps_type_object_annotation_value_16 = -1;
+static int hf_rtps_type_object_bound = -1;
+static int hf_rtps_type_object_enum_constant_name = -1;
+static int hf_rtps_type_object_enum_constant_value = -1;
+static int hf_rtps_type_object_element_shared = -1;
+static int hf_rtps_type_object_name = -1;
+static int hf_rtps_type_object_element_module_name = -1;
/* Flag bits */
static int hf_rtps_flag_reserved80 = -1;
@@ -354,7 +371,13 @@ static int hf_rtps_flag_participant_state_announcer = -1;
static int hf_rtps_flag_participant_state_detector = -1;
static int hf_rtps_flag_participant_message_datawriter = -1;
static int hf_rtps_flag_participant_message_datareader = -1;
-
+static int hf_rtps_flag_typeflag_final = -1;
+static int hf_rtps_flag_typeflag_mutable = -1;
+static int hf_rtps_flag_typeflag_nested = -1;
+static int hf_rtps_flag_memberflag_key = -1;
+static int hf_rtps_flag_memberflag_optional = -1;
+static int hf_rtps_flag_memberflag_shareable = -1;
+static int hf_rtps_flag_memberflag_union_default = -1;
static int hf_rtps_sm_rti_crc_number = -1;
static int hf_rtps_sm_rti_crc_result = -1;
@@ -403,6 +426,12 @@ static gint ett_rtps_product_version = -1;
static gint ett_rtps_property_list = -1;
static gint ett_rtps_property = -1;
static gint ett_rtps_topic_info = -1;
+static gint ett_rtps_type_object = -1;
+static gint ett_rtps_type_library = -1;
+static gint ett_rtps_type_element = -1;
+static gint ett_rtps_type_annotation_usage_list = -1;
+static gint ett_rtps_type_enum_constant = -1;
+static gint ett_rtps_type_bound_list = -1;
static expert_field ei_rtps_sm_octets_to_next_header_error = EI_INIT;
static expert_field ei_rtps_port_invalid = EI_INIT;
@@ -898,6 +927,48 @@ static const value_string acknowledgement_kind_vals[] = {
{ 0, NULL }
};
+static const value_string type_object_kind [] = {
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_NO_TYPE, "NO_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_BOOLEAN_TYPE, "BOOLEAN_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_BYTE_TYPE, "BYTE_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_INT_16_TYPE, "INT_16_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_UINT_16_TYPE, "UINT_16_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_INT_32_TYPE, "INT_32_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_UINT_32_TYPE, "UINT_32_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_INT_64_TYPE, "INT_64_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_UINT_64_TYPE, "UINT_64_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_FLOAT_32_TYPE, "FLOAT_32_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_FLOAT_64_TYPE, "FLOAT_64_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_FLOAT_128_TYPE, "FLOAT_128_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_CHAR_8_TYPE, "CHAR_8_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_CHAR_32_TYPE, "CHAR_32_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_ENUMERATION_TYPE, "ENUMERATION_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_BITSET_TYPE, "BITSET_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_ALIAS_TYPE, "ALIAS_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_ARRAY_TYPE, "ARRAY_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_SEQUENCE_TYPE, "SEQUENCE_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_STRING_TYPE, "STRING_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_MAP_TYPE, "MAP_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_UNION_TYPE, "UNION_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_STRUCTURE_TYPE, "STRUCTURE_TYPE" },
+ { RTI_CDR_TYPE_OBJECT_TYPE_KIND_ANNOTATION_TYPE, "ANNOTATION_TYPE" },
+ { 0, NULL }
+};
+
+static const int* TYPE_FLAG_FLAGS[] = {
+ &hf_rtps_flag_typeflag_nested, /* Bit 2 */
+ &hf_rtps_flag_typeflag_mutable, /* Bit 1 */
+ &hf_rtps_flag_typeflag_final, /* Bit 0 */
+ NULL
+};
+
+static const int* MEMBER_FLAGS[] = {
+ &hf_rtps_flag_memberflag_union_default, /* Bit 3 */
+ &hf_rtps_flag_memberflag_shareable, /* Bit 2 */
+ &hf_rtps_flag_memberflag_optional, /* Bit 1 */
+ &hf_rtps_flag_memberflag_key, /* Bit 0 */
+ NULL
+};
/* Vendor specific: RTI */
static const value_string ndds_transport_class_id_vals[] = {
{ NDDS_TRANSPORT_CLASSID_ANY, "ANY" },
@@ -2133,6 +2204,10 @@ gint rtps_util_add_seq_ulong(proto_tree *tree, tvbuff_t *tvb, gint offset, int h
#define LONG_ALIGN(x) (x = (x+3)&0xfffffffc)
#define SHORT_ALIGN(x) (x = (x+1)&0xfffffffe)
#define MAX_ARRAY_DIMENSION 10
+#define ALIGN_ME(offset, alignment) \
+ offset = (((offset) + ((alignment) - 1)) & ~((alignment) - 1))
+#define ALIGN_ZERO(offset, alignment, zero) (offset -= zero, ALIGN_ME(offset, alignment), offset += zero)
+
#define KEY_COMMENT (" //@key")
@@ -2747,7 +2822,451 @@ static gint rtps_util_add_typecode(proto_tree *tree, tvbuff_t *tvb, gint offset,
is_key ? KEY_COMMENT : "");
return retVal;
}
+static void rtps_util_dissect_parameter_header(tvbuff_t * tvb, gint * offset,
+ gboolean little_endian, guint32 * member_id, guint32 * member_length) {
+ *member_id = NEXT_guint16(tvb, *offset, little_endian);
+ *offset += 2;
+ *member_length = NEXT_guint16(tvb, *offset, little_endian);
+ *offset += 2;
+
+ if ((*member_id & PID_EXTENDED) == PID_EXTENDED) {
+ /* get extended member id and length */
+ *member_id = tvb_get_guint32(tvb, *offset, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
+ *offset += 4;
+ *member_length = tvb_get_guint32(tvb, *offset, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
+ *offset += 4;
+ }
+}
+
+static gint rtps_util_add_type_id(proto_tree *tree,
+ tvbuff_t * tvb, gint offset, gboolean little_endian,
+ gint zero, int hf_base, proto_item * append_info_item) {
+ proto_item * ti;
+ guint16 short_number;
+ guint64 longlong_number;
+ int hf_type;
+ short_number = NEXT_guint16(tvb, offset, little_endian);
+ ti = proto_tree_add_item(tree, hf_rtps_type_object_type_id_disc, tvb, offset,
+ 2, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ PROTO_ITEM_SET_HIDDEN(ti);
+
+ /* Here we choose the proper hf item to use */
+ if (hf_base != -1) {
+ if (short_number <= 13)
+ hf_type = hf_rtps_type_object_base_primitive_type_id;
+ else
+ hf_type = hf_rtps_type_object_base_type;
+ } else {
+ if (short_number <= 13)
+ hf_type = hf_rtps_type_object_primitive_type_id;
+ else
+ hf_type = hf_rtps_type_object_type_id;
+ }
+
+ offset += 2;
+ if (short_number <= 13) {
+ proto_tree_add_item(tree, hf_type, tvb, offset,
+ 2, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ if (append_info_item) {
+ proto_item_append_text(append_info_item, "(%s)",
+ val_to_str(short_number, type_object_kind, "(0x%016x)"));
+ }
+ offset += 2;
+ } else {
+ ALIGN_ZERO(offset, 8, zero);
+ longlong_number = tvb_get_guint64(tvb, offset,
+ little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ proto_tree_add_item(tree, hf_type, tvb, offset,
+ 8, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ if (append_info_item) {
+ proto_item_append_text(append_info_item, "(0x%016" G_GINT64_MODIFIER "x)", longlong_number);
+ }
+ offset += 8;
+ }
+
+ return offset;
+}
+
+static gint rtps_util_add_type_annotation_usage(proto_tree *tree,
+ tvbuff_t * tvb, gint offset, gboolean little_endian, gint zero) {
+ guint32 long_number, i;
+ guint16 short_number;
+ offset = rtps_util_add_type_id(tree, tvb, offset, little_endian, zero, -1, NULL);
+ long_number = NEXT_guint32(tvb, offset, little_endian);
+ offset += 4;
+ for (i = 0; i < long_number; i++) {
+ proto_tree_add_item(tree, hf_rtps_type_object_member_id, tvb, offset,
+ 4, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += 4;
+ short_number = NEXT_guint16(tvb, offset, little_endian);
+ proto_tree_add_item(tree, hf_rtps_type_object_annotation_value_d, tvb, offset,
+ 2, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += 2;
+ /* There may be more additions in the future */
+ switch (short_number) {
+ case 4: /* UINT_16 */
+ proto_tree_add_item(tree, hf_rtps_type_object_annotation_value_16, tvb, offset,
+ 2, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += 2;
+ break;
+ default:
+ break;
+ }
+
+ }
+ return offset;
+}
+static gint rtps_util_add_type_library_type(proto_tree *tree,
+ tvbuff_t * tvb, gint offset, gboolean little_endian) {
+ proto_tree * annotation_tree;
+ guint32 member_id = 0, member_length = 0, long_number, i;
+ gint offset_tmp;
+ guint16 short_number;
+ gchar * name = NULL;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset_tmp = offset;
+
+ /* dissect property */
+ short_number = NEXT_guint16(tvb, offset_tmp, little_endian);
+ proto_tree_add_bitmask_value(tree, tvb, offset_tmp, hf_rtps_type_object_flags,
+ ett_rtps_flags, TYPE_FLAG_FLAGS, short_number);
+ offset_tmp += 2;
+ offset_tmp = rtps_util_add_type_id(tree, tvb, offset_tmp, little_endian, offset, -1, tree);
+ rtps_util_add_string(tree, tvb, offset_tmp, hf_rtps_type_object_type_property_name,
+ little_endian);
+ long_number = NEXT_guint32(tvb, offset_tmp, little_endian);
+ name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset_tmp+4, long_number, ENC_ASCII);
+ proto_item_append_text(tree, " %s", name);
+ offset += member_length;
+
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset_tmp = offset;
+
+ /* dissect annotation_seq */
+ long_number = NEXT_guint32(tvb, offset_tmp, little_endian);
+ annotation_tree = proto_tree_add_subtree_format(tree, tvb, offset_tmp, member_length,
+ ett_rtps_type_annotation_usage_list, NULL, "Annotation Usage Member List (%d elements)",
+ long_number);
+ offset_tmp += 4;
+ for (i = 0; i < long_number ; i++) {
+ offset_tmp = rtps_util_add_type_annotation_usage(annotation_tree, tvb, offset_tmp,
+ little_endian, offset);
+ }
+ offset += member_length;
+
+ return offset;
+}
+static void rtps_util_add_type_element_enumeration(proto_tree *tree,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ proto_tree * enumerated_constant;
+ guint32 member_id = 0, member_length = 0;
+ guint32 long_number, i;
+ gint enum_size, offset_tmp = offset;
+ offset = rtps_util_add_type_library_type(tree, tvb, offset, little_endian);
+
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ /* dissect Bound */
+ proto_tree_add_item(tree, hf_rtps_type_object_bound, tvb, offset,
+ 4, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += member_length;
+
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ /* dissect constant seq */
+ offset_tmp = offset;
+ long_number = NEXT_guint32(tvb, offset_tmp, little_endian);
+ offset_tmp += 4;
+ for (i = 0; i < long_number; i++) {
+ gchar * name = NULL;
+ guint32 size, value;
+ enum_size = offset_tmp;
+ size = NEXT_guint32(tvb, offset_tmp + 4, little_endian);
+ name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset_tmp + 8, size, ENC_ASCII);
+ value = NEXT_guint32(tvb, offset_tmp, little_endian);
+ enumerated_constant = proto_tree_add_subtree_format(tree, tvb, offset_tmp, 0,
+ ett_rtps_type_enum_constant, NULL, "%s (%u)", name, value);
+ proto_tree_add_item(enumerated_constant, hf_rtps_type_object_enum_constant_value, tvb, offset_tmp,
+ 4, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset_tmp += 4;
+ offset_tmp = rtps_util_add_string(enumerated_constant, tvb, offset_tmp, hf_rtps_type_object_enum_constant_name,
+ little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ proto_item_set_len(enumerated_constant, offset_tmp - enum_size);
+ }
+ offset += member_length;
+}
+
+static void rtps_util_add_type_element_sequence(proto_tree *tree,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ guint32 member_id = 0, member_length = 0;
+ gint zero_alignment;
+ offset = rtps_util_add_type_library_type(tree, tvb, offset, little_endian);
+
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ zero_alignment = offset;
+ rtps_util_add_type_id(tree, tvb, offset, little_endian, zero_alignment,
+ -1 , NULL);
+ offset += member_length;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ proto_tree_add_item(tree, hf_rtps_type_object_element_shared, tvb, offset,
+ 1, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += member_length;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ /* dissect Bound */
+ proto_tree_add_item(tree, hf_rtps_type_object_bound, tvb, offset,
+ 4, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += member_length;
+}
+
+static void rtps_util_add_type_element_string(proto_tree *tree,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ guint32 member_id = 0, member_length = 0;
+ gint zero_alignment;
+ offset = rtps_util_add_type_library_type(tree, tvb, offset, little_endian);
+
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ zero_alignment = offset;
+ rtps_util_add_type_id(tree, tvb, offset, little_endian, zero_alignment,
+ -1 , NULL);
+ offset += member_length;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ proto_tree_add_item(tree, hf_rtps_type_object_element_shared, tvb, offset,
+ 1, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += member_length;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ /* dissect Bound */
+ proto_tree_add_item(tree, hf_rtps_type_object_bound, tvb, offset,
+ 4, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += member_length;
+}
+
+static void rtps_util_add_type_element_array(proto_tree *tree,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ proto_tree * bound_tree;
+ guint32 member_id = 0, member_length = 0;
+ guint32 long_number, i;
+ gint zero_alignment, offset_tmp;
+ offset = rtps_util_add_type_library_type(tree, tvb, offset, little_endian);
+
+ /* Dissect Collection Type */
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ zero_alignment = offset;
+ rtps_util_add_type_id(tree, tvb, offset, little_endian, zero_alignment,
+ -1 , NULL);
+ offset += member_length;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ proto_tree_add_item(tree, hf_rtps_type_object_element_shared, tvb, offset,
+ 1, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset += member_length;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+
+ /* dissect Bound sequence */
+
+ offset_tmp = offset;
+ long_number = NEXT_guint32(tvb, offset_tmp, little_endian);
+ bound_tree = proto_tree_add_subtree_format(tree, tvb, offset_tmp, member_length,
+ ett_rtps_type_bound_list, NULL, "Bounds (%d elements)",
+ long_number);
+ offset_tmp += 4;
+ for (i = 0; i < long_number ; i++) {
+ proto_tree_add_item(bound_tree, hf_rtps_type_object_bound, tvb, offset_tmp,
+ 4, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ offset_tmp += 4;
+ }
+}
+
+static void rtps_util_add_type_element_alias(proto_tree *tree,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ guint32 member_id = 0, member_length = 0;
+ offset = rtps_util_add_type_library_type(tree, tvb, offset, little_endian);
+
+ /* dissect base_type */
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset = rtps_util_add_type_id(tree, tvb, offset, little_endian, offset, hf_rtps_type_object_base_type, NULL);
+}
+static gint rtps_util_add_type_member(proto_tree *tree,
+ tvbuff_t * tvb, gint offset, gboolean little_endian) {
+ proto_tree * member_property, *annotation_tree;
+ guint32 member_id = 0, member_length = 0;
+ guint32 long_number, i;
+ guint16 short_number;
+ gint offset_tmp;
+ gchar * name = NULL;
+ member_property = proto_tree_add_subtree(tree, tvb, offset, 0,
+ ett_rtps_type_element, NULL, "Member Property");
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset_tmp = offset;
+ short_number = NEXT_guint16(tvb, offset_tmp, little_endian);
+ proto_tree_add_bitmask_value(tree, tvb, offset_tmp, hf_rtps_type_object_flags,
+ ett_rtps_flags, MEMBER_FLAGS, short_number);
+ offset_tmp += 2;
+ ALIGN_ZERO(offset_tmp, 4, offset);
+ proto_tree_add_item(member_property, hf_rtps_type_object_member_id, tvb, offset_tmp,
+ 4, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ member_id = NEXT_guint32(tvb, offset_tmp, little_endian);
+ offset_tmp += 4;
+ offset_tmp = rtps_util_add_type_id(member_property, tvb, offset_tmp, little_endian,
+ offset, -1, tree);
+ rtps_util_add_string(member_property, tvb, offset_tmp, hf_rtps_type_object_name,
+ little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ long_number = NEXT_guint32(tvb, offset_tmp, little_endian);
+ name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset_tmp+4, long_number, ENC_ASCII);
+ proto_item_append_text(tree, " %s (ID: %d)", name, member_id);
+ offset += member_length;
+
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset_tmp = offset;
+ long_number = NEXT_guint32(tvb, offset_tmp, little_endian);
+ annotation_tree = proto_tree_add_subtree_format(tree, tvb, offset_tmp, member_length,
+ ett_rtps_type_annotation_usage_list, NULL, "Annotation Usage Member List (%d elements)",
+ long_number);
+ offset_tmp += 4;
+ for (i = 0; i < long_number ; i++) {
+ offset_tmp = rtps_util_add_type_annotation_usage(annotation_tree, tvb, offset_tmp,
+ little_endian, offset);
+ }
+ offset += member_length;
+
+ offset += 4; /* PID_LIST_END */
+
+ return offset;
+}
+static void rtps_util_add_type_element_struct(proto_tree *tree,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ proto_tree * member;
+ guint32 member_id = 0, member_length = 0;
+ guint32 long_number, i;
+ gint offset_tmp, member_size;
+ offset = rtps_util_add_type_library_type(tree, tvb, offset, little_endian);
+
+ /* dissect base_type */
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset = rtps_util_add_type_id(tree, tvb, offset, little_endian, offset, hf_rtps_type_object_base_type, NULL);
+
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ /* dissect seq_member*/
+ offset_tmp = offset;
+ long_number = NEXT_guint32(tvb, offset_tmp, little_endian);
+ offset_tmp += 4;
+ for (i = 0; i < long_number; i++) {
+ member_size = offset_tmp;
+ member = proto_tree_add_subtree(tree, tvb, offset_tmp, 0,
+ ett_rtps_type_enum_constant, NULL, "");
+ offset_tmp = rtps_util_add_type_member(member, tvb, offset_tmp, little_endian);
+ proto_item_set_len(member, offset_tmp - member_size);
+ }
+ offset += member_length;
+}
+static void rtps_util_add_type_library(proto_tree *tree, packet_info * pinfo,
+ tvbuff_t * tvb, gint offset, gboolean little_endian, guint32 size);
+
+static void rtps_util_add_type_element_module(proto_tree *tree, packet_info * pinfo,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ guint32 long_number;
+ gchar * name = NULL;
+ long_number = tvb_get_guint32(tvb, offset, little_endian ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN);
+ name = tvb_get_string_enc(wmem_packet_scope(), tvb, offset+4, long_number, ENC_ASCII);
+ proto_item_set_text(tree, "module %s", name);
+ offset = rtps_util_add_string(tree, tvb, offset, hf_rtps_type_object_element_module_name, little_endian);
+ rtps_util_add_type_library(tree, pinfo, tvb, offset, little_endian, -1);
+}
+static gint rtps_util_add_type_library_element(proto_tree *tree, packet_info * pinfo,
+ tvbuff_t * tvb, gint offset , gboolean little_endian) {
+ proto_tree * element_tree;
+ guint32 long_number;
+ guint32 member_id = 0, member_length = 0;
+ gint initial_offset = offset;
+ long_number = NEXT_guint32(tvb, offset, little_endian);
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ long_number = NEXT_guint32(tvb, offset, little_endian);
+ element_tree = proto_tree_add_subtree(tree, tvb, offset, 0,
+ ett_rtps_type_element, NULL, "");
+ offset += member_length;
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ proto_item_set_len(element_tree, member_length + offset - initial_offset);
+ switch (long_number) {
+ case 14: /*ENUMERATION */
+ rtps_util_add_type_element_enumeration(element_tree, tvb, offset, little_endian);
+ break;
+ case 16: /* ALIAS */
+ rtps_util_add_type_element_alias(element_tree, tvb, offset, little_endian);
+ break;
+ case 17: /* ARRAY */
+ rtps_util_add_type_element_array(element_tree, tvb, offset, little_endian);
+ break;
+ case 18: /* SEQUENCE */
+ rtps_util_add_type_element_sequence(element_tree, tvb, offset, little_endian);
+ break;
+ case 19: /* STRING : COLLECTION */
+ rtps_util_add_type_element_string(element_tree, tvb, offset, little_endian);
+ break;
+ case 22: /* STRUCT */
+ rtps_util_add_type_element_struct(element_tree, tvb, offset, little_endian);
+ break;
+ case 24:
+ rtps_util_add_type_element_module(element_tree, pinfo, tvb, offset, little_endian);
+ break;
+ default:
+ proto_tree_add_item(element_tree, hf_rtps_type_object_element_raw, tvb, offset,
+ member_length, little_endian ? ENC_LITTLE_ENDIAN: ENC_BIG_ENDIAN);
+ break;
+ }
+ offset += member_length;
+ LONG_ALIGN(offset);
+ long_number = NEXT_guint32(tvb, offset, little_endian);
+ if ((long_number & PID_LIST_END) != PID_LIST_END) {
+ expert_add_info_format(pinfo, element_tree, &ei_rtps_parameter_value_invalid,
+ "Now it should be PID_LIST_END and it is not"); \
+ }
+ offset += 4;
+ proto_item_set_len(element_tree, offset - initial_offset);
+ return offset;
+}
+static void rtps_util_add_type_library(proto_tree *tree, packet_info * pinfo,
+ tvbuff_t * tvb, gint offset, gboolean little_endian, guint32 size) {
+ proto_tree * library_tree;
+ guint32 long_number, i;
+ long_number = NEXT_guint32(tvb, offset, little_endian);
+ library_tree = proto_tree_add_subtree_format(tree, tvb, offset, size,
+ ett_rtps_type_library, NULL, "Type Library (%d elements)", long_number);
+ offset += 4;
+ for (i = 0; i < long_number; i++) {
+ offset = rtps_util_add_type_library_element(library_tree, pinfo, tvb,
+ offset, little_endian);
+ }
+}
+static void rtps_util_add_typeobject(proto_tree *tree, packet_info * pinfo,
+ tvbuff_t * tvb, gint offset, gboolean little_endian, guint32 size) {
+ proto_tree * typeobject_tree;
+ gint offset_tmp = 0;
+ guint32 member_id = 0, member_length = 0;
+ guint32 long_number;
+ typeobject_tree = proto_tree_add_subtree(tree, tvb, offset, size,
+ ett_rtps_type_object, NULL, "Type Object");
+ /* --- This is the standard parameterized serialization --- */
+ /* TypeLibrary */
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset_tmp = offset;
+ /* Dissect the member */
+ rtps_util_add_type_library(typeobject_tree, pinfo, tvb, offset_tmp, little_endian, member_length);
+ offset += member_length;
+ /* End TypeLibrary */
+
+ /* _TypeId */
+ rtps_util_dissect_parameter_header(tvb, &offset, little_endian, &member_id, &member_length);
+ offset_tmp = offset;
+ /* Dissect the member. In this case, the typeid is an union with a short
+ * as a discriminator*/
+ rtps_util_add_type_id(typeobject_tree, tvb, offset_tmp, little_endian, offset, -1, NULL);
+ offset = offset + member_length;
+ /* End _TypeId */
+
+ long_number = NEXT_guint32(tvb, offset, little_endian);
+ if ((long_number & PID_LIST_END) != PID_LIST_END) {
+ expert_add_info_format(pinfo, typeobject_tree, &ei_rtps_parameter_value_invalid,
+ "This should be PID_LIST_END and it is not"); \
+ }
+
+}
/* ------------------------------------------------------------------------- */
/* Insert in the protocol tree the next bytes interpreted as Sequence of
* Octects.
@@ -3329,7 +3848,8 @@ static gboolean dissect_parameter_sequence_rti(proto_tree *rtps_parameter_tree,
}
case PID_TYPE_OBJECT: {
- /* Typeobject dissection may be added in the future */
+ rtps_util_add_typeobject(rtps_parameter_tree, pinfo, tvb,
+ offset, little_endian, param_length);
break;
}
@@ -9927,6 +10447,117 @@ void proto_register_rtps(void) {
"Participant Message DataReader", "rtps.flag.participant_message_datareader",
FT_BOOLEAN, 32, TFS(&tfs_set_notset), 0x00000800, NULL, HFILL }
},
+ { &hf_rtps_type_object_type_id_disc,
+ { "TypeId (_d)", "rtps.type_object.type_id.discr",
+ FT_INT16, BASE_DEC, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_primitive_type_id,
+ { "TypeId", "rtps.type_object.type_id",
+ FT_UINT16, BASE_HEX, VALS(type_object_kind), 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_base_primitive_type_id,
+ { "Base Id", "rtps.type_object.type_id",
+ FT_UINT16, BASE_HEX, VALS(type_object_kind), 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_type_id,
+ { "TypeId", "rtps.type_object.type_id",
+ FT_UINT64, BASE_HEX, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_base_type,
+ { "Base Type", "rtps.type_object.type_id",
+ FT_UINT64, BASE_HEX, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_element_raw, {
+ "Type Element Content", "rtps.type_object.element",
+ FT_BYTES, BASE_NONE, NULL, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_type_property_name,
+ { "Name", "rtps.type_object.property.name",
+ FT_STRING, BASE_NONE, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_member_id,
+ { "Member Id", "rtps.type_object.annotation.member_id",
+ FT_UINT32, BASE_DEC, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_name,
+ { "Name", "rtps.type_object.member.name",
+ FT_STRING, BASE_NONE, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_annotation_value_d,
+ { "Annotation Member (_d)", "rtps.type_object.annotation.value_d",
+ FT_UINT16, BASE_DEC, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_annotation_value_16,
+ { "16 bits type", "rtps.type_object.annotation.value",
+ FT_UINT16, BASE_DEC, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_bound,
+ { "Bound", "rtps.type_object.bound",
+ FT_UINT32, BASE_DEC, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_enum_constant_name,
+ { "Enum name", "rtps.type_object.enum.name",
+ FT_STRING, BASE_NONE, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_enum_constant_value,
+ { "Enum value", "rtps.type_object.enum.value",
+ FT_INT32, BASE_DEC, 0x0, 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_type_object_element_shared,
+ { "Element shared", "rtps.type_object.shared",
+ FT_BOOLEAN, 8, TFS(&tfs_true_false), 0,
+ NULL, HFILL }
+ },
+ { &hf_rtps_flag_typeflag_final, {
+ "FINAL", "rtps.flag.typeflags.final",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001, NULL, HFILL }
+ },
+ { &hf_rtps_flag_typeflag_mutable, {
+ "MUTABLE", "rtps.flag.typeflags.mutable",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002, NULL, HFILL }
+ },
+ { &hf_rtps_flag_typeflag_nested, {
+ "NESTED", "rtps.flag.typeflags.nested",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0004, NULL, HFILL }
+ },
+ { &hf_rtps_type_object_flags, {
+ "Flags", "rtps.flag.typeflags",
+ FT_UINT16, BASE_HEX, NULL, 0, NULL, HFILL }
+ },
+ { &hf_rtps_flag_memberflag_key, {
+ "Key", "rtps.flag.typeflags.key",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0001, NULL, HFILL }
+ },
+ { &hf_rtps_flag_memberflag_optional, {
+ "Optional", "rtps.flag.typeflags.key",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0002, NULL, HFILL }
+ },
+ { &hf_rtps_flag_memberflag_shareable, {
+ "Shareable", "rtps.flag.typeflags.key",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0004, NULL, HFILL }
+ },
+ { &hf_rtps_flag_memberflag_union_default, {
+ "Union default", "rtps.flag.typeflags.key",
+ FT_BOOLEAN, 16, TFS(&tfs_set_notset), 0x0008, NULL, HFILL }
+ },
+ { &hf_rtps_type_object_element_module_name,
+ { "Module name", "rtps.type_object.module_name",
+ FT_STRINGZ, BASE_NONE, NULL, 0, NULL, HFILL }
+ },
};
static gint *ett[] = {
@@ -9974,6 +10605,12 @@ void proto_register_rtps(void) {
&ett_rtps_property_list,
&ett_rtps_property,
&ett_rtps_topic_info,
+ &ett_rtps_type_object,
+ &ett_rtps_type_library,
+ &ett_rtps_type_element,
+ &ett_rtps_type_annotation_usage_list,
+ &ett_rtps_type_enum_constant,
+ &ett_rtps_type_bound_list,
};
static ei_register_info ei[] = {