static void dissect_RTPS_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags,
                const guint encoding, int octets_to_next_header, proto_tree *tree,
                guint16 vendor_id, endpoint_guid *guid) {
  /*
   *
   * 0...2...........7...............15.............23...............31
   * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
   * |RTPS_DATA_FRAG |X|X|X|X|X|K|Q|E|      octetsToNextHeader       |
   * +---------------+---------------+---------------+---------------+
   * | Flags extraFlags              |      octetsToInlineQos        |
   * +---------------+---------------+---------------+---------------+
   * | EntityId readerEntityId                                       |
   * +---------------+---------------+---------------+---------------+
   * | EntityId writerEntityId                                       |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * + SequenceNumber writerSeqNum                                   +
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   * | FragmentNumber fragmentStartingNum                            |
   * +---------------+---------------+---------------+---------------+
   * | ushort fragmentsInSubmessage  | ushort fragmentSize           |
   * +---------------+---------------+---------------+---------------+
   * | unsigned long sampleSize                                      |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * ~ ParameterList inlineQos [only if Q==1]                        ~
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   * |                                                               |
   * ~ SerializedData serializedData                                 ~
   * |                                                               |
   * +---------------+---------------+---------------+---------------+
   */
  int min_len;
  gint old_offset = offset;
  guint64 sample_seq_number = 0;
  guint32 frag_number = 0, frag_size = 0, sample_size = 0, num_frags = 0;
  guint32 wid;                  /* Writer EntityID */
  gboolean from_builtin_writer;
  guint32 status_info = 0xffffffff;
  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_FRAG_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 = 36;
  if ((flags & FLAG_RTPS_DATA_FRAG_Q) != 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 */
  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;

  /* Fragment number */
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_number, tvb, offset, 4, encoding, &frag_number);
  offset += 4;

  /* Fragments in submessage */
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_num_fragments, tvb, offset, 2, encoding, &num_frags);
  offset += 2;

  /* Fragment size */
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_size, tvb, offset, 2, encoding, &frag_size);
  offset += 2;

  /* sampleSize */
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_sample_size, tvb, offset, 4, encoding, &sample_size);
  offset += 4;

  /* InlineQos */
  if ((flags & FLAG_RTPS_DATA_FRAG_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 */
  {
    char label[20];
    g_snprintf(label, 9, "fragment");
    if ((flags & FLAG_RTPS_DATA_FRAG_K) != 0) {
        g_snprintf(label, 14, "serializedKey");
    }
    from_builtin_writer =
      (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE;

    guint32 frag_index_in_submessage = 0, this_frag_number = 0, this_frag_size = 0, fragment_offset = 0;
    gboolean more_fragments = FALSE;
    if (enable_rtps_reassembly) {
      tvbuff_t* new_tvb = NULL;
      fragment_head *frag_msg = NULL;
      while(frag_index_in_submessage < num_frags) {
        this_frag_number = frag_number + frag_index_in_submessage;
        more_fragments = (this_frag_number * frag_size < sample_size);
        this_frag_size = more_fragments ? frag_size : (sample_size - ((this_frag_number - 1) * frag_size));
        fragment_offset = this_frag_number == 1 ? 0 : (((this_frag_number - 1) * frag_size));
        pinfo->fragmented = TRUE;
        frag_msg = fragment_add_check(&rtps_reassembly_table,
            tvb, offset, pinfo,
            (guint32)sample_seq_number, /* ID for fragments belonging together */
            (void *)guid, /* make sure only fragments from the same writer are considered for reassembly */
            fragment_offset, /* fragment offset */
            this_frag_size, /* fragment length */
            more_fragments); /* More fragments? */

        new_tvb = process_reassembled_data(tvb, offset + (frag_index_in_submessage * frag_size), pinfo,
            "Reassembled sample", frag_msg, &rtps_frag_items,
            NULL, tree);

        if (frag_index_in_submessage == 0) {
          append_status_info(pinfo, wid, status_info);
          if (frag_msg) { /* Reassembled */
            col_append_fstr(pinfo->cinfo, COL_INFO, " [Reassembled]");
          } else { /* Not last packet of reassembled Short Message */
            col_append_fstr(pinfo->cinfo, COL_INFO," [RTPS fragment]");
          }
        }

        if (new_tvb) {
            g_snprintf(label, 19, "reassembled sample");
            dissect_serialized_data(tree, pinfo, new_tvb, 0,
                sample_size, label, vendor_id, from_builtin_writer, guid, NOT_A_FRAGMENT);
            break;
        } else {
            g_snprintf(label, 15, "fragment [%d]", frag_index_in_submessage);
            dissect_serialized_data(tree, pinfo, tvb, offset + (frag_index_in_submessage * frag_size),
                this_frag_size, label, vendor_id, from_builtin_writer, NULL, this_frag_number);
        }
        frag_index_in_submessage++;
      }
    } else {
      while (frag_index_in_submessage < num_frags) {
        this_frag_number = frag_number + frag_index_in_submessage;
        more_fragments = (this_frag_number * frag_size < sample_size);
        this_frag_size = more_fragments ? frag_size : (sample_size - ((this_frag_number - 1) * frag_size));
        fragment_offset = frag_index_in_submessage * frag_size;
        g_snprintf(label, 20, "fragment [%d]", frag_index_in_submessage);
        dissect_serialized_data(tree, pinfo, tvb, offset + fragment_offset,
            this_frag_size, label, vendor_id, from_builtin_writer, NULL, this_frag_number);
        frag_index_in_submessage++;
        }
      append_status_info(pinfo, wid, status_info);
    }
  }
  rtps_util_detect_coherent_set_end_empty_data_case(&coherent_set_entity_info_object);
}
static void dissect_RTPS_DATA_FRAG(tvbuff_t *tvb, packet_info *pinfo, gint offset, guint8 flags,
                const guint encoding, int octets_to_next_header, proto_tree *tree,
                guint16 vendor_id, endpoint_guid *guid) {
   
  int min_len;
  gint old_offset = offset;
  guint64 sample_seq_number = 0;
  guint32 frag_number = 0, frag_size = 0, sample_size = 0, num_frags = 0;
  guint32 wid;                   
  gboolean from_builtin_writer;
  guint32 status_info = 0xffffffff;
  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_FRAG_FLAGS, flags);

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

   
  min_len = 36;
  if ((flags & FLAG_RTPS_DATA_FRAG_Q) != 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;

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

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

   
  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;

   
  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);


   
  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;

   
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_number, tvb, offset, 4, encoding, &frag_number);
  offset += 4;

   
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_num_fragments, tvb, offset, 2, encoding, &num_frags);
  offset += 2;

   
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_size, tvb, offset, 2, encoding, &frag_size);
  offset += 2;

   
  proto_tree_add_item_ret_uint(tree, hf_rtps_data_frag_sample_size, tvb, offset, 4, encoding, &sample_size);
  offset += 4;

   
  if ((flags & FLAG_RTPS_DATA_FRAG_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);
  }

   
  {
    char label[20];
    g_snprintf(label, 9, "fragment");
    if ((flags & FLAG_RTPS_DATA_FRAG_K) != 0) {
        g_snprintf(label, 14, "serializedKey");
    }
    from_builtin_writer =
      (((wid & 0xc2) == 0xc2) || ((wid & 0xc3) == 0xc3)) ? TRUE : FALSE;

    guint32 frag_index_in_submessage = 0, this_frag_number = 0, this_frag_size = 0, fragment_offset = 0;
    gboolean more_fragments = FALSE;
    if (enable_rtps_reassembly) {
      tvbuff_t* new_tvb = NULL;
      fragment_head *frag_msg = NULL;
      while(frag_index_in_submessage < num_frags) {
        this_frag_number = frag_number + frag_index_in_submessage;
        more_fragments = (this_frag_number * frag_size < sample_size);
        this_frag_size = more_fragments ? frag_size : (sample_size - ((this_frag_number - 1) * frag_size));
        fragment_offset = this_frag_number == 1 ? 0 : (((this_frag_number - 1) * frag_size));
        pinfo->fragmented = TRUE;
        frag_msg = fragment_add_check(&rtps_reassembly_table,
            tvb, offset, pinfo,
            (guint32)sample_seq_number,  
            (void *)guid,  
            fragment_offset,  
            this_frag_size,  
            more_fragments);  

        new_tvb = process_reassembled_data(tvb, offset + (frag_index_in_submessage * frag_size), pinfo,
            "Reassembled sample", frag_msg, &rtps_frag_items,
            NULL, tree);

        if (frag_index_in_submessage == 0) {
          append_status_info(pinfo, wid, status_info);
          if (frag_msg) {  
            col_append_fstr(pinfo->cinfo, COL_INFO, " [Reassembled]");
          } else {  
            col_append_fstr(pinfo->cinfo, COL_INFO," [RTPS fragment]");
          }
        }

        if (new_tvb) {
            g_snprintf(label, 19, "reassembled sample");
            dissect_serialized_data(tree, pinfo, new_tvb, 0,
                sample_size, label, vendor_id, from_builtin_writer, guid, NOT_A_FRAGMENT);
            break;
        } else {
            g_snprintf(label, 15, "fragment [%d]", frag_index_in_submessage);
            dissect_serialized_data(tree, pinfo, tvb, offset + (frag_index_in_submessage * frag_size),
                this_frag_size, label, vendor_id, from_builtin_writer, NULL, this_frag_number);
        }
        frag_index_in_submessage++;
      }
    } else {
      while (frag_index_in_submessage < num_frags) {
        this_frag_number = frag_number + frag_index_in_submessage;
        more_fragments = (this_frag_number * frag_size < sample_size);
        this_frag_size = more_fragments ? frag_size : (sample_size - ((this_frag_number - 1) * frag_size));
        fragment_offset = frag_index_in_submessage * frag_size;
        g_snprintf(label, 20, "fragment [%d]", frag_index_in_submessage);
        dissect_serialized_data(tree, pinfo, tvb, offset + fragment_offset,
            this_frag_size, label, vendor_id, from_builtin_writer, NULL, this_frag_number);
        frag_index_in_submessage++;
        }
      append_status_info(pinfo, wid, status_info);
    }
  }
  rtps_util_detect_coherent_set_end_empty_data_case(&coherent_set_entity_info_object);
}