static void dissect_RTPS_DATA(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags,
                guint encoding, int octets_to_next_header, proto_tree *tree,
                guint16 vendor_id, gboolean is_session, endpoint_guid *guid) {
  /*
   *
   * 0...2...........7...............15.............23...............31
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * | RTPS_DATA     |X|X|X|X|K|D|Q|E|      octetsToNextHeader       |
   * +---------------+---------------+---------------+---------------+
   * | Flags extraFlags              |      octetsToInlineQos        |
   * +---------------+---------------+---------------+---------------+
   * | EntityId readerEntityId                                       |
   * +---------------+---------------+---------------+---------------+
   * | EntityId writerEntityId                                       |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * + SequenceNumber writerSeqNum                                   +
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * ~ ParameterList inlineQos [only if Q==1]                        ~
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * ~ SerializedData serializedData [only if D==1 || K==1]          ~
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   *
   * 0...2...........7...............15.............23...............31
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |RTPS_DATA_SESSI|X|X|X|X|K|D|Q|E|      octetsToNextHeader       |
   * +---------------+---------------+---------------+---------------+
   * | Flags extraFlags              |      octetsToInlineQos        |
   * +---------------+---------------+---------------+---------------+
   * | EntityId readerEntityId                                       |
   * +---------------+---------------+---------------+---------------+
   * | EntityId writerEntityId                                       |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * + SequenceNumber writerSessionSeqNum                            +
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * + SequenceNumber writerVirtualSeqNum                            +
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * ~ ParameterList inlineQos [only if Q==1]                        ~
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * ~ SerializedData serializedData [only if D==1 || K==1]          ~
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   */
  int min_len;
  gint old_offset = offset;
  guint32 wid;                  /* Writer EntityID */
  guint32 status_info = 0xffffffff;
  gboolean from_builtin_writer;
  proto_item *octet_item;
  coherent_set_entity_info coherent_set_entity_info_object;

  proto_tree_add_bitmask_value(tree, tvb, offset + 1, hf_rtps_sm_flags, ett_rtps_flags, RTPS_DATA_FLAGS, flags);

  octet_item = proto_tree_add_item(tree, hf_rtps_sm_octets_to_next_header, tvb,
                        offset + 2, 2, encoding);

  /* Calculates the minimum length for this submessage */
  min_len = 20;
  if (is_session) {
    min_len += 8;
  }
  if ((flags & FLAG_RTPS_DATA_Q) != 0) min_len += 4;
  if ((flags & FLAG_RTPS_DATA_D) != 0) min_len += 4;
  if ((flags & FLAG_RTPS_DATA_K) != 0) min_len += 4;

  if (octets_to_next_header < min_len) {
    expert_add_info_format(pinfo, octet_item, &ei_rtps_sm_octets_to_next_header_error, "(Error: should be >= %u)", min_len);
    return;
  }

  offset += 4;

  /* extraFlags */
  proto_tree_add_item(tree, hf_rtps_extra_flags, tvb, offset, 2, ENC_BIG_ENDIAN);
  offset += 2;

  /* octetsToInlineQos */
  proto_tree_add_item(tree, hf_rtps_octets_to_inline_qos, tvb, offset, 2, encoding);
  offset += 2;

  /* readerEntityId */
  rtps_util_add_entity_id(tree, tvb, offset, hf_rtps_sm_rdentity_id, hf_rtps_sm_rdentity_id_key,
                        hf_rtps_sm_rdentity_id_kind, ett_rtps_rdentity, "readerEntityId", NULL);
  offset += 4;

  /* writerEntityId */
  rtps_util_add_entity_id(tree, tvb, offset, hf_rtps_sm_wrentity_id, hf_rtps_sm_wrentity_id_key,
                        hf_rtps_sm_wrentity_id_kind, ett_rtps_wrentity, "writerEntityId", &wid);
  offset += 4;
  guid->entity_id = wid;
  guid->fields_present |= GUID_HAS_ENTITY_ID;
  rtps_util_topic_info_add_tree(tree, tvb, offset, guid);

  /* Sequence number */
  if (is_session) {
    rtps_util_add_seq_number(tree, tvb, offset, encoding, "writerSessionSeqNumber");
    offset += 8;

    rtps_util_add_seq_number(tree, tvb, offset, encoding, "writerVirtualSeqNumber");
    offset += 8;
  } else {
    coherent_set_entity_info_object.writer_seq_number = rtps_util_add_seq_number(tree, tvb, offset,
      encoding, "writerSeqNumber");
    coherent_set_entity_info_object.guid = *guid;
    offset += 8;
  }

  /* InlineQos */
  if ((flags & FLAG_RTPS_DATA_Q) != 0) {
    gboolean is_inline_qos = TRUE;
    offset = dissect_parameter_sequence(tree, pinfo, tvb, offset, encoding,
                        octets_to_next_header - (offset - old_offset) + 4,
                        "inlineQos", 0x0200, &status_info, vendor_id, is_inline_qos, &coherent_set_entity_info_object);
  }

  /* SerializedData */
  if (((flags & FLAG_RTPS_DATA_D) != 0) || ((flags & FLAG_RTPS_DATA_K) != 0)) {
    if (wid == ENTITYID_P2P_BUILTIN_PARTICIPANT_MESSAGE_WRITER) {
      /* Dissect the serialized data as ParticipantMessageData:
       *  struct ParticipantMessageData {
       *    KeyHashPrefix_t participantGuidPrefix;
       *    KeyHashSuffix_t kind;
       *    sequence<octet> data;
       * }
       */
      proto_tree *rtps_pm_tree;
      proto_tree *guid_tree;
      guint32 kind;
      guint32 encapsulation_id, encapsulation_len;
      proto_item *ti;
      rtps_pm_tree = proto_tree_add_subtree(tree, tvb, offset,
                        octets_to_next_header - (offset - old_offset) + 4,
                        ett_rtps_part_message_data, &ti, "ParticipantMessageData");

      /* Encapsulation ID */
      proto_tree_add_item_ret_uint(rtps_pm_tree, hf_rtps_param_serialize_encap_kind, tvb, offset, 2, ENC_BIG_ENDIAN, &encapsulation_id);
      offset += 2;

      encoding = (encapsulation_id == ENCAPSULATION_CDR_LE ||
          encapsulation_id == ENCAPSULATION_PL_CDR_LE ||
          encapsulation_id == ENCAPSULATION_CDR2_LE ||
          encapsulation_id == ENCAPSULATION_D_CDR2_LE ||
          encapsulation_id == ENCAPSULATION_PL_CDR2_LE)
        ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;

      /* Encapsulation length (or option) */
      proto_tree_add_item_ret_uint(rtps_pm_tree, hf_rtps_param_serialize_encap_len, tvb, offset, 2, ENC_BIG_ENDIAN, &encapsulation_len);
      offset += 2;

      guid_tree = proto_item_add_subtree(ti, ett_rtps_part_message_data);

      rtps_util_add_guid_prefix_v2(guid_tree, tvb, offset, hf_rtps_sm_guid_prefix, hf_rtps_sm_host_id,
                        hf_rtps_sm_app_id, hf_rtps_sm_instance_id, 0);
      offset += 12;

      /* Kind */
      proto_tree_add_item_ret_uint(guid_tree, hf_rtps_encapsulation_kind, tvb, offset, 4, ENC_BIG_ENDIAN, &kind);
      offset += 4;

      rtps_util_add_seq_octets(rtps_pm_tree, pinfo, tvb, offset, encoding,
                               octets_to_next_header - (offset - old_offset) + 4, hf_rtps_data_serialize_data);

    } else if (wid == ENTITYID_P2P_BUILTIN_PARTICIPANT_STATELESS_WRITER) {
      /* PGM stands for Participant Generic Message */
      proto_tree * rtps_pgm_tree, * guid_tree, * message_identity_tree;
      proto_item *ti;
      guint32 encapsulation_id, encapsulation_opt;
      gint32 alignment_zero;
      guint64 sequence_number;

      ti = proto_tree_add_boolean_format(tree, hf_rtps_pgm, tvb, offset,
              octets_to_next_header - (offset - old_offset) + 4, TRUE, "Participant Generic Message");
      rtps_pgm_tree = proto_item_add_subtree(ti, ett_rtps_pgm_data);

      proto_tree_add_item_ret_uint(rtps_pgm_tree, hf_rtps_param_serialize_encap_kind,
              tvb, offset, 2, ENC_BIG_ENDIAN, &encapsulation_id);
      encoding = (encapsulation_id == ENCAPSULATION_CDR_LE ||
          encapsulation_id == ENCAPSULATION_PL_CDR_LE ||
          encapsulation_id == ENCAPSULATION_CDR2_LE ||
          encapsulation_id == ENCAPSULATION_D_CDR2_LE ||
          encapsulation_id == ENCAPSULATION_PL_CDR2_LE) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;

      offset += 2;
      proto_tree_add_item_ret_uint(rtps_pgm_tree, hf_rtps_param_serialize_encap_len,
              tvb, offset, 2, ENC_BIG_ENDIAN, &encapsulation_opt);
      offset += 2;
      alignment_zero = offset;
        /* Message Identity */
      message_identity_tree = proto_tree_add_subtree(rtps_pgm_tree, tvb, offset,
                          24 , ett_rtps_message_identity, &ti, "Message Identity");

      guid_tree = proto_item_add_subtree(ti, ett_rtps_message_identity);
      proto_item_append_text(guid_tree, " (");
      rtps_util_add_generic_guid_v2(guid_tree, tvb, offset,
              hf_rtps_message_identity_source_guid, hf_rtps_param_host_id, hf_rtps_param_app_id,
              hf_rtps_param_instance_id, hf_rtps_param_entity, hf_rtps_param_entity_key,
              hf_rtps_param_hf_entity_kind, guid_tree);
      offset += 16;

      proto_tree_add_item(message_identity_tree, hf_rtps_sm_seq_number, tvb, offset, 8, encoding);

      /* This snippet shows the sequence number in the parent tree */
      sequence_number = tvb_get_guint64(tvb, offset, encoding);
      proto_item_append_text(guid_tree, ", sn: %" G_GINT64_MODIFIER "u)",
              sequence_number);
      offset += 8;

        /* Related Message Identity */
      message_identity_tree = proto_tree_add_subtree(rtps_pgm_tree, tvb, offset,
                          24 , ett_rtps_related_message_identity, &ti, "Related Message Identity");

      guid_tree = proto_item_add_subtree(ti, ett_rtps_related_message_identity);
      proto_item_append_text(guid_tree, " (");
      rtps_util_add_generic_guid_v2(guid_tree, tvb, offset,
              hf_rtps_message_identity_source_guid, hf_rtps_param_host_id, hf_rtps_param_app_id,
              hf_rtps_param_instance_id, hf_rtps_param_entity, hf_rtps_param_entity_key,
              hf_rtps_param_hf_entity_kind, guid_tree);
      offset += 16;

      proto_tree_add_item(message_identity_tree, hf_rtps_sm_seq_number, tvb,
                            offset, 8, encoding);

      /* This snippet shows the sequence number in the parent tree */
      sequence_number = tvb_get_guint64(tvb, offset, encoding);
      proto_item_append_text(guid_tree, ", sn: %" G_GINT64_MODIFIER "u)",
              sequence_number);
      offset += 8;

      guid_tree = proto_item_add_subtree(rtps_pgm_tree, ett_rtps_pgm_data);
      rtps_util_add_generic_guid_v2(guid_tree, tvb, offset,
              hf_rtps_pgm_dst_participant_guid, hf_rtps_param_host_id, hf_rtps_param_app_id,
              hf_rtps_param_instance_id, hf_rtps_param_entity, hf_rtps_param_entity_key,
              hf_rtps_param_hf_entity_kind, NULL);
      offset += 16;

      guid_tree = proto_item_add_subtree(rtps_pgm_tree, ett_rtps_pgm_data);
      rtps_util_add_generic_guid_v2(guid_tree, tvb, offset,
              hf_rtps_pgm_dst_endpoint_guid, hf_rtps_param_host_id, hf_rtps_param_app_id,
              hf_rtps_param_instance_id, hf_rtps_param_entity, hf_rtps_param_entity_key,
              hf_rtps_param_hf_entity_kind, NULL);
      offset += 16;

      guid_tree = proto_item_add_subtree(rtps_pgm_tree, ett_rtps_pgm_data);
      rtps_util_add_generic_guid_v2(guid_tree, tvb, offset,
              hf_rtps_pgm_src_endpoint_guid, hf_rtps_param_host_id, hf_rtps_param_app_id,
              hf_rtps_param_instance_id, hf_rtps_param_entity, hf_rtps_param_entity_key,
              hf_rtps_param_hf_entity_kind, NULL);
      offset += 16;

      offset = rtps_util_add_string(rtps_pgm_tree, tvb, offset, hf_rtps_pgm_message_class_id, encoding);

      rtps_util_add_data_holder_seq(rtps_pgm_tree, tvb, pinfo, offset,
              encoding, alignment_zero);
    } else if (wid == ENTITYID_RTI_BUILTIN_LOCATOR_PING_WRITER) {
      proto_tree * locator_ping_tree, *guid_tree;
      proto_item *ti;
      guint32 encapsulation_id, encapsulation_opt;

      locator_ping_tree = proto_tree_add_subtree(tree, tvb, offset,
                          octets_to_next_header - (offset - old_offset) + 4,
                          ett_rtps_locator_ping_tree, &ti, "Locator Ping Message");

      /* Encapsulation Id */
      proto_tree_add_item_ret_uint(locator_ping_tree, hf_rtps_encapsulation_id,
                tvb, offset, 2, ENC_BIG_ENDIAN, &encapsulation_id);
      offset += 2;
      encoding = (encapsulation_id == ENCAPSULATION_CDR_LE || encapsulation_id == ENCAPSULATION_PL_CDR_LE) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
      /* Encapsulation length (or option) */
      proto_tree_add_item_ret_uint(locator_ping_tree, hf_rtps_encapsulation_options,
                tvb, offset, 2, ENC_BIG_ENDIAN, &encapsulation_opt);
      offset += 2;

      guid_tree = proto_item_add_subtree(ti, ett_rtps_generic_guid);
      rtps_util_add_generic_guid_v2(guid_tree, tvb, offset,
                      hf_rtps_source_participant_guid, hf_rtps_param_host_id, hf_rtps_param_app_id,
                      hf_rtps_param_instance_id, hf_rtps_param_entity, hf_rtps_param_entity_key,
                      hf_rtps_param_hf_entity_kind, NULL);
      offset += 16;
      rtps_util_add_locator_t(locator_ping_tree, pinfo, tvb, offset, encoding,
              "Destination Locator");

    } else if (wid == ENTITYID_RTI_BUILTIN_SERVICE_REQUEST_WRITER) {
      /*
      struct ServiceRequest {
             long service_id;  //@key
             GUID_t instance_id; //@key
             sequence<octet> request_body;
      }; //@Extensibility EXTENSIBLE_EXTENSIBILITY
      */
      proto_tree * service_request_tree, * guid_tree;
      proto_item *ti;
      guint32 encapsulation_id, encapsulation_opt;
      gint32 service_id;

      ti = proto_tree_add_boolean_format(tree, hf_rtps_srm, tvb, offset,
              octets_to_next_header - (offset - old_offset) + 4,
              TRUE, "Service Request Message");
      service_request_tree = proto_item_add_subtree(ti, ett_rtps_service_request_tree);

      /* Encapsulation Id */
      proto_tree_add_item_ret_uint(service_request_tree, hf_rtps_encapsulation_id,
                tvb, offset, 2, ENC_BIG_ENDIAN, &encapsulation_id);
      offset += 2;
      encoding = (encapsulation_id == ENCAPSULATION_CDR_LE || encapsulation_id == ENCAPSULATION_PL_CDR_LE) ? ENC_LITTLE_ENDIAN : ENC_BIG_ENDIAN;
        /* Encapsulation length (or option) */
      proto_tree_add_item_ret_uint(service_request_tree, hf_rtps_encapsulation_options, tvb,
                offset, 2, ENC_BIG_ENDIAN, &encapsulation_opt);
      offset += 2;

      proto_tree_add_item_ret_int(service_request_tree, hf_rtps_srm_service_id, tvb,
                offset, 4, encoding, &service_id);
      offset += 4;
      guid_tree = proto_item_add_subtree(ti, ett_rtps_generic_guid);
      rtps_util_add_generic_guid_v2(guid_tree, tvb, offset,
                      hf_rtps_srm_instance_id, hf_rtps_param_host_id, hf_rtps_param_app_id,
                      hf_rtps_param_instance_id, hf_rtps_param_entity, hf_rtps_param_entity_key,
                      hf_rtps_param_hf_entity_kind, NULL);
      offset += 16;
      rtps_util_add_rti_service_request(service_request_tree, pinfo, tvb, offset,
                encoding, service_id);

    } else {
      const char *label;
      if (((flags & FLAG_RTPS_DATA_D) != 0) || ((flags & FLAG_RTPS_DATA_K) == 0)) {
        label = "serializedData";
      } else if (((flags & FLAG_RTPS_DATA_D) == 0) || ((flags & FLAG_RTPS_DATA_K) != 0)) {
        label = "serializedKey";
      } else {
        /* D==1 && K==1 */
        label = "<invalid or unknown data type>";
      }

      from_builtin_writer =
        (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE;
      /* At the end still dissect the rest of the bytes as raw data */
      dissect_serialized_data(tree, pinfo, tvb, offset,
                        octets_to_next_header - (offset - old_offset) + 4,
                        label, vendor_id, from_builtin_writer, guid, NOT_A_FRAGMENT);
    }
  }
  rtps_util_detect_coherent_set_end_empty_data_case(&coherent_set_entity_info_object);
  append_status_info(pinfo, wid, status_info);
}